If I have a latitude or longitude reading in standard NMEA format is there an easy way / formula to convert that reading to meters, which I can then implement in Java (J9)?
如果我在标准的NMEA格式中有一个纬度或经度读数,那么有一个简单的方法/公式可以将读数转换为米,然后我可以用Java (J9)实现它吗?
Edit: Ok seems what I want to do is not possible easily, however what I really want to do is:
编辑:看来我想做的事情是不容易的,然而我真正想做的是:
Say I have a lat and long of a way point and a lat and long of a user is there an easy way to compare them to decide when to tell the user they are within a reasonably close distance of the way point? I realise reasonable is subject but is this easily do-able or still overly maths-y?
假设我有一个lat和一个很长的路点,一个lat和long的用户有一个简单的方法来比较他们来决定什么时候告诉用户他们在一个合理的距离点的距离?我意识到,理性是一门学科,但这很容易做到吗?
14 个解决方案
#1
104
Here is a javascript function:
下面是一个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
}
Explanation:
解释:
https://en.wikipedia.org/wiki/Haversine_formula
https://en.wikipedia.org/wiki/Haversine_formula
#2
21
For approximating short distances between two coordinates I used formulas from http://en.wikipedia.org/wiki/Lat-lon:
为了在两个坐标之间进行近距离的近似,我使用了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 );
.
。
In the code below I've left the raw numbers to show their relation to the formula from wikipedia.
在下面的代码中,我留下了原始数据,以显示它们与来自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) );
The wikipedia entry states that the distance calcs are within 0.6m for 100km longitudinally and 1cm for 100km latitudinally but I have not verified this as anywhere near that accuracy is fine for my use.
*上的条目指出,距离calcs在100km的纵向和1cm之间的距离为0.6米,而在100公里的纬度上,我还没有证实这一点。
#3
14
Given you're looking for a simple formula, this is probably the simplest way to do it, assuming that the Earth is a sphere of perimeter 40075 km.
假设你正在寻找一个简单的公式,这可能是最简单的方法,假设地球是一个周长40075千米的球体。
Length in meters of 1° of latitude = always 111.32 km
1°的纬度的长度米= 111.32公里
Length in meters of 1° of longitude = 40075 km * cos( latitude ) / 360
经度1分的长度= 40075公里* cos(纬度)/ 360。
#4
13
Latitudes and longitudes specify points, not distances, so your question is somewhat nonsensical. If you're asking about the shortest distance between two (lat, lon) points, see this Wikipedia article on great-circle distances.
纬度和经度指定点,而不是距离,所以你的问题有点荒谬。如果你问的是两个(lat, lon)点之间的最短距离,请参阅*上关于大圆距离的文章。
#5
7
There are many tools that will make this easy. See monjardin's answer for more details about what's involved.
有许多工具可以使这个过程变得简单。参见monjardin的答案,了解更多有关的细节。
However, doing this isn't necessarily difficult. It sounds like you're using Java, so I would recommend looking into something like GDAL. It provides java wrappers for their routines, and they have all the tools required to convert from Lat/Lon (geographic coordinates) to UTM (projected coordinate system) or some other reasonable map projection.
然而,这样做并不一定困难。听起来好像你在用Java,所以我建议你去看看GDAL之类的东西。它为它们的例程提供了java包装器,并且它们拥有从Lat/Lon(地理坐标)到UTM(投影坐标系统)或其他一些合理的地图投影转换所需的所有工具。
UTM is nice, because it's meters, so easy to work with. However, you will need to get the appropriate UTM zone for it to do a good job. There are some simple codes available via googling to find an appropriate zone for a lat/long pair.
UTM很好,因为它是米,很容易处理。但是,您需要获得适当的UTM区域来完成工作。有一些简单的代码可以通过google搜索找到适合lat/long对的区域。
#6
6
The earth is an annoyingly irregular surface, so there is no simple formula to do this exactly. You have to live with an approximate model of the earth, and project your coordinates onto it. The model I typically see used for this is WGS 84. This is what GPS devices usually use to solve the exact same problem.
地球是一个不规则的不规则表面,所以没有一个简单的公式可以做到这一点。你必须与地球的一个近似模型共存,并将你的坐标投射到它上面。我通常看到的模型是WGS 84。这就是GPS设备通常用来解决完全相同的问题。
NOAA has some software you can download to help with this on their website.
美国国家海洋和大气管理局有一些软件可以在他们的网站上下载。
#7
4
One nautical mile (1852 meters) is defined as one arcminute of longitude at the equator. However, you need to define a map projection (see also UTM) in which you are working for the conversion to really make sense.
一海里(1852米)被定义为赤道上的一圈经度。但是,您需要定义一个映射投影(参见UTM),在这个投影中,您正在为转换工作而工作,从而真正有意义。
#8
4
Based on average distance for degress in the Earth.
基于地球上的平均距离。
1° = 111km;
1°= 111公里;
Converting this for radians and dividing for meters, take's a magic number for the RAD, in meters: 0.000008998719243599958;
将此转换为弧度,并将其划分为米,以米:0.000008998719243599958为RAD的一个神奇数字;
then:
然后:
const RAD = 0.000008998719243599958;
Math.sqrt(Math.pow(lat1 - lat2, 2) + Math.pow(long1 - long2, 2)) / RAD;
#9
3
There are quite a few ways to calculate this. All of them use aproximations of spherical trigonometry where the radius is the one of the earth.
有很多计算方法。它们都使用球面三角的近似值,其中半径是地球的一个。
try http://www.movable-type.co.uk/scripts/latlong.html for a bit of methods and code in different languages.
尝试使用不同语言的一些方法和代码:http://www.movabletype .co.uk/scripts/latlong.html。
#10
3
Here is the R version of b-h-'s function, just in case:
这里是b-h函数的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
}
#11
2
'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
#12
1
To convert latitude and longitude in x and y representation you need to decide what type of map projection to use. As for me, Elliptical Mercator seems very well. Here you can find an implementation (in Java too).
要在x和y表示中转换纬度和经度,您需要决定使用哪种类型的地图投影。对我来说,椭圆的墨卡托似乎很好。在这里您可以找到一个实现(在Java中也是)。
#13
0
If its sufficiently close you can get away with treating them as coordinates on a flat plane. This works on say, street or city level if perfect accuracy isnt required and all you need is a rough guess on the distance involved to compare with an arbitrary limit.
如果它足够接近,你可以把它们当作平面上的坐标。这是在说,街道或城市的水平,如果完美的准确性不需要,你所需要的只是一个粗略的猜测,涉及到与一个任意的限制的比较。
#14
-2
You need to convert the coordinates to radians to do the spherical geometry. Once converted, then you can calculate a distance between the two points. The distance then can be converted to any measure you want.
你需要把坐标转换成弧度来做球面几何。一旦转换,你就可以计算两个点之间的距离。这个距离可以转换成任何你想要的量。
#1
104
Here is a javascript function:
下面是一个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
}
Explanation:
解释:
https://en.wikipedia.org/wiki/Haversine_formula
https://en.wikipedia.org/wiki/Haversine_formula
#2
21
For approximating short distances between two coordinates I used formulas from http://en.wikipedia.org/wiki/Lat-lon:
为了在两个坐标之间进行近距离的近似,我使用了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 );
.
。
In the code below I've left the raw numbers to show their relation to the formula from wikipedia.
在下面的代码中,我留下了原始数据,以显示它们与来自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) );
The wikipedia entry states that the distance calcs are within 0.6m for 100km longitudinally and 1cm for 100km latitudinally but I have not verified this as anywhere near that accuracy is fine for my use.
*上的条目指出,距离calcs在100km的纵向和1cm之间的距离为0.6米,而在100公里的纬度上,我还没有证实这一点。
#3
14
Given you're looking for a simple formula, this is probably the simplest way to do it, assuming that the Earth is a sphere of perimeter 40075 km.
假设你正在寻找一个简单的公式,这可能是最简单的方法,假设地球是一个周长40075千米的球体。
Length in meters of 1° of latitude = always 111.32 km
1°的纬度的长度米= 111.32公里
Length in meters of 1° of longitude = 40075 km * cos( latitude ) / 360
经度1分的长度= 40075公里* cos(纬度)/ 360。
#4
13
Latitudes and longitudes specify points, not distances, so your question is somewhat nonsensical. If you're asking about the shortest distance between two (lat, lon) points, see this Wikipedia article on great-circle distances.
纬度和经度指定点,而不是距离,所以你的问题有点荒谬。如果你问的是两个(lat, lon)点之间的最短距离,请参阅*上关于大圆距离的文章。
#5
7
There are many tools that will make this easy. See monjardin's answer for more details about what's involved.
有许多工具可以使这个过程变得简单。参见monjardin的答案,了解更多有关的细节。
However, doing this isn't necessarily difficult. It sounds like you're using Java, so I would recommend looking into something like GDAL. It provides java wrappers for their routines, and they have all the tools required to convert from Lat/Lon (geographic coordinates) to UTM (projected coordinate system) or some other reasonable map projection.
然而,这样做并不一定困难。听起来好像你在用Java,所以我建议你去看看GDAL之类的东西。它为它们的例程提供了java包装器,并且它们拥有从Lat/Lon(地理坐标)到UTM(投影坐标系统)或其他一些合理的地图投影转换所需的所有工具。
UTM is nice, because it's meters, so easy to work with. However, you will need to get the appropriate UTM zone for it to do a good job. There are some simple codes available via googling to find an appropriate zone for a lat/long pair.
UTM很好,因为它是米,很容易处理。但是,您需要获得适当的UTM区域来完成工作。有一些简单的代码可以通过google搜索找到适合lat/long对的区域。
#6
6
The earth is an annoyingly irregular surface, so there is no simple formula to do this exactly. You have to live with an approximate model of the earth, and project your coordinates onto it. The model I typically see used for this is WGS 84. This is what GPS devices usually use to solve the exact same problem.
地球是一个不规则的不规则表面,所以没有一个简单的公式可以做到这一点。你必须与地球的一个近似模型共存,并将你的坐标投射到它上面。我通常看到的模型是WGS 84。这就是GPS设备通常用来解决完全相同的问题。
NOAA has some software you can download to help with this on their website.
美国国家海洋和大气管理局有一些软件可以在他们的网站上下载。
#7
4
One nautical mile (1852 meters) is defined as one arcminute of longitude at the equator. However, you need to define a map projection (see also UTM) in which you are working for the conversion to really make sense.
一海里(1852米)被定义为赤道上的一圈经度。但是,您需要定义一个映射投影(参见UTM),在这个投影中,您正在为转换工作而工作,从而真正有意义。
#8
4
Based on average distance for degress in the Earth.
基于地球上的平均距离。
1° = 111km;
1°= 111公里;
Converting this for radians and dividing for meters, take's a magic number for the RAD, in meters: 0.000008998719243599958;
将此转换为弧度,并将其划分为米,以米:0.000008998719243599958为RAD的一个神奇数字;
then:
然后:
const RAD = 0.000008998719243599958;
Math.sqrt(Math.pow(lat1 - lat2, 2) + Math.pow(long1 - long2, 2)) / RAD;
#9
3
There are quite a few ways to calculate this. All of them use aproximations of spherical trigonometry where the radius is the one of the earth.
有很多计算方法。它们都使用球面三角的近似值,其中半径是地球的一个。
try http://www.movable-type.co.uk/scripts/latlong.html for a bit of methods and code in different languages.
尝试使用不同语言的一些方法和代码:http://www.movabletype .co.uk/scripts/latlong.html。
#10
3
Here is the R version of b-h-'s function, just in case:
这里是b-h函数的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
}
#11
2
'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
#12
1
To convert latitude and longitude in x and y representation you need to decide what type of map projection to use. As for me, Elliptical Mercator seems very well. Here you can find an implementation (in Java too).
要在x和y表示中转换纬度和经度,您需要决定使用哪种类型的地图投影。对我来说,椭圆的墨卡托似乎很好。在这里您可以找到一个实现(在Java中也是)。
#13
0
If its sufficiently close you can get away with treating them as coordinates on a flat plane. This works on say, street or city level if perfect accuracy isnt required and all you need is a rough guess on the distance involved to compare with an arbitrary limit.
如果它足够接近,你可以把它们当作平面上的坐标。这是在说,街道或城市的水平,如果完美的准确性不需要,你所需要的只是一个粗略的猜测,涉及到与一个任意的限制的比较。
#14
-2
You need to convert the coordinates to radians to do the spherical geometry. Once converted, then you can calculate a distance between the two points. The distance then can be converted to any measure you want.
你需要把坐标转换成弧度来做球面几何。一旦转换,你就可以计算两个点之间的距离。这个距离可以转换成任何你想要的量。