Comment convertir latitude ou longitude en mètres?
si j'ai une lecture de latitude ou de longitude en format NMEA standard, y a-t-il un moyen / une formule simple pour convertir cette lecture en mètres, que je peux ensuite implémenter en Java (J9)?
Edit: Ok semble ce que je veux faire n'est pas possible facilement , mais ce que je veux vraiment faire est:
Dire que j'ai un lat et long d'un chemin et d'un lat et long d'un utilisateur est-il un moyen facile de les comparer, afin de décider quand à dire la utilisateur ils sont dans un raisonnablement distance proche du point de passage? Je me rends compte raisonnable est sujet, mais est-ce facilement faisable ou encore trop mathématiques?
15 réponses
Voici une fonction javascript:
function measure(lat1, lon1, lat2, lon2){ // generally used geo measurement function
var R = 6378.137; // Radius of earth in KM
var dLat = lat2 * Math.PI / 180 - lat1 * Math.PI / 180;
var dLon = lon2 * Math.PI / 180 - lon1 * Math.PI / 180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d * 1000; // meters
}
explication: https://en.wikipedia.org/wiki/Haversine_formula
la formule de haversine détermine la distance du grand cercle entre deux points sur une sphère étant donné leurs longitude et latitudes.
pour l'approximation de courtes distances entre deux coordonnées j'ai utilisé des formules de http://en.wikipedia.org/wiki/Lat-lon :
m_per_deg_lat = 111132.954 - 559.822 * cos( 2 * latMid ) + 1.175 * cos( 4 * latMid);
m_per_deg_lon = 111132.954 * cos ( latMid );
.
dans le code ci-dessous j'ai laissé les nombres bruts pour montrer leur relation avec la formule de wikipedia.
double latMid, m_per_deg_lat, m_per_deg_lon, deltaLat, deltaLon,dist_m;
latMid = (Lat1+Lat2 )/2.0; // or just use Lat1 for slightly less accurate estimate
m_per_deg_lat = 111132.954 - 559.822 * cos( 2.0 * latMid ) + 1.175 * cos( 4.0 * latMid);
m_per_deg_lon = (3.14159265359/180 ) * 6367449 * cos ( latMid );
deltaLat = fabs(Lat1 - Lat2);
deltaLon = fabs(Lon1 - Lon2);
dist_m = sqrt ( pow( deltaLat * m_per_deg_lat,2) + pow( deltaLon * m_per_deg_lon , 2) );
l'entrée de wikipedia indique que la distance de calcul est dans 0.6 m Pour 100km longitudinalement et 1cm Pour 100km latitudinalement mais Je n'ai pas vérifié cela car n'importe où près de cette précision est très bien pour mon usage.
étant donné que vous recherchez une formule simple, c'est probablement la façon la plus simple de le faire, en supposant que la Terre est une sphère de périmètre de 40075 km.
longueur en mètres de 1 ° de latitude = toujours 111,32 km
longueur en mètres de 1° de longitude = 40075 km * cos (latitude ) / 360
les Latitudes et les longitude spécifient des points, pas des distances, donc votre question est quelque peu absurde. Si vous posez des questions sur la distance la plus courte entre deux (lat, lon) points, voir cet article de Wikipedia sur les distances grand-cercle.
il y a beaucoup d'outils qui vont rendre cela facile. Voir réponse de monjardin pour plus de détails sur ce qui est en cause.
cependant, faire cela n'est pas nécessairement difficile. On dirait que vous utilisez Java, donc je vous recommande de chercher quelque chose comme GDAL . Il fournit java wrappers pour leurs routines, et ils ont tous les outils nécessaires pour passer de Lat/Lon (coordonnées géographiques) à UTM (prévu système de coordonnées) ou une autre projection cartographique raisonnable.
UTM est agréable, parce qu'il est mètres de, si facile de travailler avec. Cependant, vous aurez besoin d'obtenir le UTM zone approprié pour faire un bon travail. Il existe quelques codes simples disponibles via googling pour trouver une zone appropriée pour une paire lat/long.
la Terre est une surface anormalement irrégulière, il n'y a donc pas de formule simple pour le faire exactement. Vous devez vivre avec un modèle approximatif de la terre, et projeter vos coordonnées dessus. Le modèle que je vois généralement utilisé pour cela est WGS 84 . C'est ce que les appareils GPS utilisent habituellement pour résoudre le même problème.
NOAA a un logiciel que vous pouvez télécharger pour aider avec ce sur leur site web .
Voici la version R de B-H - 'S fonction , juste au cas où:
measure <- function(lon1,lat1,lon2,lat2) {
R <- 6378.137 # radius of earth in Km
dLat <- (lat2-lat1)*pi/180
dLon <- (lon2-lon1)*pi/180
a <- sin((dLat/2))^2 + cos(lat1*pi/180)*cos(lat2*pi/180)*(sin(dLon/2))^2
c <- 2 * atan2(sqrt(a), sqrt(1-a))
d <- R * c
return (d * 1000) # distance in meters
}
un mille marin (1852 mètres) est défini comme un arcminute de longitude à l'Équateur. Cependant, vous devez définir un projection de carte (voir aussi UTM ) dans lequel vous travaillez pour la conversion pour vraiment faire sens.
il y a plusieurs façons de calculer ceci. Tous utilisent des approximations de trigonométrie sphérique où le rayon est celui de la terre.
essayer http://www.movable-type.co.uk/scripts/latlong.html pour un peu de méthodes et de code dans différentes langues.
'below is from
'http://www.zipcodeworld.com/samples/distance.vbnet.html
Public Function distance(ByVal lat1 As Double, ByVal lon1 As Double, _
ByVal lat2 As Double, ByVal lon2 As Double, _
Optional ByVal unit As Char = "M"c) As Double
Dim theta As Double = lon1 - lon2
Dim dist As Double = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + _
Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * _
Math.Cos(deg2rad(theta))
dist = Math.Acos(dist)
dist = rad2deg(dist)
dist = dist * 60 * 1.1515
If unit = "K" Then
dist = dist * 1.609344
ElseIf unit = "N" Then
dist = dist * 0.8684
End If
Return dist
End Function
Public Function Haversine(ByVal lat1 As Double, ByVal lon1 As Double, _
ByVal lat2 As Double, ByVal lon2 As Double, _
Optional ByVal unit As Char = "M"c) As Double
Dim R As Double = 6371 'earth radius in km
Dim dLat As Double
Dim dLon As Double
Dim a As Double
Dim c As Double
Dim d As Double
dLat = deg2rad(lat2 - lat1)
dLon = deg2rad((lon2 - lon1))
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)
c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a))
d = R * c
Select Case unit.ToString.ToUpper
Case "M"c
d = d * 0.62137119
Case "N"c
d = d * 0.5399568
End Select
Return d
End Function
Private Function deg2rad(ByVal deg As Double) As Double
Return (deg * Math.PI / 180.0)
End Function
Private Function rad2deg(ByVal rad As Double) As Double
Return rad / Math.PI * 180.0
End Function
si elle est suffisamment proche, vous pouvez vous en tirer en les traitant comme des coordonnées sur un plan plat. Cela fonctionne, par exemple, au niveau de la rue ou de la ville si une précision parfaite n'est pas nécessaire et tout ce que vous avez besoin est une approximation sur la distance impliquée pour comparer avec une limite arbitraire.
basé sur la distance moyenne pour la dégressivité dans la Terre.
1 ° = 111km;
convertissant ceci pour les radians et divisant pour les mètres, prend un nombre magique pour le RAD, en mètres: 0.000008998719243599958;
puis:
const RAD = 0.000008998719243599958;
Math.sqrt(Math.pow(lat1 - lat2, 2) + Math.pow(long1 - long2, 2)) / RAD;
si vous voulez une solution simple, utilisez la formule Haversine comme indiqué dans les autres commentaires. Si vous avez une application sensible à la précision, gardez à l'esprit que la formule de Haversine ne garantit pas une précision meilleure que 0,5% car elle suppose que la Terre est un cercle. Pour considérer que la Terre est un sphéroïde oblat considérer en utilisant Vincenty's formules . De plus, Je ne suis pas sûr du rayon que nous devrions utiliser avec la formule Haversine: {Équateur: 6,378.137 km, polaire: 6 356.752 km, volumétrique: 6 371.0088 km}.
vous devez convertir les coordonnées en radians pour faire la géométrie sphérique. Une fois converti, vous pouvez calculer une distance entre les deux points. La distance peut alors être convertie à n'importe quelle mesure que vous voulez.