地图坐标系之间的转换(百度地图、GCJ、WGS84)

您所在的位置:网站首页 百度地图地点坐标 地图坐标系之间的转换(百度地图、GCJ、WGS84)

地图坐标系之间的转换(百度地图、GCJ、WGS84)

2024-07-02 08:51:37| 来源: 网络整理| 查看: 265

文章目录 文章参考坐标系介绍常见坐标系WGS84坐标系(标准的GPS坐标)WGS84 Web墨卡托(平面地图)GCJ02经纬度投影(火星坐标系)GCJ02 Web 墨卡托投影BD09 经纬度投影 常用坐标系区分? 地图偏移为什么要地图偏移?偏移在哪里?地图做了偏移,为什么地图定位很精准(百度地图说明) 坐标转换为什么要做坐标转换地图服务(后台地图引擎可提供的能力)TMS——Tile Map Service 即TMS,切片地图服务WMTS——Web Map Tile Service即WMTS,网络地图切片服务,WMS——Web Map Service,网络地图服务 常用坐标系的转换工具(百度地图、GCJ、WGS84)

文章参考 常用的几种在线地图(天地图、百度地图、高德地图)坐标系之间的转换算法 坐标系介绍 常见坐标系 WGS84坐标系(标准的GPS坐标)

GPS,WGS-84,原始坐标体系。一般用国际标准的GPS记录仪记录下来的坐标,都是GPS的坐标。

在这里插入图片描述

EPSG:4326 与WGS84的关系? 在国际上,每个坐标系统都会被分配一个 EPSG 代码,EPSG:4326 就是 WGS84 的代码

WGS84 Web墨卡托(平面地图)

EPSG:3857(WGS 84 / Pseudo-Mercator) 代号是web墨卡托的正式代号

在这里插入图片描述

GCJ02经纬度投影(火星坐标系)

GCJ-02是由中国国家测绘局(G表示Guojia国家,C表示Cehui测绘,J表示Ju局)制订的地理信息系统的坐标系统。

GCJ-02是国测局02年发布的坐标体系。又称“火星坐标”

这里的GCJ02经纬度投影,也就是在WGS84经纬度的基础之上,进行GCJ-02加偏。加偏处理是按照特殊的算法,将真实的坐标加密成虚假的坐标,而这个加偏并不是线性的加偏,所以各地的偏移情况都会有所不同。

该坐标系的坐标值为经纬度格式,单位为度。

GCJ02 Web 墨卡托投影

该坐标系的坐标值为Web墨卡托格式,单位为米。

国内政策的原因,国内地图会有加密要求,一般有两种情况:

一种是在 Web墨卡托的基础上经过国家标准加密的国标02坐标系,熟称“火星坐标系”;另一种是在国标的02坐标系下进一步进行加密,如百度地图的BD09坐标系 BD09 经纬度投影

BD09经纬度投影属于百度坐标系,

它是在标准经纬度的基础上进行GCJ-02加偏之后,再加上百度自身的加偏算法,也就是在标准经纬度的基础之上进行了两次加偏。

该坐标系的坐标值为经纬度格式,单位为度。

常用坐标系区分?

EPSG:4326,等同于WGS84坐标系

CGCS2000,天地图坐标系,与GPS一样,偏移较小

GCJ02,火星坐标系,将GPS坐标做偏移之后的数据

EPSG:3857,等同于900913,由墨卡托投影而来(最初 Web Mercator 被拒绝分配EPSG 代码。于是大家普遍使用 EPSG:900913(Google的数字变形) 的非官方代码来代表它)

BD-09:,百度地图使用坐标系

地图偏移 为什么要地图偏移?

一言以蔽之:为了国家安全。可以想象,如果地图不加密,在百度上找到关键(军事、科研所等)目标,导弹空袭,损失不可估量

偏移在哪里?

设备一般是标准的GPS信息 —— 我们也很难要求外国各个厂商按照中国的要求制造GPS设备

中国政府加密的是地图,而非GPS 信号

地图做了偏移,为什么地图定位很精准(百度地图说明)

百度地图供应商是思维图新,地图提供给百度之前,需要先提交给测绘局,测绘局对地图做偏移加密,加密地图的坐标系就变成了GCJ-02(火星坐标系)

百度收到思维图新的地图之后发现,在地图上,GPS位置会偏很远

百度再把地图软件拿到测绘局,请他们加入一个“保密插件”,对GPS做同样的偏移 对GPS偏移

总结:地图偏移 和 GPS 偏移,保证了地图和GPS重合了

坐标转换 为什么要做坐标转换

工作中,开发的项目使用的是openlayers或者leaflet 开源地图引擎,使用地图的业务逻辑已经写好了,为了提高业务组件的复用性,当地图切换的时候,最好的方式就是切换地图图层,关于业务的API不要变化,那么剩下的工作就是坐标系转换即可;

比如,要使用百度地图,使用百度的地图引擎(bmap.js),那么业务逻辑的代码就要使用百度的API来实现,等于重新开发了一次,降低了效率,不利于代码复用

让地图提供 WMTS 服务,就可以实现只换图层,不换API 的要求

地图服务(后台地图引擎可提供的能力) TMS——Tile Map Service 即TMS,切片地图服务

将地图切割成多个级别的图片金字塔(四叉树形式分割), 在这里插入图片描述 它通常需要一种遵循REST原则的URI结构去标识每一张切片。

TMS是纯RESTful的;TMS瓦片是正方形 WMTS——Web Map Tile Service即WMTS,网络地图切片服务,

它是一种在互联网上预渲染或进行实时地图瓦片计算的服务。

例如,在浏览器中输入 https://maponline0.bdimg.com/tile/?qt=vtile&x=1579&y=589&z=13&styles=pl&scaler=1&udt=20210506&from=jsapi2_0,就可以查看到图片 在这里插入图片描述

WMTS可以有三种协议:KVP、SOAP、RESTful;

WMTS瓦片是矩形;

WMTS中对应的不同比例尺瓦片可以尺寸不同

另外WMTS可以获取以下信息

可以获取地图瓦片;可以获取WMTS服务的元数据;可以获取单一瓦片的FeatureInfo;可以获取地图的图例; WMS——Web Map Service,网络地图服务

当客户端请求WMS服务时,返回给客户端是一张完整的图片,它不能让客户端知道瓦片布局,客户端取到直接展示,故WMS仅是重在灵活性。

但是复用的概率低之又低,当并发增大,服务端性能就随之大大下降。

有不同的请求类型:

GetCapabilities:返回WMS服务的元数据和可获取的图层GetMap :返回地图图片GetFeatureInfo :如果图层被标记为“queryable”,就可以通过坐标请求地图图片数据DescribeLayer :返回指定图层的要素类型GetLegendGraphic:返回地图图例图片 常用坐标系的转换工具(百度地图、GCJ、WGS84) const mapTools = (function () { const x_pi = (3.14159265358979324 * 3000.0) / 180.0; var pi = 3.14159265358979324; var a = 6378245.0; var ee = 0.00669342162296594323; var LLBAND = [75, 60, 45, 30, 15, 0]; var LL2MC = [ [ -0.0015702102444, 111320.7020616939, 1704480524535203, -10338987376042340, 26112667856603880, -35149669176653700, 26595700718403920, -10725012454188240, 1800819912950474, 82.5, ], [ 0.0008277824516172526, 111320.7020463578, 647795574.6671607, -4082003173.641316, 10774905663.51142, -15171875531.51559, 12053065338.62167, -5124939663.577472, 913311935.9512032, 67.5, ], [ 0.00337398766765, 111320.7020202162, 4481351.045890365, -23393751.19931662, 79682215.47186455, -115964993.2797253, 97236711.15602145, -43661946.33752821, 8477230.501135234, 52.5, ], [ 0.00220636496208, 111320.7020209128, 51751.86112841131, 3796837.749470245, 992013.7397791013, -1221952.21711287, 1340652.697009075, -620943.6990984312, 144416.9293806241, 37.5, ], [ -0.0003441963504368392, 111320.7020576856, 278.2353980772752, 2485758.690035394, 6070.750963243378, 54821.18345352118, 9540.606633304236, -2710.55326746645, 1405.483844121726, 22.5, ], [ -0.0003218135878613132, 111320.7020701615, 0.00369383431289, 823725.6402795718, 0.46104986909093, 2351.343141331292, 1.58060784298199, 8.77738589078284, 0.37238884252424, 7.45, ], ]; var MCBAND = [12890594.86, 8362377.87, 5591021, 3481989.83, 1678043.12, 0]; var MC2LL = [ [ 1.410526172116255e-8, 0.00000898305509648872, -1.9939833816331, 200.9824383106796, -187.2403703815547, 91.6087516669843, -23.38765649603339, 2.57121317296198, -0.03801003308653, 17337981.2, ], [ -7.435856389565537e-9, 0.000008983055097726239, -0.78625201886289, 96.32687599759846, -1.85204757529826, -59.36935905485877, 47.40033549296737, -16.50741931063887, 2.28786674699375, 10260144.86, ], [ -3.030883460898826e-8, 0.00000898305509983578, 0.30071316287616, 59.74293618442277, 7.357984074871, -25.38371002664745, 13.45380521110908, -3.29883767235584, 0.32710905363475, 6856817.37, ], [ -1.981981304930552e-8, 0.000008983055099779535, 0.03278182852591, 40.31678527705744, 0.65659298677277, -4.44255534477492, 0.85341911805263, 0.12923347998204, -0.04625736007561, 4482777.06, ], [ 3.09191371068437e-9, 0.000008983055096812155, 0.00006995724062, 23.10934304144901, -0.00023663490511, -0.6321817810242, -0.00663494467273, 0.03430082397953, -0.00466043876332, 2555164.4, ], [ 2.890871144776878e-9, 0.000008983055095805407, -3.068298e-8, 7.47137025468032, -0.00000353937994, -0.02145144861037, -0.00001234426596, 0.00010322952773, -0.00000323890364, 826088.5, ], ]; function getRange(cC, cB, T) { if (cB != null) { cC = Math.max(cC, cB); } if (T != null) { cC = Math.min(cC, T); } return cC; } function getLoop(cC, cB, T) { while (cC > T) { cC -= T - cB; } while (cC if (!cC || !cD) { return null; } let T = cD[0] + cD[1] * Math.abs(cC.x); const cB = Math.abs(cC.y) / cD[9]; let cE = cD[2] + cD[3] * cB + cD[4] * cB * cB + cD[5] * cB * cB * cB + cD[6] * cB * cB * cB * cB + cD[7] * cB * cB * cB * cB * cB + cD[8] * cB * cB * cB * cB * cB * cB; T *= cC.x x: lnglat.lng, y: lnglat.lat, }; const cC = { x: Math.abs(cB.x), y: Math.abs(cB.y), }; let cE; for (let cD = 0, len = MCBAND.length; cD cE = MC2LL[cD]; break; } } const T = convertor(cB, cE); return T; } /** * 百度BD09经纬度坐标转百度墨卡托坐标: * @param {*} T * @returns */ function convertBdLL2MC(lnglat) { const T = { x: lnglat.lng, y: lnglat.lat, }; let cD, cC, len; T.x = getLoop(T.x, -180, 180); T.y = getRange(T.y, -74, 74); const cB = T; for (cC = 0, len = LLBAND.length; cC cD = LL2MC[cC]; break; } } if (!cD) { for (cC = LLBAND.length - 1; cC >= 0; cC--) { if (cB.y lng: cE[0], lat: cE[1], }; } /*判断是否在国内,不在国内则不做偏移*/ function outOfChina(lon, lat) { if ((lon 137.8347) && (lat 55.8271)) { return true; } else { return false; } } function transformLat(x, y) { var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); ret += ((20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0) / 3.0; ret += ((20.0 * Math.sin(y * pi) + 40.0 * Math.sin((y / 3.0) * pi)) * 2.0) / 3.0; ret += ((160.0 * Math.sin((y / 12.0) * pi) + 320 * Math.sin((y * pi) / 30.0)) * 2.0) / 3.0; return ret; } function transformLon(x, y) { var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); ret += ((20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0) / 3.0; ret += ((20.0 * Math.sin(x * pi) + 40.0 * Math.sin((x / 3.0) * pi)) * 2.0) / 3.0; ret += ((150.0 * Math.sin((x / 12.0) * pi) + 300.0 * Math.sin((x / 30.0) * pi)) * 2.0) / 3.0; return ret; } function delta(lat, lon) { let a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。 let ee = 0.00669342162296594323; // ee: 椭球的偏心率。 let dLat = transformLat(lon - 105.0, lat - 35.0); let dLon = transformLon(lon - 105.0, lat - 35.0); let radLat = (lat / 180.0) * pi; let magic = Math.sin(radLat); magic = 1 - ee * magic * magic; let sqrtMagic = Math.sqrt(magic); dLat = (dLat * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * pi); dLon = (dLon * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * pi); return { lat: dLat, lon: dLon, }; } // 地球坐标系(WGS-84)转火星坐标系(GCJ): function transformWGS2GCJ(lnglat) { const wgLat = lnglat.lat; const wgLon = lnglat.lng; var mars_point = {}; if (outOfChina(wgLon, wgLat)) { mars_point.lat = wgLat; mars_point.lon = wgLon; return; } var dLat = transformLat(wgLon - 105.0, wgLat - 35.0); var dLon = transformLon(wgLon - 105.0, wgLat - 35.0); var radLat = (wgLat / 180.0) * pi; var magic = Math.sin(radLat); magic = 1 - ee * magic * magic; var sqrtMagic = Math.sqrt(magic); dLat = (dLat * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * pi); dLon = (dLon * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * pi); mars_point.lat = wgLat + dLat; mars_point.lng = wgLon + dLon; return mars_point; } // 火星坐标系GCJ02转地球坐标系WGS84: function transformGCJ2WGS(lnglat) { const gcjLat = lnglat.lat; const gcjLon = lnglat.lng; let d = delta(gcjLat, gcjLon); return { lat: gcjLat - d.lat, lng: gcjLon - d.lon, }; } /** * 百度坐标转火星坐标: * @param {*} baidu_point * @returns */ function baiduTomars(baidu_point) { var mars_point = { lng: 0, lat: 0 }; var x = baidu_point.lng - 0.0065; var y = baidu_point.lat - 0.006; var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); mars_point.lng = z * Math.cos(theta); mars_point.lat = z * Math.sin(theta); return mars_point; } /** * 火星坐标转百度坐标: * @param {*} mars_point * @returns */ function marsTobaidu(mars_point) { var baidu_point = { lng: 0, lat: 0 }; var x = mars_point.lng; var y = mars_point.lat; var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi); var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi); baidu_point.lng = z * Math.cos(theta) + 0.0065; baidu_point.lat = z * Math.sin(theta) + 0.006; return baidu_point; } // 测试百度和火星坐标系的转换 function testBaiduMars() { const lng = 116.01965; const lat = 40.043425; const lnglat = { lng, lat, }; let result; result = mapTools.baiduTomars(lnglat); console.log(result); // { lng: 116.01318467451765, lat: 40.037373017166615 } result = mapTools.marsTobaidu(result); console.log(result); } // 测试火星坐标系和WGS 相互转换 function testWGSMars() { const lng = 116.01965; const lat = 40.043425; const lnglat = { lng, lat, }; let result; result = mapTools.transformWGS2GCJ(lnglat); // 地球坐标系(WGS-84)转火星坐标系(GCJ): console.log(result); // { lng: 116.01318467451765, lat: 40.037373017166615 } result = mapTools.transformGCJ2WGS(result); console.log(result); } // 测试百度经纬度和墨卡托坐标的相互转换 function testBdMC2LL() { const lng = 116.01965; const lat = 40.043425; const lnglat = { lng, lat, }; let result; result = mapTools.convertBdLL2MC(lnglat); // 地球坐标系(WGS-84)转火星坐标系(GCJ): console.log(result); // { lng: 116.01318467451765, lat: 40.037373017166615 } result = mapTools.convertBdMC2LL(result); console.log(result); } return { test: { testBaiduMars, // 百度经纬度和GCJ坐标系的相互转换 testWGSMars, // WGS84 和 GCJ 坐标系的转换 testBdMC2LL //测试百度经纬度和墨卡托坐标的相互转换 }, convertBdMC2LL, // 百度墨卡托坐标转百度经纬度坐标: convertBdLL2MC, // 百度BD09经纬度坐标转百度墨卡托坐标: transformWGS2GCJ, // 地球坐标系(WGS-84)转火星坐标系(GCJ): transformGCJ2WGS, // 火星坐标系GCJ02转地球坐标系WGS84: baiduTomars, // 百度坐标转火星坐标: marsTobaidu, // 火星坐标转百度坐标: }; })(); // mapTools.test.testBaiduMars() // mapTools.test.testWGSMars() // mapTools.test.testBdMC2LL() export default mapTools


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭