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

The*_*imp 48 core-location cllocation equatable

我需要一种比较两种方法的方法,CLLocationCoordinate2D但是当我尝试使用==它时,它是行不通的.请有人帮助我比较它们的最佳方法吗?

小智 56

用于比较任何给定结构类型的两个实例的通用方法:

memcmp(&cllc2d1, &second_cllc2d, sizeof(CLLocationCoordinate2D))
Run Code Online (Sandbox Code Playgroud)

要么

cllc2d1.latitude == cllc2d2.latitude && cllc2d1.longitude == cllc2d2.longitude
Run Code Online (Sandbox Code Playgroud)

应该工作,如果你真的想确定他们是完全平等的.但是,鉴于纬度和经度被定义为双精度,您可能真的想要进行"足够接近"的比较:

fabs(cllc2d1.latitude - cllc2d2.latitude) <= epsilon && fabs(cllc2d1.longitude - cllc2d2.longitude) <= epsilon
Run Code Online (Sandbox Code Playgroud)

epsilon您想接受的错误级别在哪里.

  • 第一个可能被认为是粗略的,因为你假设结构被打包而成员之间没有任何字节. (5认同)

Kla*_*aas 33

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

#define CLCOORDINATES_EQUAL( coord1, coord2 ) (coord1.latitude == coord2.latitude && coord1.longitude == coord2.longitude)
Run Code Online (Sandbox Code Playgroud)

或者与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)
Run Code Online (Sandbox Code Playgroud)

这允许您进行如下比较:

CLLocationCoordinate2D resultingCoordinate = ... a method call ...;
CLLocationCoordinate2D expectedCoordinate = CLLocationCoordinate2DMake(48.11, 11.12);

if(CLCOORDINATES_EQUAL( resultingCoordinate, expectedCoordinate)) {
    NSLog(@"equal");
} else {
    NSLog(@"not equal");
}
Run Code Online (Sandbox Code Playgroud)

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

  • 永远不要将浮点数与`==`进行比较.查看人们使用`epsilon`的答案. (3认同)
  • 我仍然不明白你的观点.如果您的坐标源是例如数据库而您没有使用坐标进行任何计算,那么使用常规==比较就可以了. (2认同)

lea*_*nne 21

Swift扩展:

import MapKit

extension CLLocationCoordinate2D: Equatable {}

public func ==(lhs: CLLocationCoordinate2D, rhs: CLLocationCoordinate2D) -> Bool {
    return (lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude)
}
Run Code Online (Sandbox Code Playgroud)

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


Gre*_*sak 12

您可以使用CLLocation类的distanceFromLocation:方法.返回值是CLLocationDistance,实际上只是一个双精度数.

- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location
Run Code Online (Sandbox Code Playgroud)


小智 8

您可以定义一个感觉非常类似于来自CoreLocation的函数:

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

  • 永远不要比较浮点数!如果你这样做,这是不可靠的.在实践中,从不同的来源产生将返回实景拍摄最比较`FALSE` - 即使他们都相当接近对方,可以被认为是"平等". (2认同)

Rya*_*yan 6

在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)
    }
}
Run Code Online (Sandbox Code Playgroud)


Adr*_*ian 6

根据lean的 回答更新了Swift 5 。

import CoreLocation

extension CLLocationCoordinate2D: Equatable {
    static public func ==(lhs: Self, rhs: Self) -> Bool {
        lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude
    }
}
Run Code Online (Sandbox Code Playgroud)