Как преобразовать широту или долготу в метры?
Если у меня есть чтение широты или долготы в стандартном формате NMEA, есть ли простой способ / формула для преобразования этого чтения в метры, которые я могу реализовать в Java (J9)?
изменить: ОК, кажется, то, что я хочу сделать, невозможно легко, однако, то, что я действительно хочу сделать, это:
скажем, у меня есть lat и long точки пути и lat и long пользователя есть простой способ сравнить их, чтобы решить, когда сказать пользователю, что они находятся в пределах достаточно близкое расстояние точки пути? Я понимаю, что разумный предмет, но это легко сделать или все еще слишком математически?
15 ответов
вот функция javascript:
function measure(lat1, lon1, lat2, lon2){ // generally used geo measurement function
var R = 6378.137; // Radius of earth in KM
var dLat = lat2 * Math.PI / 180 - lat1 * Math.PI / 180;
var dLon = lon2 * Math.PI / 180 - lon1 * Math.PI / 180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d * 1000; // meters
}
объяснение:https://en.wikipedia.org/wiki/Haversine_formula
формула гаверсинуса определяет большого круга расстояние между двумя точками на сфере с учетом их долгот и широт.
для аппроксимации коротких расстояний между двумя координатами я использовал формулы из http://en.wikipedia.org/wiki/Lat-lon:
m_per_deg_lat = 111132.954 - 559.822 * cos( 2 * latMid ) + 1.175 * cos( 4 * latMid);
m_per_deg_lon = 111132.954 * cos ( latMid );
.
в коде ниже я оставил исходные цифры, чтобы показать их отношение к формуле из Википедии.
double latMid, m_per_deg_lat, m_per_deg_lon, deltaLat, deltaLon,dist_m;
latMid = (Lat1+Lat2 )/2.0; // or just use Lat1 for slightly less accurate estimate
m_per_deg_lat = 111132.954 - 559.822 * cos( 2.0 * latMid ) + 1.175 * cos( 4.0 * latMid);
m_per_deg_lon = (3.14159265359/180 ) * 6367449 * cos ( latMid );
deltaLat = fabs(Lat1 - Lat2);
deltaLon = fabs(Lon1 - Lon2);
dist_m = sqrt ( pow( deltaLat * m_per_deg_lat,2) + pow( deltaLon * m_per_deg_lon , 2) );
в записи Википедии говорится, что расстояние calcs находится в пределах 0,6 м для 100 км в продольном направлении и 1 см для 100 км в широтном направлении, но я не проверил это, как нигде рядом с этим точность хороша для моего использования.
учитывая, что вы ищете простую формулу, это, вероятно, самый простой способ сделать это, предполагая, что Земля является сферой периметра 40075 км.
длина в метрах 1° широты = всегда 111,32 км
длина в метрах 1 ° долготы = 40075 км * cos (широта) / 360
широты и долготы указывают точки, а не расстояния, поэтому ваш вопрос несколько бессмыслен. Если вы спрашиваете о кратчайшем расстоянии между двумя (lat, lon) точками, см. эта статья в Википедии на расстояниях большого круга.
есть много инструментов, которые сделают это легко. См.monjardin это для получения более подробной информации о том, что участие.
однако сделать это не обязательно сложно. Похоже, вы используете Java, поэтому я бы рекомендовал посмотреть что-то вроде GDAL. Он предоставляет Java-оболочки для их подпрограмм, и у них есть все инструменты, необходимые для преобразования из Lat /Lon (географические координаты) в UTM (проекционная система координат) или некоторые другие разумная проекция карты.
UTM приятно, потому что это метры, так легко работать. Тем не менее, вам нужно будет получить соответствующий зона UTM для того, чтобы сделать хорошую работу. Есть несколько простых кодов, доступных через googling, чтобы найти подходящую зону для пары lat/long.
Земля является раздражающе неправильной поверхностью, поэтому нет простой формулы, чтобы сделать это точно. Вы должны жить с приблизительной моделью Земли и проецировать на нее свои координаты. Модель, которую я обычно вижу, используется для этого WGS 84. Это то, что GPS-устройства обычно используют для решения одной и той же проблемы.
NOAA имеет некоторое программное обеспечение, которое вы можете скачать, чтобы помочь с этим на сайте.
вот версия R B-h-функция на всякий случай:
measure <- function(lon1,lat1,lon2,lat2) {
R <- 6378.137 # radius of earth in Km
dLat <- (lat2-lat1)*pi/180
dLon <- (lon2-lon1)*pi/180
a <- sin((dLat/2))^2 + cos(lat1*pi/180)*cos(lat2*pi/180)*(sin(dLon/2))^2
c <- 2 * atan2(sqrt(a), sqrt(1-a))
d <- R * c
return (d * 1000) # distance in meters
}
существует довольно много способов вычислить это. Все они используют апроксимации сферической тригонометрии, где радиус является радиусом Земли.
попробуйте http://www.movable-type.co.uk/scripts/latlong.html Для немного методов и кода на разных языках.
'below is from
'http://www.zipcodeworld.com/samples/distance.vbnet.html
Public Function distance(ByVal lat1 As Double, ByVal lon1 As Double, _
ByVal lat2 As Double, ByVal lon2 As Double, _
Optional ByVal unit As Char = "M"c) As Double
Dim theta As Double = lon1 - lon2
Dim dist As Double = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + _
Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * _
Math.Cos(deg2rad(theta))
dist = Math.Acos(dist)
dist = rad2deg(dist)
dist = dist * 60 * 1.1515
If unit = "K" Then
dist = dist * 1.609344
ElseIf unit = "N" Then
dist = dist * 0.8684
End If
Return dist
End Function
Public Function Haversine(ByVal lat1 As Double, ByVal lon1 As Double, _
ByVal lat2 As Double, ByVal lon2 As Double, _
Optional ByVal unit As Char = "M"c) As Double
Dim R As Double = 6371 'earth radius in km
Dim dLat As Double
Dim dLon As Double
Dim a As Double
Dim c As Double
Dim d As Double
dLat = deg2rad(lat2 - lat1)
dLon = deg2rad((lon2 - lon1))
a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(deg2rad(lat1)) * _
Math.Cos(deg2rad(lat2)) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2)
c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a))
d = R * c
Select Case unit.ToString.ToUpper
Case "M"c
d = d * 0.62137119
Case "N"c
d = d * 0.5399568
End Select
Return d
End Function
Private Function deg2rad(ByVal deg As Double) As Double
Return (deg * Math.PI / 180.0)
End Function
Private Function rad2deg(ByVal rad As Double) As Double
Return rad / Math.PI * 180.0
End Function
Если его достаточно близко, вы можете уйти с рассматривая их как координаты на плоской плоскости. Это работает, скажем, на уровне улицы или города, если идеальная точность не требуется, и все, что вам нужно, - это грубая догадка о расстоянии, которое нужно сравнить с произвольным пределом.
для преобразования широты и долготы в представлении x и y вам нужно решить, какой тип проекции карты использовать. Что касается меня, эллиптический Меркатор кажется очень хорошим. здесь вы можете найти реализацию (в Java тоже).
основан на средней дистанции за град на Земле.
1° = 111 км;
преобразование этого для радианов и деление на метры, возьмите магическое число для рад, в метрах: 0.000008998719243599958;
затем:
const RAD = 0.000008998719243599958;
Math.sqrt(Math.pow(lat1 - lat2, 2) + Math.pow(long1 - long2, 2)) / RAD;
Если вы хотите простое решение, используйте формула Haversine как указано в других комментариях. Если у вас есть приложение, чувствительное к точности, имейте в виду, что формула Haversine не гарантирует точность лучше 0,5%, поскольку она предполагает, что Земля является кругом. Чтобы считать, что Земля является сплющенным сфероидом, рассмотрим использование Vincenty по формулам. Кроме того, я не уверен, что радиус мы должны использовать с формула Гаверсинуса: {экватора: 6,378.137 км, Полярный: 6,356.752 км, объем: 6371.0088 km}.
вам нужно преобразовать координаты в радианы, чтобы сделать сферическую геометрию. После преобразования, то вы можете рассчитать расстояние между двумя точками. Затем расстояние может быть преобразовано в любую меру, которую вы хотите.