2个地理编码之间的距离

时间:2009-07-10 16:24:17

标签: map geocoding

计算2个地理编码之间距离的公式是什么?我在这个网站上看到了一些答案,但他们基本上说要依赖SQL Server 08的功能,我还没有08。任何帮助将不胜感激。

9 个答案:

答案 0 :(得分:8)

使用地球的近似值和Haversine公式。您可以在以下网址上获取javascript版本,您可以将其翻译为您选择的语言:

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

这是另一种方式:http://escience.anu.edu.au/project/04S2/SE/3DVOT/3DVOT/pHatTrack_Application/Source_code/pHatTrack/Converter.java

答案 1 :(得分:2)

答案 2 :(得分:2)

这将在c#中为您完成。

在命名空间中放置以下内容:

 public enum DistanceType { Miles, Kilometers };

public struct Position
{
    public double Latitude;
    public double Longitude;
}

class Haversine
{

    public double Distance(Position pos1, Position pos2, DistanceType type)
    {
        double preDlat = pos2.Latitude - pos1.Latitude;
        double preDlon = pos2.Longitude - pos1.Longitude;
        double R = (type == DistanceType.Miles) ? 3960 : 6371;
        double dLat = this.toRadian(preDlat);
        double dLon = this.toRadian(preDlon);
        double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
        Math.Cos(this.toRadian(pos1.Latitude)) * Math.Cos(this.toRadian(pos2.Latitude)) *
        Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
        double c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));
        double d = R * c;
        return d;
    }

    private double toRadian(double val)
    {
        return (Math.PI / 180) * val;
    }

然后在主代码中使用这些:

Position pos1 = new Position();
                    pos1.Latitude = Convert.ToDouble(hotelx.latitude);
                    pos1.Longitude = Convert.ToDouble(hotelx.longitude);
                    Position pos2 = new Position();
                    pos2.Latitude = Convert.ToDouble(lat);
                    pos2.Longitude = Convert.ToDouble(lng);
                    Haversine calc = new Haversine();

                    double result = calc.Distance(pos1, pos2, DistanceType.Miles);

答案 3 :(得分:2)

如果

  • 你知道2分是“彼此不太远”
  • 并且您可以容忍“相当小的”错误。

然后,考虑两点之间的地球是平坦的:

  • 纬度方向的距离差为EarthRadius * latitude difference
  • 经度方向的距离差为EarthRadius * longitude difference * cos(latitude)。 我们乘以cos(lat),因为如果纬度发生变化,经度度数不会达到相同的km距离。当P1和P2接近时,cos(latP1)接近cos(latP2)
  • 然后Pythagore

在JavaScript中:

function ClosePointsDistance(latP1, lngP1, latP2, lngP2) {
    var d2r = Math.PI / 180,
    R=6371; // Earth Radius in km
    latP1 *= d2r; lngP1 *= d2r; latP2 *= d2r; lngP2 *= d2r; // convert to radians
    dlat = latP2 - latP1,
    dlng = (lngP2 - lngP1) * Math.cos(latP1);
    return R * Math.sqrt( dlat*dlat + dlng*dlng );
}

我在巴黎和奥尔良(法国)之间进行了测试:公式为110.9公里,而(精确)的Haversine公式为111.0公里。

!!!注意子午线0周围的情况(你可以移动它):如果P1在Lng 359而P2在Lng 0,那么函数将会异常地考虑它们!

答案 4 :(得分:1)

如果您使用的是sql server,可以使用以下方法。

CREATE function dist (@Lat1 varchar(50), @Lng1 varchar(50),@Lat2 varchar(50), @Lng2 varchar(50)) 
returns float 
as
begin

declare @p1 geography
declare @p2 geography

set @p1 = geography::STGeomFromText('POINT('+ @Lng1+' '+ @Lat1 +')', 4326)
set @p2 = geography::STGeomFromText('POINT('+ @Lng2+' '+ @Lat2 +')', 4326)

return @p1.STDistance(@p2)
end

答案 5 :(得分:0)

你正在寻找球体上两点之间的大圆路径的长度。尝试在Google上查找“Great Circle Path”或“Great Circle Distance”。

答案 6 :(得分:0)

对不起,我不知道你在哪个国家。我们是在谈论Easting和Northings(英国,Ordance调查系统)还是Lat / Long或其他系统? 如果我们正在谈论Easting和Northing那么你可以使用
sqr((x1-x2)^ 2 +(y1-y2)^ 2)
这不允许地球是一个球体,但对于短距离你不会注意到。我们在工作中使用它来确定县内各点之间的距离 请关注您使用的网格参考时间。我认为一个8位数的参考将给你一个以米为单位的距离。如果没有其他人提供它,我将在下周的工作中获得一个明确的答案。

答案 7 :(得分:0)

其他人提出的毕达哥拉斯定理并不能很好地发挥作用。

最好的,简单的答案是将地球近似为一个球体(它实际上是一个略微扁平的球体,但这非常接近)。例如,在Haskell中,您可以使用以下内容,但数学可以转录为几乎所有内容:

distRadians (lat1,lon1) (lat2,lon2) = 
    radius_of_earth * 
    acos (cos lat1 * cos lon1 * cos lat2 * cos lon2 + 
          cos lat1 * sin lon1 * cos lat2 * sin lon2 + 
          sin lat1 * sin lat2) where
    radius_of_earth = 6378 -- kilometers


distDegrees a b = distRadians (coord2rad a) (coord2rad b) where
    deg2rad d = d * pi / 180
    coord2rad (lat,lon) = (deg2rad lat, deg2rad lon)

distRadians要求你的角度以弧度给出。

distDegrees是一个辅助函数,可以用度数来表示晶格和经度。

有关推导此公式的更多信息,请参阅this series of posts

如果确实需要通过假设地球是椭圆体而获得额外的精度,请参阅此常见问题解答:http://www.movable-type.co.uk/scripts/gis-faq-5.1.html

答案 8 :(得分:-1)

毕达哥拉斯定理?