@gdjiami/jslib
Version:
Jiami FrontEnd helpers and Services
265 lines (238 loc) • 6.41 kB
JavaScript
/**
* 地理相关工具函数
*/
var PI = 3.14159265358979324;
var X_PI = 3.14159265358979324 * 3000.0 / 180.0;
function delta(_ref) {
var latitude = _ref.latitude,
longitude = _ref.longitude;
// Krasovsky 1940
//
// a = 6378245.0, 1/f = 298.3
// b = a * (1 - f)
// ee = (a^2 - b^2) / a^2;
var a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
var ee = 0.00669342162296594323; // ee: 椭球的偏心率。
var dLat = transformLat(longitude - 105.0, latitude - 35.0);
var dLon = transformLon(longitude - 105.0, latitude - 35.0);
var radLat = latitude / 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);
return {
latitude: dLat,
longitude: dLon
};
}
/**
* WGS84 -> BD09
*/
export function wgs2bd(position) {
var gcj = wgs2gcj(position);
return gcj2bd(gcj);
}
/**
* BD09 -> WGS84
*/
export function bd2wgs(position) {
var gcj = bd2gcj(position);
return gcj2wgs(gcj);
}
/**
* WGS84 -> GCJ02
*/
export function wgs2gcj(_ref2) {
var longitude = _ref2.longitude,
latitude = _ref2.latitude;
if (outOfChina({
latitude: latitude,
longitude: longitude
})) {
return {
latitude: latitude,
longitude: longitude
};
}
var d = delta({
latitude: latitude,
longitude: longitude
});
return {
latitude: latitude + d.latitude,
longitude: longitude + d.longitude
};
}
/**
* GCJ-02 to WGS-84
*/
export function gcj2wgs(_ref3) {
var latitude = _ref3.latitude,
longitude = _ref3.longitude;
if (outOfChina({
latitude: latitude,
longitude: longitude
})) {
return {
latitude: latitude,
longitude: longitude
};
}
var d = delta({
latitude: latitude,
longitude: longitude
});
return {
latitude: latitude - d.latitude,
longitude: longitude - d.longitude
};
}
/**
* GCJ-02 to WGS-84 exactly
*/
export function gcj2wgsExact(_ref4) {
var latitude = _ref4.latitude,
longitude = _ref4.longitude;
var initDelta = 0.01;
var threshold = 0.000000001;
var dLat = initDelta;
var dLon = initDelta;
var mLat = latitude - dLat;
var mLon = longitude - dLon;
var pLat = latitude + dLat;
var pLon = longitude + dLon;
var wgsLat = latitude;
var wgsLon = longitude;
var i = 0;
while (1) {
wgsLat = (mLat + pLat) / 2;
wgsLon = (mLon + pLon) / 2;
var tmp = wgs2gcj({
latitude: wgsLat,
longitude: wgsLon
});
dLat = tmp.latitude - latitude;
dLon = tmp.longitude - longitude;
if (Math.abs(dLat) < threshold && Math.abs(dLon) < threshold) {
break;
}
if (dLat > 0) {
pLat = wgsLat;
} else {
mLat = wgsLat;
}
if (dLon > 0) {
pLon = wgsLon;
} else {
mLon = wgsLon;
}
if (++i > 10000) {
break;
}
}
return {
latitude: wgsLat,
longitude: wgsLon
};
}
/**
* GCJ-02 to BD-09
*/
export function gcj2bd(_ref5) {
var latitude = _ref5.latitude,
longitude = _ref5.longitude;
var x = longitude;
var y = latitude;
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 bdLon = z * Math.cos(theta) + 0.0065;
var bdLat = z * Math.sin(theta) + 0.006;
return {
latitude: bdLat,
longitude: bdLon
};
}
/**
* BD-09 to GCJ-02
*/
export function bd2gcj(_ref6) {
var latitude = _ref6.latitude,
longitude = _ref6.longitude;
var x = longitude - 0.0065;
var y = latitude - 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 gcjLon = z * Math.cos(theta);
var gcjLat = z * Math.sin(theta);
return {
latitude: gcjLat,
longitude: gcjLon
};
} // WGS-84 to Web mercator
// mercatorLat -> y mercatorLon -> x
export function mercatorEncrypt(_ref7) {
var latitude = _ref7.latitude,
longitude = _ref7.longitude;
var x = longitude * 20037508.34 / 180;
var y = Math.log(Math.tan((90 + latitude) * PI / 360)) / (PI / 180);
y = y * 20037508.34 / 180;
return {
latitude: y,
longitude: x
};
} // Web mercator to WGS-84
// mercatorLat -> y mercatorLon -> x
export function mercatorDecrypt(_ref8) {
var latitude = _ref8.latitude,
longitude = _ref8.longitude;
var x = longitude / 20037508.34 * 180;
var y = latitude / 20037508.34 * 180;
y = 180 / PI * (2 * Math.atan(Math.exp(y * PI / 180)) - PI / 2);
return {
latitude: y,
longitude: x
};
}
export function identity(pos) {
return pos;
} // two point's distance
export function distance(_ref9, _ref10) {
var latA = _ref9.latitude,
lonA = _ref9.longitude;
var latB = _ref10.latitude,
lonB = _ref10.longitude;
var earthR = 6371000;
var x = Math.cos(latA * PI / 180) * Math.cos(latB * PI / 180) * Math.cos((lonA - lonB) * PI / 180);
var y = Math.sin(latA * PI / 180) * Math.sin(latB * PI / 180);
var s = x + y;
if (s > 1) s = 1;
if (s < -1) s = -1;
var alpha = Math.acos(s);
var distance = alpha * earthR;
return distance;
}
/**
* @param { latitude, longitude } 坐标轴
*/
export function outOfChina(_ref11) {
var latitude = _ref11.latitude,
longitude = _ref11.longitude;
if (longitude < 72.004 || longitude > 137.8347) return true;
if (latitude < 0.8293 || latitude > 55.8271) return true;
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;
}