Created
July 24, 2018 10:52
-
-
Save denisoster/5b04e60faaa60bb4c8ff0b40880e5376 to your computer and use it in GitHub Desktop.
Converting DMS DMM DD to latitude & longitude
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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