10

此刻,我试图弄清楚 MKMapView 上的坐标是否在提前绘制的具有纬度/经度的 MKPolygon 内。

我正在使用 CGPathContainsPoint 来确定坐标是否在地图上的多边形内,但无论我选择什么坐标,它总是返回 false。

谁能解释一下到底出了什么问题?下面是我在 Swift 中的代码。

class ViewController: UIViewController, MKMapViewDelegate

@IBOutlet weak var mapView: MKMapView!

    let initialLocation = CLLocation(latitude: 43.656734, longitude: -79.381576)
    let point = CGPointMake(43.656734, -79.381576)
    let regionRadius: CLLocationDistance = 500
    let point1 = CLLocationCoordinate2D(latitude: 43.656734, longitude: -79.381576)

    var points = [CLLocationCoordinate2DMake(43.655782, -79.382094),
        CLLocationCoordinate2DMake(43.657499, -79.382310),
        CLLocationCoordinate2DMake(43.656656, -79.380497),
        CLLocationCoordinate2DMake(43.655782, -79.382094)]

    override func viewDidLoad() {
        super.viewDidLoad()

        centerMapOnLocation(initialLocation)

        let polygon = MKPolygon(coordinates: &points, count: points.count)
        mapView.addOverlay(polygon)

        var annotation = MKPointAnnotation()
        annotation.coordinate = point1
        annotation.title = "Test"
        annotation.subtitle = "Test"

        mapView.addAnnotation(annotation)
        self.mapView.delegate = self

    }

    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.redColor()

            if  CGPathContainsPoint(polygonView.path, nil, CGPointMake(43.656734, -79.381576), true) {
                print("True!!!!!")
            } else {
                println("False")
            }

            return polygonView
        }
        return nil
    }
4

3 回答 3

12

UPDATED FOR SWIFT 4

You are confusing CGPoints, which are x and y coordinate pairs that point to a location on your view, with CLLocationCoordinate2Ds, which are coordinates on Earth.

For CGPathContainsPoint, you want to pass in your polygonRenderer path (created from your polygon in viewDidLoad()) and current location like this:

let polygonRenderer = MKPolygonRenderer(polygon: polygon)
let mapPoint: MKMapPoint = MKMapPointForCoordinate(coordinate)
let polygonViewPoint: CGPoint = polygonRenderer.pointForMapPoint(mapPoint)

if polygonRenderer.path.contains(polygonViewPoint) {
    print("Your location was inside your polygon.")
}

So you want to think about where you should be putting this code, as where you currently have it is inside the function that gets called whenever an MKOverlay gets drawn on screen, and that is completely unrelated to this.

于 2016-04-13T20:13:02.013 回答
7

为 Swift 3 更新

let polygonRenderer = MKPolygonRenderer(polygon: polygon)
let mapPoint: MKMapPoint = MKMapPointForCoordinate(coordinate)
let polygonViewPoint: CGPoint = polygonRenderer.point(for: mapPoint)

if polygonRenderer.path.contains(polygonViewPoint)
{
    print("Your location was inside your polygon.")
}
于 2017-03-13T12:08:20.330 回答
0

Swift 5 的解决方案:

由于 renderer.path 的 contains 方法需要点为 CGPoint,我们需要通过 MKMapPoint 将其从地理坐标转换为 rederer 的点,否则结果将出乎意料。

@objc
func mapTapped(_ tap: UILongPressGestureRecognizer) {

    if tap.state == .recognized {
        let touchPoint = tap.location(in: mapView)
        let coord = mapView.convert(touchPoint, toCoordinateFrom: mapView)

        for overlay: MKOverlay in mapView.overlays {

            if let polygon = overlay as? MKPolygon {
                let renderer = MKPolygonRenderer(polygon: polygon)
                let mapPoint = MKMapPoint(coord)
                let rendererPoint = renderer.point(for: mapPoint)

                if renderer.path.contains(rendererPoint) {
                    // here comes your code
                }
            }
        }
    }
}

于 2020-11-02T15:33:02.937 回答