MKPolygon – 如何确定CLLocationCoordinate2D是否在CLLocationCoordinate2D多边形?

我有下面的swift代码绘制一个多边形,并在MKMapView上放下注释。 我想弄清楚如何我可以确定注释的坐标是否在多边形内?

import UIKit import MapKit class ViewController: UIViewController { @IBOutlet weak var mapView: MKMapView! override func viewDidLoad() { super.viewDidLoad() let initialLocation = CLLocation(latitude: 49.140838, longitude: -123.127886) centerMapOnLocation(initialLocation) addBoundry() var annotation = MKPointAnnotation() annotation.coordinate = point1 annotation.title = "Roatan" annotation.subtitle = "Honduras" mapView.addAnnotation(annotation) } var points = [CLLocationCoordinate2DMake(49.142677, -123.135139), CLLocationCoordinate2DMake(49.142730, -123.125794), CLLocationCoordinate2DMake(49.140874, -123.125805), CLLocationCoordinate2DMake(49.140885, -123.135214)] var point1 = CLLocationCoordinate2DMake(49.141821, -123.131577) func addBoundry() { let polygon = MKPolygon(coordinates: &points, count: points.count) mapView.addOverlay(polygon) } let regionRadius: CLLocationDistance = 1000 func centerMapOnLocation(location: CLLocation) { let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius * 2.0, regionRadius * 2.0) mapView.setRegion(coordinateRegion, animated: true) } func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! { if overlay is MKPolygon { let polygonView = MKPolygonRenderer(overlay: overlay) polygonView.strokeColor = UIColor.magentaColor() return polygonView } return nil } } 

 - (BOOL)isPoint:(MKMapPoint)point insidePolygon:(MKPolygon *)poly { MKMapPoint *a = poly.points; BOOL isInsidePolygon = NO; double testx = point.x; double testy = point.y; NSUInteger i = 0, j = 0, nvert = [poly pointCount]; for (i = 0, j = nvert - 1; i < nvert; j = i++) { if (((a[i].y >= testy) != (a[j].y >= testy)) && (testx <= (a[j].x - a[i].x) * (testy - a[i].y) / (a[j].y - a[i].y) + a[i].x)) { isInsidePolygon = !isInsidePolygon; } } return isInsidePolygon; } 

因为点xy在墨卡托投影坐标中,这是有道理的,您不需要转换为球面坐标进行计算。

为什么这里是一个正确的计算。

编辑:更新,以便计算也考虑行内的一个点作为聚合内。

如何使用MkPolygon.intersect()? 这需要将点转换成一个小小的MKMapRect,但它更简单,并可能从底层API获得一些加速:

 func pointIsInside(point: MKMapPoint, polygon: MKPolygon) -> Bool { let mapRect = MKMapRectMake(point.x, point.y, 0.0001, 0.0001) return polygon.intersects(mapRect) }