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


371

আমি দুটি জিপিএস স্থানাঙ্ক (অক্ষাংশ এবং দ্রাঘিমাংশ ব্যবহার করে) এর মধ্যে কীভাবে দূরত্ব গণনা করব?


1
এই অ্যালগরিদম গ্রেট সার্কেল দূরত্ব হিসাবে পরিচিত ।
গ্রেগ হিউগিল

উত্তর:


406

একটি জাভাস্ক্রিপ্ট বাস্তবায়ন সহ অক্ষাংশ এবং দ্রাঘিমাংশ দ্বারা দুটি স্থানাঙ্কের মধ্যে দূরত্ব গণনা করুন

পশ্চিম এবং দক্ষিণের অবস্থানগুলি নেতিবাচক। মনে রাখবেন মিনিট এবং সেকেন্ড 60 এর বাইরে রয়েছে সুতরাং এস 31 30 '-31.50 ডিগ্রি।

ডিগ্রিগুলিকে রেডিয়ানে রূপান্তর করতে ভুলবেন না । অনেক ভাষায় এই ফাংশন রয়েছে। অথবা সকালে তার একটি সহজ হিসাব: radians = degrees * PI / 180

function degreesToRadians(degrees) {
  return degrees * Math.PI / 180;
}

function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) {
  var earthRadiusKm = 6371;

  var dLat = degreesToRadians(lat2-lat1);
  var dLon = degreesToRadians(lon2-lon1);

  lat1 = degreesToRadians(lat1);
  lat2 = degreesToRadians(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)); 
  return earthRadiusKm * c;
}

ব্যবহারের কয়েকটি উদাহরণ এখানে দেওয়া হল:

distanceInKmBetweenEarthCoordinates(0,0,0,0)  // Distance between same 
                                              // points should be 0
0

distanceInKmBetweenEarthCoordinates(51.5, 0, 38.8, -77.1) // From London
                                                          // to Arlington
5918.185064088764

17
যদি এটা সুস্পষ্ট নয়, toRad () মেথড করার জন্য একটি স্বনির্ধারণ হয় নম্বর যেমন প্রোটোটাইপ: Number.prototype.toRad = function() { return this * (Math.PI / 180); }; । বা, নীচে উল্লিখিত হিসাবে, আপনি (Math.PI/2)বর্ধিত পারফরম্যান্সের জন্য 0.0174532925199433 (... আপনার যথাযথ প্রয়োজন মনে করেন) এর সাথে প্রতিস্থাপন করতে পারেন ।
ভিনি কেলি

44
যদি বিশেষত আপনার মধ্যে যারা লাইন মন্তব্যগুলির শেষের সন্ধান করেন না, তারা এই সূত্রটি দেখছেন এবং দূরত্বের একক খুঁজছেন, ইউনিটটি কিমি। :)
ডিলান নোলস

1
@ ভিনিকিলি ছোট ছোট টাইপ করুন কিন্তু প্রতিস্থাপন করুন (ম্যাথ পিপিআই / 180) না (ম্যাথ পিপিআই / 2), প্রত্যেকের সহায়তার জন্য ধন্যবাদ
প্যাট্রিক মারফি

1
@ ক্রিশ্চিয়ান কেআরাইডার প্রথম লাইনে দেখুন। Rগণিতে সাধারণত কী বোঝায় সে সম্পর্কে চিন্তা করুন , তারপরে সংখ্যাটি মিলে কিনা তা দেখতে পৃথিবী সম্পর্কিত প্রাসঙ্গিক সন্ধান করুন।
ফান্ডিং মনিকার লসুইট

3
ইম্পেরিয়াল ইউনিট (মাইল) এর জন্য আপনি হতে earthRadiusKmপারে var earthRadiusMiles = 3959;, ফাই।
চ্যাপেলজুইস

59

গুগলের সাথে হ্যাসারিন সন্ধান করুন; এখানে আমার সমাধান:

#include <math.h>
#include "haversine.h"

#define d2r (M_PI / 180.0)

//calculate haversine distance for linear distance
double haversine_km(double lat1, double long1, double lat2, double long2)
{
    double dlong = (long2 - long1) * d2r;
    double dlat = (lat2 - lat1) * d2r;
    double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2);
    double c = 2 * atan2(sqrt(a), sqrt(1-a));
    double d = 6367 * c;

    return d;
}

double haversine_mi(double lat1, double long1, double lat2, double long2)
{
    double dlong = (long2 - long1) * d2r;
    double dlat = (lat2 - lat1) * d2r;
    double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2);
    double c = 2 * atan2(sqrt(a), sqrt(1-a));
    double d = 3956 * c; 

    return d;
}

3
আপনি আরও ভাল পারফরম্যান্সের জন্য 0.0174532925199433 দিয়ে (M_PI / 180.0) প্রতিস্থাপন করতে পারেন।
হ্লুং

3
পারফরম্যান্সের ক্ষেত্রে: কেউ একবার পাপ (ডালট / ২.০) গণনা করতে পারত, এটিকে পরিবর্তনশীল এ 1 এ সংরক্ষণ করতে পারে এবং পাও (, 2) এর পরিবর্তে এ 1 * এ 1 ব্যবহার করা আরও ভাল। অন্যান্য গুদের জন্য একই ((2)।
পিএমএস

71
হ্যাঁ, বা কেবল '60 এর পরে একটি সংকলক ব্যবহার করুন।
ডানফোল্ড

17
একটি ধ্রুবককে "অনুকূলিতকরণ" (M_PI / 180.0) করার দরকার নেই যা প্রসঙ্গ ছাড়া কেউ বুঝতে পারে না। সংকলক আপনার জন্য এই নির্দিষ্ট শর্তাদি গণনা করে!
প্যাট্রিক কর্নেলিজেন

2
@ টানসামুয়েল আপনার মন্তব্যের জন্য আপনাকে অনেক ধন্যবাদ। আমি সত্যিই এটার প্রশংসা করছি. এটি বোধগম্য হয় যে অপ্টিমাইজেশান সক্ষম (-O) সহ সংকলক স্থিররূপগুলির ক্রিয়াকলাপের প্রাক-গণনা করতে পারে, ম্যানুয়াল ভেঙ্গে যাওয়াটিকে অকেজো করে তোলে। আমার সময় পেলে এটি পরীক্ষা করে নেব।
হ্লুং

44

সি # সংস্করণ হ্যাভারসাইন

double _eQuatorialEarthRadius = 6378.1370D;
double _d2r = (Math.PI / 180D);

private int HaversineInM(double lat1, double long1, double lat2, double long2)
{
    return (int)(1000D * HaversineInKM(lat1, long1, lat2, long2));
}

private double HaversineInKM(double lat1, double long1, double lat2, double long2)
{
    double dlong = (long2 - long1) * _d2r;
    double dlat = (lat2 - lat1) * _d2r;
    double a = Math.Pow(Math.Sin(dlat / 2D), 2D) + Math.Cos(lat1 * _d2r) * Math.Cos(lat2 * _d2r) * Math.Pow(Math.Sin(dlong / 2D), 2D);
    double c = 2D * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1D - a));
    double d = _eQuatorialEarthRadius * c;

    return d;
}

এটির জন্য একটি নেট ফিডল , যাতে আপনি এটি নিজের ল্যাট / লংসের সাথে পরীক্ষা করতে পারেন।


1
আমি একটি চেকযুক্ত। নেট ফিডলও যুক্ত করেছি যাতে লোকেরা সহজেই এটি পরীক্ষা করে দেখতে পারে।
খাঁটি.ক্রোম

7
নেট ফ্রেমওয়ার্কের জিওকর্ডিনেট.গেটডেসটেনশন টু পদ্ধতিতে একটি বিল্ড রয়েছে। সমাবেশ সিস্টেম। ডিভাইস রেফারেন্স করা আছে। এমএসডিএন আর্টিকেল এমএসডিএন.মাইক্রোসফটকম / en
us/

27

এই থ্রেডটিতে রোমান মাকারোভের জবাবের ভিত্তিতে হাভারসাইন অ্যালগোরিদমের জাভা সংস্করণ

public class HaversineAlgorithm {

    static final double _eQuatorialEarthRadius = 6378.1370D;
    static final double _d2r = (Math.PI / 180D);

    public static int HaversineInM(double lat1, double long1, double lat2, double long2) {
        return (int) (1000D * HaversineInKM(lat1, long1, lat2, long2));
    }

    public static double HaversineInKM(double lat1, double long1, double lat2, double long2) {
        double dlong = (long2 - long1) * _d2r;
        double dlat = (lat2 - lat1) * _d2r;
        double a = Math.pow(Math.sin(dlat / 2D), 2D) + Math.cos(lat1 * _d2r) * Math.cos(lat2 * _d2r)
                * Math.pow(Math.sin(dlong / 2D), 2D);
        double c = 2D * Math.atan2(Math.sqrt(a), Math.sqrt(1D - a));
        double d = _eQuatorialEarthRadius * c;

        return d;
    }

}

@ রাদু নিশ্চিত করুন যে আপনি এটি সঠিকভাবে ব্যবহার করছেন এবং কোনও পদ্ধতিতে পাস করার সময় ল্যাট / লগ জায়গাগুলি বিনিময় করছেন না।
পাওলো মিগুয়েল আলমেইদা

1
আমি এই সূত্রটি ব্যবহার করে যুক্তিসঙ্গত নিকট উত্তর পেয়েছি। আমি এই ওয়েবসাইটটি ব্যবহার করে নির্ভুলতার ভিত্তিতে তৈরি করেছি: चलযোগ্য টাইপ.কম / স্ক্রিপ্টস / ল্যাটলং এইচটিএমএল যা আমাকে 0.07149কিমি দিয়েছে যেখানে আপনার সূত্রটি আমাকে দিয়েছে 0.07156যা প্রায় 99% এর যথার্থতা
জানাক মীনা

24

এসকিউএল সার্ভার ২০০৮-তে ভৌগলিক প্রকারের সাথে এটি করা খুব সহজ।

SELECT geography::Point(lat1, lon1, 4326).STDistance(geography::Point(lat2, lon2, 4326))
-- computes distance in meters using eliptical model, accurate to the mm

4326 হ'ল WGS84 এলিপসয়েডাল আর্থ মডেলের জন্য এসআরআইডি


19

পাইথনে একটি হ্যাভারসাইন ফাংশন যা আমি ব্যবহার করি:

from math import pi,sqrt,sin,cos,atan2

def haversine(pos1, pos2):
    lat1 = float(pos1['lat'])
    long1 = float(pos1['long'])
    lat2 = float(pos2['lat'])
    long2 = float(pos2['long'])

    degree_to_rad = float(pi / 180.0)

    d_lat = (lat2 - lat1) * degree_to_rad
    d_long = (long2 - long1) * degree_to_rad

    a = pow(sin(d_lat / 2), 2) + cos(lat1 * degree_to_rad) * cos(lat2 * degree_to_rad) * pow(sin(d_long / 2), 2)
    c = 2 * atan2(sqrt(a), sqrt(1 - a))
    km = 6367 * c
    mi = 3956 * c

    return {"km":km, "miles":mi}

16

এটি নির্ভর করে যে আপনার এটি কতটা সঠিক হতে হবে, যদি আপনার পয়েন্টপয়েন্ট নির্ভুলতার প্রয়োজন হয় তবে ভিনসেন্টির অ্যালগরিদম মতো গোলকের চেয়ে এলিপসয়েড ব্যবহার করে একটি অ্যালগরিদমটি দেখা ভাল which http://en.wikipedia.org/wiki/Vincenty%27s_algorithm


11

এখানে এটি সি # তে রয়েছে (ল্যাড এবং রেডিয়ানে দীর্ঘ):

double CalculateGreatCircleDistance(double lat1, double long1, double lat2, double long2, double radius)
{
    return radius * Math.Acos(
        Math.Sin(lat1) * Math.Sin(lat2)
        + Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(long2 - long1));
}

যদি আপনার ল্যাট এবং লম্বা ডিগ্রীতে থাকে তবে রেডিয়ানে রূপান্তর করতে 180 / পিআই দিয়ে ভাগ করুন।


1
এটি হ'ল "কোসাইনের গোলকের আইন" গণনা যা একটি দুর্দান্ত বৃত্তের দূরত্ব গণনার সর্বনিম্ন সঠিক এবং সবচেয়ে ত্রুটি-প্রবণ পদ্ধতি।
জন মাচিন

11

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

function distance(lat1, lon1, lat2, lon2) {
  var p = 0.017453292519943295;    // Math.PI / 180
  var c = Math.cos;
  var a = 0.5 - c((lat2 - lat1) * p)/2 + 
          c(lat1 * p) * c(lat2 * p) * 
          (1 - c((lon2 - lon1) * p))/2;

  return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}

আপনি আমার jscreen নিয়ে খেলতে পারেন এবং ফলাফলগুলি এখানে দেখতে পারেন

সম্প্রতি পাইথনেও আমার একই কাজ করা দরকার ছিল, তাই এখানে অজগর বাস্তবায়ন :

from math import cos, asin, sqrt
def distance(lat1, lon1, lat2, lon2):
    p = 0.017453292519943295
    a = 0.5 - cos((lat2 - lat1) * p)/2 + cos(lat1 * p) * cos(lat2 * p) * (1 - cos((lon2 - lon1) * p)) / 2
    return 12742 * asin(sqrt(a))

এবং সম্পূর্ণতার জন্য: উইকিতে হ্যাভারসাইন


11

পিএইচপি সংস্করণ:

( deg2rad()যদি আপনার স্থানাঙ্কগুলি ইতিমধ্যে রেডিয়ানে থাকে তবে সমস্ত সরান ))

$R = 6371; // km
$dLat = deg2rad($lat2-$lat1);
$dLon = deg2rad($lon2-$lon1);
$lat1 = deg2rad($lat1);
$lat2 = deg2rad($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;

1
অনুগ্রহ করে ল্যাট 1 এবং ল্যাট 2 কে $ ল্যাট 1 ন্যাড $ ল্যাট 2 এ পরিবর্তন করুন।
পরিবর্তে

7

একটি টি-এসকিউএল ফাংশন, যা আমি কোনও কেন্দ্রের দূরত্ব অনুসারে রেকর্ড নির্বাচন করতে ব্যবহার করি

Create Function  [dbo].[DistanceInMiles] 
 (  @fromLatitude float ,
    @fromLongitude float ,
    @toLatitude float, 
    @toLongitude float
  )
   returns float
AS 
BEGIN
declare @distance float

select @distance = cast((3963 * ACOS(round(COS(RADIANS(90-@fromLatitude))*COS(RADIANS(90-@toLatitude))+ 
SIN(RADIANS(90-@fromLatitude))*SIN(RADIANS(90-@toLatitude))*COS(RADIANS(@fromLongitude-@toLongitude)),15)) 
)as float) 
  return  round(@distance,1)
END

এটি হ'ল "কোসাইনের গোলকের আইন" গণনা যা একটি বৃহত বৃত্তের দূরত্ব গণনার সর্বনিম্ন সঠিক এবং সর্বাধিক ত্রুটি-প্রবণ পদ্ধতি।
জন মাচিন

5

আপনার যদি আরও সঠিক কিছু প্রয়োজন হয় তবে এটি একবার দেখুন

থানডিয়াস ভিনসেন্টি (1975a) দ্বারা বর্ধিত গোলকের পৃষ্ঠের দুটি পয়েন্টের মধ্যকার দূরত্ব গণনা করতে ভিনসেন্টির সূত্রগুলি জিওডেসিতে ব্যবহৃত দুটি সম্পর্কিত পুনরাবৃত্ত পদ্ধতি যা এগুলি পৃথিবীর চিত্রটি একটি বিচ্ছিন্ন গোলক, এই ধারণার উপর ভিত্তি করে তৈরি করা হয়েছে গোলাকৃতির পৃথিবী ধরে নিয়েছে এমন মহাকেন্দ্রের দূরত্বের মতো পদ্ধতির চেয়ে আরও সঠিক।

প্রথম (প্রত্যক্ষ) পদ্ধতিটি একটি বিন্দুর অবস্থান নির্ধারণ করে যা প্রদত্ত দূরত্ব এবং অন্য বিন্দু থেকে আজিমুথ (দিকনির্দেশ)। দ্বিতীয় (বিপরীত) পদ্ধতি দুটি প্রদত্ত পয়েন্টের মধ্যে ভৌগলিক দূরত্ব এবং আজিমুথকে গণনা করে। এগুলি জিওডেসিতে ব্যাপকভাবে ব্যবহৃত হয়েছে কারণ তারা পৃথিবী উপবৃত্তাকারে 0.5 মিমি (0.020 ″) এর মধ্যে সঠিক accurate


5

I. "ব্রেডক্রাম্বস" পদ্ধতি সম্পর্কে

  1. পৃথিবীর ব্যাসার্ধ বিভিন্ন ল্যাটকে আলাদা। এটি অবশ্যই হাভারসাইন অ্যালগরিদমে বিবেচনা করা উচিত।
  2. ভারবহন পরিবর্তন বিবেচনা করুন, যা খিলানগুলিতে সোজা রেখাগুলি পরিণত করে (যা দীর্ঘ হয়)
  3. গতিতে পরিবর্তনটি অ্যাকাউন্টে নিলে খিলানগুলি সর্পিলগুলিতে পরিণত হবে (যা দীর্ঘ বা খিলানের চেয়ে ছোট)
  4. উচ্চতা পরিবর্তন ফ্ল্যাট সর্পিলগুলিকে 3 ডি স্পিরালগুলিতে পরিণত করবে (যা আবার দীর্ঘ হয়)। এটি পার্বত্য অঞ্চলের জন্য খুব গুরুত্বপূর্ণ।

নীচে সিতে ফাংশনটি দেখুন যা # 1 এবং # 2 অ্যাকাউন্টে নেয়:

double   calcDistanceByHaversine(double rLat1, double rLon1, double rHeading1,
       double rLat2, double rLon2, double rHeading2){
  double rDLatRad = 0.0;
  double rDLonRad = 0.0;
  double rLat1Rad = 0.0;
  double rLat2Rad = 0.0;
  double a = 0.0;
  double c = 0.0;
  double rResult = 0.0;
  double rEarthRadius = 0.0;
  double rDHeading = 0.0;
  double rDHeadingRad = 0.0;

  if ((rLat1 < -90.0) || (rLat1 > 90.0) || (rLat2 < -90.0) || (rLat2 > 90.0)
              || (rLon1 < -180.0) || (rLon1 > 180.0) || (rLon2 < -180.0)
              || (rLon2 > 180.0)) {
        return -1;
  };

  rDLatRad = (rLat2 - rLat1) * DEGREE_TO_RADIANS;
  rDLonRad = (rLon2 - rLon1) * DEGREE_TO_RADIANS;
  rLat1Rad = rLat1 * DEGREE_TO_RADIANS;
  rLat2Rad = rLat2 * DEGREE_TO_RADIANS;

  a = sin(rDLatRad / 2) * sin(rDLatRad / 2) + sin(rDLonRad / 2) * sin(
              rDLonRad / 2) * cos(rLat1Rad) * cos(rLat2Rad);

  if (a == 0.0) {
        return 0.0;
  }

  c = 2 * atan2(sqrt(a), sqrt(1 - a));
  rEarthRadius = 6378.1370 - (21.3847 * 90.0 / ((fabs(rLat1) + fabs(rLat2))
              / 2.0));
  rResult = rEarthRadius * c;

  // Chord to Arc Correction based on Heading changes. Important for routes with many turns and U-turns

  if ((rHeading1 >= 0.0) && (rHeading1 < 360.0) && (rHeading2 >= 0.0)
              && (rHeading2 < 360.0)) {
        rDHeading = fabs(rHeading1 - rHeading2);
        if (rDHeading > 180.0) {
              rDHeading -= 180.0;
        }
        rDHeadingRad = rDHeading * DEGREE_TO_RADIANS;
        if (rDHeading > 5.0) {
              rResult = rResult * (rDHeadingRad / (2.0 * sin(rDHeadingRad / 2)));
        } else {
              rResult = rResult / cos(rDHeadingRad);
        }
  }
  return rResult;
}

২। একটি সহজ উপায় আছে যা বেশ ভাল ফলাফল দেয়।

গড় গতি দ্বারা

ট্রিপ_দূরত্ব = ট্রিপ_ভরেজ_স্পিড * ট্রিপ_টাইম

যেহেতু জিপিএস স্পিডটি ডপলার এফেক্ট দ্বারা সনাক্ত করা হয়েছে এবং [লন, ল্যাট] এর সাথে সরাসরি সম্পর্কিত নয় তবে এটি মূল দূরত্ব গণনা পদ্ধতি হিসাবে না হলেও এটি অন্তত মাধ্যমিক (ব্যাকআপ বা সংশোধন) হিসাবে বিবেচনা করা যেতে পারে।


4

যদি আপনি। নেট ব্যবহার করে থাকেন তবে চাকাটি পুনর্বার করবেন না। System.Device.Location দেখুন । অন্য উত্তরে মন্তব্যগুলিতে fnx ক্রেডিট ।

using System.Device.Location;

double lat1 = 45.421527862548828D;
double long1 = -75.697189331054688D;
double lat2 = 53.64135D;
double long2 = -113.59273D;

GeoCoordinate geo1 = new GeoCoordinate(lat1, long1);
GeoCoordinate geo2 = new GeoCoordinate(lat2, long2);

double distance = geo1.GetDistanceTo(geo2);

3

এই লুয়া কোডটি উইকিপিডিয়ায় এবং রবার্ট লিপের জিপিএসবাবেল সরঞ্জামে পাওয়া স্টাফ থেকে অভিযোজিত :

local EARTH_RAD = 6378137.0 
  -- earth's radius in meters (official geoid datum, not 20,000km / pi)

local radmiles = EARTH_RAD*100.0/2.54/12.0/5280.0;
  -- earth's radius in miles

local multipliers = {
  radians = 1, miles = radmiles, mi = radmiles, feet = radmiles * 5280,
  meters = EARTH_RAD, m = EARTH_RAD, km = EARTH_RAD / 1000, 
  degrees = 360 / (2 * math.pi), min = 60 * 360 / (2 * math.pi)
}

function gcdist(pt1, pt2, units) -- return distance in radians or given units
  --- this formula works best for points close together or antipodal
  --- rounding error strikes when distance is one-quarter Earth's circumference
  --- (ref: wikipedia Great-circle distance)
  if not pt1.radians then pt1 = rad(pt1) end
  if not pt2.radians then pt2 = rad(pt2) end
  local sdlat = sin((pt1.lat - pt2.lat) / 2.0);
  local sdlon = sin((pt1.lon - pt2.lon) / 2.0);
  local res = sqrt(sdlat * sdlat + cos(pt1.lat) * cos(pt2.lat) * sdlon * sdlon);
  res = res > 1 and 1 or res < -1 and -1 or res
  res = 2 * asin(res);
  if units then return res * assert(multipliers[units])
  else return res
  end
end

3
    private double deg2rad(double deg)
    {
        return (deg * Math.PI / 180.0);
    }

    private double rad2deg(double rad)
    {
        return (rad / Math.PI * 180.0);
    }

    private double GetDistance(double lat1, double lon1, double lat2, double lon2)
    {
        //code for Distance in Kilo Meter
        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.Abs(Math.Round(rad2deg(Math.Acos(dist)) * 60 * 1.1515 * 1.609344 * 1000, 0));
        return (dist);
    }

    private double GetDirection(double lat1, double lon1, double lat2, double lon2)
    {
        //code for Direction in Degrees
        double dlat = deg2rad(lat1) - deg2rad(lat2);
        double dlon = deg2rad(lon1) - deg2rad(lon2);
        double y = Math.Sin(dlon) * Math.Cos(lat2);
        double x = Math.Cos(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) - Math.Sin(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * Math.Cos(dlon);
        double direct = Math.Round(rad2deg(Math.Atan2(y, x)), 0);
        if (direct < 0)
            direct = direct + 360;
        return (direct);
    }

    private double GetSpeed(double lat1, double lon1, double lat2, double lon2, DateTime CurTime, DateTime PrevTime)
    {
        //code for speed in Kilo Meter/Hour
        TimeSpan TimeDifference = CurTime.Subtract(PrevTime);
        double TimeDifferenceInSeconds = Math.Round(TimeDifference.TotalSeconds, 0);
        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 = rad2deg(Math.Acos(dist)) * 60 * 1.1515 * 1.609344;
        double Speed = Math.Abs(Math.Round((dist / Math.Abs(TimeDifferenceInSeconds)) * 60 * 60, 0));
        return (Speed);
    }

    private double GetDuration(DateTime CurTime, DateTime PrevTime)
    {
        //code for speed in Kilo Meter/Hour
        TimeSpan TimeDifference = CurTime.Subtract(PrevTime);
        double TimeDifferenceInSeconds = Math.Abs(Math.Round(TimeDifference.TotalSeconds, 0));
        return (TimeDifferenceInSeconds);
    }

1
আমি মনে করি মিটার আপনার ফাংশন GetDistance আয় মান
Przemek

এটা কি সঠিক? GetDirection () 'dlat' ব্যবহার করে না।
গুবি

3

এটি মাইএসকিউএল এবং কিলোমিটারের জন্য অভিযোজিত "হেনরি ভিলিনস্কি" এর সংস্করণ:

CREATE FUNCTION `CalculateDistanceInKm`(
  fromLatitude float,
  fromLongitude float,
  toLatitude float, 
  toLongitude float
) RETURNS float
BEGIN
  declare distance float;

  select 
    6367 * ACOS(
            round(
              COS(RADIANS(90-fromLatitude)) *
                COS(RADIANS(90-toLatitude)) +
                SIN(RADIANS(90-fromLatitude)) *
                SIN(RADIANS(90-toLatitude)) *
                COS(RADIANS(fromLongitude-toLongitude))
              ,15)
            )
    into distance;

  return  round(distance,3);
END;

MySQLবলেছেনSomething is wrong in your syntax near '' on line 8 // declare distance float;
2:36

এটি হ'ল "কোসাইনের গোলাকার আইন" গণনা যা একটি দুর্দান্ত বৃত্তের দূরত্ব গণনার সর্বনিম্ন নির্ভুল এবং সবচেয়ে ত্রুটি-প্রবণ পদ্ধতি
জন মাচিন

3

উত্তর থেকে সুইফ্ট বাস্তবায়ন এখানে

func degreesToRadians(degrees: Double) -> Double {
    return degrees * Double.pi / 180
}

func distanceInKmBetweenEarthCoordinates(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Double {

    let earthRadiusKm: Double = 6371

    let dLat = degreesToRadians(degrees: lat2 - lat1)
    let dLon = degreesToRadians(degrees: lon2 - lon1)

    let lat1 = degreesToRadians(degrees: lat1)
    let lat2 = degreesToRadians(degrees: lat2)

    let a = sin(dLat/2) * sin(dLat/2) +
    sin(dLon/2) * sin(dLon/2) * cos(lat1) * cos(lat2)
    let c = 2 * atan2(sqrt(a), sqrt(1 - a))
    return earthRadiusKm * c
}

3

আমি শীর্ষস্থানীয় উত্তর নিয়েছি এবং এটি একটি স্কালা প্রোগ্রামে ব্যবহার করেছি

import java.lang.Math.{atan2, cos, sin, sqrt}

def latLonDistance(lat1: Double, lon1: Double)(lat2: Double, lon2: Double): Double = {
    val earthRadiusKm = 6371
    val dLat = (lat2 - lat1).toRadians
    val dLon = (lon2 - lon1).toRadians
    val latRad1 = lat1.toRadians
    val latRad2 = lat2.toRadians

    val a = sin(dLat / 2) * sin(dLat / 2) + sin(dLon / 2) * sin(dLon / 2) * cos(latRad1) * cos(latRad2)
    val c = 2 * atan2(sqrt(a), sqrt(1 - a))
    earthRadiusKm * c
}

আমি দুটি স্থানে স্থির একটিতে সহজেই ফাংশন উত্পাদন করতে সক্ষম হতে এবং দূরত্ব তৈরি করতে কেবল এক জোড়া লাত / লম্বা প্রয়োজন i


2

আমার ধারণা আপনি পৃথিবীর বক্রতা বরাবর এটি চান। আপনার দুটি পয়েন্ট এবং পৃথিবীর কেন্দ্র একটি বিমানে আছে। পৃথিবীর কেন্দ্র that বিমানের একটি বৃত্তের কেন্দ্র এবং দুটি বিন্দু (মোটামুটি) সেই বৃত্তের ঘেরে। এর থেকে আপনি এক বিন্দু থেকে অন্য বিন্দুতে কোণটি নির্ধারণ করে দূরত্ব গণনা করতে পারেন।

পয়েন্টগুলি যদি একই উচ্চতা না হয়, বা আপনার যদি বিবেচনার প্রয়োজন হয় যে পৃথিবীটি নিখুঁত ক্ষেত্র নয় তবে এটি আরও কিছুটা কঠিন হয়ে যায়।


2

আমাকে সম্প্রতি একই জিনিস করতে হয়েছিল। আমি এই ওয়েবসাইটটি খুব সহজেই উদাহরণস্বরূপ অনুসরণ করতে পারি যেগুলি অনুসরণ করা সহজ sp


2

আপনি এফএসনিপে F # তে (কিছু ভাল ব্যাখ্যা সহ) এর একটি বাস্তবায়ন পেতে পারেন

এখানে গুরুত্বপূর্ণ অংশগুলি রয়েছে:


let GreatCircleDistance<[<Measure>] 'u> (R : float<'u>) (p1 : Location) (p2 : Location) =
    let degToRad (x : float<deg>) = System.Math.PI * x / 180.0<deg/rad>

    let sq x = x * x
    // take the sin of the half and square the result
    let sinSqHf (a : float<rad>) = (System.Math.Sin >> sq) (a / 2.0<rad>)
    let cos (a : float<deg>) = System.Math.Cos (degToRad a / 1.0<rad>)

    let dLat = (p2.Latitude - p1.Latitude) |> degToRad
    let dLon = (p2.Longitude - p1.Longitude) |> degToRad

    let a = sinSqHf dLat + cos p1.Latitude * cos p2.Latitude * sinSqHf dLon
    let c = 2.0 * System.Math.Atan2(System.Math.Sqrt(a), System.Math.Sqrt(1.0-a))

    R * c

2

আমার পাওয়ারশেলের মধ্যে এটি বাস্তবায়ন করা দরকার, আশা করি এটি অন্য কাউকে সহায়তা করতে পারে। এই পদ্ধতি সম্পর্কে কিছু নোট

  1. কোনও লাইন বিভক্ত করবেন না বা গণনাটি ভুল হবে
  2. কে এম তে গণনা করতে 1000 দূরত্বের গণনায় * 1000 সরিয়ে ফেলুন
  3. $ আর্থস রেডিয়াস = 3963.19059 পরিবর্তন করুন এবং মাইলের মধ্যে দূরত্বকে গণনা করতে $ দূরত্বের গণনায় * 1000 সরিয়ে ফেলুন
  4. আমি হ্যাভারসাইন ব্যবহার করছি, যেহেতু অন্যান্য পোস্টগুলি ভিনসেন্টির সূত্রগুলি আরও সঠিকভাবে নির্দেশ করেছে

    Function MetresDistanceBetweenTwoGPSCoordinates($latitude1, $longitude1, $latitude2, $longitude2)  
    {  
      $Rad = ([math]::PI / 180);  
    
      $earthsRadius = 6378.1370 # Earth's Radius in KM  
      $dLat = ($latitude2 - $latitude1) * $Rad  
      $dLon = ($longitude2 - $longitude1) * $Rad  
      $latitude1 = $latitude1 * $Rad  
      $latitude2 = $latitude2 * $Rad  
    
      $a = [math]::Sin($dLat / 2) * [math]::Sin($dLat / 2) + [math]::Sin($dLon / 2) * [math]::Sin($dLon / 2) * [math]::Cos($latitude1) * [math]::Cos($latitude2)  
      $c = 2 * [math]::ATan2([math]::Sqrt($a), [math]::Sqrt(1-$a))  
    
      $distance = [math]::Round($earthsRadius * $c * 1000, 0) #Multiple by 1000 to get metres  
    
      Return $distance  
    }
    

2

স্কালা সংস্করণ

  def deg2rad(deg: Double) = deg * Math.PI / 180.0

  def rad2deg(rad: Double) = rad / Math.PI * 180.0

  def getDistanceMeters(lat1: Double, lon1: Double, lat2: Double, lon2: Double) = {
    val theta = lon1 - lon2
    val dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) *
      Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta))
    Math.abs(
      Math.round(
        rad2deg(Math.acos(dist)) * 60 * 1.1515 * 1.609344 * 1000)
    )
  }

1

// হয়ত টাইপোর ত্রুটি? আমি অনুমান করি যে
getDirection এ আমাদের একটি অব্যবহৃত ভেরিয়েবল dlon আছে

double y = Math.Sin(dlon) * Math.Cos(lat2);
// cannot use degrees in Cos ?

হতে হবে

double y = Math.Sin(dlon) * Math.Cos(dlat);

1
এটি কোনও উত্তর নয়, এটি সর্বোত্তম মন্তব্য।
কেভিন

1

এলিক্সিরে আমার বাস্তবায়ন এখানে

defmodule Geo do
  @earth_radius_km 6371
  @earth_radius_sm 3958.748
  @earth_radius_nm 3440.065
  @feet_per_sm 5280

  @d2r :math.pi / 180

  def deg_to_rad(deg), do: deg * @d2r

  def great_circle_distance(p1, p2, :km), do: haversine(p1, p2) * @earth_radius_km
  def great_circle_distance(p1, p2, :sm), do: haversine(p1, p2) * @earth_radius_sm
  def great_circle_distance(p1, p2, :nm), do: haversine(p1, p2) * @earth_radius_nm
  def great_circle_distance(p1, p2, :m), do: great_circle_distance(p1, p2, :km) * 1000
  def great_circle_distance(p1, p2, :ft), do: great_circle_distance(p1, p2, :sm) * @feet_per_sm

  @doc """
  Calculate the [Haversine](https://en.wikipedia.org/wiki/Haversine_formula)
  distance between two coordinates. Result is in radians. This result can be
  multiplied by the sphere's radius in any unit to get the distance in that unit.
  For example, multiple the result of this function by the Earth's radius in
  kilometres and you get the distance between the two given points in kilometres.
  """
  def haversine({lat1, lon1}, {lat2, lon2}) do
    dlat = deg_to_rad(lat2 - lat1)
    dlon = deg_to_rad(lon2 - lon1)

    radlat1 = deg_to_rad(lat1)
    radlat2 = deg_to_rad(lat2)

    a = :math.pow(:math.sin(dlat / 2), 2) +
        :math.pow(:math.sin(dlon / 2), 2) *
        :math.cos(radlat1) * :math.cos(radlat2)

    2 * :math.atan2(:math.sqrt(a), :math.sqrt(1 - a))
  end
end

1

ডার্ট সংস্করণ

হ্যাভারসাইন অ্যালগরিদম।

import 'dart:math';

class GeoUtils {

  static double _degreesToRadians(degrees) {
    return degrees * pi / 180;
  }

  static double distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) {
    var earthRadiusKm = 6371;

    var dLat = _degreesToRadians(lat2-lat1);
    var dLon = _degreesToRadians(lon2-lon1);

    lat1 = _degreesToRadians(lat1);
    lat2 = _degreesToRadians(lat2);

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

0

আমি মনে করি আর এর মধ্যে অ্যালগোরিদমের একটি সংস্করণ এখনও অনুপস্থিত:

gpsdistance<-function(lat1,lon1,lat2,lon2){

# internal function to change deg to rad

degreesToRadians<- function (degrees) {
return (degrees * pi / 180)
}

R<-6371e3  #radius of Earth in meters

phi1<-degreesToRadians(lat1) # latitude 1
phi2<-degreesToRadians(lat2) # latitude 2
lambda1<-degreesToRadians(lon1) # longitude 1
lambda2<-degreesToRadians(lon2) # longitude 2

delta_phi<-phi1-phi2 # latitude-distance
delta_lambda<-lambda1-lambda2 # longitude-distance

a<-sin(delta_phi/2)*sin(delta_phi/2)+
cos(phi1)*cos(phi2)*sin(delta_lambda/2)*
sin(delta_lambda/2)

cc<-2*atan2(sqrt(a),sqrt(1-a))

distance<- R * cc

return(distance)  # in meters
}

0

এখানে একটি কোটলিন বৈচিত্র:

import kotlin.math.*

class HaversineAlgorithm {

    companion object {
        private const val MEAN_EARTH_RADIUS = 6371.0
        private const val D2R = Math.PI / 180.0
    }

    private fun haversineInKm(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double {
        val lonDiff = (lon2 - lon1) * D2R
        val latDiff = (lat2 - lat1) * D2R
        val latSin = sin(latDiff / 2.0)
        val lonSin = sin(lonDiff / 2.0)
        val a = latSin * latSin + (cos(lat1 * D2R) * cos(lat2 * D2R) * lonSin * lonSin)
        val c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a))
        return EQATORIAL_EARTH_RADIUS * c
    }
}

আপনি কেন পৃথিবী ব্যাসার্ধের পরিবর্তে নিরক্ষীয় ব্যাসার্ধ ব্যবহার করলেন?
ব্যবহারকারী13044086

@ ব্যবহারকারী13044086 ভাল প্রশ্ন। এর কারণ আমি এটি পাওলো মিগুয়েল আলমেডার জাভা সংস্করণ থেকে পেয়েছি। দেখে মনে হচ্ছে সি # সংস্করণটিও সেই দূরত্বটি ব্যবহার করছে। অন্যান্য সংস্করণগুলির এখানে 71৩71১ টি রয়েছে, তবে আপনাকে বুঝতে হবে যে এই সমস্ত অ্যালগোরিদমগুলি পৃথিবীর জিওড আকারটি পুরোপুরি পরিচালনা করতে পারে না। এটি সংশোধন করতে নির্দ্বিধায় এবং 71৩71১ ব্যবহার করুন you আপনি যদি আমাকে বলেন যে এটি আরও সুনির্দিষ্ট মানের দিকে নিয়ে যায় আমি আমার উত্তরটি পরিবর্তন করব।
সিএসবা তোথ

1
6371.008 সাধারণত ব্যবহৃত হয় কারণ এটি পৃষ্ঠার চলনযোগ্য-type.co.uk/scriptts/latlong.html#ellipsoid
ব্যবহারকারী 13044086

যথেষ্ট ফর্সা! আমি আগামীকাল আমার উত্তরটি সম্পাদনা করব
সিএসবা টথ

@ ব্যবহারকারী13044086 লিঙ্কটির জন্য ধন্যবাদ, আমি এর ভিত্তিতে কিছুক্ষণ আগে আমার উত্তর সম্পাদনা করেছি
সিএসবা তোথ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.