math - How to convert latitude or longitude to meters?


Translate

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)?

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?


All Answers
  • Translate

    Here is a javascript function:

    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

    The haversine formula determines the great-circle distance between two points on a sphere given their longitudes and latitudes.


  • Translate

    Given you're looking for a simple formula, this is probably the simplest way to do it, assuming that the Earth is a sphere with a circumference of 40075 km.

    Length in meters of 1° of latitude = always 111.32 km

    Length in meters of 1° of longitude = 40075 km * cos( latitude ) / 360


  • Translate

    For approximating short distances between two coordinates I used formulas from 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.

    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.


  • Translate

    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.


  • Translate

    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.

    NOAA has some software you can download to help with this on their website.


  • Translate

    There are many tools that will make this easy. See monjardin's answer for more details about what's involved.

    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.

    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.


  • Translate

    Here is the R version of b-h-'s function, just in case:

    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
    }
    

  • Translate

    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.


  • Translate

    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.


  • Translate

    Based on average distance for degress in the Earth.

    1° = 111km;

    Converting this for radians and dividing for meters, take's a magic number for the RAD, in meters: 0.000008998719243599958;

    then:

    const RAD = 0.000008998719243599958;
    Math.sqrt(Math.pow(lat1 - lat2, 2) + Math.pow(long1 - long2, 2)) / RAD;
    

  • Translate
        '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
    

  • Martha Lee
    Translate

    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).


  • Translate

    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.


  • Translate

    If you want a simple solution then use the Haversine formula as outlined by the other comments. If you have an accuracy sensitive application keep in mind the Haversine formula does not guarantee an accuracy better then 0.5% as it is assuming the earth is a circle. To consider that Earth is a oblate spheroid consider using Vincenty's formulae. Additionally, I'm not sure what radius we should use with the Haversine formula: {Equator: 6,378.137 km, Polar: 6,356.752 km, Volumetric: 6,371.0088 km}.


  • Translate

    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.