Etant donné un point existant en lat/long, une distance en (en KM) et un relèvement (en degrés convertis en radians), j'aimerais calculer le nouveau lat/long. This site surgit maintes et maintes fois, mais je ne peux tout simplement pas faire en sorte que la formule fonctionne pour moi.
Les formules telles que prises ci-dessus sont les suivantes:
lat2 = asin(sin(lat1)*cos(d/R) + cos(lat1)*sin(d/R)*cos(θ))
lon2 = lon1 + atan2(sin(θ)*sin(d/R)*cos(lat1), cos(d/R)−sin(lat1)*sin(lat2))
La formule ci-dessus s’applique à MSExcel où-
asin = arc sin()
d = distance (in any unit)
R = Radius of the earth (in the same unit as above)
and hence d/r = is the angular distance (in radians)
atan2(a,b) = arc tan(b/a)
θ is the bearing (in radians, clockwise from north);
Voici le code que j'ai en Python.
import math
R = 6378.1 #Radius of the Earth
brng = 1.57 #Bearing is 90 degrees converted to radians.
d = 15 #Distance in km
#lat2 52.20444 - the lat result I'm hoping for
#lon2 0.36056 - the long result I'm hoping for.
lat1 = 52.20472 * (math.pi * 180) #Current lat point converted to radians
lon1 = 0.14056 * (math.pi * 180) #Current long point converted to radians
lat2 = math.asin( math.sin(lat1)*math.cos(d/R) +
math.cos(lat1)*math.sin(d/R)*math.cos(brng))
lon2 = lon1 + math.atan2(math.sin(brng)*math.sin(d/R)*math.cos(lat1),
math.cos(d/R)-math.sin(lat1)*math.sin(lat2))
print(lat2)
print(lon2)
Je reçois
lat2 = 0.472492248844
lon2 = 79.4821662373
Nécessaire pour convertir les réponses de radians en degrés. Code de travail ci-dessous:
import math
R = 6378.1 #Radius of the Earth
brng = 1.57 #Bearing is 90 degrees converted to radians.
d = 15 #Distance in km
#lat2 52.20444 - the lat result I'm hoping for
#lon2 0.36056 - the long result I'm hoping for.
lat1 = math.radians(52.20472) #Current lat point converted to radians
lon1 = math.radians(0.14056) #Current long point converted to radians
lat2 = math.asin( math.sin(lat1)*math.cos(d/R) +
math.cos(lat1)*math.sin(d/R)*math.cos(brng))
lon2 = lon1 + math.atan2(math.sin(brng)*math.sin(d/R)*math.cos(lat1),
math.cos(d/R)-math.sin(lat1)*math.sin(lat2))
lat2 = math.degrees(lat2)
lon2 = math.degrees(lon2)
print(lat2)
print(lon2)
La bibliothèque geopy supporte ceci:
import geopy
from geopy.distance import VincentyDistance
# given: lat1, lon1, b = bearing in degrees, d = distance in kilometers
Origin = geopy.Point(lat1, lon1)
destination = VincentyDistance(kilometers=d).destination(Origin, b)
lat2, lon2 = destination.latitude, destination.longitude
Trouvé via https://stackoverflow.com/a/4531227/37610
Peut-être un peu tard pour répondre, mais après avoir testé les autres réponses, il apparaît qu'elles ne fonctionnent pas correctement. Voici un code PHP que nous utilisons pour notre système. Travailler dans toutes les directions.
Code PHP:
lat1 = latitude du point de départ en degrés
long1 = longitude du point de départ en degrés
d = distance en km
angle = relèvement en degrés
function get_gps_distance($lat1,$long1,$d,$angle)
{
# Earth Radious in KM
$R = 6378.14;
# Degree to Radian
$latitude1 = $lat1 * (M_PI/180);
$longitude1 = $long1 * (M_PI/180);
$brng = $angle * (M_PI/180);
$latitude2 = asin(sin($latitude1)*cos($d/$R) + cos($latitude1)*sin($d/$R)*cos($brng));
$longitude2 = $longitude1 + atan2(sin($brng)*sin($d/$R)*cos($latitude1),cos($d/$R)-sin($latitude1)*sin($latitude2));
# back to degrees
$latitude2 = $latitude2 * (180/M_PI);
$longitude2 = $longitude2 * (180/M_PI);
# 6 decimal for Leaflet and other system compatibility
$lat2 = round ($latitude2,6);
$long2 = round ($longitude2,6);
// Push in array and get back
$tab[0] = $lat2;
$tab[1] = $long2;
return $tab;
}
lon1 et lat1 en degrés
brng = roulement en radians
d = distance en km
R = rayon de la Terre en km
lat2 = math.degrees((d/R) * math.cos(brng)) + lat1
long2 = math.degrees((d/(R*math.sin(math.radians(lat2)))) * math.sin(brng)) + long1
J'ai implémenté votre algorithme et le mien dans PHP et je l'ai analysé. Cette version a fonctionné environ 50% du temps. Les résultats générés étaient identiques, il semble donc être mathématiquement équivalent.
Je n'ai pas testé le code python ci-dessus, il pourrait donc y avoir des erreurs de syntaxe.
Également en retard, mais pour ceux qui pourraient le trouver, vous obtiendrez des résultats plus précis en utilisant la bibliothèque -ographicallib . Consultez les descriptions de problèmes géodésiques et les exemples JavaScript pour une introduction facile à l'utilisation de la réponse à la question sur le sujet, ainsi que pour de nombreuses autres. Implémentations dans une variété de langages, y compris Python. Bien mieux que de coder le vôtre si vous vous souciez de la précision; mieux que VincentyDistance dans la recommandation "utilisez une bibliothèque" antérieure. Comme le dit la documentation: "L'accent est mis sur le retour de résultats précis avec des erreurs proches de l'arrondi (environ 5-15 nanomètres)."
Manière rapide en utilisant geopy
from geopy import distance
#distance.distance(unit=15).destination((lat,lon),bering)
#Exemples
distance.distance(nautical=15).destination((-24,-42),90)
distance.distance(miles=15).destination((-24,-42),90)
distance.distance(kilometers=15).destination((-24,-42),90)
Il suffit d'échanger les valeurs dans la fonction atan2 (y, x). Pas atan2 (x, y)!
J'ai porté la réponse de Brad à la réponse JS de Vanilla, sans dépendance de cartes Bing
https://jsfiddle.net/kodisha/8a3hcjtd/
// ----------------------------------------
// Calculate new Lat/Lng from original points
// on a distance and bearing (angle)
// ----------------------------------------
let llFromDistance = function(latitude, longitude, distance, bearing) {
// taken from: https://stackoverflow.com/a/46410871/13549
// distance in KM, bearing in degrees
const R = 6378.1; // Radius of the Earth
const brng = bearing * Math.PI / 180; // Convert bearing to radian
let lat = latitude * Math.PI / 180; // Current coords to radians
let lon = longitude * Math.PI / 180;
// Do the math magic
lat = Math.asin(Math.sin(lat) * Math.cos(distance / R) + Math.cos(lat) * Math.sin(distance / R) * Math.cos(brng));
lon += Math.atan2(Math.sin(brng) * Math.sin(distance / R) * Math.cos(lat), Math.cos(distance / R) - Math.sin(lat) * Math.sin(lat));
// Coords back to degrees and return
return [(lat * 180 / Math.PI), (lon * 180 / Math.PI)];
}
let pointsOnMapCircle = function(latitude, longitude, distance, numPoints) {
const points = [];
for (let i = 0; i <= numPoints - 1; i++) {
const bearing = Math.round((360 / numPoints) * i);
console.log(bearing, i);
const newPoints = llFromDistance(latitude, longitude, distance, bearing);
points.Push(newPoints);
}
return points;
}
const points = pointsOnMapCircle(41.890242042122836, 12.492358982563019, 0.2, 8);
let geoJSON = {
"type": "FeatureCollection",
"features": []
};
points.forEach((p) => {
geoJSON.features.Push({
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
p[1],
p[0]
]
}
});
});
document.getElementById('res').innerHTML = JSON.stringify(geoJSON, true, 2);
En outre, j’ai ajouté l’exportation geoJSON afin que vous puissiez simplement coller le résultat geoJSON dans http://geojson.io/#map=17/41.89017/12.49171 et voir les résultats instantanément.
J'ai porté la réponse de @David M à Java si quelqu'un le souhaitait ... J'ai un résultat légèrement différent, 52.20462299620793, 0.360433887489931
double R = 6378.1; //Radius of the Earth
double brng = 1.57; //Bearing is 90 degrees converted to radians.
double d = 15; //Distance in km
double lat2 = 52.20444; // - the lat result I'm hoping for
double lon2 = 0.36056; // - the long result I'm hoping for.
double lat1 = Math.toRadians(52.20472); //Current lat point converted to radians
double lon1 = Math.toRadians(0.14056); //Current long point converted to radians
lat2 = Math.asin( Math.sin(lat1)*Math.cos(d/R) +
Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng));
lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1),
Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));
lat2 = Math.toDegrees(lat2);
lon2 = Math.toDegrees(lon2);
System.out.println(lat2 + ", " + lon2);
J'ai porté le Python en Javascript. Cela retourne un objet Bing Maps Location
, que vous pouvez modifier comme bon vous semble.
getLocationXDistanceFromLocation: function(latitude, longitude, distance, bearing) {
// distance in KM, bearing in degrees
var R = 6378.1, // Radius of the Earth
brng = Math.radians(bearing) // Convert bearing to radian
lat = Math.radians(latitude), // Current coords to radians
lon = Math.radians(longitude);
// Do the math magic
lat = Math.asin(Math.sin(lat) * Math.cos(distance / R) + Math.cos(lat) * Math.sin(distance / R) * Math.cos(brng));
lon += Math.atan2(Math.sin(brng) * Math.sin(distance / R) * Math.cos(lat), Math.cos(distance/R)-Math.sin(lat)*Math.sin(lat));
// Coords back to degrees and return
return new Microsoft.Maps.Location(Math.degrees(lat), Math.degrees(lon));
},
Voici une version PHP basée sur Ed Williams Aviation Formulary. Modulus est traité un peu différemment en PHP. Cela fonctionne pour moi.
function get_new_waypoint ( $lat, $lon, $radial, $magvar, $range )
{
// $range in nm.
// $radial is heading to or bearing from
// $magvar for local area.
$range = $range * pi() /(180*60);
$radial = $radial - $magvar ;
if ( $radial < 1 )
{
$radial = 360 + $radial - $magvar;
}
$radial = deg2rad($radial);
$tmp_lat = deg2rad($lat);
$tmp_lon = deg2rad($lon);
$new_lat = asin(sin($tmp_lat)* cos($range) + cos($tmp_lat) * sin($range) * cos($radial));
$new_lat = rad2deg($new_lat);
$new_lon = $tmp_lon - asin(sin($radial) * sin($range)/cos($new_lat))+ pi() % 2 * pi() - pi();
$new_lon = rad2deg($new_lon);
return $new_lat." ".$new_lon;
}