দুটি স্থানাঙ্কের মধ্যে দূরত্ব গণনা করার কাজ


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

জেএসফিডাল: http://jsfiddle.net/edgren/gAHJB/



4
আমি কেবল এই সূত্রটি পেতে এখানে এসেছি, ধন্যবাদ :)
ডেভিড কলানান

উত্তর:


173

আপনি যা ব্যবহার করছেন তাকে হ্যাওয়ারসিন সূত্র বলে , যা কাকটি উড়ে যাওয়ার সাথে সাথে একটি গোলকের দুটি পয়েন্টের মধ্যকার দূরত্ব গণনা করে । আপনার প্রদত্ত গুগল ম্যাপস লিঙ্কটি দূরত্বটি ২.২ কিমি হিসাবে দেখায় কারণ এটি কোনও সরল রেখা নয়।

ওল্ফ্রাম আলফা ভৌগলিক গণনা করার জন্য একটি দুর্দান্ত উত্স, এবং এই দুটি পয়েন্টের মধ্যে 1.652 কিমি দূরত্বও দেখায়

ড্রাইভ দূরত্ব বনাম সোজা রেখার দূরত্ব (লাল রেখা খনি)।

যদি আপনি সরলরেখার দূরত্বের (কাক ফাইল হিসাবে) সন্ধান করেন তবে আপনার ফাংশনটি সঠিকভাবে কাজ করছে। আপনি যা চান তা যদি ড্রাইভিং দূরত্ব (বা বাইক চালানোর দূরত্ব বা পাবলিক ট্রান্সপোর্টের দূরত্ব বা হাঁটার দূরত্ব) হয় তবে আপনাকে ম্যাপিং এপিআই ব্যবহার করতে হবে ( গুগল বা ) হয় তবে উপযুক্ত রুট পেতে আপনাকে বিং সবচেয়ে জনপ্রিয় হিসাবে পরিচিত) ব্যবহার করতে হবে, যার মধ্যে দূরত্ব অন্তর্ভুক্ত থাকবে।

ঘটনাচক্রে, গুগল ম্যাপস এপিআই এর মধ্যে গোলাকার দূরত্বের জন্য একটি প্যাকেজযুক্ত পদ্ধতি সরবরাহ করে google.maps.geometry.spherical নাম স্থানটিতে (সন্ধান করুন computeDistanceBetween) । এটি সম্ভবত আপনার নিজের রোলিংয়ের চেয়ে ভাল (শুরুর জন্য, এটি পৃথিবীর ব্যাসার্ধের জন্য আরও সুনির্দিষ্ট মান ব্যবহার করে)।

আমাদের মধ্যে বাছাইয়ের জন্য, যখন আমি "সরলরেখার দূরত্ব" বলি, আমি অবশ্যই একটি "গোলকের উপর সোজা রেখা" উল্লেখ করি যা অবশ্যই একটি বাঁকানো রেখা (অর্থাৎ মহান-বৃত্তের দূরত্ব) অবশ্যই।


5
আমার আনন্দ! উত্তর দিতে মজা লাগছিল।
ইথান ব্রাউন

4
এটি একটি সুন্দর উত্তর। আমি সুন্দর বলি কারণ প্রদত্ত বিবরণগুলি আমার মতো একজন নবজাতকের পক্ষেও পার্থক্যটি বোঝার জন্য খুব ভাল।
সুপ্রিত

78

আমি এর আগেও অনুরূপ সমীকরণ লিখেছি - এটি পরীক্ষা করেছি এবং ১.6 কিমিও পেয়েছি।

আপনার গুগল মানচিত্রগুলি ড্রাইভের দূরত্বটি দেখাচ্ছে।

কাকটি উড়ে যাওয়ার সাথে সাথে আপনার ক্রিয়া গণনা করা হচ্ছে (সরল রেখার দূরত্ব)।

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
আমার মনে হয় আপনার পরিবর্তনশীল নামগুলি খুব বর্ণনামূলক :)
পাই 6 কে

14

ডেরেকের সমাধানটি আমার পক্ষে ভাল কাজ করেছে এবং আমি কেবল এটিকে পিএইচপিতে রূপান্তর করেছি, আশা করি এটি কারওর পক্ষে সাহায্য করবে!

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

এটা চেষ্টা কর. এটি ভিবি নেটনে রয়েছে এবং আপনার এটি জাভাস্ক্রিপ্টে রূপান্তর করতে হবে। এই ফাংশন দশমিক মিনিটে প্যারামিটার গ্রহণ করে।

    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
这个问题问了জাভাস্ক্রিপ্ট的答案.. আপনাকে এটিকে ইংরেজী রূপান্তর করতে হবে :)
ভল্ফ কমপ্রেসর

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

নমুনা কোডটি এলজিপিএলভি 3 এর অধীনে লাইসেন্সযুক্ত।


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

দুর্দান্ত বৃত্তের দূরত্ব - জ্যা দৈর্ঘ্য থেকে

কৌশল ডিজাইনের প্যাটার্ন প্রয়োগ করে একটি মার্জিত সমাধান এখানে দেওয়া হয়েছে; আমি আশা করি এটি যথেষ্ট পাঠযোগ্য।

টু পয়েন্টস ডিস্টেন্সেসক্যালকুলেটরস্ট্রেজি.জেএস :

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/scriptts/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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.