@gdjiami/jslib
Version:
Jiami FrontEnd helpers and Services
216 lines (215 loc) • 6.87 kB
JavaScript
/**
* 地理相关工具函数
*/
var PI = 3.14159265358979324;
var X_PI = (3.14159265358979324 * 3000.0) / 180.0;
function delta(_a) {
var latitude = _a.latitude, longitude = _a.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(_a) {
var longitude = _a.longitude, latitude = _a.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(_a) {
var latitude = _a.latitude, longitude = _a.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(_a) {
var latitude = _a.latitude, longitude = _a.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(_a) {
var latitude = _a.latitude, longitude = _a.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(_a) {
var latitude = _a.latitude, longitude = _a.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(_a) {
var latitude = _a.latitude, longitude = _a.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(_a) {
var latitude = _a.latitude, longitude = _a.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(_a, _b) {
var latA = _a.latitude, lonA = _a.longitude;
var latB = _b.latitude, lonB = _b.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(_a) {
var latitude = _a.latitude, longitude = _a.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;
}