SwiftUI - как узнать, находится ли пользователь в MKPolygon? - PullRequest
0 голосов
/ 04 августа 2020

Как я могу определить, находится ли пользователь в MKPolygon? Я попытался найти что-то вроде этого:

проверить, что текущее местоположение находится в 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)
        }
    }
}

Файл mapView:

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)*/
    }
}

Файл LocationManager:

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, который является местоположением пользователя

Я надеюсь, что теперь редактирование более детализировано

1 Ответ

0 голосов
/ 07 августа 2020

Я не вижу никакого кода, который действительно обрабатывает обновления местоположения?

Предполагается, что вы реализовали это в своем LocationManager в строках:

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

Ваша проблема Строка c изменится с:

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)

Если вы уже реализовали not делегат fun didUpdateLocations c, прочтите один или два урока по базовому местоположению.

...