दो निर्देशांक के बीच की दूरी की गणना करने का कार्य


136

मैं वर्तमान में नीचे दिए गए फ़ंक्शन का उपयोग कर रहा हूं और यह ठीक से काम नहीं करता है। गूगल मैप्स के अनुसार, के बीच की दूरी इन निर्देशांक (से 59.3293371,13.4877472करने के लिए 59.3225525,13.4619422) कर रहे हैं 2.2किलोमीटर की दूरी पर है, जबकि समारोह रिटर्न 1.6किलोमीटर। मैं इस फ़ंक्शन को सही दूरी कैसे लौटा सकता हूं?

function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2-lat1);  // deg2rad below
  var dLon = deg2rad(lon2-lon1); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * 
    Math.sin(dLon/2) * Math.sin(dLon/2)
    ; 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c; // Distance in km
  return d;
}

function deg2rad(deg) {
  return deg * (Math.PI/180)
}

jsFiddle: http://jsfiddle.net/edgren/gAHJB/



4
मैं यहाँ सिर्फ इस सूत्र को पाने के लिए आया, धन्यवाद :)
डेविड कॉलनान

जवाबों:


173

क्या आप उपयोग कर रहे कहा जाता है haversine सूत्र है, जो एक क्षेत्र पर दो अंक के बीच की दूरी की गणना करता है कौवा मक्खियों के रूप में । आपके द्वारा प्रदान किया गया Google मानचित्र लिंक दूरी को 2.2 किमी दिखाता है क्योंकि यह एक सीधी रेखा नहीं है।

भौगोलिक गणना करने के लिए वोलफ्राम अल्फा एक बेहतरीन संसाधन है, और इन दो बिंदुओं के बीच 1.652 किमी की दूरी भी दिखाता है ।

ड्राइव दूरी बनाम सीधी रेखा की दूरी (लाल रेखा की खान)।

यदि आप स्ट्रेट-लाइन दूरी (कौवा फ़ाइलों के रूप में) की तलाश कर रहे हैं, तो आपका फ़ंक्शन सही ढंग से काम कर रहा है। यदि आप जो चाहते हैं वह दूरी (या बाइकिंग दूरी या सार्वजनिक परिवहन दूरी या पैदल दूरी) है, तो आपको उचित मार्ग प्राप्त करने के लिए एक मैपिंग एपीआई ( Google या बिंग सबसे लोकप्रिय) का उपयोग करना होगा, जिसमें दूरी शामिल होगी।

संयोग से, Google मैप्स एपीआई गोलाकार दूरी के लिए एक पैक विधि प्रदान करता है, अपने google.maps.geometry.sphericalनाम स्थान (देखने के लिए computeDistanceBetween) में। यह संभवतः अपना स्वयं का रोल करने से बेहतर है (शुरुआत के लिए, यह पृथ्वी की त्रिज्या के लिए अधिक सटीक मूल्य का उपयोग करता है)।

हमारे बीच में उठा-पटक के लिए, जब मैं "स्ट्रेट-लाइन डिस्टेंस" कहता हूं, तो मैं एक "स्ट्रेट लाइन ऑन ए स्फीयर" की बात कर रहा हूं, जो कि वास्तव में एक कर्व्ड लाइन (यानी महान-सर्कल की दूरी) है।


5
मेरा सौभाग्य! जवाब देने में मजा आया।
एथन ब्राउन

4
यह एक सुंदर उत्तर है। मैं सुंदर कहता हूं क्योंकि प्रदान किए गए विवरण मेरे जैसे नौसिखिए के लिए भी अंतर को समझने के लिए बहुत अच्छे हैं।
सुप्रीत

78

मैंने पहले भी इसी तरह का समीकरण लिखा है - इसका परीक्षण किया और 1.6 किमी भी मिला।

आपका Google मानचित्र DRIVING दूरी दिखा रहा था।

आपका कार्य कौवा मक्खियों (सीधी रेखा दूरी) के रूप में गणना कर रहा है।

alert(calcCrow(59.3293371,13.4877472,59.3225525,13.4619422).toFixed(1));



    //This function takes in latitude and longitude of two location and returns the distance between them as the crow flies (in km)
    function calcCrow(lat1, lon1, lat2, lon2) 
    {
      var R = 6371; // km
      var dLat = toRad(lat2-lat1);
      var dLon = toRad(lon2-lon1);
      var lat1 = toRad(lat1);
      var lat2 = toRad(lat2);

      var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
      var d = R * c;
      return d;
    }

    // Converts numeric degrees to radians
    function toRad(Value) 
    {
        return Value * Math.PI / 180;
    }

5
मुझे लगता है कि आपके चर नाम बहुत अधिक वर्णनात्मक हैं :)
pie6k

14

डेरेक के समाधान ने मेरे लिए ठीक काम किया, और मैंने बस इसे PHP में बदल दिया है, आशा है कि यह किसी को वहां से बाहर निकालने में मदद करता है!

function calcCrow($lat1, $lon1, $lat2, $lon2){
        $R = 6371; // km
        $dLat = toRad($lat2-$lat1);
        $dLon = toRad($lon2-$lon1);
        $lat1 = toRad($lat1);
        $lat2 = toRad($lat2);

        $a = sin($dLat/2) * sin($dLat/2) +sin($dLon/2) * sin($dLon/2) * cos($lat1) * cos($lat2); 
        $c = 2 * atan2(sqrt($a), sqrt(1-$a)); 
        $d = $R * $c;
        return $d;
}

// Converts numeric degrees to radians
function toRad($Value) 
{
    return $Value * pi() / 180;
}

5

इसे इस्तेमाल करे। यह VB.net में है और आपको इसे जावास्क्रिप्ट में बदलने की आवश्यकता है। यह फ़ंक्शन दशमलव मिनटों में मापदंडों को स्वीकार करता है।

    Private Function calculateDistance(ByVal long1 As String, ByVal lat1 As String, ByVal long2 As String, ByVal lat2 As String) As Double
    long1 = Double.Parse(long1)
    lat1 = Double.Parse(lat1)
    long2 = Double.Parse(long2)
    lat2 = Double.Parse(lat2)

    'conversion to radian
    lat1 = (lat1 * 2.0 * Math.PI) / 60.0 / 360.0
    long1 = (long1 * 2.0 * Math.PI) / 60.0 / 360.0
    lat2 = (lat2 * 2.0 * Math.PI) / 60.0 / 360.0
    long2 = (long2 * 2.0 * Math.PI) / 60.0 / 360.0

    ' use to different earth axis length
    Dim a As Double = 6378137.0        ' Earth Major Axis (WGS84)
    Dim b As Double = 6356752.3142     ' Minor Axis
    Dim f As Double = (a - b) / a        ' "Flattening"
    Dim e As Double = 2.0 * f - f * f      ' "Eccentricity"

    Dim beta As Double = (a / Math.Sqrt(1.0 - e * Math.Sin(lat1) * Math.Sin(lat1)))
    Dim cos As Double = Math.Cos(lat1)
    Dim x As Double = beta * cos * Math.Cos(long1)
    Dim y As Double = beta * cos * Math.Sin(long1)
    Dim z As Double = beta * (1 - e) * Math.Sin(lat1)

    beta = (a / Math.Sqrt(1.0 - e * Math.Sin(lat2) * Math.Sin(lat2)))
    cos = Math.Cos(lat2)
    x -= (beta * cos * Math.Cos(long2))
    y -= (beta * cos * Math.Sin(long2))
    z -= (beta * (1 - e) * Math.Sin(lat2))

    Return Math.Sqrt((x * x) + (y * y) + (z * z))
End Function

जावास्क्रिप्ट में परिवर्तित कार्य संपादित करें

function calculateDistance(lat1, long1, lat2, long2)
  {    

      //radians
      lat1 = (lat1 * 2.0 * Math.PI) / 60.0 / 360.0;      
      long1 = (long1 * 2.0 * Math.PI) / 60.0 / 360.0;    
      lat2 = (lat2 * 2.0 * Math.PI) / 60.0 / 360.0;   
      long2 = (long2 * 2.0 * Math.PI) / 60.0 / 360.0;       


      // use to different earth axis length    
      var a = 6378137.0;        // Earth Major Axis (WGS84)    
      var b = 6356752.3142;     // Minor Axis    
      var f = (a-b) / a;        // "Flattening"    
      var e = 2.0*f - f*f;      // "Eccentricity"      

      var beta = (a / Math.sqrt( 1.0 - e * Math.sin( lat1 ) * Math.sin( lat1 )));    
      var cos = Math.cos( lat1 );    
      var x = beta * cos * Math.cos( long1 );    
      var y = beta * cos * Math.sin( long1 );    
      var z = beta * ( 1 - e ) * Math.sin( lat1 );      

      beta = ( a / Math.sqrt( 1.0 -  e * Math.sin( lat2 ) * Math.sin( lat2 )));    
      cos = Math.cos( lat2 );   
      x -= (beta * cos * Math.cos( long2 ));    
      y -= (beta * cos * Math.sin( long2 ));    
      z -= (beta * (1 - e) * Math.sin( lat2 ));       

      return (Math.sqrt( (x*x) + (y*y) + (z*z) )/1000);  
    }

6
这个问题问了जावास्क्रिप्ट的答案.. आपको इसे अंग्रेजी में बदलना है :)
VulfCompressor

2
एक जावास्क्रिप्ट संस्करण जोड़ा
नूरुल

अपने चर के लिए और अधिक सार्थक नामों का उपयोग करने का प्रयास करें। वर्बोज़ होने से डरो मत, क्योंकि आजकल जावास्क्रिप्ट आमतौर पर छोटा होता है और चर नाम तो केवल मनुष्यों के लिए उपयोगी हो जाते हैं। उदाहरण के लिए: const earthsMajorAccess = 6378137.0; सहायक टिप्पणियों की आवश्यकता को समाप्त करना (चूँकि चर नाम का अर्थ है कि यह क्या है)
एड्रियानो माइकल

यह फ़ंक्शन 5 साल से अधिक समय पहले लिखा गया था। आप को संशोधित करने का स्वागत है :)
नूरुल

2

जावास्क्रिप्ट में दो बिंदुओं के बीच की दूरी की गणना करें

function distance(lat1, lon1, lat2, lon2, unit) {
        var radlat1 = Math.PI * lat1/180
        var radlat2 = Math.PI * lat2/180
        var theta = lon1-lon2
        var radtheta = Math.PI * theta/180
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        dist = Math.acos(dist)
        dist = dist * 180/Math.PI
        dist = dist * 60 * 1.1515
        if (unit=="K") { dist = dist * 1.609344 }
        if (unit=="N") { dist = dist * 0.8684 }
        return dist
}

अधिक जानकारी के लिए इसे देखें: संदर्भ लिंक


2

हैवेरसिन सूत्र का उपयोग करना, कोड का स्रोत :

//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//:::                                                                         :::
//:::  This routine calculates the distance between two points (given the     :::
//:::  latitude/longitude of those points). It is being used to calculate     :::
//:::  the distance between two locations using GeoDataSource (TM) prodducts  :::
//:::                                                                         :::
//:::  Definitions:                                                           :::
//:::    South latitudes are negative, east longitudes are positive           :::
//:::                                                                         :::
//:::  Passed to function:                                                    :::
//:::    lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees)  :::
//:::    lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees)  :::
//:::    unit = the unit you desire for results                               :::
//:::           where: 'M' is statute miles (default)                         :::
//:::                  'K' is kilometers                                      :::
//:::                  'N' is nautical miles                                  :::
//:::                                                                         :::
//:::  Worldwide cities and other features databases with latitude longitude  :::
//:::  are available at https://www.geodatasource.com                         :::
//:::                                                                         :::
//:::  For enquiries, please contact sales@geodatasource.com                  :::
//:::                                                                         :::
//:::  Official Web site: https://www.geodatasource.com                       :::
//:::                                                                         :::
//:::               GeoDataSource.com (C) All Rights Reserved 2018            :::
//:::                                                                         :::
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

function distance(lat1, lon1, lat2, lon2, unit) {
    if ((lat1 == lat2) && (lon1 == lon2)) {
        return 0;
    }
    else {
        var radlat1 = Math.PI * lat1/180;
        var radlat2 = Math.PI * lat2/180;
        var theta = lon1-lon2;
        var radtheta = Math.PI * theta/180;
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        if (dist > 1) {
            dist = 1;
        }
        dist = Math.acos(dist);
        dist = dist * 180/Math.PI;
        dist = dist * 60 * 1.1515;
        if (unit=="K") { dist = dist * 1.609344 }
        if (unit=="N") { dist = dist * 0.8684 }
        return dist;
    }
}

नमूना कोड LGPLv3 के तहत लाइसेंस प्राप्त है।


1

मैंने दो निर्देशांक के बीच दूरी खोजने के लिए फ़ंक्शन लिखा है। यह मीटर में दूरी लौटाएगा।

 function findDistance() {
   var R = 6371e3; // R is earth’s radius
   var lat1 = 23.18489670753479; // starting point lat
   var lat2 = 32.726601;         // ending point lat
   var lon1 = 72.62524545192719; // starting point lon
   var lon2 = 74.857025;         // ending point lon
   var lat1radians = toRadians(lat1);
   var lat2radians = toRadians(lat2);

   var latRadians = toRadians(lat2-lat1);
   var lonRadians = toRadians(lon2-lon1);

   var a = Math.sin(latRadians/2) * Math.sin(latRadians/2) +
        Math.cos(lat1radians) * Math.cos(lat2radians) *
        Math.sin(lonRadians/2) * Math.sin(lonRadians/2);
   var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

   var d = R * c;

   console.log(d)
}

function toRadians(val){
    var PI = 3.1415926535;
    return val / 180.0 * PI;
}

1

ग्रेट-सर्कल दूरी - कॉर्ड लंबाई से

यहां रणनीति डिजाइन पैटर्न को लागू करने का एक सुंदर समाधान है; मुझे उम्मीद है कि यह काफी पठनीय होगा।

TwoPointsDistanceCalculatorStrategy.js :

module.exports = () =>

class TwoPointsDistanceCalculatorStrategy {

    constructor() {}

    calculateDistance({ point1Coordinates, point2Coordinates }) {}
};

GreatCircleTwoPointsDistanceCalculatorStrategy.js:

module.exports = ({ TwoPointsDistanceCalculatorStrategy }) =>

class GreatCircleTwoPointsDistanceCalculatorStrategy extends TwoPointsDistanceCalculatorStrategy {

    constructor() {
        super();
    }

    /**
     * Following the algorithm documented here: 
     * https://en.wikipedia.org/wiki/Great-circle_distance#Computational_formulas
     * 
     * @param {object} inputs
     * @param {array} inputs.point1Coordinates
     * @param {array} inputs.point2Coordinates
     * 
     * @returns {decimal} distance in kelometers
     */
    calculateDistance({ point1Coordinates, point2Coordinates }) {

        const convertDegreesToRadians = require('../convert-degrees-to-radians');
        const EARTH_RADIUS = 6371;   // in kelometers

        const [lat1 = 0, lon1 = 0] = point1Coordinates;
        const [lat2 = 0, lon2 = 0] = point2Coordinates;

        const radianLat1 = convertDegreesToRadians({ degrees: lat1 });
        const radianLon1 = convertDegreesToRadians({ degrees: lon1 });
        const radianLat2 = convertDegreesToRadians({ degrees: lat2 });
        const radianLon2 = convertDegreesToRadians({ degrees: lon2 });

        const centralAngle = _computeCentralAngle({ 
            lat1: radianLat1, lon1: radianLon1, 
            lat2: radianLat2, lon2: radianLon2, 
        });

        const distance = EARTH_RADIUS * centralAngle;

        return distance;
    }
};


/**
 * 
 * @param {object} inputs
 * @param {decimal} inputs.lat1
 * @param {decimal} inputs.lon1
 * @param {decimal} inputs.lat2
 * @param {decimal} inputs.lon2
 * 
 * @returns {decimal} centralAngle
 */
function _computeCentralAngle({ lat1, lon1, lat2, lon2 }) {

    const chordLength = _computeChordLength({ lat1, lon1, lat2, lon2 });
    const centralAngle = 2 * Math.asin(chordLength / 2);

    return centralAngle;
}


/**
 * 
 * @param {object} inputs
 * @param {decimal} inputs.lat1
 * @param {decimal} inputs.lon1
 * @param {decimal} inputs.lat2
 * @param {decimal} inputs.lon2
 * 
 * @returns {decimal} chordLength
 */
function _computeChordLength({ lat1, lon1, lat2, lon2 }) {

    const { sin, cos, pow, sqrt } = Math;

    const ΔX = cos(lat2) * cos(lon2) - cos(lat1) * cos(lon1);
    const ΔY = cos(lat2) * sin(lon2) - cos(lat1) * sin(lon1);
    const ΔZ = sin(lat2) - sin(lat1);

    const ΔXSquare = powX, 2);
    const ΔYSquare = powY, 2);
    const ΔZSquare = powZ, 2);

    const chordLength = sqrtXSquare + ΔYSquare + ΔZSquare);

    return chordLength;
}

परिवर्तित डिग्री करने वाली radians.js:

module.exports = function convertDegreesToRadians({ degrees }) {

    return degrees * Math.PI / 180;
};

यह ग्रेट-सर्कल दूरी निम्नलिखित है - कॉर्ड की लंबाई से, यहां प्रलेखित ।


0

इस पते पर जाएं। https://www.movable-type.co.uk/scripts/latlong.html आप इस कोड का उपयोग कर सकते हैं:

JavaScript:     

const R = 6371e3; // metres
const φ1 = lat1 * Math.PI/180; // φ, λ in radians
const φ2 = lat2 * Math.PI/180;
const Δφ = (lat2-lat1) * Math.PI/180;
const Δλ = (lon2-lon1) * Math.PI/180;

const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
          Math.cos1) * Math.cos2) *
          Math.sin(Δλ/2) * Math.sin(Δλ/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

const d = R * c; // in metres
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.