ios:lat / long在矩形内

时间:2012-05-18 11:24:44

标签: ios core-location

我有CLLocation对象,其中包含用户的当前位置,并且我有一个矩形的每个角可以成角度的4个纬度/长对。现在我想检查CLLocation坐标是否在该矩形内。

以下是矩形的坐标

#define NorthEast_LAT 51.514894
#define NorthEast_LNG -0.135306
#define SouthEast_LAT 51.514831
#define SouthEast_LNG -0.135153
#define NorthWest_LAT 51.514719
#define NorthWest_LNG -0.135858
#define SouthWest_LAT 51.514556
#define SouthWest_LNG -0.135714

我尝试过以下代码,但我认为它只适用于矩形角度为0度的情况。

 BOOL withinRect = [delegate.CLController latlngWithInBox:location 
                                                    point1:CLLocationCoordinate2DMake(NorthEast_LAT, NorthEast_LNG) 
                                                    point2:CLLocationCoordinate2DMake(SouthEast_LAT, SouthEast_LNG) 
                                                    point3:CLLocationCoordinate2DMake(NorthWest_LAT, NorthWest_LNG)
                                                    point4:CLLocationCoordinate2DMake(SouthWest_LAT, SouthWest_LNG)];

 - (BOOL) latlngWithInBox:(CLLocation *)position point1:(CLLocationCoordinate2D)point1 point2:(CLLocationCoordinate2D)point2 point3:(CLLocationCoordinate2D)point3 point4:(CLLocationCoordinate2D)point4 {

if (position.coordinate.latitude >= point3.latitude && position.coordinate.latitude <= point2.latitude
    && position.coordinate.longitude >= point3.longitude && position.coordinate.longitude <= point2.longitude) {
    return YES;
}
return NO;

}

3 个答案:

答案 0 :(得分:8)

确定某个点是否在地图矩形内的另一种方法是使用MKMapKit的函数:

  1. MKMapPointForCoordinate - 将坐标转换为地图点
  2. MKMapRectMake - 使用这些点创建矩形
  3. MKMapRectContainsPoint - 确定指定的地图点是否位于 在矩形
  4. 优点是MKMapKit(MKMapPoint,MKMapRect)使用地图的墨卡托投影,因此您不需要提供球体计算。但是其中一些功能在iOS 4.0及更高版本中可用。

    更新:

    // 1 ------- 2
    // |         |
    // |      x  |
    // |         |
    // 3 ------- 4    
    
    // 1 = topLeftCorner
    // 4 = bottomRightCorner
    // x = targetCoordinate
    
    CLLocationCoordinate2D topLeftCorner = /* some coordinate */, bottomRightCorner = /* some coordinate */;
    CLLocationCoordinate2D targetCoordinate = /* some coordinate */;
    MKMapPoint topLeftPoint = MKMapPointForCoordinate(topLeftCorner);
    MKMapPoint bottomRightPoint = MKMapPointForCoordinate(bottomRightCorner);
    MKMapRect mapRect = MKMapRectMake(topLeftPoint.x, topLeftPoint.y, bottomRightPoint.x - topLeftPoint.x, bottomRightPoint.y - topLeftPoint.y);
    MKMapPoint targetPoint = MKMapPointForCoordinate(targetCoordinate);   
    
    BOOL isInside = MKMapRectContainsPoint(mapRect, targetPoint);
    

答案 1 :(得分:1)

让我们忽略地理坐标的矩形在球体上(数学很困难)。所以你想知道一个点是否在四边形内。

最简单的方法是首先添加限制:必须以特定顺序(NE,NW,SE,SW)给出点。然后,将它们视为普通的二维坐标(经度= x,纬度= y)。

下一步是减少问题:让坐标形成2个三角形,例如NE-NW-SE和NW-SE-SW。然后检查您的point is within one of those two triangles

答案 2 :(得分:0)

- (BOOL) latlngWithInBox:(CLLocation *)position point1:(CLLocationCoordinate2D)point1 point2:(CLLocationCoordinate2D)point2 point3:(CLLocationCoordinate2D)point3 point4:(CLLocationCoordinate2D)point4 {
    //&& position.coordinate.latitude >= [[point4 objectAtIndex:0] floatValue] && position.coordinate.latitude <= [[point1 objectAtIndex:0] floatValue] && position.coordinate.longitude <= [[point4 objectAtIndex:1] floatValue] && position.coordinate.longitude >= [[point1 objectAtIndex:1] floatValue]
    if (PointInTriangle(position.coordinate, point1, point2, point3) || PointInTriangle(position.coordinate, point2, point3, point4)) {
        return YES;
    }
    return NO;
}

float sign(CLLocationCoordinate2D p1, CLLocationCoordinate2D p2, CLLocationCoordinate2D p3)
{
    return (p1.longitude - p3.longitude) * (p2.latitude - p3.latitude) - (p2.longitude - p3.longitude) * (p1.latitude - p3.latitude);
}

bool PointInTriangle(CLLocationCoordinate2D pt, CLLocationCoordinate2D v1, CLLocationCoordinate2D v2, CLLocationCoordinate2D v3)
{
    bool b1, b2, b3;

    b1 = sign(pt, v1, v2) < 0.0f;
    b2 = sign(pt, v2, v3) < 0.0f;
    b3 = sign(pt, v3, v1) < 0.0f;

//    NSLog(@"b1-%@", [NSNumber numberWithBool:b1]);
//    NSLog(@"b2-%@", [NSNumber numberWithBool:b2]);
//    NSLog(@"b3-%@", [NSNumber numberWithBool:b3]);

    return ((b1 == b2) && (b2 == b3));
}