GPS(lon_base、lat_base)からの位置情報があります。場所のリストがあります(lon1、lat1 | lon2、lat2 | lon3、lat3 ...)このリストは非常に長く、世界中にあります。
私の質問は次のとおりです。1。そのリストから、lon_base\lat_baseから1マイル離れたlon\latのみを取得するにはどうすればよいですか。2.それらを最も近いものから最も遠いものに並べ替えるにはどうすればよいですか?
前もって感謝します!
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ではなく、独自のLocationクラスを含むリストです。
大円距離を使用して、緯度と経度の座標がわかっている2点間の距離を計算できます。数式のコーディングは非常に簡単です。
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;
}
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()
、2点間の距離を計算するだけです。Androidを使用している場合、GoogleマップのAPIのどこかに、これを実行する関数があると思います。
編集:あなたはあなたcalcDistance()
の関数をChrisJのdistance
関数のように見せたいでしょう。
-tjw
followig近似を使用して(1マイルは地球の半径よりもはるかに小さいため)、ベースからの距離を計算できます。
dx = cos(phi_base) * (theta - theta_base)
dy = phi - phi_base
dist = sqrt(dx*dx+dy*dy)
と:phi
=緯度とtheta
=経度
結果は、度で指定されている場合theta
、60海里の単位になります。phi
緯度がベースの緯度と大きく異なるポイントの場合、結果はかなり間違っていますが、ベースから約1マイルのポイントを知りたい場合は、これは問題ではありません。
ほとんどのプログラミング言語では、を使用するphi_base
ためにラジアンに変換する必要があります(pi / 180を掛けます)cos()
。
(注意:ベース経度が180°または-180°に非常に近い場合は、特別な注意が必要ですが、おそらくそうではありません:-)
計算された距離を並べ替えキーとして使用して、ポイントを並べ替えます。
より正確にする必要がある場合(たとえば、自宅から約2000マイル離れているすべてのポイントを知りたい場合)、大圏距離の式を使用して、球上の2つのポイントの正確な距離を計算する必要があります。
このリンクによると、 私は作業方法を作りました。緯度/経度をラジアンに変換しないため、上記の答えは間違っていました。
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;
}