दो भू बिंदुओं के बीच की दूरी प्राप्त करें


108

मैं एक ऐप बनाना चाहता हूं जो निकटतम स्थान की जांच करता है जहां उपयोगकर्ता है। मुझे उपयोगकर्ता का स्थान आसानी से मिल सकता है और मेरे पास अक्षांश और देशांतर वाले स्थानों की एक सूची पहले से है।

वर्तमान उपयोगकर्ता स्थान के खिलाफ सूची के निकटतम स्थान को जानने का सबसे अच्छा तरीका क्या होगा।

मुझे Google API में कुछ भी नहीं मिला।

जवाबों:


164
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(android.location.Location)


2
संभवतः Location.DistanceBetween () का उपयोग करने की तुलना में धीमा है क्योंकि यह स्थान ऑब्जेक्ट्स का उपयोग कर रहा है लेकिन मेरे उद्देश्यों के लिए बहुत अच्छी तरह से काम करता है।
3

स्थान के लिए मुझे कौन सा वर्ग आयात करना है import android.location.Location;या कौन सा
प्रणव एमएस

@PranavMS हां android.location.Location;
एंड्रयूज

मुझे लगता है कि दूरी पहले और अंतिम बिंदु के बीच की दूरी को वापस लेती है, लेकिन एक रेक्टल लाइन में, इसलिए यदि आप बिंदु से b तक कोई अन्य दिशा-निर्देश लेते हैं, तो रास्ते से अलग होने के बाद कभी भी इसे स्वीकार नहीं किया जाना चाहिए, जब दूरी से जुड़ता है, तो आप कर सकते हैं बनाए गए बिंदुओं के बीच प्रत्येक दूरी को सहेजें और फिर अंतिम पैरामीटर परिणामों के साथ [] सही दूरी प्राप्त करें।
गैस्टोन सेलेन

122

http://developer.android.com/reference/android/location/Location.html

दूरी या दूरी में देखो। आप अक्षांश और देशांतर से स्थान ऑब्जेक्ट बना सकते हैं:

Location location = new Location("");
location.setLatitude(lat);
location.setLongitude(lon);

37
दूरीबेटन एक स्थिर विधि है जो 2 सेट लंबे लंबे बिंदुओं को लेती है, इसलिए आपको स्थान ऑब्जेक्ट =) को
तुरंत हटाने की

4
मुझे यकीन है कि वह distanceToविधि के लिए इसका मतलब है ।
laph

यह महान और सुपर सहायक है, लेकिन कंस्ट्रक्टर में स्ट्रिंग प्रदाता क्या है?
miss.serena

33

एक अनुमानित समाधान (एक समभुज प्रक्षेपण पर आधारित), बहुत तेज़ी से (इसमें केवल 1 ट्रिगर और 1 वर्गमूल की आवश्यकता होती है)।

यदि आपके बिंदु बहुत अलग नहीं हैं, तो यह अनुमान प्रासंगिक है। यह हमेशा वास्तविक हैवरसिन दूरी की तुलना में अधिक-अनुमान लगाएगा। उदाहरण के लिए, यह वास्तविक दूरी से 0.05382% से अधिक नहीं जोड़ेगा यदि आपके दो बिंदुओं के बीच डेल्टा अक्षांश या देशांतर 4 दशमलव डिग्री से अधिक नहीं है

मानक सूत्र (हैवरसाइन) सटीक एक है (अर्थात, यह पृथ्वी पर देशांतर / अक्षांश के किसी भी जोड़े के लिए काम करता है) लेकिन बहुत धीमा है क्योंकि इसे 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;

आप इसे आगे भी अनुकूलित कर सकते हैं:

  1. वर्गमूल निकालना यदि आप बस दूरी की तुलना दूसरे से करते हैं (उस स्थिति में दोनों वर्ग दूरी की तुलना करें);
  2. यदि आप एक मास्टर बिंदु से कई अन्य लोगों की दूरी की गणना करते हैं, तो कोसाइन-फैक्टरिंग (उस स्थिति में आप मास्टर बिंदु पर केंद्रित समकालिक अप्रत्यक्ष प्रक्षेपण करते हैं, इसलिए आप सभी तुलनाओं के लिए एक बार कॉशन की गणना कर सकते हैं)।

अधिक जानकारी के लिए देखें: http://www.movable-type.co.uk/scripts/latlong.html

कई भाषाओं में हैवरसाइन सूत्र का एक अच्छा संदर्भ कार्यान्वयन है: http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe


महान आदमी थैंक्स। लेकिन अगर मुझे एक परिधि में एक स्थान के आसपास के स्थानों का एक सेट प्राप्त करने की आवश्यकता है, तो क्या मुझे खोजे गए स्थान के खिलाफ प्रत्येक स्थान की जांच करने के लिए लूप का उपयोग करना चाहिए और केवल उन लोगों को रखना चाहिए जो परिधि में हैं?
themhz

आप कर सकते हैं, लेकिन यह एक जानवर-बल दृष्टिकोण है O(n)। एक O(1)समाधान के लिए, सटीक समाधान की गणना करने से पहले संभावित मैचों को ट्रिम करने के लिए 2 डी स्थानिक सूचकांक का उपयोग करें। हम इस प्रश्न के दायरे को छोड़ रहे हैं :)
लॉरेंट ग्रेजायर

यह अच्छा संभव अनुकूलन का एक बहुत अच्छा रैपअप है .. thx! वास्तव में मैं क्या देख रहा था
सैम Vloeberghs

मैं बस यह जानना चाहता था कि क्या यह सूत्र बड़ी दूरी के लिए काम करता है
संदीपन मजी

उत्तर देखें, लेकिन संक्षेप में: नहीं , यह बड़ी दूरी के लिए काम नहीं करता है। सटीक की तुलना में त्रुटि बड़ा दो अंक के बीच की दूरी, बड़ा Haversine सूत्रों।
लॉरेंट ग्रैगोइरे

11

ऐसी कुछ विधियाँ हैं जिनका आप उपयोग कर सकते हैं, लेकिन यह निर्धारित करने के लिए कि हमें सबसे पहले यह जानने की आवश्यकता है कि क्या आपको उपयोगकर्ता की ऊँचाई, साथ ही साथ अन्य बिंदुओं की ऊँचाई के बारे में पता है?

आपके द्वारा की जाने वाली सटीकता के स्तर के आधार पर, आप या तो हैवेर्सिन या विन्सेन्टी फ़ार्मुलों में देख सकते हैं ...

ये पृष्ठ सूत्र का विस्तार करते हैं, और, कम गणितीय रूप से इच्छुक के लिए भी उन्हें स्क्रिप्ट में लागू करने के तरीके की व्याख्या प्रदान करते हैं!

हैवरसाइन फॉर्मूला: http://www.movable-type.co.uk/scripts/latlong.html

विन्सेंटी फॉर्मूला: http://www.movable-type.co.uk/scripts/latlong-vincenty.html

यदि आपको सूत्रों में किसी भी अर्थ के साथ कोई समस्या है, तो टिप्पणी करें और मैं उनका उत्तर देने की पूरी कोशिश करूंगा :)


4

LatLng के बीच दूरी पाने के दो तरीके हैं।

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

यह देखो

और दूसरा

public float distanceTo (Location dest) के रूप में praveen द्वारा उत्तर दिया गया।



1

बस निम्नलिखित विधि का उपयोग करें, इसे अव्यक्त और लंबा पास करें और मीटर में दूरी प्राप्त करें:

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

2
latlong1 और latlong2 परिभाषित नहीं हैं
लड़का

1
latlong1 और latlong2 क्या है?
निस्सल मलिंडा लिवर

0

आप 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);


}

0

a = sinφ (Δφ / 2) + cos ⋅1 φ cos ⋅2 ² sin² (2λ / 2)

c = 2 = atan2 (2a, 1 (1) a))

दूरी = आर = सी

जहां, अक्षांश है, λ देशांतर है, R पृथ्वी की त्रिज्या है (माध्य त्रिज्या = 6,371 किमी);

ध्यान दें कि कोणों को ट्रिगर कार्यों के लिए पारित करने के लिए रेडियन में होने की आवश्यकता है!

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)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.