Check if user location is inside a shape

北战南征 提交于 2019-12-21 06:38:16

问题


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


回答1:


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)



回答2:


Swift 3, Xcode 8 answer:

func userInsidePolygon(userlocation: CLLocationCoordinate2D ) -> Bool {
    var containsPoint: Bool = false
    // 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:CGMutablePath  = CGMutablePath()
            // get points of polygon
            let arrPoints = polygon.points()
            // create cgpath
            for i in 0..<polygon.pointCount {

                let polygonMapPoint: MKMapPoint = arrPoints[i]
                let polygonCoordinate = MKCoordinateForMapPoint(polygonMapPoint)
                let polygonPoint = self.mapView.convert(polygonCoordinate, toPointTo: self.mapView)

                if (i == 0){
                    polygonPath.move(to: CGPoint(x: polygonPoint.x, y: polygonPoint.y))
                }
                else{
                    polygonPath.addLine(to: CGPoint(x: polygonPoint.x, y: polygonPoint.y))
                }
            }
            let mapPointAsCGP:CGPoint = self.mapView.convert(userlocation, toPointTo: self.mapView)
            containsPoint =  polygonPath.contains(mapPointAsCGP)
            if containsPoint {
                return true
            }
        }
    }
    return containsPoint
}


来源:https://stackoverflow.com/questions/36016764/check-if-user-location-is-inside-a-shape

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!