pageadmin做网站要钱吗,网络营销就是什么,机械外贸网站,网站设计理论前言
我最近在做一个和地图有关的项目#xff0c;这里本人地图采用的是mapbox#xff0c;其中涉及一个功能需要根据用户输入的地点直接定位到地图上的对应的位置#xff0c;本人开始想的是直接调用百度的接口根据地名直接获取坐标#xff0c;发现在地图上的位置有偏移不够…
前言
我最近在做一个和地图有关的项目这里本人地图采用的是mapbox其中涉及一个功能需要根据用户输入的地点直接定位到地图上的对应的位置本人开始想的是直接调用百度的接口根据地名直接获取坐标发现在地图上的位置有偏移不够准确后面发现地图服务之间有自己的坐标系不同的坐标系之间的坐标会有一定的偏移。
地图的地理坐标系
是一种球面坐标是使用三维球面来定义地球表面位置以实现通过经纬度对地球表面点位引用的坐标系也就是说坐标单位是经纬度。
地球坐标系(WGS84)
GPSWGS-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