检查用户位置是否在形状内

时间:2016-03-15 16:21:59

标签: ios swift mapkit userlocation mkpolygon

我使用此方法检查用户位置是否在地图视图(mapkit)的多边形内。 我将方法传递给当前用户位置(CLLocationCoordinate2D)并返回一个布尔值,以便知道用户是否在多边形中。

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
}

我不太明白为什么,但在此测试后,用户永远不会在多边形内部。 (而且我很确定他是)

我认为我可能存在针对x,y的lat / long的逻辑问题。

有人已经有这样的工作吗?

提前感谢所有建议。

干杯

2 个答案:

答案 0 :(得分:2)

问题是您要将userLocation从地图坐标转换为视图坐标,但在构建路径时,您不必将这些点转换为视图坐标。

您需要将MKMapPoint转换为CLLocationCoordinate2D,然后转换为CGPoint

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

然后在构建路径时使用polygonPoint

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

答案 1 :(得分:1)

Swift 3,Xcode 8回答:

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
}