基于Java后台实现百度、高德和WGS84坐标的转换实战
目录
前言
一、需求的缘由
1、百度坐标拾取
2、高德坐标拾取
3、不同地图的坐标展示
二、后端坐标偏移转换处理
1、相关类库介绍
2、coordtransorm类图介绍
3、后台实际转换
三、总结
前言
在当今数字化时代,地理位置信息的精确性和实时性对于各种应用至关重要。其实在之前的博客中,我们曾将提到过高德AOI的位置偏移,也讲过如何来解决这些位置偏移带来的问题,基于Leaflet的高德AOI数据在天地图底图可视化纠偏实践。无论是地图导航、物流配送还是社交网络,都依赖于精确的地理坐标系统来提供服务。然而,不同的地图服务提供商,如百度地图、高德地图和国际上广泛使用的WGS84坐标系统,它们之间存在着坐标系的差异。这种差异给开发者在实现跨平台、跨服务的地理信息服务时带来了挑战。因此,掌握如何在这些不同的坐标系统之间进行转换,成为了后端开发人员的一项必备技能。在下图中详细演示了这种场景,以天地图底图为例,右边两个位置分别是百度和高德的位置,紫色的位置是正确的原始位置。
本文旨在探讨如何使用Java后台技术实现百度、高德和WGS84坐标之间的转换。我们将深入分析这些坐标系统的特点,以及它们之间的转换逻辑和算法。通过实战案例,我们将展示如何在Java环境中编写高效、可靠的坐标转换代码,以满足不同业务场景的需求。
首先,我们需要了解不同的坐标系统下,比如百度、高德的具体位置展示。然后在技术实现上,我们将探讨如何利用java来简化开发过程,提高开发效率。此外,本文还将分享一些在实际开发中遇到的常见问题及其解决方案,比如如何处理坐标转换中的精度问题、如何优化大规模坐标转换的性能等。通过这些实战经验的分享,我们希望能够帮助开发者在面对复杂的地理信息服务时,能够更加从容不迫。最后,随着技术的不断进步,坐标转换的方法和工具也在不断更新。本文将提供一个持续学习和探索的平台,鼓励开发者关注最新的技术动态,不断优化和升级自己的坐标转换解决方案,以适应不断变化的市场需求。
一、需求的缘由
说起一个在刚开始接触GIS时一位老同志讲的故事,虽然现在听起来有点不可思议。但是当时,说不定你也是抱有同样的疑问。故事的起因是这样,某公司要求一名工程师通过手机去采集车辆的轨迹信息,然后将轨迹信息放到地图中去展示。需求很简单,没什么复杂的。手机嘛,一般都是用的GPS的信息,底图有点意思。当时用户没有自己的离线地图,因此就尝试用高德地图作为他们的离线地图服务器。三下五除二,把坐标导出来,然后连接成一条线,接着二三并作五,再把生成的线叠加到地图上。本来以为手到擒来,可以汇报结果。可当一群人看到地图上的曲线傻眼了。明明自己只是过了一座桥,怎么在地图上跑河里去了。于是大家你一言,我一语的说。张三说,这是有人搞破坏,我们的数据被篡改了。有的说,发生了不可描述的事情,大家被带偏了。一时没有了主义。于是找到了一个大牛,将情况跟大佬说了一下。大佬听到了高德地图,眼神闪过一丝亮光,似乎有了答案,又卖了一个关子。
相信以上场景,对于半路出家的GISER同学来说,确实有点悬,明明是好的。来的时候明明走的陆地,怎么到这里却飞了呢?不是走的河里,就是穿墙而过。当你在这一行有了一定的经验后,一定会会心的一笑。那么我们先来使用地图来情景再现一下。当然,这里我们只是模拟,通过现象看本质。为了起到对比的作用,这里分别选用百度地图和高德地图的坐标拾取器来对同一个标志物(长沙市橘子洲景区的橘市文创店)进行拾取,然后将两者的坐标叠加到天地图中。来看看是在山上还是河里?
1、百度坐标拾取
首先我们打开百度地图的坐标拾取器地址百度地图坐标拾取器,然后缩放到我们的目标地点。如下所示:
首先当我们在地图上找到我们的目标点,即橘市文创店。然后点击鼠标的左键。在界面的右上角就有生成的当前选择地点的坐标位置。可以点击按钮实现复制。当前的坐标信息如下:
(112.967397, 28.172314)
在获取了百度的坐标之后,接下来我们尝试在高德地图上获取同一个位置的坐标。
2、高德坐标拾取
与百度地图一样,高德地图也提供的坐标拾取的功能,它的官方地址是:高德坐标拾取器。依然选择缩放到橘市文创店附近,如下图所示:
最终得到的高德坐标为:
(112.960922, 28.166447)
到这里,可能您并不觉得他们有什么问题,因为我们还没有把他们放到一起来进行展示。是骡子是马,是该拉出来溜溜。因此下面我们统一将他们放到天地图中进行展示。
3、不同地图的坐标展示
为了解决工作量,也为了有统一展示的效果。我们将采集到的百度坐标和高德坐标进行统一展示。展示组件依然选用Leaflet。Leaflet展示点的关键代码如下:
// 待标绘的点
var dataJson = [{lat:28.172314,lon:112.967397,name:"橘市文创店-百度坐标(转换前)",color:"#aba021"},{lat:28.166447,lon:112.960922,name:"橘市文创店-高德坐标(转换前)",color:"#21abab"}
];for(var i=0;i<dataJson.length;i++){L.marker([dataJson[i].lat, dataJson[i].lon], {icon: L.divIcon({iconSize: null,className: '',popupAnchor:[5,5],shadowAnchor:[5,5],html: "<div class='marsBlackPanel' animation-spaceInDown style='background:"+dataJson[i].color+"'>"+"<div class='marsBlackPanel-text' style=''>"+dataJson[i].name+"</div>"+"<div class='marsBlackPanel-text' style=''>经度:"+dataJson[i].lon+"</div>"+"<div class='marsBlackPanel-text' style=''>经度:"+dataJson[i].lat+"</div>"+"</div>"})}).addTo(map);
}
首先来看一下这时的效果:
是不是符合你的预期呢?将百度的坐标和高德的坐标叠加在天地图的底图上,你会惊奇的发现。点居然跑了。不在我们预期的橘子洲头的位置。而且,百度的坐标偏的更厉害。这也就解释了什么事二次偏移。在高德的偏移上还加了自己的偏移。 到这里,能理解为什么GPS的信息,可能到了高德这里,会跑到河里了吧。
遇到问题不可怕,下面我们来解决问题。之前我们曾经分享过了如何在Javascript前端来解决,下面我们来介绍如何使用后端的方式来进行处理。
二、后端坐标偏移转换处理
在之前的博客中,我们介绍了使用JavaScript前端的方式来进行坐标的转换。这种方式在前端使用普遍,而且能很好的与前端开发语言进行结合。但是缺点也同样的明显,很多场景中,我们需要在后台进行数据的处理,比如某接口调用的是百度或者高德的地图的API接口。通过这些API接口得到的坐标都是对应平台的。通过前面的博客可以得知,其坐标在不同的平台有不同的偏移。因此急需在后台来进行相应的坐标转换。同时,我们还可以在后台以接口的形式提供对外服务,提供坐标转换的服务。因此本节来具体介绍如何在后台,以java语言为例,详细介绍如何进行坐标偏移转换。
1、相关类库介绍
这里提供一个开源的java坐标转换组件。不再进行重复造轮子。为了让大家熟悉相关的组件和方法,这里还是对组件进行简单的介绍。coordtransform java实现。
这个组件主要提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换的工具模块 (参考wandergis的python版coordtransform的Java版实现)。也是我们在后台进行坐标转换的主要方法。
2、coordtransorm类图介绍
左边转换的类比较简单,这里采用面向对象的方法对它的类图进行介绍,让大家对转换组件有一个详细的认识。类图结构如下所示:
属性列表:
序号 | 参数 | 参数说明 |
1 | x_pi | 3.14159265358979324 * 3000.0 / 180.0 |
2 | π | 3.1415926535897932384626 |
3 | a | 长半轴,6378245.0 |
4 | ee | 扁率,0.00669342162296594323 |
方法列表:
序号 | 方法名 | 方法说明 | 参数说明 |
1 | bd09towgs84 | 百度坐标系(BD-09)转WGS坐标 | 百度坐标经纬度 |
2 | wgs84tobd09 | WGS坐标转百度坐标系(BD-09) | WGS84坐标系的经纬度 |
3 | gcj02tobd09 | 火星坐标系(GCJ-02)转百度坐标系(BD-09) | 火星坐标系经纬度 |
4 | bd09togcj02 | 百度坐标系(BD-09)转火星坐标系(GCJ-02) | 百度坐标系经纬度 |
5 | wgs84togcj02 | WGS84转GCJ02(火星坐标系) | WGS84坐标系的经纬度 |
6 | gcj02towgs84 | GCJ02(火星坐标系)转GPS84 | 火星坐标系经纬度 |
7 | transformlat | 纬度转换 | |
8 | transformlng | 经度转换 | |
9 | out_of_china | 判断是否在国内,不在国内不做偏移 |
在掌握了以上的参数和方法之后,下面我们使用Java开发语言在后台来进行相关坐标的转换与转换。
3、后台实际转换
下面根据第一章中采集的百度和高德坐标,在后台分别进行相应的转换。变成我们需要的WGS84坐标后,然后我们在天地图中进行WebGIS展示。
public static void main(String[] args) {double [] bd284 = CoordinateTransformUtil.bd09towgs84(112.967397D, 28.172314D);System.out.println("百度坐标转wgs84坐标" + bd284[0] + "=" + bd284[1]);double [] gcj284 = CoordinateTransformUtil.gcj02towgs84(112.960922D, 28.166447D);System.out.println("高德坐标转wgs84坐标" + gcj284[0] + "=" + gcj284[1]);
}
在控制台中看到以下的转换结果,如下所示:
百度坐标转wgs84坐标112.95536764126244=28.16996238135615
高德坐标转wgs84坐标112.95541908168103=28.16990747088316
单从转换后的结果可以看到,两个坐标的值是非常接近的。稍微有点偏差,这可能与我们在实际拾取坐标时有一定的偏差。将转换后的坐标在Leaflet中进行展示。关键代码如下:
// 待标绘的点
var dataJson = [{lat:28.172314,lon:112.967397,name:"橘市文创店-百度坐标(转换前)",color:"#aba021"},{lat:28.166447,lon:112.960922,name:"橘市文创店-高德坐标(转换前)",color:"#21abab"},{lat:28.16996238135615,lon:112.95536764126244,name:"橘市文创店-百度坐标(转换后)",color:"#b91980"},{lat:28.16990747088316,lon:112.95541908168103,name:"橘市文创店-高德坐标(转换后)",color:"#b91980"}
];
最后来看一下经过转换后的坐标在天地图中的位置展示如下:
可以看到,经过纠偏后的坐标基本实现了还原,有一点的误差,大概率是我们在拾取时可能手抖了导致的。忽略这个误差,说明我们的转换结果符合我们的需求。至此,基于后台来进行相关坐标的转换就已经实现。
三、总结
以上就是本文的主要内容,本文旨在探讨如何使用Java后台技术实现百度、高德和WGS84坐标之间的转换。我们将深入分析这些坐标系统的特点,以及它们之间的转换逻辑和算法。通过实战案例,我们将展示如何在Java环境中编写高效、可靠的坐标转换代码,以满足不同业务场景的需求。行文藏度,定有诸多不足之处,如有不足,还恳请各位专家朋友在评论区批评指出,不胜感激。文章重点在讲解偏移的出现场景,通过场景的还原让大家了解不同的坐标展示效果,同时为下一步进行转换奠定基础。关于java的转换代码,完全是开源的,大家可以根据需要集成到自己的gis系统当中。
参考地址:coordtransform java转换
相关文章:

基于Java后台实现百度、高德和WGS84坐标的转换实战
目录 前言 一、需求的缘由 1、百度坐标拾取 2、高德坐标拾取 3、不同地图的坐标展示 二、后端坐标偏移转换处理 1、相关类库介绍 2、coordtransorm类图介绍 3、后台实际转换 三、总结 前言 在当今数字化时代,地理位置信息的精确性和实时性对于各种应用至…...

SQL,力扣题目1635,Hopper 公司查询 I
一、力扣链接 LeetCode_1635 二、题目描述 表: Drivers ---------------------- | Column Name | Type | ---------------------- | driver_id | int | | join_date | date | ---------------------- driver_id 是该表的主键(具有唯一值的列)。 该表的每一行…...

Android 分区相关介绍
目录 一、MTK平台 1、MTK平台分区表配置 2、MTK平台刷机配置表 3、MTK平台分区表配置不生效 4、Super分区的研究 1)Super partition layout 2)Block device table 二、高通平台 三、展锐平台 四、相关案例 1、Super分区不够导致编译报错 经验…...

JMeter监听器与压测监控之 InfluxDB
1. 简介 在本文中,我们将介绍如何在 Kali Linux 上通过 Docker 安装 InfluxDB,并使用 JMeter 对其进行性能监控。InfluxDB 是一个高性能的时序数据库,而 JMeter 是一个开源的性能测试工具,可以用于对各种服务进行负载测试和性能监…...

信息安全管理与评估赛项(网络安全)--应急响应专项训练
web1 题目来源:https://mp.weixin.qq.com/s/89IS3jPePjBHFKPXnGmKfA 题目 1.攻击者的shell密码2.攻击者的IP地址3.攻击者的隐藏账户名称4.攻击者挖矿程序的矿池域名(仅域名)5.有实力的可以尝试着修复漏洞靶机 用户:administrator密码:Zgsfadmin.com题解 攻击者…...

ElasticSearch学习篇18_《检索技术核心20讲》LevelDB设计思想
目录 一些常见的设计思想以及基于LSM树的LevelDB是如何利用这些设计思想优化存储、检索效率的。 几种常见的设计思想 索引和数据分离减少磁盘IO读写分离分层思想 LevelDB的设计思想 读写分离设计分层设计与延迟合并LRU缓存加速检索 几种常见设计思想 索引与数据分离 索引…...

使用 FFmpeg 提取音频的详细指南
FFmpeg 是一个开源的多媒体处理工具,支持视频、音频的编码、解码、转换等多种功能。通过 FFmpeg,提取视频中的音频并保存为各种格式非常简单和高效。这在音视频剪辑、媒体处理、转码等场景中具有广泛的应用。 本文将详细讲解如何使用 FFmpeg 提取音频&a…...

中国省级新质生产力发展指数数据(任宇新版本)2010-2023年
一、测算方式:参考C刊《财经理论与实践》任宇新(2024)老师的研究,新质生产力以劳动者劳动资料劳动对象及其优化组合的质变为 基本内涵,借 鉴 王 珏 和 王 荣 基 的 做 法构建新质生产力发展水平评价指标体系如下所示&a…...

C++设计模式:建造者模式(Builder) 房屋建造案例
什么是建造者模式? 建造者模式是一种创建型设计模式,它用于一步步地构建一个复杂对象,同时将对象的构建过程与它的表示分离开。简单来说: 它将复杂对象的“建造步骤”分成多部分,让我们可以灵活地控制这些步骤。通过…...

Python 快速入门(上篇)❖ Python基础知识
Python 基础知识 Python安装**运行第一个程序:基本数据类型算术运算符变量赋值操作符转义符获取用户输入综合案例:简单计算器实现Python安装** Linux安装: yum install python36 -y或者编译安装指定版本:https://www.python.org/downloads/source/ wget https://www.pyt…...

string接口的模拟实现
文章目录 一. string底层逻辑演示声明和定义分开 二. size()三. operator[]四. 迭代器四. const迭代器五. 预留空间(reserve)六. 尾插一个字符push_back七. 尾插一个字符串append八. operator九. operator 一. string底层逻辑 (1)为了和库里面…...

sed使用扩展正则表达式时, -i 要写在 -r 或 -E 的后面
sed使用扩展正则表达式时, -i 要写在 -r 或 -E 的后面 前言 -r 等效 -E , 启用扩展正则表达式 -E是新叫法,更统一,能增强可移植性 , 但老系统,比如 CentOS-7 的 sed 只能用 -r ### Ubuntu24.04-E, -r, --regexp-extendeduse extended regular expressions in the script(fo…...

Verilog HDL可综合与不可综合语句
目录 什么是逻辑综合 可综合语句 不可综合语句 逻辑综合建模建议 综合流程 什么是逻辑综合 所谓逻辑综合就是在标准单元库和特定的设计约束的基础上,把设计的高层次描述转换成优化的门级网表的过程。 标准单元库(工艺库)可以包含简单的…...

tomcat 后台部署 war 包 getshell
1. tomcat 后台部署 war 包 getshell 首先进入该漏洞的文件目录 使用docker启动靶场环境 查看端口的开放情况 访问靶场:192.168.187.135:8080 访问靶机地址 http://192.168.187.135:8080/manager/html Tomcat 默认页面登录管理就在 manager/html 下,…...

网络云计算】2024第47周-每日【2024/11/21】周考-实操题-RAID6实操解析1
文章目录 1、RAID6配置指南(大致步骤)2、注意事项3、截图和视频 网络云计算】2024第47周-每日【2024/11/21】周考-实操题-RAID6实操 RAID6是一种在存储系统中实现数据冗余和容错的技术,其最多可以容忍两块磁盘同时损坏而不造成数据丢失。RAID…...

前端面试题大汇总:React 篇
基础知识 1. 什么是 React?它的主要特点是什么? React 是一个用于构建用户界面的 JavaScript 库,由 Facebook 开发并维护。它主要用于构建单页应用程序(SPA)和复杂的用户界面。React 的主要特点包括: 组件…...

【prism】遇到一个坑,分享!
背景 我通用prism的方式写了一个弹窗,弹窗绑定一个 Loaded 事件,但是Loaded事件一直不触发!!! 具体过程 我的loaded事件也是通过命令的方式绑定的: <i:Interaction.Triggers><i:EventTrigger EventName="Loaded...

Python+Selenium+Pytest+Allure+ Jenkins webUI自动化框架
Python+Selenium+Pytest+Allure+ Jenkins webUI自动化框架 WebUI接口框架使用的工具...

智象未来(HiDream.ai)技术赋能,开启AR眼镜消费时代
Rokid Jungle 2024合作伙伴暨新品发布会于近日隆重举行,标志着AR眼镜跑步进入消费时代,更预示着ARAI技术融合的新篇章。智象未来(HiDream.ai),作为多模态生成式人工智能技术的领跑者,与Rokid的深度合作&…...

element dialog 2层弹窗数据同步问题
注意:本帖为公开技术贴,不得用做任何商业用途 element dialog 2层弹窗数据同步问题 如果嵌套dialog,也就是多层dialog嵌套 2个input,key用同样的值 会导致内外2层dialog,用相同key值的input会数据同步 原因如下&a…...

向量数据库FAISS之五:原理(LSH、PQ、HNSW、IVF)
1.Locality Sensitive Hashing (LSH) 使用 Shingling MinHashing 进行查找 左侧是字典,右侧是 LSH。目的是把足够相似的索引放在同一个桶内。 LSH 有很多的版本,很灵活,这里先介绍第一个版本,也是原始版本 Shingling one-hot …...

要素市场与收入分配
生产要素与家庭收入 生产要素:企业用于生产产品或劳务的最初投入,主要分为三类: 劳动:工人的时间和技能 土地:代指自然资源 资本:指的是货币形式的资本,可以供企业用来购置厂房、设备等资本品…...

Web3的核心技术:区块链如何确保信息安全与共享
在互联网不断迭代的进程中,Web3被视为下一代互联网的核心发展方向,其目标是构建更加开放、安全、去中心化的数字生态。在这一过程中,区块链作为核心技术,为信息安全与共享提供了全新解决方案。本文将深入探讨区块链如何在Web3中实…...

2025蓝桥杯(单片机)备赛--扩展外设之UART1的原理与应用(十二)
一、串口1的实现原理 a.查看STC15F2K60S2数据手册: 串口一在590页,此款单片机有两个串口。 串口1相关寄存器: SCON:串行控制寄存器(可位寻址) SCON寄存器说明: 需要PCON寄存器的SMOD0/PCON.6为0,使SM0和SM1一起指定工作模式,这里选择工作模式1,REN位置1,允许接受, …...

Js中的常见全局函数
文章目录 1、encodeURI、decodeURI2、encodeURIComponent、decodeURIComponent3、parseInt4、parseFloat5、String6、Number7、Boolean8、isNaN、Number.isNaN()9、JSON10、toString Js内置了一些函数和变量,全局都可以获取使用(本文归纳非构造函数作用的…...

MySQL连接查询之自连接
自连接 相当于等值连接,只不过是自己连接自己,不像等值连接是两个不同的表之间的 案例 查询员工名和他的上司的名字 select e.last_name,m.last_name from employees e, employees m #把同一张表当成两张不同表 where e.manager_id m.employee_id;...

Python 爬虫 (1)基础 | 基础操作
一、基础操作 1、快速构建一个爬虫 ConvertCurl: https://curlconverter.com/选择URL,点击右键,选择 Copy >> Copy as cURL(bash) 安装JS环境:https://www.jb51.net/python/307069k7q.htm...

JAVA八股与代码实践----如何为springboot设置Servlet容器为jetty,jetty的优点是什么?
1、实践 排除原来的springboot-web依赖(默认是tomcat),加入jetty的依赖 <dependencies><!-- Spring Boot Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-s…...

idea怎么打开两个窗口,运行两个项目
今天在开发项目的时候,前端希望运行一下以前的项目,于是就需要开两个 idea 窗口,运行两个项目 这里记录一下如何设置:首先依次点击: File -> Settings -> Appearance & Behavior ->System Settings 看到如…...

wend看源码-APISJON
项目地址 腾讯APIJSON官方网站 定义 APIJSON 可以定义为一个面向HTTP 协议的JSON 规范,一个面向数据访问层的ORM 框架。其主要工作流程包括:前端按照既定格式组装 JSON 请求报文,通过 APIJSON-ORM 将这些报文直接转换为 SQL 语句,…...