Search code examples
iosswiftmapkituserlocationmkpolygon

Check if user location is inside a shape


I made this method to check if an user location is inside a polygon on a map view (mapkit). I pass to the method the current user location (CLLocationCoordinate2D) and return a boolean just to know if the user is in a polygon or not.

func userInsidePolygon(userlocation: CLLocationCoordinate2D ) -> Bool{
    // get every overlay on the map  
    let o = self.mapView.overlays
    // loop every overlay on map
    for overlay in o {
        // handle only polygon
        if overlay is MKPolygon{
            let polygon:MKPolygon =  overlay as! MKPolygon
            let polygonPath:CGMutablePathRef  = CGPathCreateMutable()
            // get points of polygon
            let arrPoints = polygon.points()
            // create cgpath
            for (var i:Int=0; i < polygon.pointCount; i++){
                let mp:MKMapPoint = arrPoints[i]
                if (i == 0){
                    CGPathMoveToPoint(polygonPath, nil, CGFloat(mp.x), CGFloat(mp.y))
                }
                else{
                    CGPathAddLineToPoint(polygonPath, nil, CGFloat(mp.x), CGFloat(mp.y))
                }
            }
            let mapPointAsCGP:CGPoint = self.mapView.convertCoordinate(userlocation, toPointToView: self.mapView)
            return CGPathContainsPoint(polygonPath , nil, mapPointAsCGP, false)
        }
    }
    return false
}

I don't really understand why, but the user is never inside a polygon after this test. (and i'm pretty sure he is)

I think it's possible that i have a logic problem with lat/long against x,y.

Does anybody already have work with like this ?

Thanks in advance for all suggestions.

Cheers


Solution

  • The problem is that you are converting the userLocation from the map coordinates to the view coordinates but when you build the path, you don't convert the points to the views coordinates.

    You'll need to convert the MKMapPoint to a CLLocationCoordinate2D then to a CGPoint.

    let polygonMapPoint: MKMapPoint = arrPoints[i]
    let polygonCoordinate = MKCoordinateForMapPoint(polygonPoint)
    let polygonPoint self.mapView.convertCoordinate(polygonPointAsCoordinate, toPointToView: self.mapView)
    

    Then use polygonPoint when building the path

    CGPathMoveToPoint(polygonPath, nil, polygonPoint.x, polygonPoint.y)