不同坐标系转换
// 定义一些常量
const x_PI = 3.14159265358979324 * 3000.0 / 180.0
const PI = 3.1415926535897932384626 // 圆周率
const a = 6378245.0 // 地球半径(米)
const ee = 0.00669342162296594323
(一)地图的偏移
1、百度地图的偏移差别是(0.01185,-0.00328)
即如果百度地图的经纬度是(lon,lat),实际的应该是(lon-0.01185,lat-0.00328)
2、google Map的偏移差别是(0.0143,-0.014)
即如果用getscreen截图,如果要截的范围为(lon,lat),输入getscreen的为(lon-0.0143,lat+0.014)
(二)度分秒坐标转换为经纬度
比如,采集到的是39°31'20.51,那么应该这样换算,31分就是31/60度,20.51秒就是20.51/3600度,结果就是39+ 31/60 + 20.51/3600 度。
(三)GCJ-02与BD-09之间互转
即国家测绘局GCJ-02坐标系(谷歌地图、高德地图、腾讯地图)与BD-09坐标系(百度坐标,只适用于百度地图的相关产品)的转换。
百度坐标系转火星坐标系
function bd_encrypt(gg_lon, gg_lat){
var pi_value=Math.PI;
var X_PI = pi_value * 3000.0 / 180.0;
var x = gg_lon, y = gg_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);
var bd_lon = z * Math.cos(theta) + 0.0065;
var bd_lat = z * Math.sin(theta) + 0.006;
return {
bd_lat: bd_lat,
bd_lon: bd_lon
};
}
火星坐标系转百度坐标系
function bd_decrypt(bd_lon,bd_lat) {
var pi_value=Math.PI;
var X_PI = pi_value * 3000.0 / 180.0;
var x = bd_lon - 0.0065;
var y = bd_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);
var gg_lon = z * Math.cos(theta);
var gg_lat = z * Math.sin(theta);
return {
gg_lon: gg_lon,
gg_lat: gg_lat
}
}
当然还有简化版,如下
to_b是转到百度,to_g是转到GCJ-02。
var to_blng = function(lng) {
return lng+0.0065;
};
var to_blat = function(lat) {
return lat+0.0060;
};
var to_glng = function(lng) {
return lng-0.0065;
};
var to_glat = function(lat) {
return lat-0.0060;
};
(四)经纬度与墨卡托之间互转
//经纬度转墨卡托
function lonlatTomercator(lonlat) {
var mercator={x:0,y:0};
var x = lonlat.x *20037508.34/180;
var y = Math.log(Math.tan((90+lonlat.y)*Math.PI/360))/(Math.PI/180);
y = y *20037508.34/180;
mercator.x = x;
mercator.y = y;
return mercator ;
}
//墨卡托转经纬度
function mercatorTolonlat(mercator){
var lonlat={x:0,y:0};
var x = mercator.x/20037508.34*180;
var y = mercator.y/20037508.34*180;
y= 180/Math.PI*(2*Math.atan(Math.exp(y*Math.PI/180))-Math.PI/2);
lonlat.x = x;
lonlat.y = y;
return lonlat;
}
(五)GCJ-02与WGS84之间互转
// WGS84坐标系转火星坐标系
export function wgs84togcj02 (lng, lat) {
if (outOfChina(lng, lat)) {
return [lng, lat]
}
else {
var dlat = transformlat(lng - 105.0, lat - 35.0)
var dlng = transformlng(lng - 105.0, lat - 35.0)
var radlat = lat / 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)
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)
const mglat = lat + dlat
const mglng = lng + dlng
return [mglng, mglat]
}
}
// 火星坐标系 转 WGS84
export function gcj02towgs84 (lng, lat) {
if (outOfChina(lng, lat)) {
return [lng, lat]
}
else {
var dlat = transformlat(lng - 105.0, lat - 35.0)
var dlng = transformlng(lng - 105.0, lat - 35.0)
var radlat = lat / 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)
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]
}
}
(六)BD-09与WGS84之间互转
// 百度坐标系转wgs84
export function bd09towgs84 (lng, lat) {
// 百度坐标系先转为火星坐标系
const gcj02 = bd09togcj02(lng, lat)
// 火星坐标系转wgs84坐标系
const result = gcj02towgs84(gcj02[0], gcj02[1])
return result
}
// wgs84转百度坐标系
export function wgs84tobd09 (lng, lat) {
// wgs84先转为火星坐标系
const gcj02 = wgs84togcj02(lng, lat)
// 火星坐标系转百度坐标系
const result = gcj02tobd09(gcj02[0], gcj02[1])
return result
}
坐标转换之后还有偏移
随之而来的问题是坐标转换之后还有偏移,那么需要考虑以下几个方面:
1.原始坐标系弄错
比如以为自己是GPS坐标,但其实已经是GCJ-02坐标。
解决方案:请确保采集到的数据是哪个坐标体系,需要转换到哪个坐标系,再进行坐标转换。
2.原始坐标准确度不够
解决方案:如果您是GPS坐标,请确保采集GPS数据时,搜到至少4颗以上的卫星。并且GPS数据准不准,还取决于周围建筑物的高度,越高越不准,因为有遮挡。
如果本来就是GCJ-02坐标,在不同地图放大级别的时候,看到的地方可能不一样。比如你在地图级别4(国家)取到的坐标,放大到地图12级(街道)时,坐标就偏了。请确保在地图最大放大级别时,拾取坐标。
3.度分秒的概念混淆
比如,在googleearth上采集到的是39°31'20.51,那么应该这样换算,31分就是31/60度,20.51秒就是20.51/3600度,结果就是39+ 31/60 + 20.51/3600 度。
4.经纬度顺序写反了
比如高德,百度,腾讯是先经度,再纬度,即Point(lng,lat)。但谷歌坐标的顺序恰好相反,是(lat, lng)。
|