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


95

এখানে আমার চেষ্টা, এটি আমার কোডের স্নিপেট:

final double RADIUS = 6371.01;
double temp = Math.cos(Math.toRadians(latA))
            * Math.cos(Math.toRadians(latB))
            * Math.cos(Math.toRadians((latB) - (latA)))
            + Math.sin(Math.toRadians(latA))
            * Math.sin(Math.toRadians(latB));
    return temp * RADIUS * Math.PI / 180;

অক্ষাংশ এবং দ্রাঘিমাংশ পেতে আমি এই সূত্রগুলি ব্যবহার করছি:

x = Deg + (Min + Sec / 60) / 60)

উত্তর:


221

উপরের ডোমারের দেওয়া জাভা কোড কিছুটা ভুল ফলাফল দেয় তবে আপনি যদি জিপিএস ট্র্যাক করে প্রসেসিং করেন তবে ছোট ত্রুটিগুলি যুক্ত হয় add এখানে জাভাতে হাওয়ারসাইন পদ্ধতির একটি বাস্তবায়ন রয়েছে যা দুটি পয়েন্টের মধ্যেও উচ্চতার পার্থক্যের বিষয়টি গ্রহণ করে।

/**
 * Calculate distance between two points in latitude and longitude taking
 * into account height difference. If you are not interested in height
 * difference pass 0.0. Uses Haversine method as its base.
 * 
 * lat1, lon1 Start point lat2, lon2 End point el1 Start altitude in meters
 * el2 End altitude in meters
 * @returns Distance in Meters
 */
public static double distance(double lat1, double lat2, double lon1,
        double lon2, double el1, double el2) {

    final int R = 6371; // Radius of the earth

    double latDistance = Math.toRadians(lat2 - lat1);
    double lonDistance = Math.toRadians(lon2 - lon1);
    double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
            + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
            * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    double distance = R * c * 1000; // convert to meters

    double height = el1 - el2;

    distance = Math.pow(distance, 2) + Math.pow(height, 2);

    return Math.sqrt(distance);
}

7
ডিগ্রাড্রেড () এর পরিবর্তে ম্যাথ টু রেডিয়ান () কেন নয়? এটি সত্যিই স্বনির্ভর হবে।
অ্যারন লরিঞ্জ

4
@ বালা - আমার খারাপ, এটি আমার কম্পিউটারের কোডটির মন্তব্যে রয়েছে তবে এখানে অনুপস্থিত। মিটারে দূরত্ব।
ডেভিড জর্জ

4
@ অরননমমন্ডমমেগায়েজেটেকনেভেম আপনার খুব ভাল পরামর্শটি ব্যবহার করার জন্য আমি পদ্ধতিটি আপডেট করেছি।
ডেভিড জর্জ


পরিবর্তনশীল নামের সাথে কোনও বিশেষ প্রাসঙ্গিকতা aএবং c? এগুলি কি traditionalতিহ্যবাহী লেবেলের সাথে ডান-কোণযুক্ত ত্রিভুজের দিকগুলি a,b এবং c?
এলেনডি

76

এখানে একটি জাভা ফাংশন যা নীচে পোস্ট করা দুটি ল্যাট / লম্বা পয়েন্টগুলির মধ্যে দূরত্ব গণনা করে , কেবল যদি এটি আবার অদৃশ্য হয়ে যায় তবে।

    private double distance(double lat1, double lon1, double lat2, double lon2, char unit) {
      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 * 180.0 / Math.PI);
    }
    
    System.out.println(distance(32.9697, -96.80322, 29.46786, -98.53506, 'M') + " Miles\n");
    System.out.println(distance(32.9697, -96.80322, 29.46786, -98.53506, 'K') + " Kilometers\n");
    System.out.println(distance(32.9697, -96.80322, 29.46786, -98.53506, 'N') + " Nautical Miles\n");

4
গুগল ম্যাপ 12.915700, 77.632046, 11.665154, 78.145657 এর জন্য 200 কিলোমিটার দেখায় যেখানে উপরের কোডগুলি 149.82 কিলোমিটার দেখায়। কিছু এখনও ভুল আছে।
স্যামি

4
@ সামি উপরের ফাংশনটি আপনাকে সরল রেখার দূরত্ব দেয়।
রাহুল_পাওয়ার

4
বিকাশকারীদের ইউনিটগুলির সাথে তাদের ভেরিয়েবলগুলি লেবেল করার জন্য আমার কিংডম । ডাবল ডিস্ট => ডাবল ডিস্টইনমাইলস (বা অনুরূপ) (আমি এই উত্তর পোস্ট করা ব্যক্তিকে কড়া দিচ্ছি না, আমি উজ্জীবিত করছি ....... বরং কোডটির মূল প্রয়োগকারী)
গ্রানাডা কোডার

14

দ্রষ্টব্য: এই সমাধানটি কেবল স্বল্প দূরত্বের জন্য কাজ করে।

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

public class FlatEarthDist {
    //returns distance in meters
    public static double distance(double lat1, double lng1, 
                                      double lat2, double lng2){
     double a = (lat1-lat2)*FlatEarthDist.distPerLat(lat1);
     double b = (lng1-lng2)*FlatEarthDist.distPerLng(lat1);
     return Math.sqrt(a*a+b*b);
    }

    private static double distPerLng(double lat){
      return 0.0003121092*Math.pow(lat, 4)
             +0.0101182384*Math.pow(lat, 3)
                 -17.2385140059*lat*lat
             +5.5485277537*lat+111301.967182595;
    }

    private static double distPerLat(double lat){
            return -0.000000487305676*Math.pow(lat, 4)
                -0.0033668574*Math.pow(lat, 3)
                +0.4601181791*lat*lat
                -1.4558127346*lat+110579.25662316;
    }
}

14

ভবিষ্যতের পাঠকরা যারা এই এসওএফ নিবন্ধটিতে হোঁচট খায়।

স্পষ্টতই, প্রশ্নটি 2010 সালে এবং এটি এখন 2019 সালে জিজ্ঞাসা করা হয়েছিল But তবে এটি একটি ইন্টারনেট অনুসন্ধানের প্রথম দিকে উঠে আসে। মূল প্রশ্নটি তৃতীয় পক্ষের-লাইব্রেরির ব্যবহার ছাড় দেয় না (যখন আমি এই উত্তরটি লিখেছি)।

public double calculateDistanceInMeters(double lat1, double long1, double lat2,
                                     double long2) {


    double dist = org.apache.lucene.util.SloppyMath.haversinMeters(lat1, long1, lat2, long2);
    return dist;
}

এবং

<dependency>
  <groupId>org.apache.lucene</groupId>
  <artifactId>lucene-spatial</artifactId>
  <version>8.2.0</version>
</dependency>

https://mvnrepository.com/artifact/org.apache.lucene/lucene-spatial/8.2.0

ডুব দেওয়ার আগে দয়া করে "স্লোপিপ্যাথ" সম্পর্কে ডকুমেন্টেশন পড়ুন!

https://lucene.apache.org/core/8_2_0/core/org/apache/lucene/util/SloppyMath.html


আপনি কি নিশ্চিত যে এটি ঠিক? এই জার ফাইলটিতে ".util" থাকতে হবে না আমি কেবল এটি যাচাই করেছি।
আদনান আলী

এজন্য আমি সর্বদা উত্তর সহ সংস্করণটি প্রকাশ করি। আপনি 8.2.0 পেয়েছেন তা নিশ্চিত করুন। ১৩ টি আপভোটও উত্তরটি সঠিক বলে প্রস্তাব দেয়।
গ্রানাডা কোডার

5

বিভিন্ন গোলাকার গণনার জন্য জাভাস্ক্রিপ্ট উদাহরণ সহ একটি পৃষ্ঠা এখানে রয়েছে। পৃষ্ঠার প্রথমটি আপনাকে যা প্রয়োজন তা দেবে।

http://www.movable-type.co.uk/scriptts/latlong.html

এখানে জাভাস্ক্রিপ্ট কোড

var R = 6371; // km
var dLat = (lat2-lat1).toRad();
var dLon = (lon2-lon1).toRad(); 
var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
        Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
        Math.sin(dLon/2) * Math.sin(dLon/2); 
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
var d = R * c;

যেখানে 'd' দূরত্বটি ধরে রাখবে।


"এ" কি কখনও নেতিবাচক হতে পারে?
Xi ওয়েই

1
package distanceAlgorithm;

public class CalDistance {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
    CalDistance obj=new CalDistance();
    /*obj.distance(38.898556, -77.037852, 38.897147, -77.043934);*/
        System.out.println(obj.distance(38.898556, -77.037852, 38.897147, -77.043934, "M") + " Miles\n");
        System.out.println(obj.distance(38.898556, -77.037852, 38.897147, -77.043934, "K") + " Kilometers\n");
        System.out.println(obj.distance(32.9697, -96.80322, 29.46786, -98.53506, "N") + " Nautical Miles\n");       
    }   
    public double distance(double lat1, double lon1, double lat2, double lon2, String sr) {


          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 (sr.equals("K")) {
            dist = dist * 1.609344;
          } else if (sr.equals("N")) {
            dist = dist * 0.8684;
            }
          return (dist);
        }
    public double deg2rad(double deg) {
          return (deg * Math.PI / 180.0);
        }
    public double rad2deg(double rad) {
          return (rad * 180.0 / Math.PI);
        }


    }

1

প্রচুর দুর্দান্ত উত্তর ছিল তবে আমি কিছু পারফরম্যান্সের ঘাটতি খুঁজে পেয়েছি, সুতরাং আমাকে কর্মক্ষমতা মাথায় রেখে একটি সংস্করণ সরবরাহ করতে দিন offer প্রতিটি ধ্রুবক প্রাক্কলকুলেটেড হয় এবং একই মান দুবার গণনা এড়াতে x, y ভেরিয়েবলগুলি প্রবর্তিত হয়। আশা করি এটা সাহায্য করবে

    private static final double r2d = 180.0D / 3.141592653589793D;
    private static final double d2r = 3.141592653589793D / 180.0D;
    private static final double d2km = 111189.57696D * r2d;
    public static double meters(double lt1, double ln1, double lt2, double ln2) {
        final double x = lt1 * d2r;
        final double y = lt2 * d2r;
        return Math.acos( Math.sin(x) * Math.sin(y) + Math.cos(x) * Math.cos(y) * Math.cos(d2r * (ln1 - ln2))) * d2km;
    }

1

@ ডেভিড জর্জের সামান্য আপগ্রেড উত্তর:

public static double distance(double lat1, double lat2, double lon1,
                              double lon2, double el1, double el2) {

    final int R = 6371; // Radius of the earth

    double latDistance = Math.toRadians(lat2 - lat1);
    double lonDistance = Math.toRadians(lon2 - lon1);
    double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
            + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
            * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    double distance = R * c * 1000; // convert to meters

    double height = el1 - el2;

    distance = Math.pow(distance, 2) + Math.pow(height, 2);

    return Math.sqrt(distance);
}

public static double distanceBetweenLocations(Location l1, Location l2) {
    if(l1.hasAltitude() && l2.hasAltitude()) {
        return distance(l1.getLatitude(), l2.getLatitude(), l1.getLongitude(), l2.getLongitude(), l1.getAltitude(), l2.getAltitude());
    }
    return l1.distanceTo(l2);
}

দূরত্ব ফাংশনটি একই, তবে আমি তৈরি করেছি ছোট ছোট র‍্যাপার ফাংশন, যা 2 অবস্থানের অবজেক্ট নেয় takes এর জন্য ধন্যবাদ, আমি কেবলমাত্র দূরত্ব ফাংশনটি ব্যবহার করি যদি উভয় জায়গাতেই উচ্চতার উচ্চতা থাকে, কারণ কখনও কখনও তারা না থাকে। এবং এটি অদ্ভুত ফলাফলের দিকে নিয়ে যেতে পারে (যদি অবস্থানটি না জানলে এর উচ্চতা 0 ফিরে আসবে)। এই ক্ষেত্রে, আমি ক্লাসিক দূরত্বের ফাংশনে ফিরে যাই ।


-1

এই উইকিপিডিয়া নিবন্ধটি সূত্র এবং একটি উদাহরণ সরবরাহ করে। পাঠ্যটি জার্মান ভাষায়, তবে গণনাগুলি তাদের পক্ষে কথা বলে।

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