我希望制作一个应用程序,可以检查用户最近的位置。我可以轻松获取用户的位置信息,并且已经有了一份包含纬度和经度的地点列表。
如何才能知道当前用户位置与列表中最近地点的距离?
在谷歌API中我找不到相关的信息。
我希望制作一个应用程序,可以检查用户最近的位置。我可以轻松获取用户的位置信息,并且已经有了一份包含纬度和经度的地点列表。
如何才能知道当前用户位置与列表中最近地点的距离?
在谷歌API中我找不到相关的信息。
Location loc1 = new Location("");
loc1.setLatitude(lat1);
loc1.setLongitude(lon1);
Location loc2 = new Location("");
loc2.setLatitude(lat2);
loc2.setLongitude(lon2);
float distanceInMeters = loc1.distanceTo(loc2);
http://developer.android.com/reference/android/location/Location.html
使用 distanceTo 或 distanceBetween 方法。你可以通过经纬度创建一个 Location 对象:
Location location = new Location("");
location.setLatitude(lat);
location.setLongitude(lon);
distanceTo
方法。 - laph一种近似解法(基于等经纬投影),速度更快(只需要1个三角函数和1个平方根)。
如果您的点不是太远,则此逼近值相关。与真实的haversine距离相比,它将始终高估。例如,如果您两点之间的纬度或经度差不超过4个小数位,则它将最多增加0.05382%到真实距离。
标准公式(Haversine)是精确的(即它适用于地球上任何经纬度对),但速度慢得多,因为它需要7个三角函数和2个平方根。如果您的两个点不是太远,并且绝对精度不是关键,则可以使用此近似版本(等经纬度投影),它更快,因为它仅使用一个三角函数和一个平方根。
// Approximate Equirectangular -- works if (lat1,lon1) ~ (lat2,lon2)
int R = 6371; // km
double x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2);
double y = (lat2 - lat1);
double distance = Math.sqrt(x * x + y * y) * R;
你可以通过以下两种方式进一步优化:O(n)
。为了得到一个O(1)
的解决方案,在计算精确解之前使用二维空间索引来修剪潜在匹配项。我们正在离开这个问题的范围 :) - Laurent Grégoire有几种方法可以使用,但要确定哪种是最佳的,我们首先需要知道您是否知道用户的高度以及其他点的高度?
根据您所追求的精度级别,您可以查看Haversine或Vincenty公式...
这些页面详细介绍了公式,并且对于不那么数学倾向的人还提供了如何在脚本中实现它们的解释!
Haversine公式:http://www.movable-type.co.uk/scripts/latlong.html
Vincenty公式:http://www.movable-type.co.uk/scripts/latlong-vincenty.html
如果您对公式中的任何含义有问题,请留言,我会尽力回答:)
获取LatLng之间距离的方法有两种。
public static void distanceBetween (double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results)
点击此处查看相关信息。
其次,praveen回答的是public float distanceTo (Location dest)
方法。
private float getDistance(double lat1, double lon1, double lat2, double lon2) {
float[] distance = new float[2];
Location.distanceBetween(lat1, lon1, lat2, lon2, distance);
return distance[0];
}
只需使用以下方法,传递经度和纬度,即可获得以米为单位的距离:
private static double distance_in_meter(final double lat1, final double lon1, final double lat2, final double lon2) {
double R = 6371000f; // Radius of the earth in m
double dLat = (lat1 - lat2) * Math.PI / 180f;
double dLon = (lon1 - lon2) * Math.PI / 180f;
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(latlong1.latitude * Math.PI / 180f) * Math.cos(latlong2.latitude * Math.PI / 180f) *
Math.sin(dLon/2) * Math.sin(dLon/2);
double c = 2f * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double d = R * c;
return d;
}
a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
c = 2 ⋅ atan2( √a, √(1−a) )
distance = R ⋅ c
其中,φ为纬度,λ为经度,R为地球半径(平均半径=6,371km);
注意,角度需要转换为弧度才能传递给三角函数!
fun distanceInMeter(firstLocation: Location, secondLocation: Location): Double {
val earthRadius = 6371000.0
val deltaLatitudeDegree = (firstLocation.latitude - secondLocation.latitude) * Math.PI / 180f
val deltaLongitudeDegree = (firstLocation.longitude - secondLocation.longitude) * Math.PI / 180f
val a = sin(deltaLatitudeDegree / 2).pow(2) +
cos(firstLocation.latitude * Math.PI / 180f) * cos(secondLocation.latitude * Math.PI / 180f) *
sin(deltaLongitudeDegree / 2).pow(2)
val c = 2f * atan2(sqrt(a), sqrt(1 - a))
return earthRadius * c
}
data class Location(val latitude: Double, val longitude: Double)
你可以使用Google Map API获取距离和时间(Google Map API链接)
只需将下载的JSON传递给此方法,即可获得两个经纬度之间的实时距离和时间
void parseJSONForDurationAndKMS(String json) throws JSONException {
Log.d(TAG, "called parseJSONForDurationAndKMS");
JSONObject jsonObject = new JSONObject(json);
String distance;
String duration;
distance = jsonObject.getJSONArray("routes").getJSONObject(0).getJSONArray("legs").getJSONObject(0).getJSONObject("distance").getString("text");
duration = jsonObject.getJSONArray("routes").getJSONObject(0).getJSONArray("legs").getJSONObject(0).getJSONObject("duration").getString("text");
Log.d(TAG, "distance : " + distance);
Log.d(TAG, "duration : " + duration);
distanceBWLats.setText("Distance : " + distance + "\n" + "Duration : " + duration);
}
import android.location.Location;
吗? - Pranav MS