SwiftUI - 如何知道用户位置是否在 MKPolygon 中?

SwiftUI - how to know if the user location is in a MKPolygon?

如何检测用户位置是否在 MKPolygon 中? 我试图搜索类似的内容:

check current location is in MkPolygons

但答案是旧的,所以它不适合当前的代码。 这是协调器文件

import MapKit

final class Coordinator: NSObject, MKMapViewDelegate {
var parent: MapView

init(_ parent: MapView) {
    self.parent = parent
}

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if overlay is ModelMapOverlay {
        return ModelMapOverlayView(overlay: overlay, overlayImage: UIImage(imageLiteralResourceName: "overlay_model"))
    } else if overlay is MKPolyline {
        let lineView = MKPolylineRenderer(overlay: overlay)
        lineView.strokeColor = .green

        return lineView
    } else if overlay is MKPolygon {
        let polygonView = MKPolygonRenderer(overlay: overlay)
        
        if theme == "Ciano" {
            polygonView.strokeColor = .init(red: 0/255, green: 255/255, blue: 255/255, alpha: 0.66)
            polygonView.fillColor = .init(red: 0/255, green: 255/255, blue: 255/255, alpha: 0.1)
        } else if theme == "Rosso" {
            polygonView.strokeColor = .init(red: 255/255, green: 0/255, blue: 0/255, alpha: 0.66)
            polygonView.fillColor = .init(red: 255/255, green: 0/255, blue: 0/255, alpha: 0.1)
        } else if theme == "Verde" {
            polygonView.strokeColor = .init(red: 0/255, green: 255/255, blue: 0/255, alpha: 0.66)
            polygonView.fillColor = .init(red: 0/255, green: 255/255, blue: 0/255, alpha: 0.1)
        } else if theme == "Magenta" {
            polygonView.strokeColor = .init(red: 255/255, green: 0/255, blue: 255/255, alpha: 0.66)
            polygonView.fillColor = .init(red: 255/255, green: 0/255, blue: 255/255, alpha: 0.1)
        } else if theme == "Giallo" {
            polygonView.strokeColor = .init(red: 255/255, green: 255/255, blue: 0/255, alpha: 0.66)
            polygonView.fillColor = .init(red: 255/255, green: 255/255, blue: 0/255, alpha: 0.1)
        } else if theme == "Arancione" {
            polygonView.strokeColor = .init(red: 255/255, green: 153/255, blue: 51/255, alpha: 0.66)
            polygonView.fillColor = .init(red: 255/255, green: 153/255, blue: 51/255, alpha: 0.1)
        } else if theme == "Verde Turchese" {
            polygonView.strokeColor = .init(red: 50/255, green: 198/255, blue: 166/255, alpha: 0.66)
            polygonView.fillColor = .init(red: 50/255, green: 198/255, blue: 166/255, alpha: 0.1)
        } else if theme == "Blu" {
            polygonView.strokeColor = .init(red: 0/255, green: 66/255, blue: 255/255, alpha: 0.66)
            polygonView.fillColor = .init(red: 0/255, green: 66/255, blue: 255/255, alpha: 0.1)
        }/* else {
            polygonView.strokeColor = .init(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)
            polygonView.fillColor = .init(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)
        }*/
        polygonView.alpha = 1.0
        polygonView.lineWidth = 5.0
        
        return polygonView

    } else if let character = overlay as? Character {
        let circleView = MKCircleRenderer(overlay: character)
        circleView.strokeColor = character.color
        return circleView
    }

    return MKOverlayRenderer()
}

extension MKPolygon {
    func isCoordinateInsidePolyon(coordinate: CLLocationCoordinate2D) -> Bool {
        let polygonRenderer = MKPolygonRenderer(polygon: self)
        let currentMapPoint: MKMapPoint = MKMapPoint(coordinate)
        let polygonViewPoint: CGPoint = polygonRenderer.point(for: currentMapPoint)
        if polygonRenderer.path == nil {
            return false
        } else {
            return polygonRenderer.path.contains(polygonViewPoint)
        }
    }
}

地图视图文件:

import SwiftUI
import MapKit

let model = Model(filename: "ZONE_LIST")
var mapView = MKMapView() // (frame: UIScreen.main.bounds)

var theme = ""

struct MapView: UIViewRepresentable {
    
    //var coordinates: CLLocationCoordinate2D
    
    func makeUIView(context: Context) -> MKMapView {
        let latDelta = model.overlayTopLeftCoordinate.latitude - model.overlayBottomRightCoordinate.latitude

        let rootSpan = MKCoordinateSpan(latitudeDelta: fabs(latDelta), longitudeDelta: 0.99)
        let rootRegion = MKCoordinateRegion(center: model.midCoordinate, span: rootSpan)
        
        mapView.showsUserLocation = true
        
        mapView.region = rootRegion
        mapView.delegate = context.coordinator
        
        mapView.userLocation.title = "WILLIAMONE" // 39,9873 | 18,2420
        
        return mapView
    }
        
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
        
    func updateUIView(_ uiView: MKMapView, context: UIViewRepresentableContext<MapView>) {
        /*let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
        let region = MKCoordinateRegion(center: coordinates, span: span)
        mapView.setRegion(region, animated: true)*/
    }
}

位置管理器文件:

import MapKit

class LocationManager: NSObject, CLLocationManagerDelegate {
    
    private let locationManager = CLLocationManager()
    var location: CLLocation? = nil
    
    override init() {
        super.init()
        if CLLocationManager.locationServicesEnabled() {
            self.locationManager.delegate = self
            self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
            self.locationManager.distanceFilter = kCLDistanceFilterNone
            self.locationManager.requestWhenInUseAuthorization()
            self.locationManager.startUpdatingLocation()
        }
    }
}

在内容视图中:

import SwiftUI
import MapKit

struct ContentView: View {
    
    private var locationManager = LocationManager()
    @State var isInArea: Bool = false

然后在正文中我使用了这个调用区域的函数和你与我分享的代码片段,我亲爱的好朋友:)

mapView.addOverlay(MKPolygon(coordinates: model.zona40, count: model.zona40.count)) // LECCE TANGENZIALE EST

self.isInArea = MKPolygon(coordinates: model.zona40, count: model.zona40.count).isCoordinateInsidePolyon(coordinate: locationManager)

错误是参数需要一个 CLLocationCoordinate2D 而不是我的 LocationManager 即用户位置

希望现在的编辑更详细

我没有看到任何实际处理位置更新的代码?

假设您已经在 LocationManager 中按照以下行实施了:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let loc = locations.first {
        self.location = loc
    }
}

您的问题行将从:

self.isInArea = MKPolygon(coordinates: model.zona40, count: model.zona40.count).isCoordinateInsidePolyon(coordinate: locationManager)

至:

guard let c2D = self.locationManager.location?.coordinate else {
    return
}

self.isInArea = MKPolygon(coordinates: model.zona40, count: model.zona40.count).isCoordinateInsidePolyon(coordinate: c2D)

如果您没有已经实现了didUpdateLocations委托功能,请阅读一两个核心位置教程。