如果我有标准NMEA格式的纬度或经度读数,是否有一种简单的方法/公式将该读数转换为米,然后可以在Java(J9)中实现?
编辑:好的,似乎我想做的事并不容易,但是我真正想做的是:
假设我有一个纬度和距离较长的用户,并且用户有一个纬度和较长时间,是否有一种简单的方法可以将它们进行比较,以决定何时告诉用户他们在相距合理距离内?我知道合理的科目,但这是容易实现的还是算术过度?
如果我有标准NMEA格式的纬度或经度读数,是否有一种简单的方法/公式将该读数转换为米,然后可以在Java(J9)中实现?
编辑:好的,似乎我想做的事并不容易,但是我真正想做的是:
假设我有一个纬度和距离较长的用户,并且用户有一个纬度和较长时间,是否有一种简单的方法可以将它们进行比较,以决定何时告诉用户他们在相距合理距离内?我知道合理的科目,但这是容易实现的还是算术过度?
Answers:
这是一个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
Haversine公式根据给定的经度和纬度确定球体上两个点之间的大圆距离。
考虑到您正在寻找一个简单的公式,这可能是最简单的方法,假设地球是一个周长为40075公里的球体。
以纬度1度为单位的米长度=始终为111.32 km
经度1度的米长度= 40075公里* cos(纬度)/ 360
为了近似估计两个坐标之间的短距离,我使用了来自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 );
。
在下面的代码中,我留下了原始数字,以显示它们与Wikipedia中公式的关系。
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) );
Wikipedia条目指出,纵向距离100 km的距离计算在0.6m范围内,而横向距离100 km的距离计算在1cm范围内,但我尚未对此进行验证,因为该精度范围适合我使用。
纬度和经度指定点,而不是距离,因此您的问题有点荒谬。如果您询问两个(纬度,经度)点之间的最短距离,请参阅有关大圆距离的Wikipedia文章。
有许多工具可以简化这一过程。查看monjardin的答案有关所涉及内容的更多详细信息,。
但是,这样做不一定很困难。听起来您正在使用Java,所以我建议您研究一下GDAL之类的东西。它为例程提供了Java包装器,并且具有将Lat / Lon(地理坐标)转换为UTM(投影坐标系)或其他一些合理的地图投影所需的所有工具。
UTM很好,因为它是米,所以使用起来很容易。但是,您需要获得适当的UTM区域才能做好工作。通过谷歌搜索可以找到一些简单的代码,以找到适合经纬度的区域。
这是bh-函数的R版本,以防万一:
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
如果其足够接近,则可以将它们视为平面上的坐标。如果不需要完美的精度,这可以说是在街道或城市级别,并且您所需要做的就是粗略估算与任意限制进行比较的距离。
根据地球上的平均降落距离。
1°= 111公里;
将其转换为弧度并除以米,以RAD为单位的魔术数,以米为单位:0.000008998719243599958;
然后:
const RAD = 0.000008998719243599958;
Math.sqrt(Math.pow(lat1 - lat2, 2) + Math.pow(long1 - long2, 2)) / RAD;
如果您想要一个简单的解决方案,请使用其他注释所概述的Haversine公式。如果您有一个对精度要求很高的应用程序,请记住,Haversine公式不能保证精度优于0.5%,因为假设地球是一个球体。要考虑地球是扁球体,请考虑使用Vincenty公式。此外,我不确定应使用Haversine公式使用什么半径:{赤道:6,378.137公里,极地:6,356.752公里,体积:6,371.0088公里}。
it is assuming the earth is a circle
^^如今有些奇怪的人在做这个……但是,您的意思可能是it is assuming the earth is a sphere
;;)