From f1ea263462d1f3f10a886fb083536a38b03a1ceb Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期三, 14 五月 2025 17:33:04 +0800
Subject: [PATCH] 1. 新增动态污染溯源的数据异常判断逻辑 2. 新增动态污染溯源websocket连接功能

---
 src/main/kotlin/com/flightfeather/uav/common/utils/MapUtil.kt |  133 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 122 insertions(+), 11 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 cdcfcb9..5ae24c7 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 {*[]}*/
 
     /**
      * 鏍规嵁鍧愭爣鐐广�佽窛绂诲拰瑙掑害锛岃幏鍙栧彟涓�涓潗鏍�
@@ -93,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 澶氳竟褰㈠潗鏍囩偣鏁扮粍
@@ -102,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
     }
@@ -146,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
@@ -177,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) / 1000000;
+            val mglng = Math.round((lng * 2 - lng - dlng) * 1000000) / 1000000;
+            return mglng.toDouble() to mglat.toDouble()
+        }
+    }
+
+    /**
+     * 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