How to convert degree minute second to degree decimal

Question:

I receive the latitude and longitude from GPS with this format:

Latitude : 78°55’44.29458"N

I need convert this data to:

latitude: 78.9288888889

I found this code here: link

import re

def dms2dd(degrees, minutes, seconds, direction):
    dd = float(degrees) + float(minutes)/60 + float(seconds)/(60*60);
    if direction == 'E' or direction == 'S':
        dd *= -1
    return dd;

def dd2dms(deg):
    d = int(deg)
    md = abs(deg - d) * 60
    m = int(md)
    sd = (md - m) * 60
    return [d, m, sd]

def parse_dms(dms):
    parts = re.split('[^dw]+', dms)
    lat = dms2dd(parts[0], parts[1], parts[2], parts[3])
 
    return (lat)

dd = parse_dms("78°55'44.33324"N )

print(dd)

It is working for for this format

dd = parse_dms("78°55'44.33324'N" )

but it is not working for my datafromat. Can anyone help me to solve this problem?

Asked By: bikuser

||

Answers:

The problem is that the seconds 44.29458 are split at ..

You could either define the split characters directly (instead of where not to split):

>>> re.split('[°'"]+', """78°55'44.29458"N""")
['78', '55', '44.29458', 'N']

or leave the regular expression as it is and merge parts 2 and 3:

dms2dd(parts[0], parts[1], parts[2] + "." + parts[3], parts[4])

Update:

Your method call dd = parse_dms("78°55'44.33324"N ) is a syntax error. Add the closing " and escape the other one. Or use tripple quotes for the string definition:

parse_dms("""78°55'44.29458"N""")
Answered By: Falko

I have slightly modified the re:

parts = re.split('[^dw.]+', dms)

And as @Falko advised to make it work, you can either use double double quotes or escape your quotes characters

parse_dms("53°19'51.8"N")
Answered By: Lili

The function above (dms2dd) is incorrect.

Actual (With error):

if direction == ‘E’ or direction == ‘N’:
dd *= -1

Corrected Condition:

if direction == ‘W‘ or direction == ‘S‘:
dd *= -1

Answered By: Rodrigo Santiago

Here’s my one liner (fine, fine – maybe it’s two lines) 🙂

import re
lat = '''51°36'9.18"N'''
deg, minutes, seconds, direction =  re.split('[°'"]', lat)
(float(deg) + float(minutes)/60 + float(seconds)/(60*60)) * (-1 if direction in ['W', 'S'] else 1)

This outputs 51.60255

Answered By: Inti

For multiple coordinates, you can read them in using pandas. Formatting is important – there should not be any white spaces. White spaces can be removed using the replace function. The outputs can be easily saved as a text file or spreadsheet. I just printed them for validation and rounded the decimals locations out to 4.

### read input file
df = pd.read_excel('dms.xlsx')

n = len(df)

for i in range(n):
  Lat_d = round(parse_dms(df.Lat[i].replace(" ", "")),4)
  Long_d = round(parse_dms(df.Long[i].replace(" ", "")),4)
  print(Lat_d, Long_d)
Answered By: bfree67

I know this is an old question, but for whoever is following along, just thought I’d point out that you seem to have incorrect logic in your dms2dd() function regarding the sign of your decimals. You have:

if direction == 'E' or direction == 'N':
    dd *= -1

But it should only be negative if the direction is West (W) of the Prime Meridian or South (S) of the equator. So it should rather be:

if direction == 'W' or direction == 'S':
    dd *= -1

Here’s a quote from a thorough guide: https://www.ubergizmo.com/how-to/read-gps-coordinates/

The coordinate for the line of latitude represents north of the
Equator because it is positive. If the number is negative, it
represents south of the Equator.

[…] The coordinate for the line of longitude represents east of the
Prime Meridian because it is positive. If the number is negative, it
represents west of the Prime Meridian.

Answered By: Isaac Asante

You can use the function clean_lat_long() from the library DataPrep if your data is in a DataFrame. Install DataPrep with pip install dataprep.

from dataprep.clean import clean_lat_long
df = pd.DataFrame({"Latitude": ["78°55'44.29458''N", "51°36'9.18''N"]})

df2 = clean_lat_long(df, lat_col="Latitude")
            Latitude  Latitude_clean
0  78°55'44.29458''N         78.9290
1      51°36'9.18''N         51.6026
Answered By: victoria55

You can use this module https://pypi.org/project/dms2dec/

Convert DMS to Decimal.

Usage

from dms2dec.dms_convert import dms2dec

dms2dec('''36°44'47.69"N''') # converts to dec
dms2dec('''3° 2'33.53"E''') # converts to dec
Answered By: Victor Stanescu

You could simply use pygeodesy which is useful for many other functions anyway, like finding mid-points of coordinates, accurate distance and bearing calculations.

from pygeodesy import parse3llh, fstr

x = parse3llh('000° 00′ 05.31″W, 51° 28′ 40.12″ N')
print (fstr(x, prec=6))

Result

51.477811, -0.001475, 0.0
Answered By: BBSysDyn

https://github.com/medo-mi/dms-to-dd

import re

#Degrees Minutes Seconds to Decimal Degrees
def dms_dd(dd):
    dd = f"""{dd}"""
    dd = re.sub('[^a-zA-Z0-9. ]', '', dd)
    dd = dd.split(" ")
    return round(float(dd[0])+(float(dd[1])/60)+(float(dd[2])/3600), 8)
Answered By: medo-mi
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.