দুটি অক্ষাংশ এবং দ্রাঘিমাংশ জিওকর্ডিনেটের মধ্যে দূরত্ব গণনা করা হচ্ছে


139

আমি দুটি জিওকর্ডিনেটের মধ্যে দূরত্ব গণনা করছি। আমি আমার অ্যাপ্লিকেশনটি 3-4 টি অ্যাপের বিপরীতে পরীক্ষা করছি। যখন আমি দূরত্ব গণনা করছি, আমার গণনার জন্য আমি গড়ে গড়ে ৩.৩ মাইল পাবে বলে অন্য অ্যাপ্লিকেশনগুলি ৩.৫ মাইল পাচ্ছে। আমি যে গণনাটি সম্পাদন করার চেষ্টা করছি তার পক্ষে এটি একটি বড় পার্থক্য। দূরত্ব গণনার জন্য এখানে কি কোনও ভাল শ্রেণির পাঠাগার রয়েছে? আমি এটি সি # তে এরকম গণনা করছি:

public static double Calculate(double sLatitude,double sLongitude, double eLatitude, 
                               double eLongitude)
{
    var radiansOverDegrees = (Math.PI / 180.0);

    var sLatitudeRadians = sLatitude * radiansOverDegrees;
    var sLongitudeRadians = sLongitude * radiansOverDegrees;
    var eLatitudeRadians = eLatitude * radiansOverDegrees;
    var eLongitudeRadians = eLongitude * radiansOverDegrees;

    var dLongitude = eLongitudeRadians - sLongitudeRadians;
    var dLatitude = eLatitudeRadians - sLatitudeRadians;

    var result1 = Math.Pow(Math.Sin(dLatitude / 2.0), 2.0) + 
                  Math.Cos(sLatitudeRadians) * Math.Cos(eLatitudeRadians) * 
                  Math.Pow(Math.Sin(dLongitude / 2.0), 2.0);

    // Using 3956 as the number of miles around the earth
    var result2 = 3956.0 * 2.0 * 
                  Math.Atan2(Math.Sqrt(result1), Math.Sqrt(1.0 - result1));

    return result2;
}

আমি কী ভুল করছি? আমি কি প্রথমে কিমিটারে এটি গণনা করে তারপরে মাইল রূপান্তর করব?


1
পৃথিবীর গড় ব্যাসার্ধ = 6,371 কিলোমিটার = 3958.76 মাইল
মিচ গম


এটি gis.stackexchange.com এ থাকা উচিত নয়
ড্যানিয়েল পাওয়েল

এটি থাকতে পারে, তবে আমার প্রশ্নটি একটি উইন্ডোজ ফোনে এটি গণনা করার সাথে আরও সম্পর্কিত যা কিছুটা আলাদা। সূত্রটি একই, তবে ডিস্টেনশনটো পদ্ধতির মতো নতুন পদ্ধতির কলগুলি অগত্যা উপলব্ধ নয়।
জেসন এন গাইলর্ড

1
আপনি পাই / 180 সঞ্চয় করার পরামর্শ দিন যাতে আপনার গণনা পুনরাবৃত্তি করতে হবে না।
ক্রিস ক্যাভিনিস

উত্তর:


313

GeoCoordinate শ্রেণী (.NET ফ্রেমওয়ার্ক 4 এবং উচ্চতর) ইতিমধ্যে GetDistanceToপদ্ধতি।

var sCoord = new GeoCoordinate(sLatitude, sLongitude);
var eCoord = new GeoCoordinate(eLatitude, eLongitude);

return sCoord.GetDistanceTo(eCoord);

দূরত্বটি মিটারে।

আপনাকে System.Divice উল্লেখ করতে হবে।


নাইজেল, আপনি কি নিশ্চিত যে দূরত্বের পদ্ধতি ফোনে কাজ করবে? আমি ভেবেছিলাম এটি ডাব্লুপি 7 এর জন্য জিওকর্ডিনেটের 2.0 সংস্করণটি ব্যবহার করেছে।
জেসন এন। গাইলর্ড

1
আমি এটি যাচাই করেছিলাম এবং ডিভাইসটির জন্য জিও কর্ডিনেটে একটি getDistanceTo পদ্ধতি রয়েছে যা আপনি উল্লেখ করেছেন (তবে আপনার উপরে যা আছে তা নয়)। কোন ব্যাপারই না. আমি এটি পরীক্ষা করে দেখতে যাচ্ছি যে বিল্ট ইন গণনাটি আরও ভাল কিনা to ধন্যবাদ নাইজেল!
জেসন এন গাইলর্ড

1
আমি একটি ভুল প্রশ্ন জিজ্ঞাসা করতে পারে, কিন্তু ফলাফল কোন ইউনিটে? এটি মাইলস, না কিলোমিটার। আমি এটি কোথাও খুঁজে পাচ্ছি না।
সা Saeedদ নেমতি

3
@SaeedNeamati - খুব এই খুঁজছেন ছিল অনুযায়ী msdn.microsoft.com/en-us/library/... - এটা মিটার আছে।
অ্যান্ডি বাটল্যান্ড

হ্যাঁ, GeoCoordinate.GetDistanceTo () মিটারে মান দেয়। আমার জন্য, মার্কিন যুক্তরাষ্ট্রে, যদি এটি 1610 এরও কম হয় তবে আমি এটিকে ফুট (মিটার * 3.28084) এ রূপান্তর করি অন্যথায় আমি মাইল (মিটার * 0.000621371) এ রূপান্তর করি। নির্ভুলতা আমার উদ্দেশ্যে যথেষ্ট ভাল চেয়ে বেশি।
ব্যবহারকারী3235770

110

গেটডেস্টেন্স হ'ল সেরা সমাধান তবে অনেক ক্ষেত্রে আমরা এই পদ্ধতিটি ব্যবহার করতে পারি না (যেমন ইউনিভার্সাল অ্যাপ)

  • Coorindates মধ্যে দূরত্ব গণনা করতে অ্যালগরিদমের সিউডোকোড :

    public static double DistanceTo(double lat1, double lon1, double lat2, double lon2, char unit = 'K')
    {
        double rlat1 = Math.PI*lat1/180;
        double rlat2 = Math.PI*lat2/180;
        double theta = lon1 - lon2;
        double rtheta = Math.PI*theta/180;
        double dist =
            Math.Sin(rlat1)*Math.Sin(rlat2) + Math.Cos(rlat1)*
            Math.Cos(rlat2)*Math.Cos(rtheta);
        dist = Math.Acos(dist);
        dist = dist*180/Math.PI;
        dist = dist*60*1.1515;
    
        switch (unit)
        {
            case 'K': //Kilometers -> default
                return dist*1.609344;
            case 'N': //Nautical Miles 
                return dist*0.8684;
            case 'M': //Miles
                return dist;
        }
    
        return dist;
    }
  • রিয়েল ওয়ার্ল্ড সি # বাস্তবায়ন , যা একটি এক্সটেনশন পদ্ধতি ব্যবহার করে

    ব্যবহার:

    var distance = new Coordinates(48.672309, 15.695585)
                    .DistanceTo(
                        new Coordinates(48.237867, 16.389477),
                        UnitOfLength.Kilometers
                    );

    বাস্তবায়ন:

    public class Coordinates
    {
        public double Latitude { get; private set; }
        public double Longitude { get; private set; }
    
        public Coordinates(double latitude, double longitude)
        {
            Latitude = latitude;
            Longitude = longitude;
        }
    }
    public static class CoordinatesDistanceExtensions
    {
        public static double DistanceTo(this Coordinates baseCoordinates, Coordinates targetCoordinates)
        {
            return DistanceTo(baseCoordinates, targetCoordinates, UnitOfLength.Kilometers);
        }
    
        public static double DistanceTo(this Coordinates baseCoordinates, Coordinates targetCoordinates, UnitOfLength unitOfLength)
        {
            var baseRad = Math.PI * baseCoordinates.Latitude / 180;
            var targetRad = Math.PI * targetCoordinates.Latitude/ 180;
            var theta = baseCoordinates.Longitude - targetCoordinates.Longitude;
            var thetaRad = Math.PI * theta / 180;
    
            double dist =
                Math.Sin(baseRad) * Math.Sin(targetRad) + Math.Cos(baseRad) *
                Math.Cos(targetRad) * Math.Cos(thetaRad);
            dist = Math.Acos(dist);
    
            dist = dist * 180 / Math.PI;
            dist = dist * 60 * 1.1515;
    
            return unitOfLength.ConvertFromMiles(dist);
        }
    }
    
    public class UnitOfLength
    {
        public static UnitOfLength Kilometers = new UnitOfLength(1.609344);
        public static UnitOfLength NauticalMiles = new UnitOfLength(0.8684);
        public static UnitOfLength Miles = new UnitOfLength(1);
    
        private readonly double _fromMilesFactor;
    
        private UnitOfLength(double fromMilesFactor)
        {
            _fromMilesFactor = fromMilesFactor;
        }
    
        public double ConvertFromMiles(double input)
        {
            return input*_fromMilesFactor;
        }
    } 

1
আপনি কি এই ক্যালকুলাসের জন্য ব্যবহৃত সূত্রটি সরবরাহ করতে পারেন বা কোনও রেখাটি সম্পর্কে কিছু মন্তব্য থাকতে পারে? রূপান্তর না করে সরাসরি মাইলের পরিবর্তে কিমিটার দূরত্বে আমার কী পরিবর্তন করতে হবে?
AlbertoFdzM

একটি ভাল সমাধানের জন্য ধন্যবাদ, আমি এখন এটি আমার ডেস্কটপ অ্যাপ্লিকেশনটিতে ব্যবহার করতে পারি।
জামশেদ কামরান

আমার ইউডাব্লুপি অ্যাপে দুর্দান্ত কাজ করেছে যেখানে আমি জিওকর্ডিনেট ব্যবহার করতে পারি না cannot
জাচ গ্রিন

1
গণনা 95% সত্য। ফাংশন নিচে 100% নির্ভুল নয়: stackoverflow.com/a/51839058/3736063
মালেক Tubaisaht

31

এবং এখানে, এখনও সন্তুষ্ট নয় তাদের জন্য। নেট-ফ্রেমওয়ার্ক GeoCoordinateশ্রেণীর মূল কোড , একটি স্ট্যান্ডেলোন পদ্ধতিতে রিফ্যাক্টার্ড:

public double GetDistance(double longitude, double latitude, double otherLongitude, double otherLatitude)
{
    var d1 = latitude * (Math.PI / 180.0);
    var num1 = longitude * (Math.PI / 180.0);
    var d2 = otherLatitude * (Math.PI / 180.0);
    var num2 = otherLongitude * (Math.PI / 180.0) - num1;
    var d3 = Math.Pow(Math.Sin((d2 - d1) / 2.0), 2.0) + Math.Cos(d1) * Math.Cos(d2) * Math.Pow(Math.Sin(num2 / 2.0), 2.0);

    return 6376500.0 * (2.0 * Math.Atan2(Math.Sqrt(d3), Math.Sqrt(1.0 - d3)));
}

8
সুন্দর উত্তর, আমি উল্লেখ করতে চাই যে ফলস্বরূপ দূরত্বটি মিটারে। অফিসিয়াল ডকুমেন্টেশনে
লিভিয়াথনকোড

ধন্যবাদ! আমি জিওকর্ডিনেট শ্রেণিতে ব্যবহৃত পৃথিবীর আসল ব্যাসার্ধের সন্ধান করছিলাম।
কেআরয়

গৌণ অপ্টিমাইজেশান, বা সহজ পড়ার জন্য, পাই / 180 টি গুনতে পারে double oneDegree = Math.PI / 180.0;?
ব্রেকারু

1
আপনার উত্তরটির জন্য ধন্যবাদ। আমি উত্তরটি যেমন আছে তেমন ছেড়ে দিতে চাই, কারণ এটি মূল। নেট কোড code অবশ্যই আপনার পরামর্শ অনুসরণ করতে দ্বিধা বোধ করতে পারেন যে কেউ অবশ্যই।
মার্ক

17

এখানে জাভাস্ক্রিপ্ট সংস্করণ বলছি এবং gals

function distanceTo(lat1, lon1, lat2, lon2, unit) {
      var rlat1 = Math.PI * lat1/180
      var rlat2 = Math.PI * lat2/180
      var rlon1 = Math.PI * lon1/180
      var rlon2 = Math.PI * lon2/180
      var theta = lon1-lon2
      var rtheta = Math.PI * theta/180
      var dist = Math.sin(rlat1) * Math.sin(rlat2) + Math.cos(rlat1) * Math.cos(rlat2) * Math.cos(rtheta);
      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
}

10

যারা জামারিন ব্যবহার করছেন এবং জিওকর্ডিনেট ক্লাসে অ্যাক্সেস নেই তাদের জন্য, আপনি তার পরিবর্তে অ্যান্ড্রয়েড লোকেশন ক্লাসটি ব্যবহার করতে পারেন:

public static double GetDistanceBetweenCoordinates (double lat1, double lng1, double lat2, double lng2) {
            var coords1 = new Location ("");
            coords1.Latitude = lat1;
            coords1.Longitude = lng1;
            var coords2 = new Location ("");
            coords2.Latitude = lat2;
            coords2.Longitude = lng2;
            return coords1.DistanceTo (coords2);
        }

3

আপনি এই ফাংশনটি ব্যবহার করতে পারেন:

উত্স: https://www.geodatasource.com/developers/c-sharp

private double distance(double lat1, double lon1, double lat2, double lon2, char unit) {
  if ((lat1 == lat2) && (lon1 == lon2)) {
    return 0;
  }
  else {
    double theta = lon1 - lon2;
    double dist = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * Math.Cos(deg2rad(theta));
    dist = Math.Acos(dist);
    dist = rad2deg(dist);
    dist = dist * 60 * 1.1515;
    if (unit == 'K') {
      dist = dist * 1.609344;
    } else if (unit == 'N') {
      dist = dist * 0.8684;
    }
    return (dist);
  }
}

//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::  This function converts decimal degrees to radians             :::
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
private double deg2rad(double deg) {
  return (deg * Math.PI / 180.0);
}

//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::  This function converts radians to decimal degrees             :::
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
private double rad2deg(double rad) {
  return (rad / Math.PI * 180.0);
}

Console.WriteLine(distance(32.9697, -96.80322, 29.46786, -98.53506, "M"));
Console.WriteLine(distance(32.9697, -96.80322, 29.46786, -98.53506, "K"));
Console.WriteLine(distance(32.9697, -96.80322, 29.46786, -98.53506, "N"));

পুরোপুরি কাজ করে! ধন্যবাদ!
Schnapz

3

এই প্ল্যাটফর্মগুলির জন্য এই লাইব্রেরি জিও-কর্ডিনেট রয়েছে :

  • মনো
  • .NET 4.5
  • .NET কোর
  • উইন্ডোজ ফোন 8.x
  • ইউনিভার্সাল উইন্ডোজ প্ল্যাটফর্ম
  • জামারিন আইওএস
  • জামারিন অ্যান্ড্রয়েড

নুগেটের মাধ্যমে ইনস্টলেশন সম্পন্ন করা হয়:

প্রধানমন্ত্রী> ইনস্টল-প্যাকেজ জিওকর্ডিনেট

ব্যবহার

GeoCoordinate pin1 = new GeoCoordinate(lat, lng);
GeoCoordinate pin2 = new GeoCoordinate(lat, lng);

double distanceBetween = pin1.GetDistanceTo(pin2);

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


3

এলিয়ট উডের ক্রিয়াকলাপের উপর ভিত্তি করে এবং যদি কেউ কোনও সি ফাংশনে আগ্রহী হন তবে এইটি কাজ করছে ...

#define SIM_Degree_to_Radian(x) ((float)x * 0.017453292F)
#define SIM_PI_VALUE                         (3.14159265359)

float GPS_Distance(float lat1, float lon1, float lat2, float lon2)
{
   float theta;
   float dist;

   theta = lon1 - lon2;

   lat1 = SIM_Degree_to_Radian(lat1);
   lat2 = SIM_Degree_to_Radian(lat2);
   theta = SIM_Degree_to_Radian(theta);

   dist = (sin(lat1) * sin(lat2)) + (cos(lat1) * cos(lat2) * cos(theta));
   dist = acos(dist);

//   dist = dist * 180.0 / SIM_PI_VALUE;
//   dist = dist * 60.0 * 1.1515;
//   /* Convert to km */
//   dist = dist * 1.609344;

   dist *= 6370.693486F;

   return (dist);
}

আপনি এটি দ্বিগুণ করতে পারেন । এটি কিমি থেকে মান দেয় returns


2

অক্ষাংশ এবং দ্রাঘিমাংশ পয়েন্টের মধ্যে দূরত্ব গণনা করা হচ্ছে ...

        double Lat1 = Convert.ToDouble(latitude);
        double Long1 = Convert.ToDouble(longitude);

        double Lat2 = 30.678;
        double Long2 = 45.786;
        double circumference = 40000.0; // Earth's circumference at the equator in km
        double distance = 0.0;
        double latitude1Rad = DegreesToRadians(Lat1);
        double latititude2Rad = DegreesToRadians(Lat2);
        double longitude1Rad = DegreesToRadians(Long1);
        double longitude2Rad = DegreesToRadians(Long2);
        double logitudeDiff = Math.Abs(longitude1Rad - longitude2Rad);
        if (logitudeDiff > Math.PI)
        {
            logitudeDiff = 2.0 * Math.PI - logitudeDiff;
        }
        double angleCalculation =
            Math.Acos(
              Math.Sin(latititude2Rad) * Math.Sin(latitude1Rad) +
              Math.Cos(latititude2Rad) * Math.Cos(latitude1Rad) * Math.Cos(logitudeDiff));
        distance = circumference * angleCalculation / (2.0 * Math.PI);
        return distance;

1

এটি একটি পুরানো প্রশ্ন, তবুও উত্তরগুলি পারফরম্যান্স এবং অপ্টিমাইজেশন সম্পর্কিত আমাকে সন্তুষ্ট করেনি।

এখানে আমার অপ্টিমাইজড সি # ভেরিয়েন্ট (কিলোমিটারের দূরত্ব, ভেরিয়েবল এবং অপ্রয়োজনীয় গণনা ছাড়াই, হ্যাভারসাইন ফর্মুলার https://en.wikedia.org/wiki/Haversine_formula এর গাণিতিক প্রকাশের খুব কাছাকাছি )।

দ্বারা অনুপ্রাণিত: https://rosettacode.org/wiki/Haversine_forula#C.23

public static class Haversine
{
    public static double Calculate(double lat1, double lon1, double lat2, double lon2)
    {
        double rad(double angle) => angle * 0.017453292519943295769236907684886127d; // = angle * Math.Pi / 180.0d
        double havf(double diff) => Math.Pow(Math.Sin(rad(diff) / 2d), 2); // = sin²(diff / 2)
        return 12745.6 * Math.Asin(Math.Sqrt(havf(lat2 - lat1) + Math.Cos(rad(lat1)) * Math.Cos(rad(lat2)) * havf(lon2 - lon1))); // earth radius 6.372,8‬km x 2 = 12745.6
    }
}

উইকিপিডিয়া থেকে হাভারসাইন সূত্র


0

এটা চেষ্টা কর:

    public double getDistance(GeoCoordinate p1, GeoCoordinate p2)
    {
        double d = p1.Latitude * 0.017453292519943295;
        double num3 = p1.Longitude * 0.017453292519943295;
        double num4 = p2.Latitude * 0.017453292519943295;
        double num5 = p2.Longitude * 0.017453292519943295;
        double num6 = num5 - num3;
        double num7 = num4 - d;
        double num8 = Math.Pow(Math.Sin(num7 / 2.0), 2.0) + ((Math.Cos(d) * Math.Cos(num4)) * Math.Pow(Math.Sin(num6 / 2.0), 2.0));
        double num9 = 2.0 * Math.Atan2(Math.Sqrt(num8), Math.Sqrt(1.0 - num8));
        return (6376500.0 * num9);
    }

0

আপনি ব্যবহার করতে পারেন System.device.Location:

System.device.Location.GeoCoordinate gc = new System.device.Location.GeoCoordinate(){
Latitude = yourLatitudePt1,
Longitude = yourLongitudePt1
};

System.device.Location.GeoCoordinate gc2 = new System.device.Location.GeoCoordinate(){
Latitude = yourLatitudePt2,
Longitude = yourLongitudePt2
};

Double distance = gc2.getDistanceTo(gc);

শুভকামনা


0

যখন সিপিইউ / গণিতের কম্পিউটিং পাওয়ার সীমাবদ্ধ থাকে:

এমন সময় আছে (যেমন আমার কাজ হিসাবে) যখন কম্পিউটিং পাওয়ার অভাব হয় (যেমন কোনও ফ্লোটিং পয়েন্ট প্রসেসর নয়, ছোট মাইক্রোকন্ট্রোলারের সাথে কাজ করা হয়) যেখানে কিছু ট্রিগ ফাংশনগুলি সিপিইউ সময়ের একটি অত্যধিক পরিমাণে নিতে পারে (যেমন 3000+ ঘড়ি চক্র), তাই যখন আমি কেবলমাত্র একটি আনুমানিক প্রয়োজন, বিশেষত যদি সিপিইউকে দীর্ঘ সময়ের জন্য আবদ্ধ করা না হয়, আমি সিপিইউ ওভারহেডকে হ্রাস করতে এটি ব্যবহার করি:

/**------------------------------------------------------------------------
 * \brief  Great Circle distance approximation in km over short distances.
 *
 * Can be off by as much as 10%.
 *
 * approx_distance_in_mi = sqrt(x * x + y * y)
 *
 * where x = 69.1 * (lat2 - lat1)
 * and y = 69.1 * (lon2 - lon1) * cos(lat1/57.3)
 *//*----------------------------------------------------------------------*/
double    ApproximateDisatanceBetweenTwoLatLonsInKm(
                  double lat1, double lon1,
                  double lat2, double lon2
                  ) {
    double  ldRadians, ldCosR, x, y;

    ldRadians = (lat1 / 57.3) * 0.017453292519943295769236907684886;
    ldCosR = cos(ldRadians);
    x = 69.1 * (lat2 - lat1);
    y = 69.1 * (lon2 - lon1) * ldCosR;

    return sqrt(x * x + y * y) * 1.609344;  /* Converts mi to km. */
}

ক্রেডিট https://github.com/kristianmandrup/geo_vectors/blob/master/ দূরত্ব ৯২০calc%20notes.txt এ যায় ।

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