115 votes

Obtenir la latitude/longitude à partir du point actuel, de la distance et du relèvement

Étant donné un point existant en lat/long, la distance en (en KM) et le relèvement (en degrés convertis en radians), j'aimerais calculer la nouvelle lat/long. Le présent Le site de la Commission européenne revient sans cesse, mais je n'arrive pas à trouver la formule qui me convienne.

Les formules indiquées dans le lien 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)

J'obtiens

lat2 = 0.472492248844 
lon2 = 79.4821662373

133voto

David M Points 2153

Nécessité de reconvertir les réponses en radians en degrés. Code de travail ci-dessous :

from math import asin, atan2, cos, degrees, radians, sin

def get_point_at_distance(lat1, lon1, d, bearing, R=6371):
    """
    lat: initial latitude, in degrees
    lon: initial longitude, in degrees
    d: target distance from initial
    bearing: (true) heading in degrees
    R: optional radius of sphere, defaults to mean radius of earth

    Returns new lat/lon coordinate {d}km from initial, in degrees
    """
    lat1 = radians(lat1)
    lon1 = radians(lon1)
    a = radians(bearing)
    lat2 = asin(sin(lat1) * cos(d/R) + cos(lat1) * sin(d/R) * cos(a))
    lon2 = lon1 + atan2(
        sin(a) * sin(d/R) * cos(lat1),
        cos(d/R) - sin(lat1) * sin(lat2)
    )
    return (degrees(lat2), degrees(lon2),)

lat = 52.20472
lon = 0.14056
distance = 15
bearing = 90
lat2, lon2 = get_point_at_distance(lat, lon, distance, bearing)

# lat2  52.20444 - the lat result I'm hoping for
# lon2  0.36056 - the long result I'm hoping for.

print(lat2, lon2)
# prints "52.20451523755824 0.36067845713550956"

41voto

Emrit Points 11

En géopie soutient cette démarche :

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

33voto

user1147688 Points 391

Cette question est connue sous le nom de problème direct dans l'étude de géodésie .

Il s'agit là d'une question très fréquente et d'une source constante de confusion. La raison en est que la plupart des gens recherchent une réponse simple et directe. Mais il n'y en a pas, car la plupart des personnes qui posent cette question ne fournissent pas suffisamment d'informations, tout simplement parce qu'elles n'en sont pas conscientes :

  1. La Terre n'est pas une sphère parfaite, puisqu'elle est aplatie/compressée par les pôles.
  2. A cause de (1) la terre n'a pas un rayon constant, R . Voir ici .
  3. La Terre n'est pas parfaitement lisse (variations d'altitude), etc.
  4. En raison du mouvement des plaques tectoniques, la position lat/lon d'un point géographique peut changer de plusieurs millimètres (au moins) chaque année.

Il existe donc de nombreuses hypothèses différentes utilisées dans les divers modèles géométriques qui s'appliquent différemment, en fonction de la précision recherchée. Pour répondre à la question, vous devez donc déterminer dans quelle mesure précision vous souhaitez obtenir votre résultat.

Quelques exemples :

  • Je cherche juste une localisation approximative à quelques kilomètres près pour les petits ( < 100 km) distances de en latitudes entre 0-70 deg N|S . (La Terre est un modèle plat.)
  • Je veux une réponse qui soit valable partout sur le globe, mais précise à quelques mètres près.
  • Je veux un positionnement super précis qui soit valable jusqu'à l'échelle atomique. nanometers [nm].
  • Je veux des réponses qui soient très rapides et faciles à calculer et qui ne nécessitent pas de calculs intensifs.

Vous avez donc le choix entre plusieurs algorithmes. En outre, chaque langage de programmation possède sa propre implémentation ou "package", multiplié par le nombre de modèles et les besoins spécifiques des développeurs de modèles. Pour des raisons pratiques, il est préférable d'ignorer tout autre langage. javascript car il est très proche du pseudo-code de par sa nature. Il peut donc être facilement converti dans n'importe quel autre langage, avec un minimum de modifications.

Les principaux modèles sont les suivants :

  • Euclidian/Flat earth model : bon pour les très courtes distances inférieures à ~10 km
  • Spherical model Le système d'information sur l'état de l'environnement : bon pour les grandes distances longitudinales, mais avec une faible différence latitudinale. Modèle populaire :
    • Haversine : compteur précision à l'échelle du [km], code très simple.
  • Ellipsoidal models : Le plus précis pour n'importe quelle latitude et distance, mais il s'agit toujours d'une approximation numérique qui dépend de la précision dont vous avez besoin. Voici quelques modèles populaires :
    • Lambert : ~10 mètres précision sur des milliers de km .
    • Paul D.Thomas : Approche d'Andoyer-Lambert
    • Vincenty : millimètre la précision et l'efficacité des calculs
    • Kerney : nanomètre précision

Références :

16voto

Peter Points 535

Il est peut-être un peu tard pour répondre, mais après avoir testé les autres réponses, il semble qu'elles ne fonctionnent pas correctement. Voici un code PHP que nous utilisons pour notre système. Il fonctionne 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;
 }

13voto

Steevn Points 61

J'ai porté la réponse de Brad à la réponse JS vanille, sans dépendance à l'égard de Bing maps.

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é geoJSON afin que vous puissiez simplement coller le geoJSON résultant dans : http://geojson.io/#map=17/41.89017/12.49171 pour voir les résultats instantanément.

Résultat : geoJSON Screenshot

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X