基于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…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
