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?
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""")
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")
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
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
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)
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.
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
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
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
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)
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?
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""")
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")
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
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
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)
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.
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
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
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
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)