From eb3dd00b0b7fcda477229d518d250f9c842b790b Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期二, 21 十月 2025 17:45:44 +0800
Subject: [PATCH] 2025.10.21 1. 走航季度报告相关数据计算逻辑调整
---
src/main/kotlin/com/flightfeather/uav/common/utils/MapUtil.kt | 136 +++++++++++++++++++++++++++++++++++++++++----
1 files changed, 124 insertions(+), 12 deletions(-)
diff --git a/src/main/kotlin/com/flightfeather/uav/common/utils/MapUtil.kt b/src/main/kotlin/com/flightfeather/uav/common/utils/MapUtil.kt
index e3e9917..a565a72 100644
--- a/src/main/kotlin/com/flightfeather/uav/common/utils/MapUtil.kt
+++ b/src/main/kotlin/com/flightfeather/uav/common/utils/MapUtil.kt
@@ -1,14 +1,15 @@
package com.flightfeather.uav.common.utils
-import kotlin.math.PI
-import kotlin.math.asin
-import kotlin.math.cos
-import kotlin.math.sin
+import kotlin.math.*
object MapUtil {
private const val Ea = 6378137 //璧ら亾鍗婂緞
private const val Eb = 6356725 //鏋佸崐寰�
+
+ // 鍧愭爣杞崲鍙傛暟
+ const val a = 6378245.0; //闀垮崐杞�
+ const val ee = 0.00669342162296594323; //鎵佺巼/*** GCJ02 杞崲涓� WGS84* @param lng* @param lat* @returns {*[]}*/
/**
* 鏍规嵁鍧愭爣鐐广�佽窛绂诲拰瑙掑害锛岃幏鍙栧彟涓�涓潗鏍�
@@ -51,6 +52,7 @@
/**
* 鑾峰彇涓ょ粡绾害闂寸殑璺濈
+ * @return 杩斿洖涓ょ偣闂磋窛绂伙紝鍗曚綅锛氱背
*/
fun getDistance(lng1: Double, lat1: Double, lng2: Double, lat2: Double): Double {
// lat1 = lat1 || 0;
@@ -92,6 +94,24 @@
}
/**
+ * 璁$畻澶氳竟褰㈢殑鍥涜嚦鑼冨洿
+ * @param polygon 澶氳竟褰㈠潗鏍囩偣鏁扮粍
+ * @return 鍥涜嚦鑼冨洿锛岄『搴忎负鏈�灏忕粡搴︼紝鏈�澶х粡搴�, 鏈�灏忕含搴︼紝鏈�澶х含搴�
+ */
+ fun calFourBoundaries(polygon: List<Pair<Double, Double>>): List<Double> {
+ // 璁$畻澶氳竟褰㈤《鐐圭粡搴﹁寖鍥村拰绾害鑼冨洿
+ val xsSort = polygon.map { it.first }.sorted()
+ val ysSort = polygon.map { it.second }.sorted()
+
+ val xMin = xsSort[0]
+ val yMin = ysSort[0]
+ val xMax = xsSort[xsSort.lastIndex]
+ val yMax = ysSort[ysSort.lastIndex]
+
+ return listOf(xMin, xMax, yMin, yMax)
+ }
+
+ /**
* 鍒ゆ柇鍧愭爣鐐规槸鍚﹀湪澶氳竟褰㈢殑鍥涜嚦鑼冨洿鍐�
* @param point 鍧愭爣鐐�
* @param polygon 澶氳竟褰㈠潗鏍囩偣鏁扮粍
@@ -101,13 +121,19 @@
val x = point.first
val y = point.second
// 璁$畻澶氳竟褰㈤《鐐圭粡搴﹁寖鍥村拰绾害鑼冨洿
- val xsSort = polygon.map { it.first }.sorted()
- val ysSort = polygon.map { it.second }.sorted()
+ val fb = calFourBoundaries(polygon)
+// val xsSort = polygon.map { it.first }.sorted()
+// val ysSort = polygon.map { it.second }.sorted()
+//
+// val xMin = xsSort[0]
+// val yMin = ysSort[0]
+// val xMax = xsSort[xsSort.lastIndex]
+// val yMax = ysSort[ysSort.lastIndex]
- val xMin = xsSort[0]
- val yMin = ysSort[0]
- val xMax = xsSort[xsSort.lastIndex]
- val yMax = ysSort[ysSort.lastIndex]
+ val xMin = fb[0]
+ val xMax = fb[1]
+ val yMin = fb[2]
+ val yMax = fb[3]
return x >= xMin && x <= xMax && y >= yMin && y <= yMax
}
@@ -145,7 +171,7 @@
* @param point 鍧愭爣鐐�
* @param polygon 澶氳竟褰㈠潗鏍囩偣鏁扮粍
*/
- fun inPolygon(point: Pair<Double, Double>, polygon: List<Pair<Double, Double>>):Boolean {
+ fun inPolygon(point: Pair<Double, Double>, polygon: List<Pair<Double, Double>>): Boolean {
val x = point.first
val y = point.second
var j = polygon.size - 1
@@ -167,7 +193,7 @@
* 鍒ゆ柇鍧愭爣鐐规槸鍚﹀湪澶氳竟褰㈠唴閮�
*/
fun isPointInPolygon(point: Pair<Double, Double>, polygon: List<Pair<Double, Double>>): Boolean {
- if (polygon.size < 4) throw IllegalArgumentException("not a polygon")
+ if (polygon.size < 3) throw IllegalArgumentException("not a polygon")
// 涓嶅湪鍥涜嚦鑼冨洿鍐咃紝鍒欎竴瀹氫笉鍦ㄥ杈瑰舰鍐�
if (!inBBox(point, polygon)) return false
@@ -176,4 +202,90 @@
// 璁$畻鏄惁鍦ㄥ杈瑰舰鍐呴儴
return inPolygon(point, polygon)
}
+
+ /**
+ * 鍒ゆ柇缁忕含搴︽槸鍚﹀湪鍥藉唴
+ * @return true: 缁忕含搴︿笉鍦ㄥ浗鍐咃紝false锛氱粡绾害鍦ㄥ浗鍐�
+ */
+ fun outOfChina(point: Pair<Double, Double>): Boolean {
+ val lng = point.first
+ val lat = point.second
+ return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55)
+ }
+
+ private fun transformLat(point: Pair<Double, Double>): Double {
+ val lng = point.first
+ val lat = point.second
+ var ret = -100.0 +
+ 2.0 * lng +
+ 3.0 * lat +
+ 0.2 * lat * lat +
+ 0.1 * lng * lat +
+ 0.2 * sqrt(abs(lng))
+ ret += ((20.0 * sin(6.0 * lng * PI) + 20.0 * sin(2.0 * lng * PI)) * 2.0) / 3.0
+ ret += ((20.0 * sin(lat * PI) + 40.0 * sin((lat / 3.0) * PI)) * 2.0) / 3.0
+ ret += ((160.0 * sin((lat / 12.0) * PI) + 320 * sin((lat * PI) / 30.0)) * 2.0) / 3.0
+ return ret;
+ }
+
+ private fun transformLng(point: Pair<Double, Double>): Double {
+ val lng = point.first
+ val lat = point.second
+ var ret = 300.0 +
+ lng +
+ 2.0 * lat +
+ 0.1 * lng * lng +
+ 0.1 * lng * lat +
+ 0.1 * sqrt(abs(lng));
+ ret += ((20.0 * sin(6.0 * lng * PI) + 20.0 * sin(2.0 * lng * PI)) * 2.0) / 3.0;
+ ret += ((20.0 * sin(lng * PI) + 40.0 * sin((lng / 3.0) * PI)) * 2.0) / 3.0;
+ ret += ((150.0 * sin((lng / 12.0) * PI) + 300.0 * sin((lng / 30.0) * PI)) * 2.0) / 3.0
+ return ret;
+ }
+
+ /**
+ * 鐏槦鍧愭爣绯昏浆WGS84鍧愭爣绯�
+ */
+ fun gcj02ToWgs84(point: Pair<Double, Double>): Pair<Double, Double> {
+ if (outOfChina(point)) {
+ return point;
+ } else {
+ val lng = point.first
+ val lat = point.second
+ var dlat = transformLat(lng - 105.0 to lat - 35.0);
+ var dlng = transformLng(lng - 105.0 to lat - 35.0);
+ val radlat = (lat / 180.0) * PI;
+ var magic = sin(radlat);
+ magic = 1 - ee * magic * magic;
+ val sqrtmagic = sqrt(magic);
+ dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
+ dlng = (dlng * 180.0) / ((a / sqrtmagic) * cos(radlat) * PI);
+ val mglat = Math.round((lat * 2 - lat - dlat) * 1000000).toDouble() / 1000000;
+ val mglng = Math.round((lng * 2 - lng - dlng) * 1000000).toDouble() / 1000000;
+ return mglng to mglat
+ }
+ }
+
+ /**
+ * WGS84鍧愭爣绯昏浆鐏槦鍧愭爣绯�
+ */
+ fun wgs84ToGcj02(point: Pair<Double, Double>): Pair<Double, Double> {
+ if (outOfChina(point)) {
+ return point
+ } else {
+ val lng = point.first
+ val lat = point.second
+ var dLat = transformLat(lng - 105.0 to lat - 35.0);
+ var dLon = transformLng(lng - 105.0 to lat - 35.0);
+ val radLat = (lat / 180.0) * PI;
+ var magic = sin(radLat);
+ magic = 1 - ee * magic * magic;
+ val sqrtMagic = sqrt(magic);
+ dLat = (dLat * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * PI);
+ dLon = (dLon * 180.0) / ((a / sqrtMagic) * cos(radLat) * PI);
+ val mgLat = lat + dLat;
+ val mgLon = lng + dLon;
+ return mgLon to mgLat
+ }
+ }
}
\ No newline at end of file
--
Gitblit v1.9.3