我有GPS(lon_base,lat_base)的位置。 我有一個位置列表(lon1,lat1 | lon2,lat2 | lon3,lat3 ...) 這個列表很長,遍佈世界各地。lon lat點的排序列表,從最近開始
我的問題是: 1.我如何才能從lon_base \ lat_base距離1英里的lon \ lat列表中獲得? 2.我如何從最近到最遠排序它們?
在此先感謝!
我有GPS(lon_base,lat_base)的位置。 我有一個位置列表(lon1,lat1 | lon2,lat2 | lon3,lat3 ...) 這個列表很長,遍佈世界各地。lon lat點的排序列表,從最近開始
我的問題是: 1.我如何才能從lon_base \ lat_base距離1英里的lon \ lat列表中獲得? 2.我如何從最近到最遠排序它們?
在此先感謝!
你要定義自己的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
您可以使用followig逼近(因爲,一英里比地球半徑小很多)來計算你的基地距離:與
dx = cos(phi_base) * (theta - theta_base)
dy = phi - phi_base
dist = sqrt(dx*dx+dy*dy)
:phi
=緯度和theta
=經度
如果以度爲單位給出theta
和phi
,則結果以60海里爲單位。 對於緯度與您的基本緯度有很大差異的點,結果將十分錯誤,但如果您只是想知道哪些點距離基地約1英里,則無關緊要。
對於大多數編程語言,您必須將phi_base
轉換爲弧度(乘以pi/180)才能用於cos()
。
(注意:您要特別注意,如果你的基礎經度是非常接近180°或180°,但可能不是:-)
使用計算出的距離爲排序鍵的情況下整理你的觀點。
如果您必須更加準確(例如,如果您想知道距離家中約2000英里的所有積分),則必須使用Great Circle Distance的公式計算球體上兩點的精確距離。
您可以使用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;
}
根據這一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;
}
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列表。
此代碼中的「a」值是什麼。如果您提供示例代碼,對我非常有幫助。 – pandu 2013-12-18 07:15:01