在我的“原生”Android应用程序中,我正在尝试计算地图上两个位置之间的距离和/或米(如乌鸦飞行)的距离。理想情况下,会有一种方法可以将两个LatLng值(因为我可以随时使用)作为输入并返回以米和/或码为单位的距离。如上所述,我使用的是Android Maps v2 API。
我看过许多有关计算距离的帖子(20-30),但没有找到任何帮助我解决问题的帖子。这是一个原生的Android应用程序,我正在使用Maps v2 API。
不确定这是否是最佳方法,但我目前正在尝试使用Location
方法:
distanceBetween(double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results)
但不幸的是,应用程序每次都崩溃,因为我得到了结果的空值。我已经通过调试器验证了我传入的纬度和经度虚拟值是否有效以及results
的值是否为空(因此问题)。这是LogCat:
04-04 23:48:04.770: D/onMapClick(17970): lat/lng: (32.90843038503306,-117.22537234425546)
04-04 23:48:08.710: D/dalvikvm(17970): threadid=1: still suspended after undo (sc=1 dc=1 s=Y)
04-04 23:48:08.710: D/dalvikvm(17970): GC_FOR_MALLOC freed 7010 objects / 641712 bytes in 121ms
04-04 23:48:24.980: D/AndroidRuntime(17970): Shutting down VM
04-04 23:48:24.980: W/dalvikvm(17970): threadid=1: thread exiting with uncaught exception (group=0x40020950)
04-04 23:48:25.100: E/AndroidRuntime(17970): FATAL EXCEPTION: main
04-04 23:48:25.100: E/AndroidRuntime(17970): java.lang.IllegalArgumentException: results is null or has length < 1
04-04 23:48:25.100: E/AndroidRuntime(17970): at android.location.Location.distanceBetween(Location.java:394)
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.example.googleplacesandmaps.PlacesMapActivity$1.onMapClick(PlacesMapActivity.java:259)
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.google.android.gms.maps.GoogleMap$6.onMapClick(Unknown Source)
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.google.android.gms.internal.t$a.onTransact(Unknown Source)
04-04 23:48:25.100: E/AndroidRuntime(17970): at android.os.Binder.transact(Binder.java:249)
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.google.android.gms.maps.internal.IOnMapClickListener$Stub$Proxy.onMapClick(IOnMapClickListener.java:93)
04-04 23:48:25.100: E/AndroidRuntime(17970): at maps.i.s.b(Unknown Source)
04-04 23:48:25.100: E/AndroidRuntime(17970): at maps.y.v.c(Unknown Source)
04-04 23:48:25.100: E/AndroidRuntime(17970): at maps.y.bf.onSingleTapConfirmed(Unknown Source)
04-04 23:48:25.100: E/AndroidRuntime(17970): at maps.d.v.onSingleTapConfirmed(Unknown Source)
04-04 23:48:25.100: E/AndroidRuntime(17970): at maps.d.j.handleMessage(Unknown Source)
04-04 23:48:25.100: E/AndroidRuntime(17970): at android.os.Handler.dispatchMessage(Handler.java:99)
04-04 23:48:25.100: E/AndroidRuntime(17970): at android.os.Looper.loop(Looper.java:123)
04-04 23:48:25.100: E/AndroidRuntime(17970): at android.app.ActivityThread.main(ActivityThread.java:4627)
04-04 23:48:25.100: E/AndroidRuntime(17970): at java.lang.reflect.Method.invokeNative(Native Method)
04-04 23:48:25.100: E/AndroidRuntime(17970): at java.lang.reflect.Method.invoke(Method.java:521)
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:893)
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:651)
04-04 23:48:25.100: E/AndroidRuntime(17970): at dalvik.system.NativeStart.main(Native Method)
以下是我目前用来尝试计算距离的方法:
Location.distanceBetween(Double.parseDouble(user_latitude), Double.parseDouble(user_longitude),
fxdLatitude, fxdLongitude, results);
results
被定义为类变量:private float[] results = null;
不确定我在这里做错了什么。
我宁愿有一个方法可以将两个LatLng作为输入参数,因为它们都很容易获得......但更重要的是,我只有一个位置可用作单独的经度,纬度值......第二个位置仅作为LatLng值提供,因为我通过onMapClick获取它(当用户点击屏幕时)。因此,要使用方法distanceBetween
,我需要将此LatLng值转换为纬度/经度对才能使用它。有谁知道怎么做?
希望有一种计算距离的简单方法,以及从LatLng值“提取”纬度/经度的简单方法。
答案 0 :(得分:11)
如何从两个位置制作位置对象?
private float distanceBetween(LatLng latLng1, LatLng latLng2) {
Location loc1 = new Location(LocationManager.GPS_PROVIDER);
Location loc2 = new Location(LocationManager.GPS_PROVIDER);
loc1.setLatitude(latLng1.latitude);
loc1.setLongitude(latLng1.longitude);
loc2.setLatitude(latLng2.latitude);
loc2.setLongitude(latLng2.longitude);
return loc1.distanceTo(loc2);
}
答案 1 :(得分:3)
您可以使用以下函数接受两个LatLng来计算它们之间的距离。但在使用之前,请确保您的LatLng变量不为空。
public static double distance(LatLng StartP, LatLng EndP) { double lat1 = StartP.latitude; double lat2 = EndP.latitude; double lon1 = StartP.longitude; double lon2 = EndP.longitude; double dLat = Math.toRadians(lat2-lat1); double dLon = Math.toRadians(lon2-lon1); double a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(dLon/2) * Math.sin(dLon/2); double c = 2 * Math.asin(Math.sqrt(a)); return 6366000 * c; }
答案 2 :(得分:1)
private float[] results = null;
错了。
您需要使用private float[] results = new float[1];
并使用results[0]
读取距离。
答案 3 :(得分:0)
是的,我认为MaciejGórski是对的。
计算的距离存储在结果[0]中。如果结果的长度为2或更大,则初始方位存储在结果[1]中。如果结果长度为3或更大,则最终方位存储在结果[2]中。
答案 4 :(得分:0)
在 Kotlin 中,您可以:
定义将LatLng
转换为Location
的方法:
fun LatLng.toLocation() = Location(LocationManager.GPS_PROVIDER).also {
it.latitude = latitude
it.longitude = longitude
}
在每个LatLng
上调用它并使用Location#distanceTo(...)
方法:
val distance = coords1.toLocation().distanceTo(coords2.toLocation())
为LatLngBounds
定义扩展方法:
fun LatLngBounds.computeDistance(): Float {
return northeast.toLocation().distanceTo(southwest.toLocation())
}