2011-03-22 75 views
5

我有GPS(lon_base,lat_base)的位置。 我有一個位置列表(lon1,lat1 | lon2,lat2 | lon3,lat3 ...) 這個列表很長,遍佈世界各地。lon lat點的排序列表,從最近開始

我的問題是: 1.我如何才能從lon_base \ lat_base距離1英里的lon \ lat列表中獲得? 2.我如何從最近到最遠排序它們?

在此先感謝!

回答

3

你要定義自己的Comparator,在一般情況下,看起來是這樣的:

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); 

其中calcDistance()簡單地計算兩個點之間的距離。如果你使用的是Android系統,我認爲Google地圖在他們的API中有一個功能,可以爲你做到這一點。

編輯:你會希望你的calcDistance()函數看起來像ChrisJ的distance函數。

-tjw

+0

此代碼中的「a」值是什麼。如果您提供示例代碼,對我非常有幫助。 – pandu 2013-12-18 07:15:01

1

您可以使用followig逼近(因爲,一英里比地球半徑小很多)來計算你的基地距離:與

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

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

phi =緯度和theta =經度

如果以度爲單位給出thetaphi,則結果以60海里爲單位。 對於緯度與您的基本緯度有很大差異的點,結果將十分錯誤,但如果您只是想知道哪些點距離基地約1英里,則無關緊要。

對於大多數編程語言,您必須將phi_base轉換爲弧度(乘以pi/180)才能用於cos()

(注意:您要特別注意,如果你的基礎經度是非常接近180°或180°,但可能不是:-)

使用計算出的距離爲排序鍵的情況下整理你的觀點。

如果您必須更加準確(例如,如果您想知道距離家中約2000英里的所有積分),則必須使用Great Circle Distance的公式計算球體上兩點的精確距離。

6

您可以使用great circle distance計算兩個點,其知道的經緯度座標之間的距離。該formulae是很容易代碼:

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

根據這一link 我做工作的方法。上面的答案是錯誤的,因爲它不會將經度/度數轉換爲弧度。

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

凡位置的列表是包含自己的位置類,而不是android.location.Location列表。