How can I check if CLLocationCoordinate2D is inside four CLLocationCoordinate2D Square? in Objective-C using Google Maps

I want to check if CLLocationCoordinate2D is inside a Square created from the other four CLLocationCoordinate2D

I have a structure like this:

typedef struct {
    CLLocationCoordinate2D southWest;
    CLLocationCoordinate2D southEast;
    CLLocationCoordinate2D northEast;
    CLLocationCoordinate2D northWest;
} Bounds;

And the CLLocationCoordinate2D coordinate is passed as a parameter. And I want to check if the coordinate is inside the borders. How can I check this?

- (BOOL) isCoordinate:(CLLocationCoordinate2D)coordinate insideBounds:(Bounds)bounds { ... }
+4
source share
3 answers

If you have four points, you can make a CGRect and use CGRectContainsPoint ()

+2
source

You simply create CLregionor CLCircularRegionand check if the coordinate is contained within the area ...

Like this

CLCircularRegion *myRegion = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(22, -111) radius:500 identifier:@"myRegion"];
if ([myRegion containsCoordinate:CLLocationCoordinate2DMake(22.45, -111.1)]) {
    //Do what you want here
}
+1

4 , 4 , . , 4 , . , . -, ... :

- (double)crossProductZCoordinateForCenter:(CLLocationCoordinate2D)center left:(CLLocationCoordinate2D)left right:(CLLocationCoordinate2D)right {
    CLLocationCoordinate2D A = CLLocationCoordinate2DMake(left.latitude-center.latitude, left.longitude-center.longitude);
    CLLocationCoordinate2D B = CLLocationCoordinate2DMake(right.latitude-center.latitude, right.longitude-center.longitude);

    return B.latitude*A.longitude - A.latitude*B.longitude;
}

- (BOOL)isCartesianCoordinate:(CLLocationCoordinate2D)coordinate insideBounds:(Bounds)bounds {
    // Now we will break the system into 4 triangles and check their orientation by using a z component of the cross product. If one of them if negative the coordinate is not inside the region
    if([self crossProductZCoordinateForCenter:coordinate left:bounds.southWest right:bounds.northWest] < .0) return NO;
    if([self crossProductZCoordinateForCenter:coordinate left:bounds.northWest right:bounds.northEast] < .0) return NO;
    if([self crossProductZCoordinateForCenter:coordinate left:bounds.northEast right:bounds.southEast] < .0) return NO;
    if([self crossProductZCoordinateForCenter:coordinate left:bounds.southEast right:bounds.southWest] < .0) return NO;
    return YES;
}

- (BOOL)isCoordinate:(CLLocationCoordinate2D)coordinate insideBounds:(Bounds)bounds {
    // We may treat the coordinates as cartesian but east should always be larger then west and north should be larger then south
    // Those smaller must be increased by 360 degrees
    if(bounds.southEast.latitude < bounds.southWest.latitude) bounds.southEast.latitude += 360.0;
    if(bounds.northEast.latitude < bounds.northWest.latitude) bounds.northEast.latitude += 360.0;
    if(bounds.northEast.longitude < bounds.southEast.longitude) bounds.northEast.longitude += 360.0;
    if(bounds.northWest.longitude < bounds.southWest.longitude) bounds.northWest.longitude += 360.0;
    // Check if any of the combination coordinates are cartesicly inside the bounds
    // We need to increase the longitude and the latitude by 360 and check all 4 combinations
    if([self isCartesianCoordinate:coordinate insideBounds:bounds]) return YES;
    if([self isCartesianCoordinate:CLLocationCoordinate2DMake(coordinate.latitude+360.0, coordinate.longitude) insideBounds:bounds]) return YES;
    if([self isCartesianCoordinate:CLLocationCoordinate2DMake(coordinate.latitude, coordinate.longitude+360.0) insideBounds:bounds]) return YES;
    if([self isCartesianCoordinate:CLLocationCoordinate2DMake(coordinate.latitude+360.0, coordinate.longitude+360.0) insideBounds:bounds]) return YES;
    return NO;
}

:

- (void)resampleCoordinate:(CLLocationCoordinate2D *)coordinate {
    if(coordinate->latitude < -180.0) coordinate->latitude += 360.0;
    if(coordinate->latitude > 180.0) coordinate->latitude -= 360.0;
    if(coordinate->longitude < -180.0) coordinate->longitude += 360.0;
    if(coordinate->longitude > 180.0) coordinate->longitude -= 360.0;
}

- (void)testLocationSystem {
    NSInteger numberOfTests = 0;
    NSInteger numberOfTestsCheckedOut = 0;

    for(double latitude = -180.0; latitude <= 180.0; latitude++) {
        for(double longitude = -180.0; longitude <= 180.0; longitude++) {
            Bounds bounds;
            bounds.southWest = CLLocationCoordinate2DMake(latitude-15.0, longitude-15.0);
            bounds.northEast = CLLocationCoordinate2DMake(latitude+15.0, longitude+15.0);
            bounds.northWest = CLLocationCoordinate2DMake(latitude-15.0, longitude+15.0);
            bounds.southEast = CLLocationCoordinate2DMake(latitude+15.0, longitude-15.0);
            [self resampleCoordinate:&(bounds.northWest)];
            [self resampleCoordinate:&(bounds.northEast)];
            [self resampleCoordinate:&(bounds.southEast)];
            [self resampleCoordinate:&(bounds.southWest)];

            numberOfTests++;
            BOOL success = [self isCoordinate:CLLocationCoordinate2DMake(latitude, longitude) insideBounds:bounds];
            if(success) {
                numberOfTestsCheckedOut++;
            }
            else {
                NSLog(@"Failed");
            }
        }
    }
    NSLog(@"%d/%d succeeded", (int)numberOfTestsCheckedOut, (int)numberOfTests);
}
- (void)testLocationFailSystem {
    NSInteger numberOfTests = 0;
    NSInteger numberOfTestsCheckedOut = 0;

    for(double latitude = -180.0; latitude <= 180.0; latitude++) {
        for(double longitude = -180.0; longitude <= 180.0; longitude++) {
            Bounds bounds;
            bounds.southWest = CLLocationCoordinate2DMake(latitude-15.0, longitude-15.0);
            bounds.northEast = CLLocationCoordinate2DMake(latitude+15.0, longitude+15.0);
            bounds.northWest = CLLocationCoordinate2DMake(latitude-15.0, longitude+15.0);
            bounds.southEast = CLLocationCoordinate2DMake(latitude+15.0, longitude-15.0);
            [self resampleCoordinate:&(bounds.northWest)];
            [self resampleCoordinate:&(bounds.northEast)];
            [self resampleCoordinate:&(bounds.southEast)];
            [self resampleCoordinate:&(bounds.southWest)];

            for(double angle = .0f; angle < M_PI; angle+=M_PI/10.0) {
                CLLocationCoordinate2D coordiunate = CLLocationCoordinate2DMake(latitude+cos(angle)*20.0, longitude+sin(angle)*20.0);
                [self resampleCoordinate:&coordiunate];

                numberOfTests++;

                BOOL success = [self isCoordinate:coordiunate insideBounds:bounds]; // must fail
                if(success == NO) {
                    numberOfTestsCheckedOut++;
                }
                else {
                    NSLog(@"Failed");
                }
            }

        }
    }
    NSLog(@"%d/%d succeeded", (int)numberOfTestsCheckedOut, (int)numberOfTests);
}

. , , , , .

+1

All Articles