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
Author: chilljeet, 2011-08-28

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)
 51
Author: David M,
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

 21
Author: elliot42,
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;
 }
 7
Author: Peter,
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
  1. ponieważ (1) ziemia nie ma stałego promienia, R. Zobacz tutaj .
  2. Ziemia nie jest idealnie gładka (różnice wysokości) itp.
  3. 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ędzy 0-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:

Referencje:

 5
Author: not2qubit,
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.

 3
Author: Chris,
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)."

 1
Author: jwd630,
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)!

 1
Author: Asrat,
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));

},
 0
Author: Brad Mathews,
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;

}
 0
Author: Bruce,
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.

Wynik: zrzut ekranu geoJSON

 0
Author: kodisha,
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