当前位置: 首页 > news >正文

一文讲清楚地图地理坐标系

在这里插入图片描述

前言

我最近在做一个和地图有关的项目,这里本人地图采用的是mapbox,其中涉及一个功能需要根据用户输入的地点直接定位到地图上的对应的位置,本人开始想的是直接调用百度的接口根据地名直接获取坐标,发现在地图上的位置有偏移不够准确,后面发现地图服务之间有自己的坐标系,不同的坐标系之间的坐标会有一定的偏移。

地图的地理坐标系

是一种球面坐标,是使用三维球面来定义地球表面位置,以实现通过经纬度对地球表面点位引用的坐标系,也就是说坐标单位是经纬度。
在这里插入图片描述

地球坐标系(WGS84)

GPS,WGS-84,原始坐标体系。一般用国际标准的GPS记录仪记录下来的坐标,都是GPS的坐标。也是国际地图提供商使用的坐标系。但是在中国,任何一个地图产品都不允许使用GPS坐标,据说是为了保密。

使用该坐标系的在线地图

wgs84是国际标准坐标系,谷歌国外地图、osm地图等国外地图一般是这个

火星坐标系(GCJ-02)

国测局02年发布的坐标体系。又称“火星坐标”。中国标准,从国行移动设备中定位获取的坐标数据使用这个坐标系。在中国,必须至少使用GCJ-02的坐标体系。

使用该坐标系的在线地图

IOS地图、谷歌国内地图、高德地图、腾讯地图

百度坐标系(BD-09)

百度又在火星坐标上来个二次加密,只适用于百度地图

使用该坐标系的在线地图

只有百度地图
在这里插入图片描述

天地图坐标系(CGCS-2000)

天地图采用的是CGCS-2000坐标系(2000坐标系),但是因为CGCS-2000坐标系它与WGS84坐标系都是地心坐标系,因此两者相差不大。
天地图官网:https://map.tianditu.gov.cn/
在这里插入图片描述

坐标系转换

如果像我这种情况一样地图是wgs84,却用了百度地图接口返回的坐标来定位,可以对不同坐标系的坐标进行转换。下面是转换代码:

const x_pi = 3.14159265358979324 * 3000.0 / 180.0;
const pi = 3.1415926535897932384626;
const a = 6378245.0;
const ee = 0.00669342162296594323;/*** 百度坐标系(BD-09)转WGS坐标* @param {number} lng - 百度坐标纬度* @param {number} lat - 百度坐标经度* @returns {Array} - WGS84坐标数组 [lng, lat]*/
function bd09towgs84(lng, lat) {const gcj = bd09togcj02(lng, lat);const wgs84 = gcj02towgs84(gcj[0], gcj[1]);return wgs84;
}/*** WGS坐标转百度坐标系(BD-09)* @param {number} lng - WGS84坐标系的经度* @param {number} lat - WGS84坐标系的纬度* @returns {Array} - 百度坐标数组 [lng, lat]*/
function wgs84tobd09(lng, lat) {const gcj = wgs84togcj02(lng, lat);const bd09 = gcj02tobd09(gcj[0], gcj[1]);return bd09;
}/*** 火星坐标系(GCJ-02)转百度坐标系(BD-09)* @param {number} lng - 火星坐标经度* @param {number} lat - 火星坐标纬度* @returns {Array} - 百度坐标数组 [lng, lat]*/
function gcj02tobd09(lng, lat) {const z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_pi);const theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_pi);const bd_lng = z * Math.cos(theta) + 0.0065;const bd_lat = z * Math.sin(theta) + 0.006;return [bd_lng, bd_lat];
}/*** 百度坐标系(BD-09)转火星坐标系(GCJ-02)* @param {number} bd_lon - 百度坐标经度* @param {number} bd_lat - 百度坐标维度* @returns {Array} - 火星坐标数组 [lng, lat]*/
function bd09togcj02(bd_lon, bd_lat) {const x = bd_lon - 0.0065;const y = bd_lat - 0.006;const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);const gg_lng = z * Math.cos(theta);const gg_lat = z * Math.sin(theta);return [gg_lng, gg_lat];
}/*** WGS84转GCJ02(火星坐标系)* @param {number} lng - WGS84坐标系的经度* @param {number} lat - WGS84坐标系的纬度* @returns {Array} - 火星坐标数组 [lng, lat]*/
function wgs84togcj02(lng, lat) {if (out_of_china(lng, lat)) {return [lng, lat];}let dlat = transformlat(lng - 105.0, lat - 35.0);let dlng = transformlng(lng - 105.0, lat - 35.0);const radlat = lat / 180.0 * pi;let magic = Math.sin(radlat);magic = 1 - ee * magic * magic;const sqrtmagic = Math.sqrt(magic);dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi);const mglat = lat + dlat;const mglng = lng + dlng;return [mglng, mglat];
}/*** GCJ02(火星坐标系)转GPS84* @param {number} lng - 火星坐标系的经度* @param {number} lat - 火星坐标系纬度* @returns {Array} - WGS84坐标数组 [lng, lat]*/
function gcj02towgs84(lng, lat) {if (out_of_china(lng, lat)) {return [lng, lat];}let dlat = transformlat(lng - 105.0, lat - 35.0);let dlng = transformlng(lng - 105.0, lat - 35.0);const radlat = lat / 180.0 * pi;let magic = Math.sin(radlat);magic = 1 - ee * magic * magic;const sqrtmagic = Math.sqrt(magic);dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi);const mglat = lat + dlat;const mglng = lng + dlng;return [lng * 2 - mglng, lat * 2 - mglat];
}/*** 纬度转换* @param {number} lng* @param {number} lat* @returns {number}*/
function transformlat(lng, lat) {let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lat * pi) + 40.0 * Math.sin(lat / 3.0 * pi)) * 2.0 / 3.0;ret += (160.0 * Math.sin(lat / 12.0 * pi) + 320 * Math.sin(lat * pi / 30.0)) * 2.0 / 3.0;return ret;
}/*** 经度转换* @param {number} lng* @param {number} lat* @returns {number}*/
function transformlng(lng, lat) {let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lng * pi) + 40.0 * Math.sin(lng / 3.0 * pi)) * 2.0 / 3.0;ret += (150.0 * Math.sin(lng / 12.0 * pi) + 300.0 * Math.sin(lng / 30.0 * pi)) * 2.0 / 3.0;return ret;
}/*** 判断是否在国内,不在国内不做偏移* @param {number} lng* @param {number} lat* @returns {boolean}*/
function out_of_china(lng, lat) {if (lng < 72.004 || lng > 137.8347) {return true;} else if (lat < 0.8293 || lat > 55.8271) {return true;}return false;
}

当然了,最好还是在开发前先调研清楚地图的坐标系,并去使用相同坐标系的地图接口服务。

总结

这是本人第一次开发地图相关功能,也不太了解坐标系这一概念,导致在开发定位功能时位置有所偏差,经过这次学习,了解到了地图的地理坐标系的概念以及不同地理坐标系的区别,才发现定位位置偏移的问题所在,以后开发功能前也需要更详细的去调研每块领域的相关知识。

参考
https://www.jianshu.com/p/a5ebaa859ca1
http://t.csdn.cn/IiuP2

相关文章:

一文讲清楚地图地理坐标系

前言 我最近在做一个和地图有关的项目&#xff0c;这里本人地图采用的是mapbox&#xff0c;其中涉及一个功能需要根据用户输入的地点直接定位到地图上的对应的位置&#xff0c;本人开始想的是直接调用百度的接口根据地名直接获取坐标&#xff0c;发现在地图上的位置有偏移不够…...

助力青少年科技创新人才培养,猿辅导投资1亿元设立新基金

近日&#xff0c;在日本千叶县举办的2023年第64届国际数学奥林匹克&#xff08;IMO&#xff09;竞赛公布比赛结果&#xff0c;中国队连续5年获得团体第一。奖牌榜显示&#xff0c;代表中国参赛的6名队员全部获得金牌。其中&#xff0c;猿辅导学员王淳稷、孙启傲分别以42分、39分…...

代码随想录算法训练营之JAVA|第十八天| 235. 二叉搜索树的最近公共祖先

今天是第 天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天&#xff0c;如果做不到&#xff0c;完成一件评论区点赞最高的挑战。 算法挑战链接 235. 二叉搜索树的最近公共祖先https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/descriptio…...

IO进程线程第五天(8.2)进程函数+XMind(守护进程(幽灵进程),输出一个时钟,终端输入quit时退出时钟)

1.守护进程&#xff08;幽灵进程&#xff09; #include<stdio.h> #include<head.h> int main(int argc, const char *argv[]) {pid_t cpid fork();if(0cpid){ //创建新的会话pid_t sidsetsid();printf("sid%d\n",sid);//修改运行目录为不可卸载的文件…...

物联网远程智能控制设备——开关量/正反转百分比控制

如今生产生活的便利性极大程度上得益于控制技术的发展&#xff0c;它改变了传统的工作模式&#xff0c;并将人们从【纯劳力】中解放出来。如今&#xff0c;随着科学技术的进步&#xff0c;控制器的种类及应用领域也越来越多。 物联网远程智能控制设备就是一种新型的、能够用于…...

echarts图表基本使用

折线图 import * as echarts from echarts;const chartDom document.getElementById(main); const myChart echarts.init(chartDom); const option {xAxis: {type: category,data: [Mon, Tue, Wed, Thu, Fri, Sat, Sun]},yAxis: {type: value},series: [{data: [820, 932, …...

排序进行曲-v1.0

排序 排序是将一组数据按照一定的规则进行排列的过程。在计算机科学中&#xff0c;排序是一 种常见的算法问题&#xff0c;通常用于对数据进行整理、查找、统计等操作。概念解读 基本概念 排序算法&#xff1a;排序算法是实现数据排序的具体方法。常见的排序算法包括冒泡排序…...

算法入门篇——用位运算解决一些问题

目录 1.判断一个数是2的次方数 2.统计一个数&#xff0c;它的二进制数中&#xff0c;1的个数 3.在2*&#xff08;n-1&#xff09;个数中&#xff0c;找到只出现一次的那个数 1.判断一个数是2的次方数 这个问题有好几种做法&#xff0c;但是最优雅的解法是用’位运算‘来做。…...

腾讯云-宝塔添加MySQL数据库

1. 数据库菜单 2. 添加数据库 3. 数据库添加成功 4. 上传数据库文件 5. 导入数据库文件 6. 开启数据库权限 7. 添加安全组 (宝塔/腾讯云) 8. Navicat 连接成功...

【雕爷学编程】MicroPython动手做(27)——物联网之掌控板小程序

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…...

Mysql删除重复数据通用SQL

在日常开发过程中&#xff0c;可能会出现一些 bug&#xff0c;导致 Mysql 数据库数据重复&#xff0c;需要删除重复数据&#xff0c;这里记录下删除重复数据的通用 SQL &#xff0c;方便以后需要时查阅 1、写法一 DELETE t1 FROMtbl_name t1 INNER JOIN tbl_name t2 WHEREt1.…...

“快速入门Spring Boot:从零开始构建Web应用程序“

标题&#xff1a;快速入门Spring Boot&#xff1a;从零开始构建Web应用程序 摘要&#xff1a;本文将介绍如何使用Spring Boot从零开始构建一个简单的Web应用程序。我们将学习如何配置和启动Spring Boot应用程序&#xff0c;创建控制器和路由&#xff0c;以及如何使用模板引擎来…...

微信小程序tab加列表demo

一、效果 代码复制即可使用&#xff0c;记得把图标替换成个人工程项目图片。 微信小程序开发经常会遇到各种各样的页面组合&#xff0c;本demo为list列表与tab组合&#xff0c;代码如下&#xff1a; 二、json代码 {"usingComponents": {},"navigationStyle&q…...

深入挖掘地核和地幔之间的相互作用

一本新书介绍了我们在理解地核-地幔相互作用和共同进化方面的重大进展&#xff0c;并展示了提高我们对地球深层过程的洞察力的技术发展。 与地核-地幔共同演化相关的地球深层结构和动力学的图示。图片来源&#xff1a;白石千寻 Editors Vox是 AGU 出版部的博客。 地球深层内部很…...

网络:SecureCRT介绍

1. 使用Tab键补全时出现^I&#xff0c;如下操作...

我的512天创作纪念日

眼馋csdn发的虚拟徽章&#xff0c;所以写此文。个人总结&#xff0c;无技术分享。 机缘 写代码的机缘&#xff0c;在于听说这个挣钱多&#xff0c;坐办公室&#xff0c;凤吹不着&#xff0c;雨淋不着。 而写blog的机缘&#xff0c;则在于是自己的技术的总结&#xff0c;经常是…...

mysql进阶-用户密码的设置和管理

一、修改密码 1.1 修改自己的密码 方式一&#xff1a; 推荐使用 alter user user() identified by 新密码;方式二&#xff1a; set password 新密码;演示 [rootVM-4-6-centos /]# mysql -uzhang3 -pZhangSan123456 mysql: [Warning] Using a password on the command line…...

2023年最新智能优化算法之——切诺贝利灾难优化器 (CDO),附MATLAB代码和文献

切诺贝利灾难优化器Chernobyl Disaster Optimizer (CDO)是H. Shehadeh于2023年提出的新型智能优化算法。该方法是受到切尔诺贝利核反应堆堆芯爆炸而来的启发。在CDO方法中&#xff0c;放射性的发生是由于核的不稳定性&#xff0c;核爆炸会发出不同类型的辐射。这些辐射中最常见…...

uniapp跨域解决

uniapp跨域解决 跨域是什么 跨域指的是浏览器不能执行其他网站的脚本&#xff0c;当一个网页去请求另一个域名的资源时&#xff0c;域名、端口、协议任一不同&#xff0c;就会存在跨域。跨域是由浏览器的同源策略造成的&#xff0c;是浏览器对JavaScript施加的安全限制。 报错…...

力扣-94、144、145-前中后序遍历

二叉树遍历方法总结 二叉树的遍历总体上分为深度优先遍历和广度优先遍历。常见的前中后序三种遍历方式就属于深度优先遍历&#xff0c;遍历过程中是顺着一条路径一直遍历到空节点然后向上回溯继续顺着遍历上一个节点的其他方向。层序遍历属于广度优先遍历&#xff0c;先遍历完同…...

6款高效降AI率工具 改写实力出众

写论文时反复检测出的AI痕迹总让你提心吊胆&#xff1f;别担心&#xff0c;这里整理了6款真正好用的论文降AI率工具&#xff0c;堪称应对AI生成特征的“得力助手”。它们能有效识别并消除AI生成的痕迹&#xff0c;改写能力出众&#xff0c;帮你快速降低查重率&#xff0c;顺利通…...

航空航天为什么离不开高强镁合金?国产替代到哪一步了

飞机每减重一千克&#xff0c;全年大约节省四千两百美元的燃油费用——这是航空工程师熟悉的经验值。在商业航空领域&#xff0c;这个数字还只是财务账&#xff1b;在战斗机、导弹和卫星的世界里&#xff0c;减重的收益被换算成更远的航程、更大的载荷、更高的机动性&#xff0…...

LizzieYzy:你的智能围棋教练,让AI分析变得简单有趣 [特殊字符]

LizzieYzy&#xff1a;你的智能围棋教练&#xff0c;让AI分析变得简单有趣 &#x1f3af; 【免费下载链接】lizzieyzy LizzieYzy - GUI for Game of Go 项目地址: https://gitcode.com/gh_mirrors/li/lizzieyzy 还在为复盘找不到关键点而烦恼吗&#xff1f;想提升棋力却…...

16个分片+2副本:pg_shard的master_create_worker_shards最佳实践

16个分片2副本&#xff1a;pg_shard的master_create_worker_shards最佳实践 【免费下载链接】pg_shard ATTENTION: pg_shard is superseded by Citus, its more powerful replacement 项目地址: https://gitcode.com/gh_mirrors/pg/pg_shard pg_shard作为PostgreSQL的分…...

MeloTTS实战指南:解决多语言TTS部署中的核心挑战

MeloTTS实战指南&#xff1a;解决多语言TTS部署中的核心挑战 【免费下载链接】MeloTTS High-quality multi-lingual text-to-speech library by MyShell.ai. Support English, Spanish, French, Chinese, Japanese and Korean. 项目地址: https://gitcode.com/GitHub_Trendin…...

【C++】零基础入门 · 第 6 节:数组

上一节我们学习了函数,知道了如何把代码封装起来方便复用。但在实际编程中,你很快就会遇到一个问题:如果要存储 100 个学生的成绩,难道要定义 100 个变量吗?这显然不现实。数组就是 C++ 给出的答案——它让我们能用一个变量名管理一组相同类型的数据。 1. 为什么需要数组…...

智能烹饪助手:基于传感器融合与AI的厨房自动化实践

1. 项目概述&#xff1a;一个让厨房小白也能自信下厨的智能伙伴每次站在灶台前&#xff0c;你是不是也经历过这样的场景&#xff1a;一边手忙脚乱地翻着菜谱&#xff0c;一边担心锅里的菜是不是快糊了&#xff0c;还要分心去计算各种调料该放多少&#xff1f;对于很多刚接触烹饪…...

SpringBoot WebClient 介绍

目录一、什么是 WebClient&#xff1f;二、 WebClient 能解决什么问题&#xff1f;三、WebClient 和 RestTemplate 的区别四、WebClient 的核心优势1. 非阻塞&#xff08;Non-Blocking&#xff09;2. 支持异步3. 链式 API 更现代五、WebClient 的核心对象六、Mono 和 Flux 是什…...

第5章 薪资重构——AI时代的程序员价值重估

第5章 薪资重构——AI时代的程序员价值重估 核心问题:AI时代,程序员的薪资会发生怎样的变化?哪些人在涨薪?哪些人在降薪? 5.1 问题定义:薪资分化的真相是什么? 5.1.1 一个令人震惊的数据 2026年第一季度,一个对比让整个技术圈哗然: 同一家公司内部: - 一个AI方向…...

DeepSeek代码审查配置避坑清单:12个被99%团队忽略的关键参数(含生产环境校验脚本)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;DeepSeek代码审查功能概览 DeepSeek 提供的代码审查&#xff08;Code Review&#xff09;能力基于其大语言模型对编程语义、安全规范与工程实践的深度理解&#xff0c;支持多语言静态分析、漏洞识别、可…...