基于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…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...