This commit is contained in:
@jyuhsin
2025-11-07 11:56:13 +08:00
parent 90026a54a3
commit ae86803b17
17 changed files with 381 additions and 159 deletions
@@ -0,0 +1,91 @@
// =============== 坐标系工具 ===============
const PI = 3.1415926535897932384626
const a = 6378245.0 //卫星椭球坐标投影到平面地图坐标系的投影因子。
const ee = 0.00669342162296594323 //椭球的偏心率。
const coordinateUtil = {
// 判断是否在中国范围(仅中国加密)
outOfChina(lon, lat) {
if (lon < 72.004 || lon > 137.8347) {
return true;
}
if (lat < 0.8293 || lat > 55.8271) {
return true;
}
return false;
},
// 基础偏移计算
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
},
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
},
// WGS-84 → GCJ-02(用于地图展示)
wgs84ToGcj02(lng, lat) {
let dlat = this.transformLat(lng - 105.0, lat - 35.0);
let dlng = this.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;
return [mglat, mglng];
},
// GCJ-02 → WGS-84(用于存储签到点)
gcj02ToWgs84(lng, lat) {
const originalLngSign = Math.sign(lng);
const originalLatSign = Math.sign(lat);
lat = Math.abs(lat);
lng = Math.abs(lng);
let dlat = this.transformLat(lng - 105.0, lat - 35.0)
let dlng = this.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
let lngs = lng * 2 - mglng
let lats = lat * 2 - mglat
let finalLng = originalLngSign * lngs;
let finalLat = originalLatSign * lats;
return [finalLat, finalLng];
},
// 计算两点间距离(米),输入 WGS-84 坐标
getDistance(lat1, lng1, lat2, lng2) {
const R = 6371000; // 地球半径(米)
const φ1 = lat1 * Math.PI / 180;
const φ2 = lat2 * Math.PI / 180;
const Δφ = (lat2 - lat1) * Math.PI / 180;
const Δλ = (lng2 - lng1) * Math.PI / 180;
const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
},
};