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
委托功能,请阅读一两个核心位置教程。
如何检测用户位置是否在 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
委托功能,请阅读一两个核心位置教程。