Bladeren bron

optimize location update sequnce

Groot 6 maanden geleden
bovenliggende
commit
7072cb51fc

+ 69 - 11
plugins/map_mapkit_ios/ios/Classes/Location/LocationManager.swift

@@ -18,6 +18,14 @@ class LocationManager: NSObject {
 
     private let locationManager = CLLocationManager()
 
+    #if DEBUG
+    private let filterDistance: CLLocationDistance = 5
+    #else
+    private let filterDistance: CLLocationDistance = 20
+    #endif
+    private var lastLocation: CLLocation?
+    private var lastUpdateTime: Date?
+
     var onLocationUpdate: ((CLLocation) -> Void)?
 
     private override init() {
@@ -56,32 +64,82 @@ class LocationManager: NSObject {
 //        locationManager.allowsBackgroundLocationUpdates = true
         locationManager.pausesLocationUpdatesAutomatically = false
         locationManager.desiredAccuracy = kCLLocationAccuracyBest
-        locationManager.distanceFilter = 5.0
-        locationManager.activityType = .fitness
+        locationManager.distanceFilter = filterDistance
+        locationManager.activityType = .automotiveNavigation
         locationManager.showsBackgroundLocationIndicator = false
     }
+
+    static func getAddress(location: CLLocation) async -> String? {   
+        let geocoder = CLGeocoder()
+        return await withCheckedContinuation { continuation in
+            geocoder.reverseGeocodeLocation(location) { (placemarks, error) in
+                if let error = error {
+                    print("反向地理编码失败: \(error.localizedDescription)")
+                    continuation.resume(returning: nil)
+                    return
+                }
+                
+                if let placemark = placemarks?.first {
+                    // 获取完整地址
+                    let address = [
+                        placemark.country,
+                        placemark.administrativeArea,
+                        placemark.locality,
+                        placemark.subLocality,
+                        placemark.thoroughfare,
+                        placemark.subThoroughfare,
+                        placemark.name
+                    ].compactMap { $0 }.joined(separator: "")
+                    
+                    continuation.resume(returning: address)
+                } else {
+                    continuation.resume(returning: nil)
+                }
+            }
+        }
+    }
 }
 
 extension LocationManager: CLLocationManagerDelegate {
     func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
-        guard let location = locations.last else { return }
+        guard let location = locations.last, isLocationCanUpdate(location: location) else { return }
         onLocationUpdate?(location)
         if let eventSink = locationEventSink {
-            // 转换GPS坐标系到中国坐标系
-            let transformedCoordinate = location.coordinate.wgc84ToGCJ02
-            let atLocation = ATMapLocation.fromLocation(location: location)
-            atLocation.longitude = transformedCoordinate.longitude
-            atLocation.latitude = transformedCoordinate.latitude
+            Task {
+                // 转换GPS坐标系到中国坐标系
+                let transformedCoordinate = location.coordinate.wgc84ToGCJ02
+                let atLocation = ATMapLocation.fromLocation(location: location)
+                atLocation.longitude = transformedCoordinate.longitude
+                atLocation.latitude = transformedCoordinate.latitude
+                // 获取地址
+                atLocation.address = await LocationManager.getAddress(location: location)
+                
+                let jsonMessage = atLocation.toJson()
+                print(jsonMessage)
+                await MainActor.run {
+                    eventSink(jsonMessage)
+                }
+            }
             
-            let jsonMessage = atLocation.toJson()
-            print(jsonMessage)
-            eventSink(jsonMessage)
         }
     }
 
     func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
         print("LocationManager: didFailWithError: \(error)")
     }
+
+    func isLocationCanUpdate(location: CLLocation) -> Bool {
+        if let lastLocation = lastLocation {
+            let distance = location.distance(from: lastLocation)
+            let timeInterval = location.timestamp.timeIntervalSince(lastUpdateTime ?? Date())
+            if distance < filterDistance && timeInterval < 5.0 {
+                return false
+            }
+        }
+        lastLocation = location
+        lastUpdateTime = location.timestamp
+        return true
+    }
 }
 
 extension LocationManager: FlutterStreamHandler {

+ 6 - 2
plugins/map_mapkit_ios/ios/Classes/MapView/Model/Models.swift

@@ -165,14 +165,16 @@ extension CLLocationCoordinate2D: Codable {
 class ATMapLocation: NSObject, Codable {
     var latitude: CGFloat?
     var longitude: CGFloat?
+    var address: String?
     var errorCode: Int = 0
     var time: Int?
     var bearing: CGFloat?
     var speed: CGFloat?
 
-    init(latitude: CGFloat? = nil, longitude: CGFloat? = nil, time: Int? = nil, bearing: CGFloat? = nil, speed: CGFloat? = nil) {
+    init(latitude: CGFloat? = nil, longitude: CGFloat? = nil, address: String? = nil, time: Int? = nil, bearing: CGFloat? = nil, speed: CGFloat? = nil) {
         self.latitude = latitude
         self.longitude = longitude
+        self.address = address
         self.time = time
         self.bearing = bearing
         self.speed = speed
@@ -183,9 +185,11 @@ class ATMapLocation: NSObject, Codable {
         return ATMapLocation(
             latitude: CGFloat(location.coordinate.latitude), 
             longitude: CGFloat(location.coordinate.longitude), 
-            time: Int(location.timestamp.timeIntervalSince1970), 
+            address: nil,
+            time: Int(location.timestamp.timeIntervalSince1970 * 1000), 
             bearing: CGFloat(location.course), 
             speed: CGFloat(location.speed)
         )
     }
+
 }

+ 0 - 1
plugins/map_mapkit_ios/ios/Classes/MapView/ViewModel/MapViewModel.swift

@@ -56,7 +56,6 @@ class MapViewModel: NSObject, ObservableObject, MapCapability {
         }
         
         self.markers = Array(markerDict.values)
-        print("Update Markers: --- \(markerDict["user_location"]?.markerType )")
         result(nil)
     }