Soru İki CLLocationCoordinate2D'yi nasıl karşılaştırabilirim? (iPhoneiPad)


İkiyi karşılaştırmanın bir yoluna ihtiyacım var CLLocationCoordinate2DAncak kullanmayı denediğimde == işe yaramazdı. Lütfen birisi beni karşılaştırmanın en iyi yolu ile bana yardımcı olabilir mi?


44
2018-04-17 21:04


Menşei




Cevaplar:


Herhangi bir belirli yapı türünün iki örneğini karşılaştırmak için genel yaklaşım:

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

veya

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

Eğer gerçekten emin olmak istiyorsan, çalışmalı kesinlikle eşit. Ancak, enlem ve boylam çiftler olarak tanımlandığında, "yeterince yakın" bir karşılaştırma yapmak isteyebilirsiniz:

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

nerede epsilon kabul etmek istediğiniz hata seviyesi.


56
2018-04-17 21:10



İlk, kabataslak olarak düşünülebilir, çünkü yapının, üyeler arasında herhangi bir bayt olmadan paketlendiğini varsayıyorsunuz. - joerick
İyi bir nokta. Oluşturulduğunda / ayrıldığında tüm yapıyı sıfırlarsanız, memcmp yaklaşımı paketlenmemiş yapılar için bile güvenlidir, ancak aksi halde dikkatli kullanın. - Glenn
@Glenn, abs'leri fab'lara ve <to <= 'a sabitleyebilir. - Shmidt
İyi öneriler, @Flink. Bitti. - Glenn
tüm yapının sıfır ile ne demek istiyorsun? Ve bu yapı, üyeler arasında herhangi bir bayt olmadan paketlendiği anlamına mı geliyor? Yani durum böyle olmayabilir demek istiyorsun? - J. Chang


Tüm bu cevaplara küçük bir ek olarak, bir ön işlemcinin tanımladığı karşılaştırmayı tanımlamak oldukça kullanışlıdır:

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

ya da epsilon ile:

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

Bu, aşağıdaki gibi bir karşılaştırma yapmanızı sağlar:

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

if(CLCOORDINATES_EQUAL( resultingCoordinate, expectedCoordinate)) {
    NSLog(@"equal");
} else {
    NSLog(@"not equal");
}

Bir başka alternatif ise, ön işlemciyi sevmiyorsanız, bir satır içi yöntem kullanmaktır.


33
2017-08-16 22:02



Kayan nokta sayılarını asla karşılaştırmayın ==. Kullanıcıların kullandığı cevapları görün epsilon. - DanSkeel
@DanSkeel Düzenlenmiş cevabımı görün. Bazen tam koordinatları karşılaştırmak istediğiniz bir kullanım durumunuz var. Örneğin. Koordinatların kaynağı bir yer veri tabanıysa ve sadece bunları karşılaştırmak istiyorsanız. Daha sonra eşit karşılaştırma için bir aralığa gerek yoktur. Yani tekrar oylamayı düşünebilirsin. - Klaas
Benim amacımı anlamadın. Ne zaman olduğunu düşünün 1 != 0.99999999999 ... Herhangi bir kayan nokta karşılaştırması için genel kuraldır. Hakkında okumak o. Bu kural bilgisayar olarak eskidir. - DanSkeel
Hala senin noktanı anlamıyorum. Koordinatlarınızın kaynağı örn. Bir veritabanı ve koordinatlarla herhangi bir hesaplama yapmazsanız, düzenli bir == karşılaştırması kullanmak yeterlidir. - Klaas
Ama bir tane hesaplanan koordinat. Yani tüm bu şamandıra koordinatları bir kişi tarafından manüel olarak ayarlandı mı? Bilgisayar yok mu? - DanSkeel


Hızlı bir uzantı:

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] 'den itibaren test edilmiştir [ve tabii ki, kayan nokta değerlerini karşılaştırmanın esas tehlikesi vardır, bu yüzden kullanmayı düşünebilirsiniz. epsilon önceki cevaplarda belirtildiği gibi]


14
2017-07-25 22:04





Kullanabilirsiniz CLLocation sınıf 'distanceFromLocation: yöntem. Dönüş değeri bir CLLocationDistance, bu gerçekten sadece bir çift.

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

11
2017-10-26 19:10





CoreLocation'dan gelen hoş bir işlevi tanımlayabilirsiniz:

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


8
2018-02-23 14:30



Bu en sürdürülebilir çözüm IMO olduğu için ayrılmış - mvanallen
Güzel çözüm. İşte sadece yeni arı için tam bir yöntem. - (BOOL) compairLastSavedCoordinates: (CLLocationCoordinate2D) koordinat1 withYeni Koordinatlar: (CLLocationCoordinate2D) koordinat2 {return (koordinat1.latitude == coordinate2.latitude) && (coordinate1.longitude == coordinate2.longitude); } - iLearner
Kayan nokta sayılarını asla karşılaştırmayın! Eğer yaparsan, güvenilmez. Uygulamada, farklı kaynaklardan elde edilen gerçek konumlardan çoğu karşılaştırma yapılacaktır. false - birbirlerine oldukça yakın olsalar ve "eşit" sayılabilirler. - CouchDeveloper


Swift 3'te DBL_EPSILON kullanımdan kaldırıldı. kullanım Double.ulpOfOne.

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

5
2017-07-31 16:54





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

Şaka yapmıyorum. CLLocationCoordinate2D bir C yapısıdır ve ayrı ayrı üyeleri karşılaştırmak dışında C yapılarını karşılaştırmanın kolay bir yolu yoktur.


2
2018-04-17 21:09