Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determining if Latitude/Longitude Point is in a MKPolygon within Mapview?

At this moment, I am trying to figure out whether a coordinate on a MKMapView is within a MKPolygon drawn out ahead of time with latitudes/longitudes.

I am using CGPathContainsPoint to determine whether a coordinate is within the polygon on the map but it always returns false regardless of the coordinate I choose.

Can anyone please explain what exactly is going wrong? Below is my code in 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
    }
like image 604
M_Jean Avatar asked Aug 21 '15 20:08

M_Jean


2 Answers

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.

like image 135
andrewcar Avatar answered Nov 20 '22 00:11

andrewcar


Updated for 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.")
}
like image 7
Russell Avatar answered Nov 20 '22 01:11

Russell