Parsing latitude and longitude with Ruby
-
19-09-2019 - |
Question
I need to parse some user submitted strings containing latitudes and longitudes, under Ruby.
The result should be given in a double
Example:
08º 04' 49'' 09º 13' 12''
Result:
8.080278 9.22
I've looked to both Geokit and GeoRuby but haven't found a solution. Any hint?
Solution
"08° 04' 49'' 09° 13' 12''".gsub(/(\d+)° (\d+)' (\d+)''/) do
$1.to_f + $2.to_f/60 + $3.to_f/3600
end
#=> "8.08027777777778 9.22"
Edit: or to get the result as an array of floats:
"08° 04' 49'' 09° 13' 12''".scan(/(\d+)° (\d+)' (\d+)''/).map do |d,m,s|
d.to_f + m.to_f/60 + s.to_f/3600
end
#=> [8.08027777777778, 9.22]
OTHER TIPS
How about using a regular expression? Eg:
def latlong(dms_pair)
match = dms_pair.match(/(\d\d)º (\d\d)' (\d\d)'' (\d\d)º (\d\d)' (\d\d)''/)
latitude = match[1].to_f + match[2].to_f / 60 + match[3].to_f / 3600
longitude = match[4].to_f + match[5].to_f / 60 + match[6].to_f / 3600
{:latitude=>latitude, :longitude=>longitude}
end
Here's a more complex version that copes with negative coordinates:
def dms_to_degrees(d, m, s)
degrees = d
fractional = m / 60 + s / 3600
if d > 0
degrees + fractional
else
degrees - fractional
end
end
def latlong(dms_pair)
match = dms_pair.match(/(-?\d+)º (\d+)' (\d+)'' (-?\d+)º (\d+)' (\d+)''/)
latitude = dms_to_degrees(*match[1..3].map {|x| x.to_f})
longitude = dms_to_degrees(*match[4..6].map {|x| x.to_f})
{:latitude=>latitude, :longitude=>longitude}
end
Based on the form of your question, you are expecting the solution to handle negative coordinates correctly. If you weren't, then you'd be expecting an N or S following latitude and an E or W following longitude.
Please note that the accepted solution will not provide correct results with a negative coordinate. Only the degrees will be negative, and the minutes and seconds will be positive. In those cases where the degrees are negative, the minutes and seconds will move the coordinate closer to 0° rather than further away from 0°.
Will Harris' second solution is the better way to go.
Good luck!