在我们进行地图api二次开发的时候,针对某些场景下需要使用到多放地图api,常用的有bigemap,百度,高德,由于它们所使用的坐标系不同,导致同一套数据在不同的地图上就会有点位偏差问题。
解决方法:针对bigemap(wgs84坐标系),百度(BD09),高德(GCJ02)分别进行转化处理,并将其封装在一个公共的方法里面,以备随时调用
- 定义公共数据
const xPi = 3.14159265358979324 * 3000.0 / 180.0
const pi = 3.1415926535897932384626 // π
const a = 6378245.0 //长半轴
const ee = 0.00669342162296594323 //扁率
- bigemap(wgs84)转高德(GCJ02)
// wgs84转火星
wgs84togcj02(val) {
let dlat = transformlat(val.lng - 105.0, val.lat - 35.0);
let dlng = transformlng(val.lng - 105.0, val.lat - 35.0);
let radlat = val.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 hx = {}
hx.lat = val.lat + dlat;
hx.lng = val.lng + dlng;
return hx;
},
- 高德(GCJ02)转bigemap(wgs84)
// 火星转wgs84
gcj02towgs84(val) {
let dlat = transformlat(val.lng - 105.0, val.lat - 35.0);
let dlng = transformlng(val.lng - 105.0, val.lat - 35.0);
let radlat = val.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 wgs84 = {}
let mglat = val.lat + dlat;
let mglng = val.lng + dlng;
wgs84.lat = val.lat * 2 - mglat;
wgs84.lng = val.lng * 2 - mglng;
return wgs84;
},
- 高德(GCJ02)转百度(BD09)
// 火星转百度
gcj02tobd09(val) {
let z = Math.sqrt(val.lng * val.lng + val.lat * val.lat) + 0.00002 * Math.sin(val.lat * xPi);
let theta = Math.atan2(val.lat, val.lng) + 0.000003 * Math.cos(val.lng * xPi);
let BaiduCor = {}
BaiduCor.lng = z * Math.cos(theta) + 0.0065;
BaiduCor.lat = z * Math.sin(theta) + 0.006;
return BaiduCor;
},
- 百度(BD09)转高德(GCJ02)
// 百度转火星
bd09togcj02(val) {
let x = val.lng - 0.0065;
let y = val.lat - 0.006;
let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * xPi);
let theta = Math.atan2(y, x) - .000003 * Math.cos(x * xPi);
let hx = {}
hx.lng = z * Math.cos(theta);
hx.lat = z * Math.sin(theta);
return hx;
},
- 百度(BD09)转bigemap(wgs84)
// 百度转84
bd09towgs84(val) {
let hx = bd09togcj02(val);
let wgs84 = gcj02towgs84(hx);
return wgs84;
},
- bigemap(wgs84)转百度(BD09)
// 84转百度
wgs84tobd09(val) {
let hx = wgs84togcj02(val);
let bd = gcj02tobd09(hx);
return bd;
},
- 辅助函数转换lat
// 辅助函数转换lat
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;
},
- 辅助函数转换lng
// 辅助函数转换lng
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;
}
以上就是三种不同坐标系之间相互转换的方法,结果也很好的将偏移量控制在了极小的范围内。