Получить lat/long с учетом текущей точки, расстояния и подшипника
Учитывая существующую точку в lat/long, расстояние в (в KM) и подшипник (в градусах, преобразованных в радианы), я хотел бы рассчитать новый lat/long. Этот сайт появляется снова и снова, но я просто не могу заставить формулу работать для меня.
Формулы, взятые по вышеуказанной ссылке:
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))
Вышеприведенная формула предназначена для MSExcel, где
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);
Вот код, который у меня есть на 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)
Я получаю
lat2 = 0.472492248844
lon2 = 79.4821662373
Ответы
Ответ 1
Необходимо преобразовать ответы от радианов обратно в градусы. Рабочий код ниже:
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)
Ответ 2
Библиотека geopy поддерживает это:
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
Найдено через fooobar.com/questions/146548/...
Ответ 3
Может быть, немного поздно ответить, но после тестирования других ответов оказалось, что они не работают правильно. Вот код PHP, который мы используем для нашей системы. Работа во всех направлениях.
PHP-код:
lat1 = широта начальной точки в градусах
long1 = долгота начальной точки в градусах
d = расстояние в КМ
angle = подшипник в градусах
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;
}
Ответ 4
lon1 и lat1 в градусах
brng = подшипник в радианах
d = расстояние в км
R = радиус Земли в км
lat2 = math.degrees((d/R) * math.cos(brng)) + lat1
long2 = math.degrees((d/(R*math.sin(math.radians(lat2)))) * math.sin(brng)) + long1
Я реализовал свой алгоритм и мой в PHP и сравнил его. Эта версия работала примерно в 50% случаев. Полученные результаты были идентичны, поэтому он представляется математически эквивалентным.
Я не тестировал выше код python, поэтому возможны синтаксические ошибки.
Ответ 5
Также поздно, но для тех, кто может найти это, вы получите более точные результаты, используя библиотеку geographiclib. Ознакомьтесь с описаниями геодезических проблем и примерами JavaScript для простого ознакомления с тем, как использовать ответы на вопрос, а также многие другие. Реализации на разных языках, включая Python. Далеко лучше, чем кодировать свои собственные, если вы заботитесь о точности; лучше, чем VincentyDistance в предыдущей рекомендации "использовать библиотеку". Как говорится в документации: "Акцент делается на возвращении точных результатов с ошибками, близкими к округлению (около 5-15 нанометров)".
Ответ 6
Просто измените значения в функции atan2 (y, x). Не atan2 (x, y)!
Ответ 7
Я поместил Python в Javascript. Это возвращает объект Bing Maps Location
, вы можете изменить все, что захотите.
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));
},