在iPhone sdk ios 7中检测一个点是否在MKCircle内部

5

我在我的mapview上添加了一个MKCircle覆盖层,我想知道一个点(在屏幕上的点击)是否在圆内。这是我的代码:

- (BOOL)pointInsideOverlay:(CLLocationCoordinate2D )tapPoint overlay:(id<MKOverlay>)overlay  {

   BOOL isInside = FALSE;
   MKPolygonView *polygonView = (MKPolygonView *)[self.mapView viewForOverlay:overlay];
   MKMapPoint mapPoint = MKMapPointForCoordinate(tapPoint);
   CGPoint polygonViewPoint = [polygonView pointForMapPoint:mapPoint];
   BOOL mapCoordinateIsInPolygon = CGPathContainsPoint(polygonView.path, NULL, polygonViewPoint, NO);

   if (mapCoordinateIsInPolygon) {
       isInside = TRUE;
   }
   return isInside;
}

viewForOverlaypointForMapPointpath已经过时了。这是问题所在吗?

谢谢。


对于一个圆,你不需要使用CGPathContainsPoint(但是对于iOS 7中的多边形,请参见https://dev59.com/Y2Mk5IYBdhLWcg3wvAVo)。正如答案所说,你只需检查从中心到半径的距离是否小于或等于半径。然而,你可能想使用CLLocation的distanceFromLocation方法或MapKit的MKMetersBetweenMapPoints函数,这些方法考虑了地球的曲面。 - user467105
谢谢。我使用distanceFromLocation来完成它。非常感谢 :) - aminovic09
3个回答

11

这种方法也应该有效,可以使用MKCircleRenderer

    MKCircleRenderer *circleRenderer = (MKCircleRenderer *)[mapview rendererForOverlay:circleOverlay];
    [circleRenderer invalidatePath];

    MKMapPoint mapPoint = MKMapPointForCoordinate(tapPoint);
    CGPoint circlePoint = [circleRenderer pointForMapPoint:mapPoint];
    BOOL mapCoordinateIsInCircle = CGPathContainsPoint(circleRenderer.path, NULL, circlePoint, NO);

    if ( mapCoordinateIsInCircle )

    {
        //do something
    }

非常感谢,Harri :) - aminovic09
1
invalidatePath是什么,为什么需要它? - MonkeyBonkey
1
@Harri,我和MonkeyBonkey有同样的问题 - 为什么要invalidatePath?我删除了它,因为我没有看到需要。我错过了什么吗? - knarf
在 @MonkeyBonkey 的触发下,我改变了 MKCircleRenderer 的颜色,并使用 invalidatePath 使路径重新绘制,从而实现了漂亮干净的颜色变化(即没有 UI 故障)。 - tentmaking

0
Fogmeisters的答案是不正确的,因为表达点和半径的单位系统是不同的。点是以度数表示,而半径通常以米为单位表示。Aminovic09的答案是正确的,并且是建议使用的答案,因为它利用了iOS自己的距离计算方法。

0
如果您知道圆的中心和半径,那么您可以做类似于以下的操作...
-(BOOL)isPoint:(CGPoint)point insideCircleCentre:(CGPoint)centre radius:(CGFloat)radius
{
    CGFloat dx = point.x - centre.x;
    CGFloat dy = point.y - centre.y;

    CGFloat distance = sqrtf(dx * dx + dy * dy);

    return distance <= radius;
}

2
谢谢。我使用distanceFromLocation来实现它。-(BOOL)isPoint:(CLLocationCoordinate2D)point insideCircleCentre:(CLLocationCoordinate2D)centre radius:(CGFloat)radius {CLLocation *pointALocation = [[CLLocation alloc] initWithLatitude:point.latitude longitude:point.longitude]; CLLocation *pointBLocation = [[CLLocation alloc] initWithLatitude:centre.latitude longitude:centre.longitude]; double distanceMeters = [pointALocation distanceFromLocation:pointBLocation]; if (distanceMeters > radius) { return NO; } else { return YES; }} - aminovic09

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接