2012-05-18 3 views
0

У меня есть объект CLLocation, который содержит текущее местоположение пользователя, и у меня есть 4 пары lat/long для каждого угла прямоугольника, который может быть под углом. Теперь я хочу проверить, находятся ли координаты CLLocation внутри этого прямоугольника.ios: lat/long внутри прямоугольника

Ниже приведены координаты прямоугольника

#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; 

}

+1

Ewwww ... одно предложение заключается в использовании 'CLLocationCoordinate2D' вместо массивов NSNumbers первой. Это сделает ваш код намного понятнее. Кроме того, вы не учитываете «point1» и «point2». – DarkDust

+0

да я должен изменить код для передачи CLLocationCoordinate2D вместо массивов –

+0

код изменен ... –

ответ

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)); 
} 
+0

выше решение работает для меня –

1

Давайте игнорировать, что прямоугольник для гео-координат на сфероид (математика трудно там). Итак, вы хотите узнать, находится ли точка в четырехугольниках.

Самый простой способ - сначала добавить ограничение: точки должны быть заданы в определенном порядке (NE, NW, SE, SW). Затем рассматривайте их как нормальные 2D-координаты (долгота = x, широта = y).

Следующий шаг - уменьшить проблему: пусть координаты образуют 2 треугольника, например NE-NW-SE и NW-SE-SW. Затем проверьте, есть ли ваш point is within one of those two triangles.

+0

приятное и короткое решение, но оно работает. У вас есть какой-нибудь пример кода? и является ли это x = долгота или x = широта? –

+0

Нет, я не стал писать образец кода, вы должны быть в состоянии сделать это самостоятельно :-) Долгота = восток-запад = х, широта = север-юг = у. – DarkDust

+0

Я написал код. Могу ли вы, пожалуйста, c, если все в порядке. Он не дает правильного результата все время. См. Мой ответ. –

6

Другой способ, чтобы определить, является ли какая-либо точка в карте прямоугольника использовать функции MKMapKit «s:

  1. MKMapPointForCoordinate - преобразование координат карта точек
  2. MKMapRectMake - создать прямоугольник с помощью этих точек
  3. MKMapRectContainsPoint - определить, существует ли заданная точка карты в пределах прямоугольника

Преимущество состоит в том, что MKMapKit (MKMapPoint, MKMapRect) использует проекцию Меркатора на карту Меркатора, поэтому вам не нужно предоставлять вычисления сфероида. Но некоторые из этих функций доступны в iOS 4.0 и более поздних версиях.

UPDATE:

// 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); 
+0

Как создать MKMapRect, используя четыре пары lat/long? –

+0

Также как создать MKMapPoint из CLLocationCoordinate2d? –

+0

Найти ответы в моем обновлении. – SVGreg

Смежные вопросы