Bei einem vorhandenen Punkt in Lat / Long, Entfernung in (in KM) und Peilung (in Grad umgerechnet in Bogenmaß) möchte ich das neue Lat / Long berechnen. Diese Seite taucht immer wieder auf, aber ich kann die Formel einfach nicht für mich arbeiten lassen.
Die Formeln unter dem obigen Link sind:
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))
Die obige Formel gilt für MSExcel, wobei
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);
Hier ist der Code, den ich in Python habe.
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)
Ich bekomme
lat2 = 0.472492248844
lon2 = 79.4821662373
python
gis
distance
latitude-longitude
David M.
quelle
quelle
Antworten:
Muss Antworten vom Bogenmaß zurück in Grad konvertieren. Arbeitscode unten:
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)
quelle
Die Geopy- Bibliothek unterstützt dies:
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
Gefunden über https://stackoverflow.com/a/4531227/37610
quelle
Diese Frage ist als direktes Problem bei der Untersuchung der Geodäsie bekannt .
Dies ist in der Tat eine sehr beliebte Frage, die ständig Verwirrung stiftet. Der Grund ist, dass die meisten Menschen nach einer einfachen und direkten Antwort suchen. Aber es gibt keine, weil die meisten Leute, die diese Frage stellen, nicht genügend Informationen liefern, einfach weil sie nicht wissen, dass:
R
. Siehe hier .Daher werden in den verschiedenen geometrischen Modellen viele verschiedene Annahmen verwendet, die je nach erforderlicher Genauigkeit unterschiedlich gelten. Um die Frage zu beantworten, müssen Sie überlegen, mit welcher Genauigkeit Sie Ihr Ergebnis erzielen möchten.
Einige Beispiele:
latitudes
zwischen0-70 deg
N | S . (Die Erde ist ein flaches Modell.)nanometers
[nm] gültig ist .Sie haben also viele Möglichkeiten, welchen Algorithmus Sie verwenden möchten. Darüber hinaus verfügt jede Programmiersprache über eine eigene Implementierung oder ein eigenes "Paket", multipliziert mit der Anzahl der Modelle und den spezifischen Anforderungen der Modellentwickler. Für alle praktischen Zwecke lohnt es sich, jede andere Sprache außer sich zu lassen
javascript
, da sie von Natur aus dem Pseudocode sehr ähnlich ist. Somit kann es mit minimalen Änderungen leicht in jede andere Sprache konvertiert werden.Dann sind die Hauptmodelle:
Euclidian/Flat earth model
: gut für sehr kurze Strecken unter ~ 10 kmSpherical model
: gut für große Längsabstände, aber mit geringem Breitengradunterschied. Beliebtes Modell:Ellipsoidal models
: Am genauesten bei jedem Lat / Lon und jeder Entfernung, aber immer noch eine numerische Annäherung, die davon abhängt, welche Genauigkeit Sie benötigen. Einige beliebte Modelle sind:Verweise:
quelle
Möglicherweise ist die Beantwortung etwas spät, aber nach dem Testen der anderen Antworten scheint es, dass sie nicht richtig funktionieren. Hier ist ein PHP-Code, den wir für unser System verwenden. In alle Richtungen arbeiten.
PHP-Code:
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; }
quelle
get_gps_coord
oder ähnlich sein. Du bekommst nicht die Distanz, das gibst du der Funk. Aber danke dafür, es ist genau das, wonach ich gesucht habe. Viele Suchvorgänge geben den berechneten Abstand zwischen Koordinaten zurück (falsch positive Ergebnisse). Vielen Dank!6,378.14 km
scheint der maximale Radius der Erde zu sein. Der Durchschnitt liegt bei ungefähr6,371.0 km
, was genauere Berechnungen ermöglichen kann.Ich habe die Antwort von Brad auf die Antwort von Vanilla JS portiert, ohne Abhängigkeit von Bing-Karten
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);
Außerdem habe ich den
geoJSON
Export hinzugefügt , sodass Sie das resultierende geoJSON einfach in Folgendes einfügen können:http://geojson.io/#map=17/41.89017/12.49171
um die Ergebnisse sofort anzuzeigen .Ergebnis:
quelle
Schneller Weg mit 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)
quelle
geopy.distance.distance currently uses geodesic.
geopy Und genauer gesagt, das standardmäßig verwendete Ellipsoidmodell ist das WGS-84-Ellipsoid, "das global genaueste".lon1 und lat1 in Grad
brng = Peilung im Bogenmaß
d = Entfernung in km
R = Radius der Erde in km
Ich habe Ihren und meinen Algorithmus in PHP implementiert und verglichen. Diese Version lief in etwa 50% der Fälle. Die generierten Ergebnisse waren identisch, daher scheint es mathematisch äquivalent zu sein.
Ich habe den obigen Python-Code nicht getestet, daher kann es zu Syntaxfehlern kommen.
quelle
Ebenfalls spät, aber für diejenigen, die dies möglicherweise finden, erhalten Sie mit der geographiclib- Bibliothek genauere Ergebnisse . In den geodätischen Problembeschreibungen und den JavaScript-Beispielen finden Sie eine einfache Einführung in die Beantwortung der Themenfrage sowie in viele andere. Implementierungen in verschiedenen Sprachen, einschließlich Python. Weitaus besser als das Codieren Ihrer eigenen, wenn Sie Wert auf Genauigkeit legen. besser als VincentyDistance in der früheren Empfehlung "Bibliothek verwenden". In der Dokumentation heißt es: "Der Schwerpunkt liegt auf der Rückgabe genauer Ergebnisse mit Fehlern nahe der Abrundung (ca. 5–15 Nanometer)."
quelle
Tauschen Sie einfach die Werte in der Funktion atan2 (y, x) aus. Nicht atan2 (x, y)!
quelle
Ich habe den Python nach Javascript portiert. Dies gibt ein Bing Maps-
Location
Objekt zurück, das Sie nach Belieben ändern können.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)); },
quelle
Math.degrees(lat)
undMath.degrees(lon)
Werte und mit ihnen tun , was Sie für Ihre Anwendung benötigen.Hier ist eine PHP-Version, die auf Ed Williams Aviation Formulary basiert. Der Modul wird in PHP etwas anders gehandhabt. Das funktioniert bei mir.
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; }
quelle
Ich habe die Antwort von @David M auf Java portiert, wenn jemand dies wollte ... Ich erhalte ein etwas anderes Ergebnis von 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);
quelle