From ec763e1cb7dca873caf4afbc0dfde047b51753d3 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期五, 17 十月 2025 17:26:54 +0800
Subject: [PATCH] 2025.10.17
---
src/utils/map/calculate.js | 170 +++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 147 insertions(+), 23 deletions(-)
diff --git a/src/utils/map/calculate.js b/src/utils/map/calculate.js
index b9ad407..152837c 100644
--- a/src/utils/map/calculate.js
+++ b/src/utils/map/calculate.js
@@ -94,20 +94,72 @@
}
/**
+ * 楂樺痉鍦板浘鍧愭爣杞珿PS鍧愭爣绠楁硶
+ */
+function gcj02towgs84(lng, lat) {
+ // lat = +latlng = +lng
+ if (out_of_china(lng, lat)) {
+ return [lng, lat];
+ } else {
+ let dlat = transformlat(lng - 105.0, lat - 35.0);
+ let dlng = 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 = Math.round((lat * 2 - lat - dlat) * 1000000) / 1000000;
+ let mglng = Math.round((lng * 2 - lng - dlng) * 1000000) / 1000000;
+ return [mglng, mglat];
+ }
+}
+
+//浠嶨PS杞珮寰�
+function wgs84_To_Gcj02(lon, lat) {
+ if (out_of_china(lon, lat)) {
+ return [lon, lat];
+ } else {
+ let dLat = transformlat(lon - 105.0, lat - 35.0);
+ let dLon = transformlng(lon - 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);
+ dLon = (dLon * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * PI);
+ let mgLat = lat + dLat;
+ let mgLon = lon + dLon;
+ return [mgLon, mgLat];
+ }
+}
+
+/**
* 灏唃ps缁忕含搴﹁浆鎹负楂樺痉鍦板浘缁忕含搴�
* @param {*} lnglats
* @param {*} callback
*/
function _convertLatlng(index, coor, lnglats, type = 'gps', callback) {
if (index < coor.length) {
- var path = parse2LngLat(coor[index]);
- // eslint-disable-next-line no-undef
- AMap.convertFrom(path, type, function (status, result) {
- if (result.info === 'ok') {
- lnglats.push.apply(lnglats, result.locations);
- _convertLatlng(index + 1, coor, lnglats, type, callback);
+ coor[index].forEach((c) => {
+ let r;
+ if (type == 'gps') {
+ r = wgs84_To_Gcj02(c[0], c[1]);
+ } else {
+ r = gcj02towgs84(c[0], c[1]);
}
+ lnglats.push({ lng: r[0], lat: r[1] });
});
+ _convertLatlng(index + 1, coor, lnglats, type, callback);
+
+ // var path = parse2LngLat(coor[index]);
+ // // eslint-disable-next-line no-undef
+ // AMap.convertFrom(path, type, function (status, result) {
+ // if (result.info === 'ok') {
+ // lnglats.push.apply(lnglats, result.locations);
+ // _convertLatlng(index + 1, coor, lnglats, type, callback);
+ // }
+ // });
} else {
callback(lnglats);
}
@@ -130,6 +182,57 @@
var lng = ((dx / ed + (pos[0] * Math.PI) / 180.0) * 180.0) / Math.PI;
var lat = ((dy / ec + (pos[1] * Math.PI) / 180.0) * 180.0) / Math.PI;
return [lng, lat];
+ },
+
+ /**
+ * 鑾峰彇涓や釜缁忕含搴︿箣闂寸殑瑙掑害锛�0搴�-360搴︼級
+ */
+ getAngle(lng_a, lat_a, lng_b, lat_b) {
+ var a = ((90 - lat_b) * Math.PI) / 180;
+ var b = ((90 - lat_a) * Math.PI) / 180;
+ var AOC_BOC = ((lng_b - lng_a) * Math.PI) / 180;
+ var cosc =
+ Math.cos(a) * Math.cos(b) + Math.sin(a) * Math.sin(b) * Math.cos(AOC_BOC);
+ var sinc = Math.sqrt(1 - cosc * cosc);
+ var sinA = (Math.sin(a) * Math.sin(AOC_BOC)) / sinc;
+ var A = (Math.asin(sinA) * 180) / Math.PI;
+ var res = 0;
+ if (lng_b > lng_a && lat_b > lat_a) res = A;
+ else if (lng_b > lng_a && lat_b < lat_a) res = 180 - A;
+ else if (lng_b < lng_a && lat_b < lat_a) res = 180 - A;
+ else if (lng_b < lng_a && lat_b > lat_a) res = 360 + A;
+ else if (lng_b > lng_a && lat_b == lat_a) res = 90;
+ else if (lng_b < lng_a && lat_b == lat_a) res = 270;
+ else if (lng_b == lng_a && lat_b > lat_a) res = 0;
+ else if (lng_b == lng_a && lat_b < lat_a) res = 180;
+ return res;
+ },
+
+ /**
+ * 鑾峰彇涓ょ粡绾害闂寸殑璺濈
+ */
+ getDistance(lng1, lat1, lng2, lat2) {
+ lat1 = lat1 || 0;
+ lng1 = lng1 || 0;
+ lat2 = lat2 || 0;
+ lng2 = lng2 || 0;
+
+ var rad1 = (lat1 * Math.PI) / 180.0;
+ var rad2 = (lat2 * Math.PI) / 180.0;
+ var a = rad1 - rad2;
+ var b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0;
+ var r = 6378137;
+ var distance =
+ r *
+ 2 *
+ Math.asin(
+ Math.sqrt(
+ Math.pow(Math.sin(a / 2), 2) +
+ Math.cos(rad1) * Math.cos(rad2) * Math.pow(Math.sin(b / 2), 2)
+ )
+ );
+
+ return distance;
},
/**
@@ -180,22 +283,43 @@
/**
* 楂樺痉鍦板浘鍧愭爣杞珿PS鍧愭爣绠楁硶
*/
- gcj02towgs84(lng, lat) {
- // lat = +latlng = +lng
- if (out_of_china(lng, lat)) {
- return [lng, lat];
- } else {
- let dlat = transformlat(lng - 105.0, lat - 35.0);
- let dlng = 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 = Math.round((lat * 2 - lat - dlat) * 1000000) / 1000000;
- let mglng = Math.round((lng * 2 - lng - dlng) * 1000000) / 1000000;
- return [mglng, mglat];
- }
+ gcj02towgs84,
+
+ //浠嶨PS杞珮寰�
+ wgs84_To_Gcj02,
+
+ /**
+ * 璁$畻涓�缁勭粡绾害鍧愭爣鐨勪腑蹇冪偣
+ * @param {Array} coordinates - 缁忕含搴︽暟缁勶紝鏍煎紡: [{lng: number, lat: number}, ...]
+ * @returns {Object} 涓績鐐瑰潗鏍� {lng: number, lat: number}
+ */
+ calculateCenterCoordinates(coordinates) {
+ if (coordinates.length === 0) return { lng: 0, lat: 0 };
+ if (coordinates.length === 1) return coordinates[0];
+
+ let x = 0,
+ y = 0,
+ z = 0;
+ coordinates.forEach((p) => {
+ const lng = (p.lng * Math.PI) / 180; // 缁忓害杞姬搴�
+ const lat = (p.lat * Math.PI) / 180; // 绾害杞姬搴�
+
+ // 杞崲涓轰笁缁村潗鏍�
+ x += Math.cos(lat) * Math.cos(lng);
+ y += Math.cos(lat) * Math.sin(lng);
+ z += Math.sin(lat);
+ });
+
+ // 鍙栧钩鍧囧��
+ const avgX = x / coordinates.length;
+ const avgY = y / coordinates.length;
+ const avgZ = z / coordinates.length;
+
+ // 杞崲鍥炵粡绾害
+ const lng = (Math.atan2(avgY, avgX) * 180) / Math.PI;
+ const hypotenuse = Math.sqrt(avgX ** 2 + avgY ** 2);
+ const lat = (Math.atan2(avgZ, hypotenuse) * 180) / Math.PI;
+
+ return { lng, lat };
}
};
--
Gitblit v1.9.3