Reputation: 4835
I have got CLLocation object which contains current location of user and I have got 4 lat/long pairs for each corner of a rectangle which can be angled. Now I want to check whether CLLocation coordinates are within that rectangle.
Following are the coordinates of the rectangle
#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
I have tried following code but I think it will only work when angle of rectangle is 0 deg.
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;
}
Upvotes: 1
Views: 3424
Reputation: 2368
Another way to determine whether some point is within map rectangle is to use MKMapKit
's functions:
MKMapPointForCoordinate
- convert coordinate to map point MKMapRectMake
- to create rect using these points MKMapRectContainsPoint
- determine if specified map point lies
within the rectangleThe advantage is that MKMapKit (MKMapPoint, MKMapRect) uses Mercator projection of the map, so you do not need to provide spheroid calculations. But some of these functions available in iOS 4.0 and later.
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);
Upvotes: 8
Reputation: 4835
- (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));
}
Upvotes: 0
Reputation: 92316
Let's ignore that the rectangle for geo-coordinates is on a spheroid (math is difficult there). So you want to find out whether a point is within a quadrangle.
Easiest way is to first add a restriction: the points have to be given in a certain order (NE, NW, SE, SW). Then, treat them as normal 2D-coordinates (longitude = x, latitude = y).
Next step is to reduce the problem: let the coordinates form 2 triangles, for example NE-NW-SE and NW-SE-SW. Then check whether your point is within one of those two triangles.
Upvotes: 1