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?

Was it helpful?

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!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top