什么是地图坐标系转换?
目前常用的地图坐标系有多种标准,几家主流地图(如百度地图,高德地图和QQ地图等)使用的坐标系标准也各不相同。
假如您有GPS坐标,想在百度地图上显示;或者有百度地图的坐标,但想在微信地图上显示,这时就需要使用一些算法或通过官方的API来转换坐标,在目标地图上正确显示。
主流地图坐标系说明
1、WGS84坐标系
WGS-84坐标系为一种大地坐标系(地心坐标系,GPS原始坐标体系),也是目前广泛使用的GPS全球卫星定位系统使用的坐标系。对应工
具“输入坐标类型”里的GPS坐标。
2、GCJ02坐标系
GCJ-02坐标系:国测局坐标,又名火星坐标系。
国测局02年发布的坐标体系,它是一种对经纬度数据的加密算法,即加入随机的偏差。
是国内最广泛使用的坐标体系,高德地图、腾讯地图都使用它
3、BD09坐标系
为百度地图坐标系,在GCJ02坐标系基础上再次加密。其中bd09ll表示百度经纬度坐标,bd09mc表示百度墨卡托米制坐标。
4、CGCS2000坐标系
国家大地坐标系。该坐标系是通过中国GPS 连续运行基准站、 空间大地控制网以及天文大地网与空间地网联合平差建立的地心大地坐标系统。
废话不多说,品尝正餐吧~
提示:我的业务是GPS(WGS84)坐标转换为BD-09坐标,所以函数写到一起了,有时间再来拆分~~
/**
* WGS84转GCj02
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
* @param lng // 120.63014 (并非字符串)
* @param lat // 32.394913 (并非字符串)
* @DEMO: wgs84ToGcj02ToBd09Public(120.63014, 32.394913, {aaa: "aaa",bbb: "bbb",ccc: "ccc"})
* @returns {*[{aaa: "aaa",bbb: "bbb",ccc: "ccc",latitude: 32.414345685248584,longitude: 120.52607270431302}]}
* @Intro: 先将WGS84坐标转火星坐标再将火星坐标转百度坐标
*/
function wgs84ToGcj02ToBd09Public(lng, lat) {
const xPI = (3.14159265358979324 * 3000.0) / 180.0;
const PI = 3.1415926535897932384626;
const a = 6378245.0;
const ee = 0.00669342162296594323;
// WGS84转GCj02
let dlat = transformlat(lng - 105.0, lat - 35.0);
let dlng = transformlng(lng - 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);
dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
let mglat = lat + dlat;
let mglng = lng + dlng;
// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
let z = Math.sqrt(mglng * mglng + mglat * mglat) + 0.00002 * Math.sin(mglat * xPI);
let theta = Math.atan2(mglat, mglng) + 0.000003 * Math.cos(mglng * xPI);
let bdlng = z * Math.cos(theta) + 0.0065;
let bdlat = z * Math.sin(theta) + 0.006;
// return [bdlng, bdlat]
/* Object.assign({}, target, source),其中第一个参数是一个空对象,第二个参数是目标对象,第三个参数是源对象。该方法会将源对象中不存在于目标对象中的属性复制到目标对象中,而不会覆盖目标对象中已经存在的同名属性。 */
return Object.assign({}, {longitude: bdlng, latitude: bdlat});
}
function transformlat(lng, lat) {
const PI = 3.1415926535897932384626;
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;
}
function transformlng(lng, lat) {
const PI = 3.1415926535897932384626;
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;
}
// 调用入口
var res=wgs84ToGcj02ToBd09Public(113.85872, 22.58635)
console.log(res.longitude+','+res.latitude)
小结
技术在发展,社会在进步,争取不被AI取代!!