计算谷歌地图V3中两点之间的距离

Wah*_*eed 314 javascript google-maps-api-3

如何计算Google地图V3中两个标记之间的距离?(类似于distanceFromV2中的功能.)

谢谢..

Mik*_*ams 451

如果您想自己计算,那么您可以使用Haversine公式:

var rad = function(x) {
  return x * Math.PI / 180;
};

var getDistance = function(p1, p2) {
  var R = 6378137; // Earth’s mean radius in meter
  var dLat = rad(p2.lat() - p1.lat());
  var dLong = rad(p2.lng() - p1.lng());
  var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) *
    Math.sin(dLong / 2) * Math.sin(dLong / 2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  var d = R * c;
  return d; // returns the distance in meter
};
Run Code Online (Sandbox Code Playgroud)

  • 感谢不使用API​​的替代解决方案! (37认同)
  • 伙计们.题.为什么你非常喜欢使用1个字母的变量名称来解决需要一些想象力的问题,好的变量名称可能会有所帮助?只是问问而已 :) (17认同)
  • `p1.lat()`和`p1.lng()`函数假设您的输入数据是`google.maps.LatLng`对象.如果您只有原始数据,如`{lat:__,lon:__}`,那么您可以使用`p1.lat`代替. (4认同)
  • 为什么建议使用Math.atan2(Math.sqrt(a),Math.sqrt(1-a))而不是最简单的Math.asin(Math.sqrt(a))? (3认同)
  • @EmanuelePaolini - 数学上,atan2(sqrt(a),sqrt(1-a))= asin(sqrt(a))= acos(sqrt(1-a)),但atan2版本在数值上保持更好的条件适用于所有值一个. (2认同)
  • 不应该是var R = 6371; 为公里? (2认同)
  • 我收到此错误... lat() lng() 不是函数。 (2认同)

Emi*_*adh 302

GMap3实际上似乎有一种方法.它是google.maps.geometry.spherical命名空间的静态方法.

它将两个LatLng对象作为参数,并将使用默认的地球半径6378137米,但必要时可以使用自定义值覆盖默认半径.

确保包括:

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&v=3&libraries=geometry"></script>
Run Code Online (Sandbox Code Playgroud)

在你的头部.

电话会是:

google.maps.geometry.spherical.computeDistanceBetween (latLngA, latLngB);
Run Code Online (Sandbox Code Playgroud)

  • @RamenRecon是的,Emil对此是正确的.文档说:默认半径是地球的半径__6378137米.__但是上面的Haversine中的Mike使用的是__6371km__. (11认同)
  • 那么为什么Google的球形computeDistanceBetween和Haversine距离公式给出的答案有1%的差异? (10认同)
  • @RamenRecon我不确定,但是他们会为地球半径使用不同的值. (7认同)
  • @ ABCD.ca这不是我的号码.此问题与Google地图库的第3版有关.你问为什么你的计算与他们的计算不同.这是因为他们使用的地球半径值与你的不同.数字的参考?https://developers.google.com/maps/documentation/javascript/reference#spherical正好在标题下方. (2认同)

joa*_*16v 28

使用GPS经纬度为2点的示例.

var latitude1 = 39.46;
var longitude1 = -0.36;
var latitude2 = 40.40;
var longitude2 = -3.68;

var distance = google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(latitude1, longitude1), new google.maps.LatLng(latitude2, longitude2));       
Run Code Online (Sandbox Code Playgroud)

  • 距离结果以米为单位表示. (3认同)
  • @joan16v 如何在 node.js 中要求 google.maps.geometry。我想在 node.js 中使用上面的代码。我应该安装哪个模块以及我应该需要哪些文件。 (2认同)

小智 13

只需将其添加到JavaScript代码的开头:

google.maps.LatLng.prototype.distanceFrom = function(latlng) {
  var lat = [this.lat(), latlng.lat()]
  var lng = [this.lng(), latlng.lng()]
  var R = 6378137;
  var dLat = (lat[1]-lat[0]) * Math.PI / 180;
  var dLng = (lng[1]-lng[0]) * Math.PI / 180;
  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
  Math.cos(lat[0] * Math.PI / 180 ) * Math.cos(lat[1] * Math.PI / 180 ) *
  Math.sin(dLng/2) * Math.sin(dLng/2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  var d = R * c;
  return Math.round(d);
}
Run Code Online (Sandbox Code Playgroud)

然后使用这样的函数:

var loc1 = new GLatLng(52.5773139, 1.3712427);
var loc2 = new GLatLng(52.4788314, 1.7577444);
var dist = loc2.distanceFrom(loc1);
alert(dist/1000);
Run Code Online (Sandbox Code Playgroud)


Ais*_*ngh 12

//p1 and p2 are google.maps.LatLng(x,y) objects

function calcDistance(p1, p2) {
          var d = (google.maps.geometry.spherical.computeDistanceBetween(p1, p2) / 1000).toFixed(2);
          console.log(d);              
}
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案.为什么在Google API已有功能时添加功能 (2认同)

Nav*_*mad 11

这是本论坛的c#实现

 public class DistanceAlgorithm
{
    const double PIx = 3.141592653589793;
    const double RADIO = 6378.16;

    /// <summary>
    /// This class cannot be instantiated.
    /// </summary>
    private DistanceAlgorithm() { }

    /// <summary>
    /// Convert degrees to Radians
    /// </summary>
    /// <param name="x">Degrees</param>
    /// <returns>The equivalent in radians</returns>
    public static double Radians(double x)
    {
        return x * PIx / 180;
    }

    /// <summary>
    /// Calculate the distance between two places.
    /// </summary>
    /// <param name="lon1"></param>
    /// <param name="lat1"></param>
    /// <param name="lon2"></param>
    /// <param name="lat2"></param>
    /// <returns></returns>
    public static double DistanceBetweenPlaces(
        double lon1,
        double lat1,
        double lon2,
        double lat2)
    {
        double dlon =  Radians(lon2 - lon1);
        double dlat =  Radians(lat2 - lat1);

        double a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos(Radians(lat1)) * Math.Cos(Radians(lat2)) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2));
        double angle = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
        return (angle * RADIO) * 0.62137;//distance in miles
    }

}    
Run Code Online (Sandbox Code Playgroud)

  • 这不适用于如何在Google地图中执行此操作的原始问题. (5认同)

iwe*_*ein 11

与谷歌,你可以用它做球的API,google.maps.geometry.spherical.computeDistanceBetween (latLngA, latLngB);.

但是,如果球形投影或半正弦解决方案的精度不够精确(例如,如果您接近极点或计算更长的距离),则应使用不同的库.

在我在维基百科上找到该主题上的信息在这里.

查看任何给定算法的精度是否足够的技巧是填写地球的最大和最小半径,看看差异是否可能导致您的用例出现问题.在本文中可以找到更多详细信息

最终谷歌api或者半身像将毫无问题地用于大多数目的.


Rav*_*ngh 9

使用PHP,您可以使用这个简单的函数计算距离:

// to calculate distance between two lat & lon

function calculate_distance($lat1, $lon1, $lat2, $lon2, $unit='N') 
{ 
  $theta = $lon1 - $lon2; 
  $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); 
  $dist = acos($dist); 
  $dist = rad2deg($dist); 
  $miles = $dist * 60 * 1.1515;
  $unit = strtoupper($unit);

  if ($unit == "K") {
    return ($miles * 1.609344); 
  } else if ($unit == "N") {
      return ($miles * 0.8684);
    } else {
        return $miles;
      }
}

// function ends here

  • 函数中有一个条件是,如果你将单位作为"K"传递,那么它将以Km为单位给出距离.核实. (2认同)

Mar*_*osa 8

离线解决方案 - Haversine算法

在Javascript中

var _eQuatorialEarthRadius = 6378.1370;
var _d2r = (Math.PI / 180.0);

function HaversineInM(lat1, long1, lat2, long2)
{
    return (1000.0 * HaversineInKM(lat1, long1, lat2, long2));
}

function HaversineInKM(lat1, long1, lat2, long2)
{
    var dlong = (long2 - long1) * _d2r;
    var dlat = (lat2 - lat1) * _d2r;
    var a = Math.pow(Math.sin(dlat / 2.0), 2.0) + Math.cos(lat1 * _d2r) * Math.cos(lat2 * _d2r) * Math.pow(Math.sin(dlong / 2.0), 2.0);
    var c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1.0 - a));
    var d = _eQuatorialEarthRadius * c;

    return d;
}

var meLat = -33.922982;
var meLong = 151.083853;


var result1 = HaversineInKM(meLat, meLong, -32.236457779983745, 148.69094705162837);
var result2 = HaversineInKM(meLat, meLong, -33.609020205923713, 150.77061469270831);
Run Code Online (Sandbox Code Playgroud)

C#

using System;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");

        var meLat = -33.922982;
        double meLong = 151.083853;


        var result1 = HaversineInM(meLat, meLong, -32.236457779983745, 148.69094705162837);
        var result2 = HaversineInM(meLat, meLong, -33.609020205923713, 150.77061469270831);

        Console.WriteLine(result1);
        Console.WriteLine(result2);
    }

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

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

    private 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

参考:https: //en.wikipedia.org/wiki/Great-circle_distance