|
|
@@ -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 {
|