如何根据 Android 中与当前位置的距离对地理点进行排序
How to Sort Geo-points according to the distance from current location in Android
我有一个 "Place" 对象,每个对象都有一个 LatLng 坐标:
import com.google.android.gms.maps.model.LatLng;
public class Place{
public String name;
public LatLng latlng;
public Restaurant(String name, LatLng latlng) {
this.name = name;
this.latlng = latlng;
}
}
我有一个包含这些地方的数组列表,如下所示:
ArrayList<Place> places = new ArrayList<Place>();
places.add("Place 1", LatLng(90.0,90.0));
places.add("Place 2", LatLng(93.0,93.0));
places.add("Place 3", LatLng(83.0,92.0));
places.add("Place 4", LatLng(93.0,91.0));
我有 "my" 经纬度:
LatLng myLocation = new LatLng(10.0,10.0);
如何根据离我最近的对象对这些对象进行排序?感谢帮助
得到当前位置后,可以通过计算行车距离(最适合餐厅等地方)排序如下,
计算到每个物体的距离
http://maps.googleapis.com/maps/api/directions/json?origin="+yourLat+","+yourLong+"&destination="+toLat+","+toLong+"&sensor=false&mode=DRIVING
计算出每个距离后,对这些距离应用一些简单的排序算法。
采用 this answer from the question posted by @shieldstroy, that uses the Great Circle Distance 中的算法,我使这个示例有效。
这里是 Comparator
:
public class SortPlaces implements Comparator<Place> {
LatLng currentLoc;
public SortPlaces(LatLng current){
currentLoc = current;
}
@Override
public int compare(final Place place1, final Place place2) {
double lat1 = place1.latlng.latitude;
double lon1 = place1.latlng.longitude;
double lat2 = place2.latlng.latitude;
double lon2 = place2.latlng.longitude;
double distanceToPlace1 = distance(currentLoc.latitude, currentLoc.longitude, lat1, lon1);
double distanceToPlace2 = distance(currentLoc.latitude, currentLoc.longitude, lat2, lon2);
return (int) (distanceToPlace1 - distanceToPlace2);
}
public 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;
}
}
这是高级代码,我只是把它放在 onCreate()
:
//My location, San Francisco
double lat = 37.77657;
double lng = -122.417506;
LatLng latLng = new LatLng(lat, lng);
//set up list
ArrayList<Place> places = new ArrayList<Place>();
places.add(new Place("New York", new LatLng(40.571256,73.98369)));
places.add(new Place("Colorado", new LatLng(39.260658,-105.101615)));
places.add(new Place("Los Angeles", new LatLng(33.986816,118.473819)));
for (Place p: places){
Log.i("Places before sorting", "Place: " + p.name);
}
//sort the list, give the Comparator the current location
Collections.sort(places, new SortPlaces(latLng));
for (Place p: places){
Log.i("Places after sorting", "Place: " + p.name);
}
这是日志输出:
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places before sorting﹕ Place: New York
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places before sorting﹕ Place: Colorado
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places before sorting﹕ Place: Los Angeles
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places after sorting﹕ Place: Los Angeles
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places after sorting﹕ Place: Colorado
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places after sorting﹕ Place: New York
计算距离有不同的方法。一个非常简单的公式是 Haversine 公式 (http://rosettacode.org/wiki/Haversine_formula#Java)。更准确的计算方法是 Vincenty 公式。如果两个位置相距不远,Haversine解就足够了。
计算距离后,您只需使用比较器对数组进行排序,例如:
Collections.sort(places, new Comparator<Place>() {
public int compare(Place p1, Place p2) {
return Double.compare(p1.getDistance(), p2.getDistance());
}
});
您可以使用
distanceInMeters = (loc1.distanceTo(loc2));
从google映射API,然后将结果添加到TreeMap
中的Key
我有一个 "Place" 对象,每个对象都有一个 LatLng 坐标:
import com.google.android.gms.maps.model.LatLng;
public class Place{
public String name;
public LatLng latlng;
public Restaurant(String name, LatLng latlng) {
this.name = name;
this.latlng = latlng;
}
}
我有一个包含这些地方的数组列表,如下所示:
ArrayList<Place> places = new ArrayList<Place>();
places.add("Place 1", LatLng(90.0,90.0));
places.add("Place 2", LatLng(93.0,93.0));
places.add("Place 3", LatLng(83.0,92.0));
places.add("Place 4", LatLng(93.0,91.0));
我有 "my" 经纬度:
LatLng myLocation = new LatLng(10.0,10.0);
如何根据离我最近的对象对这些对象进行排序?感谢帮助
得到当前位置后,可以通过计算行车距离(最适合餐厅等地方)排序如下,
计算到每个物体的距离
http://maps.googleapis.com/maps/api/directions/json?origin="+yourLat+","+yourLong+"&destination="+toLat+","+toLong+"&sensor=false&mode=DRIVING
计算出每个距离后,对这些距离应用一些简单的排序算法。
采用 this answer from the question posted by @shieldstroy, that uses the Great Circle Distance 中的算法,我使这个示例有效。
这里是 Comparator
:
public class SortPlaces implements Comparator<Place> {
LatLng currentLoc;
public SortPlaces(LatLng current){
currentLoc = current;
}
@Override
public int compare(final Place place1, final Place place2) {
double lat1 = place1.latlng.latitude;
double lon1 = place1.latlng.longitude;
double lat2 = place2.latlng.latitude;
double lon2 = place2.latlng.longitude;
double distanceToPlace1 = distance(currentLoc.latitude, currentLoc.longitude, lat1, lon1);
double distanceToPlace2 = distance(currentLoc.latitude, currentLoc.longitude, lat2, lon2);
return (int) (distanceToPlace1 - distanceToPlace2);
}
public 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;
}
}
这是高级代码,我只是把它放在 onCreate()
:
//My location, San Francisco
double lat = 37.77657;
double lng = -122.417506;
LatLng latLng = new LatLng(lat, lng);
//set up list
ArrayList<Place> places = new ArrayList<Place>();
places.add(new Place("New York", new LatLng(40.571256,73.98369)));
places.add(new Place("Colorado", new LatLng(39.260658,-105.101615)));
places.add(new Place("Los Angeles", new LatLng(33.986816,118.473819)));
for (Place p: places){
Log.i("Places before sorting", "Place: " + p.name);
}
//sort the list, give the Comparator the current location
Collections.sort(places, new SortPlaces(latLng));
for (Place p: places){
Log.i("Places after sorting", "Place: " + p.name);
}
这是日志输出:
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places before sorting﹕ Place: New York
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places before sorting﹕ Place: Colorado
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places before sorting﹕ Place: Los Angeles
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places after sorting﹕ Place: Los Angeles
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places after sorting﹕ Place: Colorado
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places after sorting﹕ Place: New York
计算距离有不同的方法。一个非常简单的公式是 Haversine 公式 (http://rosettacode.org/wiki/Haversine_formula#Java)。更准确的计算方法是 Vincenty 公式。如果两个位置相距不远,Haversine解就足够了。
计算距离后,您只需使用比较器对数组进行排序,例如:
Collections.sort(places, new Comparator<Place>() {
public int compare(Place p1, Place p2) {
return Double.compare(p1.getDistance(), p2.getDistance());
}
});
您可以使用
distanceInMeters = (loc1.distanceTo(loc2));
从google映射API,然后将结果添加到TreeMap
中的Key