Skip to content

Instantly share code, notes, and snippets.

@denisoster
Created July 24, 2018 10:52
Show Gist options
  • Save denisoster/5b04e60faaa60bb4c8ff0b40880e5376 to your computer and use it in GitHub Desktop.
Save denisoster/5b04e60faaa60bb4c8ff0b40880e5376 to your computer and use it in GitHub Desktop.
Converting DMS DMM DD to latitude & longitude
parseDMS = (dmsString) ->
dmsString = dmsString.trim()
dmsRe = /([NSEW])?(-)?(\d+(?:\.\d+)?)[°º:d\s]?\s?(?:(\d+(?:\.\d+)?)['’‘′:]\s?(?:(\d{1,2}(?:\.\d+)?)(?:"|″|’’|'')?)?)?\s?([NSEW])?/i
result = {}
m1 = undefined
m2 = undefined
decDeg1 = undefined
decDeg2 = undefined
dmsString2 = undefined
m1 = dmsString.match(dmsRe)
if !m1
throw 'Could not parse string'
if m1[1]
m1[6] = undefined
dmsString2 = dmsString.substr(m1[0].length - 1).trim()
else
dmsString2 = dmsString.substr(m1[0].length).trim()
decDeg1 = decDegFromMatch(m1)
m2 = dmsString2.match(dmsRe)
decDeg2 = if m2 then decDegFromMatch(m2) else {}
if typeof decDeg1.latLon == 'undefined'
if !isNaN(decDeg1.decDeg) and isNaN(decDeg2.decDeg)
return decDeg1.decDeg
else if !isNaN(decDeg1.decDeg) and !isNaN(decDeg2.decDeg)
decDeg1.latLon = 'latitude'
decDeg2.latLon = 'longitude'
else
throw 'Could not parse string'
if typeof decDeg2.latLon == 'undefined'
decDeg2.latLon = if decDeg1.latLon == 'lat' then 'lon' else 'lat'
result[decDeg1.latLon] = decDeg1.decDeg
result[decDeg2.latLon] = decDeg2.decDeg
result
decDegFromMatch = (m) ->
signIndex =
'-': -1
'N': 1
'S': -1
'E': 1
'W': -1
latLonIndex =
'N': 'lat'
'S': 'lat'
'E': 'lon'
'W': 'lon'
degrees = undefined
minutes = undefined
seconds = undefined
sign = undefined
latLon = undefined
sign = signIndex[m[2]] or signIndex[m[1]] or signIndex[m[6]] or 1
degrees = Number(m[3])
minutes = if m[4] then Number(m[4]) else 0
seconds = if m[5] then Number(m[5]) else 0
latLon = latLonIndex[m[1]] or latLonIndex[m[6]]
if !inRange(degrees, 0, 180)
throw 'Degrees out of range'
if !inRange(minutes, 0, 60)
throw 'Minutes out of range'
if !inRange(seconds, 0, 60)
throw 'Seconds out of range'
{
decDeg: sign * (degrees + minutes / 60 + seconds / 3600)
latLon: latLon
}
inRange = (value, a, b) ->
value >= a and value <= b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment