사용자가있는 가장 가까운 장소를 확인하는 앱을 만들고 싶습니다. 사용자의 위치를 쉽게 알 수 있으며 위도와 경도가있는 장소 목록이 이미 있습니다.
현재 사용자 위치에 대해 목록에서 가장 가까운 위치를 아는 가장 좋은 방법은 무엇입니까?
Google API에서 아무것도 찾을 수 없습니다.
사용자가있는 가장 가까운 장소를 확인하는 앱을 만들고 싶습니다. 사용자의 위치를 쉽게 알 수 있으며 위도와 경도가있는 장소 목록이 이미 있습니다.
현재 사용자 위치에 대해 목록에서 가장 가까운 위치를 아는 가장 좋은 방법은 무엇입니까?
Google 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);
import android.location.Location;
있는 나
http://developer.android.com/reference/android/location/Location.html
distanceTo 또는 distanceBetween을 살펴보십시오. 위도와 경도에서 Location 객체를 만들 수 있습니다.
Location location = new Location("");
location.setLatitude(lat);
location.setLongitude(lon);
distanceTo
방법 을 의미한다고 확신 합니다.
정방형 투영을 기반으로 한 근사 솔루션, 훨씬 빠릅니다 (1 삼각근과 1 제곱근 만 필요).
이 근사는 포인트가 너무 멀리 떨어져 있지 않은 경우 관련이 있습니다. 그것은 것입니다 항상 이상 견적 실제 하버 사인 거리에 비교했다. 예를 들어 두 지점 사이의 델타 위도 또는 경도가 10 진수 4도를 초과하지 않는 경우 실제 거리에 0.05382 % 이하 를 추가 합니다 .
표준 공식 (Haversine)은 정확한 공식 ( 즉, 지구상의 임의의 경도 / 위도에 대해 작동 함)이지만 7 삼각법과 2 제곱근이 필요하므로 훨씬 느립니다 . 두 개의 점이 너무 멀리 떨어져 있지 않고 절대 정밀도가 가장 중요하지 않은 경우이 근사 버전 (Equirectangular)을 사용할 수 있습니다. 이것은 삼각법과 제곱근을 하나만 사용하므로 훨씬 빠릅니다.
// 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;
다음 중 하나를 수행하여 이를 추가 로 최적화 할 수 있습니다 .
자세한 내용은 http://www.movable-type.co.uk/scripts/latlong.html을 참조하십시오.
http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe 에 여러 언어로 된 Haversine 공식의 멋진 참조 구현이 있습니다 .
O(n)
. A에 대한 O(1)
해결책, 정확한 솔루션을 계산하기 전에 잠재적 인 일치를 손질하는 2 차원 공간 인덱스를 사용합니다. 우리는 :)이 질문의 범위를 떠난다
사용할 수있는 몇 가지 방법이 있지만 가장 좋은 방법을 결정하려면 먼저 사용자의 고도와 다른 지점의 고도를 알고 있는지 알아야합니다.
추구하는 정확도 수준에 따라 Haversine 또는 Vincenty 공식을 살펴볼 수 있습니다.
이 페이지는 공식을 자세히 설명하고 수학적으로 덜 기울이는 사람들을 위해 스크립트로 구현하는 방법에 대한 설명도 제공합니다!
Haversine 공식 : http://www.movable-type.co.uk/scripts/latlong.html
Vincenty Formula : 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)
그리고 두 번째
public float distanceTo (Location dest)
praveen이 대답했습니다.
다음 방법을 사용하여 위도와 경도를 전달하고 미터 단위로 거리를 얻으십시오.
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;
}
Google Map API Google Map API를 사용하여 거리와 시간을 얻을 수 있습니다.
다운로드 한 JSON 을이 방법으로 전달하면 두 개의 latlong 사이의 실시간 거리와 시간을 얻을 수 있습니다.
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);
}
a = sin² (Δφ / 2) + cos φ1 ⋅ cos φ2 ⋅ sin² (Δλ / 2)
c = 2 ⋅ atan2 (√a, √ (1−a))
거리 = 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)