Расстояние между 2 геокодами - PullRequest
5 голосов
/ 10 июля 2009

Какова формула для расчета расстояния между 2 геокодами? Я видел некоторые ответы на этом сайте, но они в основном говорят, что полагаются на функции SQL Server 08, я еще не на 08. Любая помощь будет оценена.

Ответы [ 9 ]

8 голосов
/ 10 июля 2009

Используйте приближение Земли и формулу Haversine . Вы можете получить версию javascript по следующему адресу, которую вы можете перевести на свой язык:

http://www.movable -type.co.uk / скрипты / latlong.html

Вот еще один способ: http://escience.anu.edu.au/project/04S2/SE/3DVOT/3DVOT/pHatTrack_Application/Source_code/pHatTrack/Converter.java

2 голосов
/ 08 апреля 2013

Если

  • вы знаете, что 2 очка "не слишком далеко друг от друга"
  • и вы допускаете ошибку "достаточно мала" .

Тогда предположим, что земля плоская между двумя точками:

  • Разница расстояний в направлении широты EarthRadius * latitude difference
  • Разница расстояний в направлении долготы составляет EarthRadius * longitude difference * cos(latitude). Мы умножаем на cos(lat), потому что градусы долготы не делают то же самое расстояние в км, если широта изменяется. Поскольку P1 и P2 близки, cos (latP1) близко к cos (latP2)
  • Тогда Пифагор

В 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 км, тогда как (точная) формула Хаверсайна находит 111,0 км.

!!! Остерегайтесь ситуаций вокруг меридиана 0 (вы можете сместить его): если P1 находится на Lng 359, а P2 на Lng 0, функция будет считать их ненормально далеко !!!

2 голосов
/ 17 октября 2012

Это сделает это за вас в 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);
2 голосов
/ 10 июля 2009
1 голос
/ 24 ноября 2013

Вот способ сделать это, если вы используете 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
0 голосов
/ 10 июля 2009

Теорема Пифагора, предложенная здесь другими, работает не так хорошо.

Лучший простой ответ - приблизить Землю как сферу (на самом деле это слегка сплюснутая сфера, но это очень близко). Например, в 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 - вспомогательная функция, которая может принимать широту и долготу в градусах.

См. этой серии сообщений для получения дополнительной информации о происхождении этой формулы.

Если вам действительно нужна дополнительная точность, обеспечиваемая предположением, что Земля эллипсоидальная, см. Этот FAQ: http://www.movable -type.co.uk / scripts / gis-faq-5.1.html

0 голосов
/ 10 июля 2009

Извините, я даже не знаю, в какой вы стране. Речь идет о Easting и Northings (Великобритания, система Ordance Survey) или Lat / Long или какой-либо другой системе? Если мы говорим о восточном и северном направлениях, тогда вы можете использовать
sqr ((x1-x2) ^ 2 + (y1-y2) ^ 2)
Это не учитывает тот факт, что земля - ​​это сфера, но на короткие расстояния вы не заметите. Мы используем его на работе для расстояний между точками в округе.
Будьте осторожны с тем, как долго вы используете ссылку на сетку. Я думаю, что 8-значный эталон даст вам расстояние в метрах. Я смогу получить точный ответ на работе на следующей неделе, если никто другой не предоставит его.

0 голосов
/ 10 июля 2009

Вы ищете длину пути Великого круга между двумя точками на сфере. Попробуйте поискать "Большой круговой путь" или "Большое круговое расстояние" в Google.

0 голосов
/ 10 июля 2009

теорема Пифагора?

...