Comment puis-je vérifier si un CLLocationCoordinate2D se trouve dans quatre CLLocationCoordinate2D Square? en Objective C avec Google Maps

Je veux tester si un CLLocationCoordinate2D est dans un carré créé à partir de quatre autres CLLocationCoordinate2D

J'ai une structure comme celle-ci:

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

Et une coordonnée CLLocationCoordinate2D transmise en tant que param. Et je veux tester si la coordonnée est à l'intérieur des bornes. Comment puis-je tester cela?

 - (BOOL) isCoordinate:(CLLocationCoordinate2D)coordinate insideBounds:(Bounds)bounds { ... } 

Si vous avez quatre points, vous pouvez créer un CGRect et utiliser CGRectContainsPoint ()

Si les 4 points ne représentent pas un rectangle ou un cercle mais 4 points sur la carte, vous devrez créer le système vous-même. Pour qu'un point soit à l'intérieur d'une forme représentée par 4 points orientés, il est plus facile de vérifier le produit croisé entre le centre et chaque paire séquentielle de points limites. Tous les résultats doivent être positifs dans le sens des aiguilles d'une montre pour que le point soit à l'intérieur des limites. La deuxième chose est que vous devez convertir les coordonnées en système cartésien et les orienter … Laissez le code parler de lui-même:

 - (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 sortingangles and check their orientation by using az 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 mapsian 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 mapsicly 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; } 

Et quelques tests simples pourraient être utiles:

 - (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); } 

Tout cela passe pour moi. Si vous trouvez une situation qui ne fonctionne pas mais que vous devriez le faire, ou contactez-moi.

Vous venez de créer une CLregion ou une CLCircularRegion et de vérifier si la coordonnée est contenue dans la région …

Comme ça

 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 }