primer precio plus apple iphone ipad comparison cllocation

precio - ¿Cómo puedo comparar dos CLLocationCoordinate2D?(iPhone/iPad)



iphone 8 (10)

Como una pequeña adición a todas estas respuestas, es bastante útil tener la comparación definida como un preprocesador definir:

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

o con épsilon:

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

Esto le permite hacer una comparación de la siguiente manera:

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

Otra alternativa es usar un método en línea, si no le gusta el preprocesador.

Necesito una forma de comparar dos CLLocationCoordinate2D , sin embargo, cuando intenté usar == , no funcionaría. ¿Alguien puede ayudarme con la mejor manera de compararlos?


En Swift 3, DBL_EPSILON está en desuso. Use Double.ulpOfOne .

extension CLLocationCoordinate2D { func isEqual(_ coord: CLLocationCoordinate2D) -> Bool { return (fabs(self.latitude - coord.latitude) < .ulpOfOne) && (fabs(self.longitude - coord.longitude) < .ulpOfOne) } }


O el enfoque genérico para comparar dos instancias de cualquier tipo de estructura dada:

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

o

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

debería funcionar, si realmente quieres estar seguro de que son exactamente iguales. Sin embargo, dado que la latitud y la longitud se definen como dobles, es posible que desee hacer una comparación "lo suficientemente cerca":

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

donde epsilon es el nivel de error que quieras aceptar.


Podemos convertir latitud y longitud a NSString y hacer una comparación de cadenas.

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

}

Como% g convertirá el número decimal truncado a 4 dígitos.


Podrías definir una función que se siente como procedente de CoreLocation:

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


Puede ajustar CLLocationCoordinate en un NSValue utilizando esta función + (NSValue *)valueWithMKCoordinate:(CLLocationCoordinate2D)coordinate

Y luego use isEqualToValue para comparar.

Cita del documento Apple de la función isEqualToValue :

La clase NSValue compara el tipo y el contenido de cada objeto de valor para determinar la igualdad.

Ref .: Apple doc of NSValue


Puede utilizar el CLLocation ''distanceFromLocation: de la clase CLLocation . El valor de retorno es CLLocationDistance , que en realidad es solo un doble.

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


Una extensión Swift:

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

[probado a partir de Xcode 7.3.1, Swift 2.2] [y, por supuesto, todavía tiene el peligro intrínseco de comparar los valores de punto flotante, por lo que es posible que desee considerar el uso de epsilon como se menciona en las respuestas anteriores]


CLLocationCoordinate2D es una estructura C, por lo tanto, debe comparar sus campos:

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

Tenga en CLLocationCoordinate2D campos CLLocationCoordinate2D son double , por lo tanto, puede obtener los mismos problemas que con cualquier otra comparación de coma flotante. Por lo tanto, sugiero redondear un poco los valores, por ejemplo:

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 }

Sí, este código es más lento, pero esto puede ayudarlo a evitar problemas causados ​​por la precisión no tan perfecta de los números de punto flotante.


CLLocationCoordinate2D c1, c2; if (c1.latitude == c2.latitude && c1.longitude == c2.longitude) { // ... }

No estoy bromeando. CLLocationCoordinate2D es una estructura C, y no hay una manera fácil de comparar las estructuras C, además de comparar los miembros individuales.