2011-03-22 28 views
5

ile başla Ben GPS'den konumum var (lon_base, lat_base). Yerler listemiz var (lon1, lat1 | lon2, lat2 | lon3, lat3 ...) Bu liste çok uzun ve dünya çapında.lon lat noktalarının listesini sırala, en yakın

Sorularım şunlardır: 1. Bu listeden lon_base \ lat_base öğesinden 1 mil olan lon \ lat'ten nasıl alabilirim? 2. En yakından en uzakına nasıl sıralarım?

Şimdiden teşekkürler! Sen followig yaklaşım kullanabilirsiniz

cevap

3

Sen tanımlamak istediğiniz kendi, genel olarak, şuna benzer Comparator: calcDistance() basitçe iki nokta arasındaki mesafeyi hesaplar

LonLat myHouse = /* whatever */ ; 
Comparable comp = new Comparable() { 
    LonLat a; 
    int compareTo (Object b) { 
     int aDist = calcDistance(a, myHouse) ; 
     int bDist = calcDistance(b, myHouse) ; 
     return aDist - bDist; 
    } 
}; 
myLonLatList.sort(lonLatList, comp); 

. Android’te iseniz, Google Haritalar’ın API’nın bir kısmını sizin için yapacak olan bir işlevi olduğunu düşünüyorum.

DÜZENLEME: Eğer calcDistance() fonksiyon ChrisJ en distance fonksiyonu gibi görünmek istersiniz.

-tjw

+0

Bu kodda "a" değeri nedir. Örnek bir kod sağlarsanız benim için çok yararlıdır. – pandu

1

senin tabanından mesafeleri hesaplamak için (1 mil toprak yarıçapı çok daha küçük olduğundan): ile

dx = cos(phi_base) * (theta - theta_base) 
dy = phi - phi_base 

dist = sqrt(dx*dx+dy*dy) 

: phi = enlem ve theta = boylam

theta ve phi derece olarak verilirse sonuç 60 deniz mili birimindedir. Temel enleminizden çok farklı bir enlemi olan noktalar için sonuçlar oldukça yanlış olur, ancak yalnızca sizin için yaklaşık puanların yaklaşık 1 mil olduğunu bilmek istiyorsanız bu önemli değildir.

Programlama dillerinin çoğu için phi_base'u radyanlara (pi/180 ile çarparak) için kullanmanız gerekir.

(Dikkat: Taban boylamı 180 ° veya -180 ° çok yakındır, ama muhtemelen o

Kullanım anahtarı sıralama olarak hesaplanmış mesafeler :-) durum değilse özel bakım almak zorunda puanlarını sırala. Daha kesin olmak gerekirse (örn. Evinizden yaklaşık 2000 mil uzakta olan tüm noktaları bilmek istiyorsanız), bir küredeki iki noktanın tam mesafesini hesaplamak için Great Circle Distance formülünü kullanmanız gerekir.

6

Sen kimin enlem-boylam koordinatlarını bilen iki nokta arasındaki mesafeyi hesaplamak için great circle distance kullanabilir. formulae koduna oldukça kolaydır:

static double distance(double fromLat, double fromLon, double toLat, double toLon) { 
    double radius = 6378137; // approximate Earth radius, *in meters* 
    double deltaLat = toLat - fromLat; 
    double deltaLon = toLon - fromLon; 
    double angle = 2 * Math.asin(Math.sqrt(
     Math.pow(Math.sin(deltaLat/2), 2) + 
     Math.cos(fromLat) * Math.cos(toLat) * 
     Math.pow(Math.sin(deltaLon/2), 2))); 
    return radius * angle; 
} 
0

i yöntemini çalışma yapılan bu link göre. Yukarıdaki cevap yanlıştı, çünkü lat/lng derecelerini radyanlara dönüştürmez.

yerler listesi kendi Yer sınıfını değil, android.location.Location içeren bir listedir
private double getDistance(double fromLat, double fromLon, double toLat, double toLon){ 
     double radius = 6371; // Earth radius in km 
     double deltaLat = Math.toRadians(toLat - fromLat); 
     double deltaLon = Math.toRadians(toLon - fromLon); 
     double lat1 = Math.toRadians(fromLat); 
     double lat2 = Math.toRadians(toLat); 
     double aVal = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) + 
      Math.sin(deltaLon/2) * Math.sin(deltaLon/2) * Math.cos(lat1) * Math.cos(lat2); 
     double cVal = 2*Math.atan2(Math.sqrt(aVal), Math.sqrt(1-aVal)); 

     double distance = radius*cVal; 
     Log.d("distance","radius * angle = " +distance); 
     return distance; 
    } 
8
public static List<Location> sortLocations(List<Location> locations, final double myLatitude,final double myLongitude) { 
    Comparator comp = new Comparator<Location>() { 
     @Override 
     public int compare(Location o, Location o2) { 
      float[] result1 = new float[3]; 
      android.location.Location.distanceBetween(myLatitude, myLongitude, o.Lat, o.Long, result1); 
      Float distance1 = result1[0]; 

      float[] result2 = new float[3]; 
      android.location.Location.distanceBetween(myLatitude, myLongitude, o2.Lat, o2.Long, result2); 
      Float distance2 = result2[0]; 

      return distance1.compareTo(distance2); 
     } 
    }; 


    Collections.sort(locations, comp); 
    return locations; 
} 

.

İlgili konular