2013-04-05 16 views
5

W mojej "natywnej" aplikacji na Androida próbuję obliczyć odległość w stopach i/lub metrach (w linii prostej) między dwie lokalizacje na mapie. Idealnie byłoby zastosować metodę, która przyniosłaby dwie wartości LatLng (jako że to, co mam łatwo dostępne) jako dane wejściowe i zwróci odległość w metrach i/lub stoczniach. Jak wspomniano powyżej, używam Androida Maps v2 API.Android Maps v2 API ... Jak obliczyć odległość między dwoma lokalizacjami (Lat, Long)

Przyjrzałem się WIELU postów (20-30) dotyczących obliczania odległości i nie znalazłem żadnych, które pomogłyby mi rozwiązać mój problem. Ponownie jest to natywna aplikacja na Androida i korzystam z interfejsu API Map V2.

Nie wiem, czy jest to najlepsze podejście, ale jestem obecnie próbuje użyć metody Location:

distanceBetween(double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results) 

Ale niestety aplikacja wywala za każdym razem, bo uzyskać wartość null dla wyników. Sprawdziłem za pomocą debugera, że ​​wartości atrapa długości i szerokości geograficznej, które przekazuję są poprawne i że wartość results jest zerowa (stąd problem). Oto 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) 

Oto metoda obecnie używam, aby spróbować obliczyć odległość:

  Location.distanceBetween(Double.parseDouble(user_latitude), Double.parseDouble(user_longitude), 
       fxdLatitude, fxdLongitude, results); 

results została zdefiniowana jako zmienna Klasa: private float[] results = null;

Nie pewnie, co robię źle tutaj.

Znowu wolałbym metodę, która wymagałaby dwóch LatLng jako parametrów wejściowych, ponieważ oba są łatwo dostępne ... ale być może ważniejsze jest to, że mam jedną z lokalizacji dostępnych jako oddzielne wartości długości, szerokości geograficznej ... druga lokalizacja jest dostępna tylko jako wartość LatLng, ponieważ otrzymuję ją za pomocą onMapClick (gdy użytkownik klika ekran). Tak więc, aby użyć metody distanceBetween, potrzebowałbym jakiejś konwersji tej wartości LatLng na parę Latitude/Longitude, aby móc z niej korzystać. Czy ktoś wie, jak to zrobić?

Mamy nadzieję, że istnieje prosty sposób obliczania odległości i prosty sposób "wyodrębnienia" szerokości/długości geograficznej z wartości LatLng.

Odpowiedz

1

private float[] results = null; jest nieprawidłowa.

Musisz użyć private float[] results = new float[1]; i odczytać odległość z results[0].

3

Możesz użyć następującej funkcji, która akceptuje dwie funkcje LatLng do obliczania odległości między nimi. Ale przed użyciem tego upewnij się, że zmienne LatLng nie są puste.

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; 
} 
+0

Jak zdobyć promień z centrum LatLong w Google Maps v2? –

+0

@ KetanMehta Jeśli masz na myśli promień widocznego obszaru, możesz uzyskać widok za pomocą funkcji LatLngBounds bbox = GoogleMap.getProjection(). GetVisibleRegion(). LatLngBounds. Następnie użyj metody Sharj distance calc, aby uzyskać odległość między bbox.southwest i bbox.northeast (jaka byłaby średnica widocznego obszaru). – Marco

0

Tak, myślę MaciejGórski ma rację.

Obliczona odległość jest przechowywana w wynikach [0]. Jeśli wyniki mają długość 2 lub większą, początkowe łożysko jest przechowywane w wynikach [1]. Jeśli wyniki mają długość 3 lub większą, końcowe wyniki są zapisywane w wynikach [2].

11

Co z tworzeniem obiektu lokalizacji z dwóch?

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); 
    } 
+0

Nie musisz konwertować szerokości i długości geograficznej, ponieważ są one w mikrometrach? – Snake

+0

jeśli nie są w formacie pływającym (jak 27.132235), muszą zostać przekonwertowane. – MSaudi

+0

Interesujące .. Dziękujemy – Snake

0

W Kotlin można:

Zdefiniować metodę konwersji LatLng do Location:

fun LatLng.toLocation() = Location(LocationManager.GPS_PROVIDER).also { 
    it.latitude = latitude 
    it.longitude = longitude 
} 

Nazwać każdego LatLng i używać Location#distanceTo(...) metody:

val distance = coords1.toLocation().distanceTo(coords2.toLocation()) 

Zdefiniować metodę rozszerzenia dla LatLngBounds:

fun LatLngBounds.computeDistance(): Float { 
    return northeast.toLocation().distanceTo(southwest.toLocation()) 
} 
Powiązane problemy