Как найти расстояние от широты и долготы двух мест?

У меня есть набор широт и долгот мест.

  • Как найти расстояние из одного места в наборе в другое?
  • Есть ли формула?

Ответ 1

Формула Хаверсина предполагает сферическую землю. Однако форма уха сложнее. Сплавная сфероидная модель даст лучшие результаты.

Если такая точность необходима, вам лучше использовать формулу Vincenty inverse formula. Подробнее см. http://en.wikipedia.org/wiki/Vincenty's_formulae. Используя его, вы можете получить точность 0,5 мм для модели сфероида.

Нет идеальной формулы, так как реальная форма Земли слишком сложна, чтобы ее можно было выразить формулой. Кроме того, форма Земли изменяется из-за климатических событий (см. http://www.nasa.gov/centers/goddard/earthandsun/earthshape.html), а также изменяется со временем из-за вращения Земли.

Следует также отметить, что метод, приведенный выше, не учитывает высоты и предполагает сплюснутый сфероид на уровне моря.

Edit 10-Jul-2010: Я выяснил, что существуют редкие ситуации, в которых обратная формула Винценти не сходится к заявленной точности. Лучше всего использовать GeographicLib (см. http://sourceforge.net/projects/geographiclib/), что также более точно.

Ответ 2

Здесь один: http://www.movable-type.co.uk/scripts/latlong.html

Использование формулы Хаверсина:

R = earth’s radius (mean radius = 6,371km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c 

Ответ 3

Примените формулу Хаверсина, чтобы найти расстояние. См. Ниже код С#, чтобы найти расстояние между двумя координатами. Еще лучше, если вы хотите сказать, что найти список магазинов в определенном радиусе, вы можете применить предложение WHERE в SQL или фильтр LINQ на С#.

Формула здесь находится в километрах, вам нужно будет изменить соответствующие числа, и она будет работать на мили.

Например: Преобразовать 6371.392896 в мили.

    DECLARE @radiusInKm AS FLOAT
    DECLARE @lat2Compare AS FLOAT
    DECLARE @long2Compare AS FLOAT
    SET @radiusInKm = 5.000
    SET @lat2Compare = insert_your_lat_to_compare_here
    SET @long2Compare = insert_you_long_to_compare_here

    SELECT * FROM insert_your_table_here WITH(NOLOCK)
    WHERE (6371.392896*2*ATN2(SQRT((sin((radians(GeoLatitude - @lat2Compare)) / 2) * sin((radians(GeoLatitude - @lat2Compare)) / 2)) + (cos(radians(GeoLatitude)) * cos(radians(@lat2Compare)) * sin(radians(GeoLongitude - @long2Compare)/2) * sin(radians(GeoLongitude - @long2Compare)/2)))
    , SQRT(1-((sin((radians(GeoLatitude - @lat2Compare)) / 2) * sin((radians(GeoLatitude - @lat2Compare)) / 2)) + (cos(radians(GeoLatitude)) * cos(radians(@lat2Compare)) * sin(radians(GeoLongitude - @long2Compare)/2) * sin(radians(GeoLongitude - @long2Compare)/2)))
    ))) <= @radiusInKm

Если вы хотите выполнить формулу Хаверсина в С#,

    double resultDistance = 0.0;
    double avgRadiusOfEarth = 6371.392896; //Radius of the earth differ, I'm taking the average.

    //Haversine formula
    //distance = R * 2 * aTan2 ( square root of A, square root of 1 - A )
    //                   where A = sinus squared (difference in latitude / 2) + (cosine of latitude 1 * cosine of latitude 2 * sinus squared (difference in longitude / 2))
    //                   and R = the circumference of the earth

    double differenceInLat = DegreeToRadian(currentLatitude - latitudeToCompare);
    double differenceInLong = DegreeToRadian(currentLongitude - longtitudeToCompare);
    double aInnerFormula = Math.Cos(DegreeToRadian(currentLatitude)) * Math.Cos(DegreeToRadian(latitudeToCompare)) * Math.Sin(differenceInLong / 2) * Math.Sin(differenceInLong / 2);
    double aFormula = (Math.Sin((differenceInLat) / 2) * Math.Sin((differenceInLat) / 2)) + (aInnerFormula);
    resultDistance = avgRadiusOfEarth * 2 * Math.Atan2(Math.Sqrt(aFormula), Math.Sqrt(1 - aFormula));

DegreesToRadian - это функция, созданная пользователем, ее простой 1 лайнер "Math.PI * angle / 180.0

Моя запись в блоге - SQL Haversine

Ответ 4

Вы ищете

Формула Хаверсина

Формула Хаверсина - это уравнение важно в навигации, давая большие расстояния между двумя точки на сфере от их долготы и широты. Это частный случай более общей формулы в сферической тригонометрии, закон haversines, касающиеся сторон и углы сферических "треугольников".

Ответ 7

Эта ссылка содержит всю необходимую информацию, либо на ней, либо на ссылку.

Ответ 8

здесь есть сценарий поиска местоположений/близких мест к длине/лат по заданному IP:

http://jsfiddle.net/bassta/zrgd9qc3/2/

И вот функция, которую я использую для вычисления расстояния по прямой:

function distance(lat1, lng1, lat2, lng2) {
        var radlat1 = Math.PI * lat1 / 180;
        var radlat2 = Math.PI * lat2 / 180;
        var radlon1 = Math.PI * lng1 / 180;
        var radlon2 = Math.PI * lng2 / 180;
        var theta = lng1 - lng2;
        var radtheta = Math.PI * theta / 180;
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        dist = Math.acos(dist);
        dist = dist * 180 / Math.PI;
        dist = dist * 60 * 1.1515;

        //Get in in kilometers
        dist = dist * 1.609344;

        return dist;
    }

Он возвращает расстояние в километрах

Ответ 10

Ниже приведен модуль (закодированный в f90), содержащий три формулы, обсуждавшиеся в предыдущих ответах. Вы можете разместить этот модуль в верхней части своей программы (до PROGRAM MAIN) или скомпилировать его отдельно и включить каталог модуля во время компиляции.

module spherical_dists
contains
subroutine haversine_formula(lon1,lat1,lon2,lat2,dist)
implicit none
real,intent(in)::lon1,lon2,lat1,lat2
real,intent(out)::dist
real,parameter::pi=3.141592,mean_earth_radius=6371.0088
real::lonr1,lonr2,latr1,latr2
real::delangl,dellon,dellat,a
lonr1=lon1*(pi/180.);lonr2=lon2*(pi/180.)
latr1=lat1*(pi/180.);latr2=lat2*(pi/180.)
dellon=lonr2-lonr1
dellat=latr2-latr1
a=(sin(dellat/2))**2+cos(latr1)*cos(latr2)*(sin(dellon/2))**2
delangl=2*asin(sqrt(a)) !2*asin(sqrt(a))
dist=delangl*mean_earth_radius
end subroutine
subroutine great_circle_distance(lon1,lat1,lon2,lat2,dist)
implicit none
real,intent(in)::lon1,lon2,lat1,lat2
real,intent(out)::dist
real,parameter::pi=3.141592,mean_earth_radius=6371.0088
real::lonr1,lonr2,latr1,latr2
real::delangl,dellon
lonr1=lon1*(pi/180.);lonr2=lon2*(pi/180.)
latr1=lat1*(pi/180.);latr2=lat2*(pi/180.)
dellon=lonr2-lonr1
delangl=acos(sin(latr1)*sin(latr2)+cos(latr1)*cos(latr2)*cos(dellon))
dist=delangl*mean_earth_radius
end subroutine
subroutine vincenty_formula(lon1,lat1,lon2,lat2,dist)
implicit none
real,intent(in)::lon1,lon2,lat1,lat2
real,intent(out)::dist
real,parameter::pi=3.141592,mean_earth_radius=6371.0088
real::lonr1,lonr2,latr1,latr2
real::delangl,dellon,nom,denom
lonr1=lon1*(pi/180.);lonr2=lon2*(pi/180.)
latr1=lat1*(pi/180.);latr2=lat2*(pi/180.)
dellon=lonr2-lonr1
nom=sqrt((cos(latr2)*sin(dellon))**2. + (cos(latr1)*sin(latr2)-sin(latr1)*cos(latr2)*cos(dellon))**2.)
denom=sin(latr1)*sin(latr2)+cos(latr1)*cos(latr2)*cos(dellon)
delangl=atan2(nom,denom)
dist=delangl*mean_earth_radius
end subroutine
end module

Ответ 11

Я выполнил SQL-запрос

select, (acos (sin (input_lat 0.01745329) * sin (ширина * 0.01745329) + cos (input_lat * 0.01745329) * cos (ширина * 0.01745329) * cos ((input_long -longitude) 0.01745329)) 57.29577951) * 69.16 As D из table_name

Ответ 12

просто используйте формулу расстояния Sqrt( (x2-x1)^2 + (y2-y1)^2 )