Potrzebuję sposobu na porównanie dwóch CLLocationCoordinate2D
, jednak gdy spróbowałem użyć ==
, to nie zadziała. Czy ktoś może mi pomóc z najlepszym sposobem ich porównania?Jak mogę porównać dwa CLLocationCoordinate2D? (iPhone/iPad)
Odpowiedz
Albo ogólne podejście do porównywania dwóch wystąpień danego typu struct:
memcmp(&cllc2d1, &second_cllc2d, sizeof(CLLocationCoordinate2D))
lub
cllc2d1.latitude == cllc2d2.latitude && cllc2d1.longitude == cllc2d2.longitude
powinny działać, jeśli naprawdę chcesz mieć pewność, że są dokładnie równe . Biorąc jednak pod uwagę, że szerokość i długość geograficzna są zdefiniowane jako deblu, można naprawdę chcą zrobić „wystarczająco blisko” porównania:
fabs(cllc2d1.latitude - cllc2d2.latitude) <= epsilon && fabs(cllc2d1.longitude - cllc2d2.longitude) <= epsilon
epsilon
gdzie jest cokolwiek poziom błędu chcesz zaakceptować.
CLLocationCoordinate2D c1, c2;
if (c1.latitude == c2.latitude && c1.longitude == c2.longitude)
{
// ...
}
Nie żartuję. CLLocationCoordinate2D jest strukturą C i nie ma łatwego sposobu porównywania struktur C, oprócz porównywania poszczególnych elementów.
CLLocationCoordinate2D
jest struct C, a więc trzeba porównać swoje pola:
CLLocationCoordinate2D coord1, coord2;
if (coord1.latitude == coord2.latitude && coord1.longitude == coord2.longitude) {
// coordinates are equal
}
Uwaga, CLLocationCoordinate2D
pola są double
, w ten sposób, można uzyskać takie same problemy jak w przypadku każdego innego pływającą porównaniu pkt. Zatem proponuję wokół małe wartości bitowe, np .:
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
}
Tak, ten kod jest wolniejsza, ale może to pomóc uniknąć problemów powodowanych przez nie tak doskonałej precyzji liczb zmiennoprzecinkowych.
Jako mały Oprócz tych wszystkich odpowiedzi, to całkiem przydatny do porównania zdefiniowany jako preprocesor zdefiniować:
#define CLCOORDINATES_EQUAL(coord1, coord2) (coord1.latitude == coord2.latitude && coord1.longitude == coord2.longitude)
lub 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)
Pozwala to zrobić porównanie w następujący sposób:
CLLocationCoordinate2D resultingCoordinate = ... a method call ...;
CLLocationCoordinate2D expectedCoordinate = CLLocationCoordinate2DMake(48.11, 11.12);
if(CLCOORDINATES_EQUAL(resultingCoordinate, expectedCoordinate)) {
NSLog(@"equal");
} else {
NSLog(@"not equal");
}
Inną alternatywą jest zastosowanie metody liniowej, jeśli robisz nie jak preprocesor.
Nigdy nie porównuj liczb zmiennoprzecinkowych z '=='. Zobacz odpowiedzi, gdzie ludzie używają 'epsilon'. – DanSkeel
@DanSkeel Zobacz moją zmienioną odpowiedź. Czasami masz przypadek użycia, w którym chcesz porównać dokładne współrzędne. Na przykład. jeśli źródłem współrzędnych jest baza danych miejsc i chcesz je tylko porównać. Wtedy nie ma potrzeby stosowania zakresu dla równego porównania. Możesz więc ponownie pomyśleć o swoim głosowaniu w dół. – Klaas
Nie zrozumiałeś mojego punktu. Wyobraź sobie przypadek, gdy '1! = 0.99999999999' ... Jest to ogólna zasada dla każdego porównania zmiennoprzecinkowego. [Przeczytaj o] (http://floating-point-gui.de/errors/comparison/) to.Ta zasada jest stara jak komputer. – DanSkeel
Można użyć metody "distanceFromLocation: class CLLocation". Wartość zwracana to CLLocationDistance, która jest naprawdę tylko podwójna.
- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location
Można zdefiniować funkcję, która czuje się całkiem jak pochodzące z CoreLocation:
BOOL CLLocationCoordinateEqual(CLLocationCoordinate2D coordinate1, CLLocationCoordinate2D coordinate2) { return (fabs(coordinate1.latitude - coordinate2.latitude) <= DBL_EPSILON && fabs(coordinate1.longitude - coordinate2.longitude) <= DBL_EPSILON); }
przegłosowano, ponieważ jest to najbardziej konserwowalne rozwiązanie. IMO – mvanallen
Dobre rozwiązanie. Oto pełna metoda dla nowej pszczoły. - (BOOL) compairLastSavedCoordinates: (CLLocationCoordinate2D) coordinate1 withNewCoordinates: (CLLocationCoordinate2D) coordinate2 { return (coordinate1.latitude == coordinate2.latitude) && (coordinate1.longitude == coordinate2.longitude); } – iLearner
Nigdy nie porównuj liczb zmiennoprzecinkowych! Jeśli tak, to niewiarygodne. W praktyce większość porównań z rzeczywistych lokalizacji wygenerowanych przez różne źródła zwróci wartość "false" - nawet jeśli są one blisko siebie i mogą być uznane za "równe". – CouchDeveloper
można zawinąć CLLocationCoordinate
do wiadomości NSValue
użyciem tej funkcji + (NSValue *)valueWithMKCoordinate:(CLLocationCoordinate2D)coordinate
a następnie użyć isEqualToValue
porównać .
Cytat firmy Apple DOC isEqualToValue
funkcji:
Klasa NSValue porównuje rodzaj i zawartość każdego obiektu w celu ustalenia wartości równości.
Ref: Jabłko doc z NSValue
Możemy konwertować długość i szerokość geograficzną, aby NSString i zrobić ciąg porównania.
+ (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;
}
}
ponieważ% g przekształci obcina liczbę dziesiętną 4 cyfry.
Swift rozszerzenie:
import MapKit
extension CLLocationCoordinate2D: Equatable {}
public func ==(lhs: CLLocationCoordinate2D, rhs: CLLocationCoordinate2D) -> Bool {
return (lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude)
}
[Testowany Xcode 7.3.1 Swift 2.2] [i, oczywiście, nadal ma wewnętrzną niebezpieczeństwo porównując zmiennoprzecinkowych, więc może chcesz rozważ użycie opcji epsilon
, jak wspomniano we wcześniejszych odpowiedziach]
W Swift 3, DBL_EPSILON
jest przestarzałe. Użyj Double.ulpOfOne
.
extension CLLocationCoordinate2D {
func isEqual(_ coord: CLLocationCoordinate2D) -> Bool {
return (fabs(self.latitude - coord.latitude) < .ulpOfOne) && (fabs(self.longitude - coord.longitude) < .ulpOfOne)
}
}
- 1. Jak porównać dwa zapytania?
- 2. Jak porównać dwa wyrażenia lambda?
- 3. Jak porównać dwa pliki CSV?
- 4. Jak porównać dwa wyrazy regularne?
- 5. Jak porównać dwa obiekty Java
- 6. jak porównać dwa std :: set?
- 7. Jak mogę porównać dwa pliki podobne do vim vimdiff?
- 8. porównać dwa datownik w java
- 9. Jak porównać dwa szyfrowane (bcrypt) hasło laravel
- 10. C++ porównać dwa ciągi literałów
- 11. jak porównać dwa elementy w jquery
- 12. Jak porównać dwa obrazy za pomocą Node.js
- 13. Jak porównać dwa ciągi znaków w scala?
- 14. Jak porównać dwa razy w PHP
- 15. Jak porównać dwa pliki w Rubim 1.9?
- 16. jak porównać dwa datepicker dat jquery
- 17. Jak porównać dwa obiekty jQuery dla tożsamości?
- 18. jQuery porównać dwa obiekty DOM?
- 19. porównać dwa pliki xml z xslt?
- 20. Porównać (i połączyć) dwa projekty VS C#
- 21. porównać dwa pliki tekstowe przy użyciu linq?
- 22. Chcę porównać dwa projekty w studiu Android
- 23. Jak porównać dwa obiekty z wartościami zmiennoprzecinkowymi w jaśminu?
- 24. Awk: jak porównać dwa ciągi w jednym wierszu
- 25. Jak porównać dwa wykresy obiektów .NET dla różnic?
- 26. utworzyć CLLocationCoordinate2D z tablicy
- 27. Kodowanie obiektu CLLocationcoordinate2D
- 28. Jak porównać dwa katalogi podczas ignorowania określonych nazw katalogów?
- 29. Jak porównać dwa wyraźnie różne obiekty o podobnych właściwościach?
- 30. Jak porównać dwa ciągi numer wersji w golang
Pierwszy z nich można uznać za szkicowy, ponieważ przyjmuje się, że struktura jest spakowana bez żadnych bajtów między elementami. – joerick
Dobra uwaga. Jeśli wyzerujesz całą strukturę, gdy zostanie ona utworzona/przydzielona, wówczas podejście memcmp jest bezpieczne nawet w przypadku niezapakowanych struktur, ale poza tym należy zachować ostrożność. – Glenn
@ Glenn możesz naprawić abs do fabs i
Shmidt