Skip to content

Instantly share code, notes, and snippets.

@tomwhipple
Created September 2, 2012 16:25
Show Gist options
  • Save tomwhipple/3601130 to your computer and use it in GitHub Desktop.
Save tomwhipple/3601130 to your computer and use it in GitHub Desktop.
convert DMS coordinates to decimal in Python
#!/env/python
# coding=utf8
"""
Converting Degrees, Minutes, Seconds formatted coordinate strings to decimal.
Formula:
DEC = (DEG + (MIN * 1/60) + (SEC * 1/60 * 1/60))
Assumes S/W are negative.
"""
import re
def dms2dec(dms_str):
"""Return decimal representation of DMS
>>> dms2dec(utf8(48°53'10.18"N))
48.8866111111F
>>> dms2dec(utf8(2°20'35.09"E))
2.34330555556F
>>> dms2dec(utf8(48°53'10.18"S))
-48.8866111111F
>>> dms2dec(utf8(2°20'35.09"W))
-2.34330555556F
"""
dms_str = re.sub(r'\s', '', dms_str)
if re.match('[swSW]', dms_str):
sign = -1
else:
sign = 1
(degree, minute, second, frac_seconds, junk) = re.split('\D+', dms_str, maxsplit=4)
return sign * (int(degree) + float(minute) / 60 + float(second) / 3600 + float(frac_seconds) / 36000)
@Nodd
Copy link

Nodd commented Aug 19, 2014

I used something simpler for frac_seconds:

second += "." + frac_seconds
return sign * (int(degree) + float(minute) / 60 + float(second) / 3600)

@jeteon
Copy link

jeteon commented May 6, 2016

Also assumes a very rigid format in line 39. This also chokes on something like S26d15'10" as the degree variable would then be an empty string. I changed this to:

    numbers = filter(len, re.split('\D+', dms_str, maxsplit=4))       # Use filter function to remove empty strings from result
    degree = numbers[0]
    minute = numbers[1] if len(numbers) >= 2 else '0'
    second = numbers[2] if len(numbers) >= 3 else '0'
    frac_seconds = numbers[3] if len(numbers) >= 4 else '0'

I put up a fork with this fix and the fixes mentioned by others here: https://gist.github.com/jeteon/89c41e4081d87b798d8006b16a52c695.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment