Instantly share code, notes, and snippets.

# tomwhipple/dms2dec.py Created Sep 2, 2012

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)

### jelson commented Dec 21, 2013

 This code has several bugs. On line 34, re.search should be used instead of re.match -- match only matches the beginning of the string, whereas search finds the pattern anywhere. On line 41, the formula for conversion does not handle frac_seconds correctly; it assumes exactly one digit of frac_seconds is provided. I fixed it using the following: ``````frac_seconds_len = len(frac_seconds) frac_seconds = float(frac_seconds) for i in xrange(frac_seconds_len): frac_seconds = frac_seconds / 10.0 return sign * (int(degree) + float(minute) / 60 + float(second) / 3600 + float(frac_seconds) / 3600) ``````

### 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 commented May 6, 2016 • edited

 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 minute = numbers if len(numbers) >= 2 else '0' second = numbers if len(numbers) >= 3 else '0' frac_seconds = numbers 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.