Рассчитать расстояние между двумя точками широты-долготы? (Формула гаверсинуса )
Как рассчитать расстояние между двумя точками, указанными широтой и долготой?
для уточнения я хотел бы расстояние в километрах; точки используют систему WGS84, и я хотел бы понять относительную точность доступных подходов.
30 ответов:
этой ссылке может быть полезно для вас, так как он подробно описывает использование формула Гаверсинуса для расчета расстояния.
выдержка:
этот скрипт [в Javascript] вычисляет расстояния большого круга между двумя точками – то есть самое короткое расстояние над поверхностью земли-с помощью ‘Гаверсинус формула.
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) { var R = 6371; // Radius of the earth in km var dLat = deg2rad(lat2-lat1); // deg2rad below var dLon = deg2rad(lon2-lon1); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon/2) * Math.sin(dLon/2) ; var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = R * c; // Distance in km return d; } function deg2rad(deg) { return deg * (Math.PI/180) }
мне нужно было рассчитать много расстояний между точками для моего проекта, поэтому я пошел вперед и попытался оптимизировать код, который я нашел здесь. В среднем в разных браузерах моя новая реализация работает в 2 раза быстрее чем самый популярный ответ.
function distance(lat1, lon1, lat2, lon2) { var p = 0.017453292519943295; // Math.PI / 180 var c = Math.cos; var a = 0.5 - c((lat2 - lat1) * p)/2 + c(lat1 * p) * c(lat2 * p) * (1 - c((lon2 - lon1) * p))/2; return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km }вы можете играть с моим jsPerf и увидеть здесь.
недавно мне нужно было сделать то же самое в python, так что вот python реализация:
from math import cos, asin, sqrt def distance(lat1, lon1, lat2, lon2): p = 0.017453292519943295 #Pi/180 a = 0.5 - cos((lat2 - lat1) * p)/2 + cos(lat1 * p) * cos(lat2 * p) * (1 - cos((lon2 - lon1) * p)) / 2 return 12742 * asin(sqrt(a)) #2*R*asin...и для полноты картины: Haversine на вики.
вот реализация C#:
static class DistanceAlgorithm { const double PIx = 3.141592653589793; const double RADIUS = 6378.16; /// <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 * RADIUS; }
вот реализация java формулы Haversine.
public final static double AVERAGE_RADIUS_OF_EARTH_KM = 6371; public int calculateDistanceInKilometer(double userLat, double userLng, double venueLat, double venueLng) { double latDistance = Math.toRadians(userLat - venueLat); double lngDistance = Math.toRadians(userLng - venueLng); double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) + Math.cos(Math.toRadians(userLat)) * Math.cos(Math.toRadians(venueLat)) * Math.sin(lngDistance / 2) * Math.sin(lngDistance / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return (int) (Math.round(AVERAGE_RADIUS_OF_EARTH_KM * c)); }обратите внимание, что здесь мы округляем ответ до ближайшего километра.
большое спасибо за все это. Я использовал следующий код в моем приложении Objective-C iPhone:
const double PIx = 3.141592653589793; const double RADIO = 6371; // Mean radius of Earth in Km double convertToRadians(double val) { return val * PIx / 180; } -(double)kilometresBetweenPlace1:(CLLocationCoordinate2D) place1 andPlace2:(CLLocationCoordinate2D) place2 { double dlon = convertToRadians(place2.longitude - place1.longitude); double dlat = convertToRadians(place2.latitude - place1.latitude); double a = ( pow(sin(dlat / 2), 2) + cos(convertToRadians(place1.latitude))) * cos(convertToRadians(place2.latitude)) * pow(sin(dlon / 2), 2); double angle = 2 * asin(sqrt(a)); return angle * RADIO; }широта и долгота указаны в десятичной системе счисления. Я не использовал min() для вызова asin (), поскольку расстояния, которые я использую, настолько малы, что они не требуют этого.
Он дал неправильные ответы, пока я не передал значения в радианах-теперь это почти то же самое, что и значения, полученные из приложения Карты Apple :-)
дополнительные обновления:
Если вы не используя iOS4 или более позднюю версию, Apple предоставляет некоторые методы для этого, чтобы та же функциональность была достигнута с помощью:
-(double)kilometresBetweenPlace1:(CLLocationCoordinate2D) place1 andPlace2:(CLLocationCoordinate2D) place2 { MKMapPoint start, finish; start = MKMapPointForCoordinate(place1); finish = MKMapPointForCoordinate(place2); return MKMetersBetweenMapPoints(start, finish) / 1000; }
это простая функция PHP, которая даст очень разумное приближение (при + / -1% погрешности).
<?php function distance($lat1, $lon1, $lat2, $lon2) { $pi80 = M_PI / 180; $lat1 *= $pi80; $lon1 *= $pi80; $lat2 *= $pi80; $lon2 *= $pi80; $r = 6372.797; // mean radius of Earth in km $dlat = $lat2 - $lat1; $dlon = $lon2 - $lon1; $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlon / 2) * sin($dlon / 2); $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); $km = $r * $c; //echo '<br/>'.$km; return $km; } ?>Как уже было сказано, земля не является сферой. Это похоже на старый, старый бейсбол, с которым Марк Макгвайр решил попрактиковаться - он полон вмятин и ударов. Более простые вычисления (как это) рассматривают его как сферу.
различные методы могут быть более или менее точными в зависимости от того, где вы находитесь на этом нерегулярном яйце и как далеко друг от друга ваш точки (чем ближе они находятся, тем меньше абсолютная погрешность). Чем точнее ваши ожидания, тем сложнее математика.
дополнительная информация: wikipedia географическое расстояние
Я размещаю здесь мой рабочий пример.
перечислите все точки в таблице, имеющие расстояние между назначенной точкой (мы используем случайную точку-lat: 45.20327, long: 23.7806) менее 50 км, с широтой и долготой, в MySQL (поля таблицы coord_lat и coord_long):
перечислите все имеющие расстояние
SELECT denumire, (6371 * acos( cos( radians(45.20327) ) * cos( radians( coord_lat ) ) * cos( radians( 23.7806 ) - radians(coord_long) ) + sin( radians(45.20327) ) * sin( radians(coord_lat) ) )) AS distanta FROM obiective WHERE coord_lat<>'' AND coord_long<>'' HAVING distanta<50 ORDER BY distanta descприведенный выше пример был протестирован в MySQL 5.0.95 и 5.5.16 (Linux).
в других ответах реализация в r отсутствует.
расчет расстояния между двумя точками довольно прост с
вы можете использовать сборку в CLLocationDistance для вычисления этого:
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:latitude1 longitude:longitude1]; CLLocation *location2 = [[CLLocation alloc] initWithLatitude:latitude2 longitude:longitude2]; [self distanceInMetersFromLocation:location1 toLocation:location2] - (int)distanceInMetersFromLocation:(CLLocation*)location1 toLocation:(CLLocation*)location2 { CLLocationDistance distanceInMeters = [location1 distanceFromLocation:location2]; return distanceInMeters; }в вашем случае, если вы хотите, километров просто разделить на 1000.
haversine определенно является хорошей формулой для, вероятно, большинства случаев, другие ответы уже включают его, поэтому я не собираюсь брать пространство. Но важно отметить, что неважно какая формула используется (да не один). Из-за огромного диапазона возможной точности, а также требуемого времени вычисления. Выбор формулы требует немного больше размышлений, чем простой ответ без проблем.
это сообщение от человека в НАСА, является лучшим, что я нашел при обсуждении варианты
http://www.cs.nyu.edu/visual/home/proj/tiger/gisfaq.html
например, если вы просто сортируете строки по расстоянию в радиусе 100 миль. Формула плоской Земли будет намного быстрее, чем haversine.
HalfPi = 1.5707963; R = 3956; /* the radius gives you the measurement unit*/ a = HalfPi - latoriginrad; b = HalfPi - latdestrad; u = a * a + b * b; v = - 2 * a * b * cos(longdestrad - longoriginrad); c = sqrt(abs(u + v)); return R * c;обратите внимание, есть только один Косинус и квадратный корень. Против 9 из них на формула Гаверсинуса.
Я не люблю добавлять еще один ответ, но карты Google API версии 3 имеет сферическую геометрию (и более). После преобразования WGS84 в десятичные Градусы вы можете сделать это:
<script src="http://maps.google.com/maps/api/js?sensor=false&libraries=geometry" type="text/javascript"></script> distance = google.maps.geometry.spherical.computeDistanceBetween( new google.maps.LatLng(fromLat, fromLng), new google.maps.LatLng(toLat, toLng));ни слова о том, насколько точны вычисления Google или даже какая модель используется (хотя она говорит "сферическая", а не "геоид". Кстати, расстояние "прямой линии", очевидно, будет отличаться от расстояния, если вы путешествуете по поверхности Земли, что кажется всем чтобы быть самонадеянным.
Это скорее зависит от того, насколько точно вы хотите быть и что datum lat и long определяются on. Очень, очень приблизительно вы делаете небольшую сферическую тригонометрию, но поправка на то, что Земля не является сферой, делает формулы более сложными.
может быть более простое решение и более правильное: периметр Земли составляет 40 000 км на экваторе, около 37 000 на Гринвичском (или любом долготном) цикле. Таким образом:
pythagoras = function (lat1, lon1, lat2, lon2) { function sqr(x) {return x * x;} function cosDeg(x) {return Math.cos(x * Math.PI / 180.0);} var earthCyclePerimeter = 40000000.0 * cosDeg((lat1 + lat2) / 2.0); var dx = (lon1 - lon2) * earthCyclePerimeter / 360.0; var dy = 37000000.0 * (lat1 - lat2) / 360.0; return Math.sqrt(sqr(dx) + sqr(dy)); };Я согласен, что он должен быть точно настроен, поскольку я сам сказал, что это эллипсоид, поэтому радиус, который нужно умножить на косинус, меняется. Но это немного точнее. По сравнению с Google Maps, и это значительно уменьшило ошибку.
здесь typescript реализации формула Гаверсинуса
static getDistanceFromLatLonInKm(lat1: number, lon1: number, lat2: number, lon2: number): number { var deg2Rad = deg => { return deg * Math.PI / 180; } var r = 6371; // Radius of the earth in km var dLat = deg2Rad(lat2 - lat1); var dLon = deg2Rad(lon2 - lon1); var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2Rad(lat1)) * Math.cos(deg2Rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); var d = r * c; // Distance in km return d; }
все вышеприведенные ответы предполагают, что Земля является сферой. Однако более точным приближением был бы сплюснутый сфероид.
a= 6378.137#equitorial radius in km b= 6356.752#polar radius in km def Distance(lat1, lons1, lat2, lons2): lat1=math.radians(lat1) lons1=math.radians(lons1) R1=(((((a**2)*math.cos(lat1))**2)+(((b**2)*math.sin(lat1))**2))/((a*math.cos(lat1))**2+(b*math.sin(lat1))**2))**0.5 #radius of earth at lat1 x1=R*math.cos(lat1)*math.cos(lons1) y1=R*math.cos(lat1)*math.sin(lons1) z1=R*math.sin(lat1) lat2=math.radians(lat2) lons2=math.radians(lons2) R1=(((((a**2)*math.cos(lat2))**2)+(((b**2)*math.sin(lat2))**2))/((a*math.cos(lat2))**2+(b*math.sin(lat2))**2))**0.5 #radius of earth at lat2 x2=R*math.cos(lat2)*math.cos(lons2) y2=R*math.cos(lat2)*math.sin(lons2) z2=R*math.sin(lat2) return ((x1-x2)**2+(y1-y2)**2+(z1-z2)**2)**0.5
чтобы вычислить расстояние между двумя точками на сфере, вам нужно сделать вычисление Большого Круга.
есть ряд библиотек C/C++, чтобы помочь с проекцией карты в MapTools Если вам нужно перепроектировать ваши расстояния до плоской поверхности. Для этого вам понадобится проекционная строка из различных систем координат.
вы можете найти MapWindow полезный инструмент для визуализации точек. Также как и его с открытым исходным кодом это полезное руководство по использованию proj.библиотека dll, которая, по-видимому, является основной библиотекой проекций с открытым исходным кодом.
имплиментация Python Происхождение-центр смежных Соединенных Штатов.
from haversine import haversine origin = (39.50, 98.35) paris = (48.8567, 2.3508) haversine(origin, paris, miles=True)чтобы получить ответ в километрах просто установите miles=false.
этот скрипт [в PHP] вычисляет расстояния между двумя точками.
public static function getDistanceOfTwoPoints($source, $dest, $unit='K') { $lat1 = $source[0]; $lon1 = $source[1]; $lat2 = $dest[0]; $lon2 = $dest[1]; $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 == "M") { return ($miles * 1.609344 * 1000); } else if ($unit == "N") { return ($miles * 0.8684); } else { return $miles; } }
я сократил вычисление, упростив формулу.
вот он в Ruby:
include Math earth_radius_mi = 3959 radians = lambda { |deg| deg * PI / 180 } coord_radians = lambda { |c| { :lat => radians[c[:lat]], :lng => radians[c[:lng]] } } # from/to = { :lat => (latitude_in_degrees), :lng => (longitude_in_degrees) } def haversine_distance(from, to) from, to = coord_radians[from], coord_radians[to] cosines_product = cos(to[:lat]) * cos(from[:lat]) * cos(from[:lng] - to[:lng]) sines_product = sin(to[:lat]) * sin(from[:lat]) return earth_radius_mi * acos(cosines_product + sines_product) end
вот принятая реализация ответа, перенесенная на Java, если кому-то это нужно.
package com.project529.garage.util; /** * Mean radius. */ private static double EARTH_RADIUS = 6371; /** * Returns the distance between two sets of latitudes and longitudes in meters. * <p/> * Based from the following JavaScript SO answer: * http://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula, * which is based on https://en.wikipedia.org/wiki/Haversine_formula (error rate: ~0.55%). */ public double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) { double dLat = toRadians(lat2 - lat1); double dLon = toRadians(lon2 - lon1); double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); double d = EARTH_RADIUS * c; return d; } public double toRadians(double degrees) { return degrees * (Math.PI / 180); }
здесь есть хороший пример для расчета расстояния с помощью PHP http://www.geodatasource.com/developers/php:
function distance($lat1, $lon1, $lat2, $lon2, $unit) { $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; } }
вот реализация VB.NET, эта реализация даст вам результат в КМ или милях на основе значения перечисления, которое вы передаете.
Public Enum DistanceType Miles KiloMeters End Enum Public Structure Position Public Latitude As Double Public Longitude As Double End Structure Public Class Haversine Public Function Distance(Pos1 As Position, Pos2 As Position, DistType As DistanceType) As Double Dim R As Double = If((DistType = DistanceType.Miles), 3960, 6371) Dim dLat As Double = Me.toRadian(Pos2.Latitude - Pos1.Latitude) Dim dLon As Double = Me.toRadian(Pos2.Longitude - Pos1.Longitude) Dim a As Double = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(Me.toRadian(Pos1.Latitude)) * Math.Cos(Me.toRadian(Pos2.Latitude)) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2) Dim c As Double = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a))) Dim result As Double = R * c Return result End Function Private Function toRadian(val As Double) As Double Return (Math.PI / 180) * val End Function End Class
вот моя реализация java для вычисления расстояния через десятичные Градусы после некоторого поиска. Я использовал средний радиус мира (из Википедии) В км. Если вы хотите получить результат миль, то используйте мировой радиус в милях.
public static double distanceLatLong2(double lat1, double lng1, double lat2, double lng2) { double earthRadius = 6371.0d; // KM: use mile here if you want mile result double dLat = toRadian(lat2 - lat1); double dLng = toRadian(lng2 - lng1); double a = Math.pow(Math.sin(dLat/2), 2) + Math.cos(toRadian(lat1)) * Math.cos(toRadian(lat2)) * Math.pow(Math.sin(dLng/2), 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); return earthRadius * c; // returns result kilometers } public static double toRadian(double degrees) { return (degrees * Math.PI) / 180.0d; }
в Mysql используйте следующую функцию передать параметры как с помощью
POINT(LONG,LAT)CREATE FUNCTION `distance`(a POINT, b POINT) RETURNS double DETERMINISTIC BEGIN RETURN GLength( LineString(( PointFromWKB(a)), (PointFromWKB(b)))) * 100000; -- To Make the distance in meters END;
function getDistanceFromLatLonInKm(position1, position2) { "use strict"; var deg2rad = function (deg) { return deg * (Math.PI / 180); }, R = 6371, dLat = deg2rad(position2.lat - position1.lat), dLng = deg2rad(position2.lng - position1.lng), a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad(position1.lat)) * Math.cos(deg2rad(position1.lat)) * Math.sin(dLng / 2) * Math.sin(dLng / 2), c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; } console.log(getDistanceFromLatLonInKm( {lat: 48.7931459, lng: 1.9483572}, {lat: 48.827167, lng: 2.2459745} ));
вот пример postgres sql (в КМ, для версии миль, заменить 1.609344 на 0.8684 версии)
CREATE OR REPLACE FUNCTION public.geodistance(alat float, alng float, blat float, blng float) RETURNS float AS $BODY$ DECLARE v_distance float; BEGIN v_distance = asin( sqrt( sin(radians(blat-alat)/2)^2 + ( (sin(radians(blng-alng)/2)^2) * cos(radians(alat)) * cos(radians(blat)) ) ) ) * cast('7926.3352' as float) * cast('1.609344' as float) ; RETURN v_distance; END $BODY$ language plpgsql VOLATILE SECURITY DEFINER; alter function geodistance(alat float, alng float, blat float, blng float) owner to postgres;
geoDistance(50,5,58,3) Haversine: 899 km Maymenn: 833 km Keerthana: 897 km google.maps.geometry.spherical.computeDistanceBetween(): 900 km geoDistance(50,5,-58,-3) Haversine: 12030 km Maymenn: 11135 km Keerthana: 10310 km google.maps.geometry.spherical.computeDistanceBetween(): 12044 km geoDistance(.05,.005,.058,.003) Haversine: 0.9169 km Maymenn: 0.851723 km Keerthana: 0.917964 km google.maps.geometry.spherical.computeDistanceBetween(): 0.917964 km geoDistance(.05,80,.058,80.3) Haversine: 33.37 km Maymenn: 33.34 km Keerthana: 33.40767 km google.maps.geometry.spherical.computeDistanceBetween(): 33.40770 kmна небольших расстояниях алгоритм Киртаны, похоже, совпадает с алгоритмом Google Maps. Google Maps, похоже, не следует какому-либо простому алгоритму, предполагая, что это может быть самый точный метод здесь.
в любом случае, вот реализация Javascript Keerthana алгоритм:
function geoDistance(lat1, lng1, lat2, lng2){ const a = 6378.137; // equitorial radius in km const b = 6356.752; // polar radius in km var sq = x => (x*x); var sqr = x => Math.sqrt(x); var cos = x => Math.cos(x); var sin = x => Math.sin(x); var radius = lat => sqr((sq(a*a*cos(lat))+sq(b*b*sin(lat)))/(sq(a*cos(lat))+sq(b*sin(lat)))); lat1 = lat1 * Math.PI / 180; lng1 = lng1 * Math.PI / 180; lat2 = lat2 * Math.PI / 180; lng2 = lng2 * Math.PI / 180; var R1 = radius(lat1); var x1 = R1*cos(lat1)*cos(lng1); var y1 = R1*cos(lat1)*sin(lng1); var z1 = R1*sin(lat1); var R2 = radius(lat2); var x2 = R2*cos(lat2)*cos(lng2); var y2 = R2*cos(lat2)*sin(lng2); var z2 = R2*sin(lat2); return sqr(sq(x1-x2)+sq(y1-y2)+sq(z1-z2)); }
вот простая функция javascript, которая может быть полезна из этого ссылке.. как-то связано, но мы используем плагин Google earth javascript вместо maps
function getApproximateDistanceUnits(point1, point2) { var xs = 0; var ys = 0; xs = point2.getX() - point1.getX(); xs = xs * xs; ys = point2.getY() - point1.getY(); ys = ys * ys; return Math.sqrt(xs + ys); }единицы tho находятся не на расстоянии, а с точки зрения отношения относительно ваших координат. Есть и другие вычисления, связанные вы можете заменить функцию getApproximateDistanceUnits ссылка здесь
затем я использую эту функцию, чтобы увидеть, если долгота широта в радиусе
function isMapPlacemarkInRadius(point1, point2, radi) { if (point1 && point2) { return getApproximateDistanceUnits(point1, point2) <= radi; } else { return 0; } }точка может быть определена как
$$.getPoint = function(lati, longi) { var location = { x: 0, y: 0, getX: function() { return location.x; }, getY: function() { return location.y; } }; location.x = lati; location.y = longi; return location; };тогда вы можете сделать свое дело, чтобы увидеть, если точка находится в пределах области с радиусом сказать:
//put it on the map if within the range of a specified radi assuming 100,000,000 units var iconpoint = Map.getPoint(pp.latitude, pp.longitude); var centerpoint = Map.getPoint(Settings.CenterLatitude, Settings.CenterLongitude); //approx ~200 units to show only half of the globe from the default center radius if (isMapPlacemarkInRadius(centerpoint, iconpoint, 120)) { addPlacemark(pp.latitude, pp.longitude, pp.name); } else { otherSidePlacemarks.push({ latitude: pp.latitude, longitude: pp.longitude, name: pp.name }); }
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2,units) { var R = 6371; // Radius of the earth in km var dLat = deg2rad(lat2-lat1); // deg2rad below var dLon = deg2rad(lon2-lon1); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon/2) * Math.sin(dLon/2) ; var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = R * c; var miles = d / 1.609344; if ( units == 'km' ) { return d; } else { return miles; }}решение Чака, действительное и для миль.
//JAVA public Double getDistanceBetweenTwoPoints(Double latitude1, Double longitude1, Double latitude2, Double longitude2) { final int RADIUS_EARTH = 6371; double dLat = getRad(latitude2 - latitude1); double dLong = getRad(longitude2 - longitude1); double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(getRad(latitude1)) * Math.cos(getRad(latitude2)) * Math.sin(dLong / 2) * Math.sin(dLong / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return (RADIUS_EARTH * c) * 1000; } private Double getRad(Double x) { return x * Math.PI / 180; }
Comments