Calcular a distância entre dois pontos de latitude e longitude? (Fórmula de Haversine)

Como faço para calcular a distância entre dois pontos especificados por latitude e longitude?

Para esclarecimento, eu gostaria da distância em quilômetros; os pontos usam o sistema WGS84 e eu gostaria de entender as precisões relativas das abordagens disponíveis.

Esse link pode ser útil para você, pois detalha o uso da fórmula de Haversine para calcular a distância.

Excerto:

Este script [em Javascript] calcula as distâncias dos grandes círculos entre os dois pontos – isto é, a menor distância sobre a superfície da Terra – usando a fórmula ‘Haversine’.

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) } 

Eu precisava calcular muitas distâncias entre os pontos do meu projeto, então fui em frente e tentei otimizar o código, eu encontrei aqui. Em média, em diferentes navegadores, minha nova implementação é executada duas vezes mais rápido que a resposta mais votada.

 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 } 

Você pode jogar com o meu jsPerf e ver os resultados aqui .

Recentemente eu precisei fazer o mesmo em python, então aqui está uma implementação em 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... 

E por uma questão de completude: Haversine no wiki.

Aqui está uma implementação do C #:

 static class DistanceAlgorithm { const double PIx = 3.141592653589793; const double RADIUS = 6378.16; ///  /// Convert degrees to Radians ///  /// Degrees /// The equivalent in radians public static double Radians(double x) { return x * PIx / 180; } ///  /// Calculate the distance between two places. ///  ///  ///  ///  ///  ///  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; } 

Aqui está uma implementação java da fórmula 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)); } 

Note que aqui estamos arredondando a resposta para o km mais próximo.

Muito obrigado por tudo isso. Eu usei o seguinte código no meu aplicativo para iPhone Objective-C:

 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; } 

Latitude e Longitude estão em decimal. Eu não usei min () para a chamada asin (), pois as distâncias que estou usando são tão pequenas que elas não exigem isso.

Deu respostas incorretas até que eu passei os valores em radianos – agora é praticamente o mesmo que os valores obtidos do aplicativo Map da Apple 🙂

Atualização extra:

Se você estiver usando o iOS4 ou posterior, a Apple fornecerá alguns methods para isso, para que a mesma funcionalidade seja obtida com:

 -(double)kilometresBetweenPlace1:(CLLocationCoordinate2D) place1 andPlace2:(CLLocationCoordinate2D) place2 { MKMapPoint start, finish; start = MKMapPointForCoordinate(place1); finish = MKMapPointForCoordinate(place2); return MKMetersBetweenMapPoints(start, finish) / 1000; } 

Esta é uma function PHP simples que dará uma aproximação muito razoável (abaixo de +/- 1% de margem de erro).

 < ?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 '
'.$km; return $km; } ?>

Como dito antes; a terra não é uma esfera. É como um velho e antigo beisebol com o qual Mark McGwire decidiu praticar – está cheio de amolgadelas e solavancos. Os cálculos mais simples (como este) tratam-no como uma esfera.

Diferentes methods podem ser mais ou menos precisos de acordo com o local onde você está neste irregular ovóide e quão distantes estão os seus pontos (quanto mais próximos estiverem, menor a margem de erro absoluto). Quanto mais precisa sua expectativa, mais complexa é a matemática.

Para mais informações: distância geográfica wikipedia

Eu posto aqui meu exemplo de trabalho.

Listar todos os pontos na tabela com distância entre um ponto designado (usamos um ponto random – lat: 45.20327, long: 23.7806) menor que 50 KM, com latitude e longitude, no MySQL (os campos da tabela são coord_lat e coord_long):

Listar todos tendo DISTANCE <50, em Quilômetros (considerados como raio da terra 6371 KM):

 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 

O exemplo acima foi testado no MySQL 5.0.95 e 5.5.16 (Linux).

Nas outras respostas, uma implementação em r está faltando.

Calcular a distância entre dois pontos é bastante simples com a function distm do pacote da geosphere :

 distm(p1, p2, fun = distHaversine) 

Onde:

 p1 = longitude/latitude for point(s) p2 = longitude/latitude for point(s) # type of distance calculation fun = distCosine / distHaversine / distVincentySphere / distVincentyEllipsoid 

Como a Terra não é perfeitamente esférica, a fórmula Vincenty para elipsóides é provavelmente a melhor maneira de calcular distâncias. Assim, no pacote da geosphere , você usa então:

 distm(p1, p2, fun = distVincentyEllipsoid) 

Claro que você não precisa necessariamente usar o pacote geosphere , você também pode calcular a distância na base R com uma function:

 hav.dist < - function(long1, lat1, long2, lat2) { R <- 6371 diff.long <- (long2 - long1) diff.lat <- (lat2 - lat1) a <- sin(diff.lat/2)^2 + cos(lat1) * cos(lat2) * sin(diff.long/2)^2 b <- 2 * asin(pmin(1, sqrt(a))) d = R * b return(d) } 

Você pode usar a construção em CLLocationDistance para calcular isso:

 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; } 

No seu caso, se você quiser quilômetros, basta dividir por 1000.

O haversine é definitivamente uma boa fórmula para provavelmente a maioria dos casos, outras respostas já incluem, então eu não vou tomar o espaço. Mas é importante notar que não importa qual fórmula é usada (sim, não apenas uma). Devido à enorme variedade de precisão possível, bem como o tempo de computação necessário. A escolha da fórmula requer um pouco mais de reflection do que uma simples resposta simples.

Esta postagem de uma pessoa na NASA é a melhor que encontrei para discutir as opções

http://www.cs.nyu.edu/visual/home/proj/tiger/gisfaq.html

Por exemplo, se você está apenas classificando linhas por distância em um raio de 100 milhas. A fórmula da terra plana será muito mais rápida do que a haversina.

 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; 

Observe que há apenas um cosseno e uma raiz quadrada. Vs 9 deles na fórmula de Haversine.

Não gosto de adicionar mais uma resposta, mas a API de mapas do Google v.3 tem geometry esférica (e mais). Depois de converter seu WGS84 em graus decimais, você pode fazer isso:

  distance = google.maps.geometry.spherical.computeDistanceBetween( new google.maps.LatLng(fromLat, fromLng), new google.maps.LatLng(toLat, toLng)); 

Nenhuma palavra sobre como os cálculos do Google são precisos ou até mesmo qual modelo é usado (embora ele diga “esférico” em vez de “geóide”. A propósito, a distância “em linha reta” obviamente será diferente da distância se a pessoa viajar no superfície da terra que é o que todo mundo parece estar presumindo.

Em vez disso, depende de quão preciso você quer ser e de qual dado o lat e long estão definidos. Muito, muito aproximadamente você faz um pequeno gatilho esférico, mas corrigir pelo fato de que a terra não é uma esfera torna as fórmulas mais complicadas.

Poderia haver uma solução mais simples e mais correta: o perímetro da Terra é de 40.000 km no equador, cerca de 37.000 no ciclo de Greenwich (ou qualquer longitude). Portanto:

 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)); }; 

Eu concordo que deve ser ajustado como, eu mesmo disse que é um elipsóide, então o raio a ser multiplicado pelo cosseno varia. Mas é um pouco mais preciso. Comparado com o Google Maps e reduziu significativamente o erro.

Todas as respostas acima assumem que a terra é uma esfera. No entanto, uma aproximação mais precisa seria a de um esferóide oblato.

 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 

Para calcular a distância entre dois pontos em uma esfera, você precisa fazer o cálculo do Grande Círculo .

Há várias bibliotecas C / C ++ para ajudar na projeção de mapa no MapTools se você precisar reprojetar suas distâncias para uma superfície plana. Para fazer isso, você precisará da sequência de projeção dos vários sistemas de coordenadas.

Você também pode encontrar o MapWindow como uma ferramenta útil para visualizar os pontos. Também como seu código aberto é um guia útil sobre como usar a biblioteca proj.dll, que parece ser a principal biblioteca de projeção de código aberto.

Implantação Python A origem é o centro dos Estados Unidos contíguos.

 from haversine import haversine origin = (39.50, 98.35) paris = (48.8567, 2.3508) haversine(origin, paris, miles=True) 

Para obter a resposta em quilômetros, basta definir milhas = falso.

Aqui está uma implementação datilografada da fórmula de Haversine

 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; } 

Este script [em PHP] calcula distâncias entre os dois pontos.

 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; } } 

Eu resumi o cálculo simplificando a fórmula.

Aqui está em 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 

Aqui está a implementação de resposta aceita portada para Java no caso de alguém precisar dela.

 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. * 

* 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); }

há um bom exemplo aqui para calcular a distância com 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; } } 

Aqui está a implementação VB.NET, esta implementação lhe dará o resultado em KM ou Miles com base em um valor de Enum que você passar.

 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 

Aqui está a minha implementação de java para a distância de cálculo através de graus decimais depois de alguma pesquisa. Eu usei raio médio do mundo (da wikipedia) em km. Se você quiser milhas de resultado, use o raio mundial em milhas.

 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; } 

No Mysql use a seguinte function passar os parâmetros como usando 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} )); 

aqui está um exemplo em postgres sql (em km, para versão de milhas, substitua 1.609344 pela versão 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; 

Como apontado, um cálculo preciso deve levar em conta que a Terra não é uma esfera perfeita. Aqui estão algumas comparações dos vários algoritmos oferecidos aqui:

 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 

Em pequenas distâncias, o algoritmo de Keerthana parece coincidir com o do Google Maps. O Google Maps parece não seguir nenhum algoritmo simples, sugerindo que pode ser o método mais preciso aqui.

Enfim, aqui está uma implementação de Javascript do algoritmo de 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)); } 

Aqui está uma function javascript simples que pode ser útil a partir deste link .. de alguma forma relacionada, mas estamos usando o plugin javascript do Google Earth em vez de mapas

 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); } 

As unidades não estão na distância, mas em termos de uma relação em relação às suas coordenadas. Existem outros cálculos relacionados que você pode replace o link da function getApproximateDistanceUnits aqui

Então eu uso essa function para ver se uma longitude de latitude está dentro do raio

 function isMapPlacemarkInRadius(point1, point2, radi) { if (point1 && point2) { return getApproximateDistanceUnits(point1, point2) < = radi; } else { return 0; } } 

ponto pode ser definido como

  $$.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; }; 

então você pode fazer sua coisa para ver se um ponto está dentro de uma região com um raio dizer:

  //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; }} 

A solução de Chuck, válida também para milhas.

 //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; }