Convert Latitude Longitude to Degree Minutes Seconds for Maps

Hello World!

If you have ever done mapping applications, you may have encountered needing to do this.  It takes a lot of looking around the internet to finally find the right equation etc.  For our application, we need to do this for google maps, as it does not take a latitude/longitude combination like bing maps.  If you choose to support ONLY bing maps, your job is easy, as here is the format: http://www.bing.com/maps/default.aspx?q=LATITUDE%2c+LONGITUDE (include negative signs if necessary).  However Google maps requires more work (UGH!) https://www.google.com/maps/place/LATITUDE <directional> LONGITUDE <directional>, ZOOM (with various encoded separators).

This article goes through the code that converts latitude longitude like you will pull from a phone’s gps into the DMS format needed by google maps.  Again, you don’t even need to bother with this conversion if you choose to use bing maps, it is simply as stated above.

Conversion

So if you want to read more about geographic coordinates and coordinate systems, I suggest reading the Wikipedia page.  But for now, lets just understand the basic concept is that latitude longitude is two numbers between -180 and +180 to describe a specific location on an ellipsoid given a specific map or coordinate projection.  To read more map projections, check out this page.  The system google uses is described as degrees, minutes and seconds.  This really only becomes important during the lat/long conversion after the decimal point.  Lets just look at the specific code.

    ///Converts Floating Point Numbers to Degrees, Minutes, Seconds for google.
    let ConvertFloatToDMS(loc:float32) =
        //split the decimal away.
        let vals = loc.ToString().Split('.')
        //degrees is prior to the decimal
        let degrees = float(vals.[0])
        //create a temporary holder
        let temp = "0." + vals.[1]
        //calculate total number of seconds
        let tSeconds = float(temp) * 3600.0
        //grab minutes, and remove decimals
        let minutes = floor(tSeconds / 60.0)
        //remove minutes from seconds to get total remaining
        let seconds = tSeconds - (minutes * 60.0)
        //do some rounding
        let seconds = round(seconds)
        //separate sign for easier manipulation later.
        match degrees < 0.0 with
        | true -> 
            let degrees = degrees * -1.0
            [|degrees.ToString(); minutes.ToString(); seconds.ToString(); "-1"|]
        | false -> [|degrees.ToString(); minutes.ToString(); seconds.ToString(); "1"|]

So lets look at this.  First, there are 60 minutes in a degree and 60 seconds in a minute.  Therefor, we need to multiply the decimal by 3600 to get the total number of seconds.  Dividing this number by 60 gives us the total minutes.  We then want to take the total seconds and remove the number of minutes (as seconds) to get the remainder, which is then our seconds.  We round this to keep our url short incase we get something like .33333333333 etc etc.

Converting sign into directional

    ///Takes in the Degree Arrays Produced and converts the final number into N, E, S, W 
    ///Used for correct representation on maps
    let generateMods(latDMS:array<string>, lonDMS:array<string>) =
        match latDMS.[3], lonDMS.[3] with
        | "1" , "1" -> [|"N"; "E"|]
        | "-1" , "1" -> [|"S"; "E"|]
        | "1" , "-1" -> [|"N"; "W"|]
        | _ , _ -> [|"S"; "W"|]

North and East is represented as positive signs.  This goes back to graphs and how the projection works.  Top right is +,+ while bottom left (SW) is -,-.

Produce the final link

    ///Takes Latitude and Longitude
    ///Produces a Google Maps link that can provide directions
    let CreateGoogleLink(latitude:float32, longitude:float32) =
        let uriBase = "https://www.google.com/maps/place/"
        let dmsLat = latitude |> ConvertFloatToDMS
        let dmsLon = longitude |> ConvertFloatToDMS
        let mods = generateMods(dmsLat, dmsLon)
        let latPortion = dmsLat.[0] + "%C2%B0" + dmsLat.[1] + "'" + dmsLat.[2] + "%22" + mods.[0]
        let lonPortion = dmsLon.[0] + "%C2%B0" + dmsLon.[1] + "'" + dmsLon.[2] + "%22" + mods.[1]
        uriBase + latPortion + "+" + lonPortion + "/@" + latitude.ToString() + "," + longitude.ToString() + ",18z"

The final link has everything to do with the taxonomy of how google builds its map links.  We are taking the base uri adding in our lat/long portions including the directional modifiers and initiating a zoom of 18.  This produces a really nice effect.  You can now take any gps location provided in the format Latitude, Longitude and convert to a format that google takes for its maps, or better yet, just use bing, because you don’t have to do any of that crazy math.

Summary

So building mapping applications definitely as of today is easier with Bing.  The api’s are just cleaner and therefor less conversion necessary and reduces the load on my servers.  The bing team has done a good job here and aligned their api with the common formats and projections of most gps devices.  Google went the other direction for whatever reason and incurred this extra work.  My theory on software is to support everything, so there you go!

For final reference, here is the bing taxonomy:

http://www.bing.com/maps/default.aspx?q=LATITUDE%2c+LONGITUDE

example: http://www.bing.com/maps/default.aspx?q=35.777915%2c+-78.638987

Leave a Reply

Your email address will not be published. Required fields are marked *