如何使用经纬度计算两个位置之间的距离

66

以下是我的代码,我使用下面的代码来计算两个位置之间的距离,使用它们的纬度和经度。但是它给出了错误的距离,有时会得到正确的结果,有时会得到不相关的距离。

我们从数据库中获取lat1和lng1。

//getting lat2 and lng2 from GPS as below

public class MyLocationListener implements LocationListener {

  @Override
  public void onLocationChanged(Location loc)
  {
    lat2=loc.getLatitude();
    lng2=loc.getLongitude();
    String Text = "My current location is: " +"Latitud = "+ loc.getLatitude() +"Longitud = " + loc.getLongitude();

    //System.out.println("Lat & Lang form Loc"+Text);
    //Toast.makeText( getApplicationContext(), Text,Toast.LENGTH_SHORT).show();
  }

  @Override
  public void onProviderDisabled(String provider)
  {
  }

  @Override
  public void onProviderEnabled(String provider)
  {
  }

  @Override
  public void onStatusChanged(String provider, int status, Bundle extras)
  {
  }


  //Calculating distance
  double earthRadius = 3958.75;

  double dLat = Math.toRadians(lat1-lat2);
  double dLng = Math.toRadians(lng1-lng2);
  double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
             Math.cos(Math.toRadians(lat2)) * Math.cos(Math.toRadians(lat1)) *
             Math.sin(dLng/2) * Math.sin(dLng/2);
  double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  double dist = earthRadius * c;

请参考 https://dev59.com/I3A65IYBdhLWcg3wrQl4#3694410/ - General Grievance
14个回答

102

2
这是空中距离还是路程距离? - Rajat Gupta
可能是Aerial - Pulkit
5
肯定是空中的 :) - Milad Yarmohammadi

96

正如https://dzone.com/articles/distance-calculation-using-3中所述,并且在计算两点之间距离,使用经纬度?的答案中提到 —

private double distance(double lat1, double lon1, double lat2, double
lon2) {
    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;
    return (dist); }

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

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

1
如果您在回答中添加单位会更好。 - Basanth
12
我认为这个输出单位是英里,你可以使用这个公式将其转换为公里 -> km = mi / 0.62137。 - tej shah
整个堆栈中找到的最佳距离计算代码。非常准确。但请解释每个步骤。不理解你做了什么。感谢分享! - Dinith Rukshan Kumara
1
该方法返回英里数。由于给定的是度数(和度数的分数),因此一度有60个海里,因此60 * 1.1515英里,以及60 * 1.1515 * 1.609344公里。 - Krishnarjun Banoth
@KrishnarjunBanoth 我也检查了这个方法,它返回的是英里,你有没有任何改进版的方法可以返回公里数。 - xaif
显示剩余3条评论

84

尝试这段代码。

startPoint.distanceTo(endPoint)函数以米为单位返回这些地点之间的距离。

Location startPoint=new Location("locationA");
startPoint.setLatitude(17.372102);
startPoint.setLongitude(78.484196);

Location endPoint=new Location("locationA");
endPoint.setLatitude(17.375775);
endPoint.setLongitude(78.469218);

double distance=startPoint.distanceTo(endPoint);

这里"distance"是我们需要的结果,以为单位。希望它能在安卓上运行。


嘿@sandeepmaaram,我正在使用“SphericalUtil.computeDistanceBetween(from, to);”来计算距离,但问题是,当我在日志中打印该距离时,它给出的是13047。实际距离为15.6公里。所以我很困惑那些数字是什么?如果这是距离,那么它是如何计算的。 - MashukKhan
SphericalUtil是Java/Android提供的API吗?你试过我的解决方案了吗? - sandeepmaaram
1
非常感谢@sandeepmaaram,我尝试了您的解决方案,您的答案给出了我想要的确切位置。是的,SphericalUtil API由Android提供。 - MashukKhan
这个是土耳其坐标最接近的。 - Muhammed Aydogan

12

在 build.gradle 中:

compile 'com.google.maps.android:android-maps-utils:0.4'

接着:

public static Double distanceBetween(LatLng point1, LatLng point2) {
    if (point1 == null || point2 == null) {
        return null;
    }

    return SphericalUtil.computeDistanceBetween(point1, point2);
}

在这个方法distanceBetween()中,LatLng是什么?我尝试传递经度和纬度的double值,但它不支持。 - Himadri
1
你需要使用LatLng类型而不是double类型,格式应该像LatLng[21.432432,76.543543]。 - Adnan Bashir

9
如果您有两个位置对象Location loc1Location loc2,则可以执行以下操作:
float distance = loc1.distanceTo(loc2);

如果您有经纬度的数值,可以使用静态的distanceBetween()函数。
    float[] results = new float[1];
    Location.distanceBetween(startLatitude, startLongitude,
    endLatitude, endLongitude, results);
    float distance = results[0];

4
在 Kotlin 中
private fun distanceInMeter(startLat: Double, startLon: Double, endLat: Double, endLon: Double): Float {
    var results = FloatArray(1)
    Location.distanceBetween(startLat,startLon,endLat,endLon,results)  
    return results[0]
}

3
private String getDistanceOnRoad(double latitude, double longitude,
        double prelatitute, double prelongitude) {
    String result_in_kms = "";
    String url = "http://maps.google.com/maps/api/directions/xml?origin="
            + latitude + "," + longitude + "&destination=" + prelatitute
            + "," + prelongitude + "&sensor=false&units=metric";
    String tag[] = { "text" };
    HttpResponse response = null;
    try {
        HttpClient httpClient = new DefaultHttpClient();
        HttpContext localContext = new BasicHttpContext();
        HttpPost httpPost = new HttpPost(url);
        response = httpClient.execute(httpPost, localContext);
        InputStream is = response.getEntity().getContent();
        DocumentBuilder builder = DocumentBuilderFactory.newInstance()
                .newDocumentBuilder();
        Document doc = builder.parse(is);
        if (doc != null) {
            NodeList nl;
            ArrayList args = new ArrayList();
            for (String s : tag) {
                nl = doc.getElementsByTagName(s);
                if (nl.getLength() > 0) {
                    Node node = nl.item(nl.getLength() - 1);
                    args.add(node.getTextContent());
                } else {
                    args.add(" - ");
                }
            }
            result_in_kms = String.format("%s", args.get(0));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result_in_kms;
}

2
private float distanceFrom_in_Km(float lat1, float lng1, float lat2, float lng2) {

     if (lat1== null || lng1== null || lat2== null || lng2== null) 
     {
                return null;
     }

 double earthRadius = 6371000; //meters
    double dLat = Math.toRadians(lat2-lat1);
    double dLng = Math.toRadians(lng2-lng1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
               Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
               Math.sin(dLng/2) * Math.sin(dLng/2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    float dist = (float) (earthRadius * c);

    return dist;
    }    

2
使用以下方法计算两个不同位置之间的距离。最初的回答:

使用以下方法计算两个不同位置之间的距离。

public double getKilometers(double lat1, double long1, double lat2, double long2) {
 double PI_RAD = Math.PI / 180.0;
 double phi1 = lat1 * PI_RAD;
 double phi2 = lat2 * PI_RAD;
 double lam1 = long1 * PI_RAD;
 double lam2 = long2 * PI_RAD;

return 6371.01 * acos(sin(phi1) * sin(phi2) + cos(phi1) * cos(phi2) * cos(lam2 - lam1));}

2
尝试以下方法代码以获取两个位置之间的距离(单位为米),希望能帮助您。
 public static double distance(LatLng start, LatLng end){
    try {
        Location location1 = new Location("locationA");
        location1.setLatitude(start.latitude);
        location1.setLongitude(start.longitude);
        Location location2 = new Location("locationB");
        location2.setLatitude(end.latitude);
        location2.setLongitude(end.longitude);
        double distance = location1.distanceTo(location2);
        return distance;
    } catch (Exception e) {

        e.printStackTrace();

    }
    return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接