我如何比较两个CLLocationCoordinate2D? (iPhone / ipad公司)

我需要一种比较两个CLLocationCoordinate2D的方式,但是当我尝试使用==它不会工作。 请有人可以帮助我比较他们的最佳方式吗?

要么比较任何给定结构types的两个实例的通用方法:

 memcmp(&cllc2d1, &second_cllc2d, sizeof(CLLocationCoordinate2D)) 

要么

 cllc2d1.latitude == cllc2d2.latitude && cllc2d1.longitude == cllc2d2.longitude 

应该工作,如果你真的想确定他们是完全平等的。 但是,鉴于经度和纬度被定义为双打,你可能真的想做一个“足够接近”的比较:

 fabs(cllc2d1.latitude - cllc2d2.latitude) <= epsilon && fabs(cllc2d1.longitude - cllc2d2.longitude) <= epsilon 

epsilon是你想要接受的任何级别的错误。

作为所有这些答案的一个小补充,将比较定义为预处理器定义是非常方便的:

 #define CLCOORDINATES_EQUAL( coord1, coord2 ) (coord1.latitude == coord2.latitude && coord1.longitude == coord2.longitude) 

或与epsilon:

 #define CLCOORDINATE_EPSILON 0.005f #define CLCOORDINATES_EQUAL2( coord1, coord2 ) (fabs(coord1.latitude - coord2.latitude) < CLCOORDINATE_EPSILON && fabs(coord1.longitude - coord2.longitude) < CLCOORDINATE_EPSILON) 

这可以让你做一个比较如下:

 CLLocationCoordinate2D resultingCoordinate = ... a method call ...; CLLocationCoordinate2D expectedCoordinate = CLLocationCoordinate2DMake(48.11, 11.12); if(CLCOORDINATES_EQUAL( resultingCoordinate, expectedCoordinate)) { NSLog(@"equal"); } else { NSLog(@"not equal"); } 

另一种select是使用内联方法,如果你不喜欢预处理器。

您可以使用CLLocation类的distanceFromLocation:方法。 返回值是一个CLLocationDistance ,这实际上只是一个双倍的。

 - (CLLocationDistance)distanceFromLocation:(const CLLocation *)location 

Swift扩展:

 import MapKit extension CLLocationCoordinate2D: Equatable {} public func ==(lhs: CLLocationCoordinate2D, rhs: CLLocationCoordinate2D) -> Bool { return (lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude) } 

[从Xcode 7.3.1,Swift 2.2开始testing] [当然,仍然有比较浮点值的内在危险,因此您可能需要考虑使用前面提到的epsilon ]

你可以定义一个类似于CoreLocation的函数:

BOOL CLLocationCoordinateEqual(CLLocationCoordinate2D coordinate1, CLLocationCoordinate2D coordinate2) { return (fabs(coordinate1.latitude - coordinate2.latitude) <= DBL_EPSILON && fabs(coordinate1.longitude - coordinate2.longitude) <= DBL_EPSILON); }

在Swift 3中, DBL_EPSILON已经被弃用了。 使用Double.ulpOfOne

 extension CLLocationCoordinate2D { func isEqual(_ coord: CLLocationCoordinate2D) -> Bool { return (fabs(self.latitude - coord.latitude) < .ulpOfOne) && (fabs(self.longitude - coord.longitude) < .ulpOfOne) } } 
 CLLocationCoordinate2D c1, c2; if (c1.latitude == c2.latitude && c1.longitude == c2.longitude) { // ... } 

我不是在开玩笑。 CLLocationCoordinate2D是一个C结构体,除了比较各个成员之外,没有简单的方法来比较C结构体。

CLLocationCoordinate2D是一个C结构,因此,你需要比较它的字段:

 CLLocationCoordinate2D coord1, coord2; if (coord1.latitude == coord2.latitude && coord1.longitude == coord2.longitude) { // coordinates are equal } 

请注意, CLLocationCoordinate2D字段是double ,因此,您可能会遇到与任何其他浮点比较相同的问题。 因此,我build议圆一点点的价值观,例如:

 CLLocationCoordinate2D coord1, coord2; if (round(coord1.latitude * 1000.0) == round(coord2.latitude * 1000.0) && round(coord1.longitude * 1000.0) == round(coord2.longitude * 1000.0)) { // coordinates are equal } 

是的,这个代码是比较慢的,但是这样可以帮助你避免由于浮点数的精度不够好而引起的问题。

你可以使用这个函数把CLLocationCoordinate包装成一个NSValue + (NSValue *)valueWithMKCoordinate:(CLLocationCoordinate2D)coordinate

然后使用isEqualToValue进行比较。

来自Apple文档的isEqualToValue函数引用:

NSValue类比较每个值对象的types和内容以确定相等性。

参考:苹果doc的NSValue

我们可以将经度和纬度转换为NSString并进行string比较。

 + (BOOL)isEqualWithCoordinate:(CLLocationCoordinate2D)location1 withAnotherCoordinate:(CLLocationCoordinate2D)location2{ NSString *locationString1 = [NSString stringWithFormat:@"%g, %g", location1.latitude, location1.longitude]; NSString *locationString2 = [NSString stringWithFormat:@"%g, %g", location2.latitude, location2.longitude]; if ([locationString1 isEqualToString:locationString2]) { return YES; }else{ return NO; } 

}

由于%g会将截断十进制数转换为4位数。