Get lat / long biorąc pod uwagę aktualny punkt, odległość i łożysko
Biorąc pod uwagę istniejący punkt w lat / long, odległość w (w KM) i łożysko (w stopniach przeliczonych na radiany), chciałbym obliczyć nowy lat/long. ta strona pojawia się w kółko, ale po prostu nie mogę sprawić, by formuła działała dla mnie.
Wzory podane w powyższym linku to:
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))
Powyższy wzór jest dla MSExcel, gdzie -
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);
Oto kod, który mam w Pythonie.
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)
I get
lat2 = 0.472492248844
lon2 = 79.4821662373
10 answers
Potrzebne do konwersji odpowiedzi z radianów z powrotem na stopnie. Kod roboczy poniżej:
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-20 11:34:51
Biblioteka geopy obsługuje to:
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
Znalezione przez https://stackoverflow.com/a/4531227/37610
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:30
Może być trochę za późno na odpowiedź, ale po przetestowaniu innych odpowiedzi okazuje się, że nie działają poprawnie. Oto kod PHP, którego używamy dla naszego systemu. Praca we wszystkich kierunkach.
Kod PHP:
Lat1 = szerokość geograficzna punktu początkowego w stopniach
Long1 = długość punktu początkowego w stopniach
D = odległość w KM
Kąt = łożysko w stopniach
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-19 10:48:13
To pytanie jest znane jako problem bezpośredni W badaniu Geodezji.
Jest to bardzo popularne pytanie, które jest stałą przyczyną zamieszania. Powodem jest to, że większość ludzi szuka prostej i prostej odpowiedzi. Ale nie ma, ponieważ większość ludzi zadających to pytanie nie dostarcza wystarczającej ilości informacji, po prostu dlatego, że nie są świadomi, że: {]}-
[17]} Ziemia nie jest sferą idealną, ponieważ jest spłaszczony / ściśnięty przez słupy it
- ponieważ (1) ziemia nie ma stałego promienia,
R
. Zobacz tutaj . - Ziemia nie jest idealnie gładka (różnice wysokości) itp.
- ze względu na ruchy płyt tektonicznych, położenie punktu geograficznego lat / lon może zmieniać się co roku o kilka milimetrów (co najmniej).
Dlatego istnieje wiele różnych założeń stosowanych w różnych modelach geometrycznych, które stosują się w różny sposób, w zależności od potrzeb dokładność. Aby odpowiedzieć na pytanie, musisz zastanowić się, do jakiej dokładności chciałbyś mieć swój wynik.
Niektóre przykłady:
- Szukam tylko przybliżonej lokalizacji do najbliższych kilku kilometrów dla małych ( 100 km) odległości in
latitudes
pomiędzy0-70 deg
N / s . (Ziemia jest ~ model płaski.) - chcę odpowiedzi, która jest dobra w dowolnym miejscu na świecie, ale tylko dokładna do kilku metrów
- I want a super dokładne pozycjonowanie, które jest ważne do skali atomowej
nanometers
[nm]. - chcę odpowiedzi, które są bardzo szybkie i łatwe do obliczenia, a nie obliczeniowo intensywne.
Więc możesz mieć wiele wyborów, w których algorytm użyć. Ponadto każdy język programowania ma własną implementację lub" pakiet " pomnożony przez liczbę modeli i specyficzne potrzeby programistów. Ze wszystkich praktycznych względów tutaj opłaca się ignorować każdy inny język poza javascript
, ponieważ z natury bardzo przypomina pseudokod. W ten sposób można go łatwo przekonwertować na dowolny inny język, z minimalnymi zmianami.
Wtedy głównymi modelami są:
-
Euclidian/Flat earth model
: dobre na bardzo krótkie dystanse poniżej ~10 km -
Spherical model
: dobre dla dużych odległości podłużnych, ale z małą różnicą szerokości geograficznej. Popularny model:- Haversine: Miernik dokładność na skalach [km] , bardzo prosty kod.
-
Ellipsoidal models
: najdokładniejsze w dowolnym lat/lon i odległości, ale nadal jest przybliżeniem numerycznym, które zależy od dokładności, jakiej potrzebujesz. Niektóre popularne modele to:- Lambert: ~10 metr precyzja ponad 1000 ' s z km .
- Paul D. Thomas : przybliżenie Andoyer-Lambert
- Wincenty: milimetr precyzja i wydajność obliczeniowa
- Kerney: Nanometr precision
Referencje:
- https://en.wikipedia.org/wiki/Reference_ellipsoid
- https://en.wikipedia.org/wiki/Haversine_formula
- https://en.wikipedia.org/wiki/Earth_ellipsoid
- https://en.wikipedia.org/wiki/Geodesics_on_an_ellipsoid
- https://en.wikipedia.org/wiki/Vincenty%27s_formulae
- https://geographiclib.sourceforge.io/scripts/geod-calc.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-22 16:44:54
Lon1 i lat1 w stopniach
Brng = łożysko w radianach
D = odległość w km
R = promień Ziemi w km
lat2 = math.degrees((d/R) * math.cos(brng)) + lat1
long2 = math.degrees((d/(R*math.sin(math.radians(lat2)))) * math.sin(brng)) + long1
Zaimplementowałem twój i mój algorytm w PHP i porównałem go. Ta wersja działała w około 50% przypadków. Uzyskane wyniki były identyczne, więc wydaje się być matematycznie równoważne.
Nie testowałem powyższego kodu Pythona, więc mogą być Błędy składniowe.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-31 04:13:46
Również późno, ale dla tych, którzy mogą to znaleźć, otrzymasz dokładniejsze wyniki za pomocą biblioteki geographiclib . Zapoznaj się z opisami problemów geodezyjnych i przykładami JavaScript, aby uzyskać łatwe wprowadzenie do tego, jak używać, aby odpowiedzieć na pytanie dotyczące tematu,a także wiele innych. Implementacje w różnych językach, w tym w Pythonie. O wiele lepsze niż kodowanie własne, jeśli zależy ci na dokładności; lepsze niż wcześniejsze zalecenie "użyj biblioteki". Jako dokumentacja mówi: "nacisk kładziony jest na zwracanie dokładnych wyników z błędami bliskimi zaokrągleniu (Około 5-15 nanometrów)."
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-25 19:14:00
Wystarczy wymienić wartości w funkcji atan2(y,x). Nie atan2 (x,y)!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-01 16:51:51
Przeportowałem Pythona do Javascript. Zwróci to obiekt Bing Maps Location
, który możesz zmienić na dowolny.
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));
},
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-25 17:26:27
Oto wersja PHP oparta na wzorze Eda Williamsa. Moduł jest obsługiwany nieco inaczej w PHP. To mi pasuje.
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-05 20:51:44
Przeportowałem odpowiedź Brada na vanilla js answer, Bez zależności 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);
Dodatkowo dodałem geoJSON export, dzięki czemu można po prostu wkleić wynikowy geoJSON do http://geojson.io/#map=17/41.89017/12.49171 i zobaczyć wyniki natychmiast.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-09 11:42:14