Module: GeoUnits::Converter::Dms
- Extended by:
- Dms
- Includes:
- NumericCheckExt
- Included in:
- Dms
- Defined in:
- lib/geo_units/converter/dms.rb
Defined Under Namespace
Classes: ParseError
Instance Method Summary collapse
- #parse_dms(dms_str, options = {}) ⇒ Object
-
#to_dms(deg, format = :dms, dp = nil) ⇒ Object
Convert decimal degrees to deg/min/sec format - degree, prime, double-prime symbols are added, but sign is discarded, though no compass direction is added.
Instance Method Details
#parse_dms(dms_str, options = {}) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/geo_units/converter/dms.rb', line 11 def parse_dms dms_str, = {} # check for signed decimal degrees without NSEW, if so return it directly return dms_str if is_numeric?(dms_str) raise ParseError, "DMS parse error: #{dms_str}" if !(dms_str =~ /[NSEW]$/) || (dms_str =~ /\./) # strip off any sign or compass dir'n & split out separate d/m/s dms = dms_str.strip.gsub(/^-/,'').gsub(/[NSEW]$/i,'').split(/[^0-9.,]+/).map(&:strip).map(&:to_f) return nil if dms.empty? # and convert to decimal degrees... deg = case dms.length when 3 # interpret 3-part result as d/m/s dms[0]/1 + dms[1]/60 + dms[2]/3600 when 2 # interpret 2-part result as d/m dms[0]/1 + dms[1]/60 when 1 # just d (possibly decimal) or non-separated dddmmss d = dms[0]; # check for fixed-width unseparated format eg 0033709W d = "0#{d}" if (/[NS]/i.match(dms_str)) # - normalise N/S to 3-digit degrees d = "#{d.slice(0,3)/1}#{deg.slice(3,5)/60}#{deg.slice(5)/3600}" if (/[0-9]{7}/.match(deg)) d else nil end raise ParseError, "DMS parse error: #{deg} for #{dms_str}" if !deg deg = (deg * -1) if (/^-|[WS]$/i.match(dms_str.strip)) # take '-', west and south as -ve deg.to_f end |
#to_dms(deg, format = :dms, dp = nil) ⇒ Object
Convert decimal degrees to deg/min/sec format
- degree, prime, double-prime symbols are added, but sign is discarded, though no compass
direction is added
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/geo_units/converter/dms.rb', line 54 def to_dms deg, format = :dms, dp = nil deg = begin deg.to_f rescue nil end return nil if !deg # give up here if we can't make a number from deg # default values format ||= :dms dp = if dp.nil? case format.to_sym when :d 4 when :dm 2 else 0 # default end end dp ||= 0 deg = deg.abs # (unsigned result ready for appending compass dir'n) case format when :d d = deg.round(dp) # round degrees ds = "0#{d}" if (d <100) # pad with leading zeros ds = "0#{ds}" if (d <10) dms = ds.to_s.concats("\u00B0") # add º symbol when :dm min = (deg*60).round(dp) # convert degrees to minutes & round d = d.to_i d = (min / 60).floor # get component deg/min m = (min % 60).round(dp) # pad with trailing zeros ds = d ms = m ds = "0#{d}" if (d<100) # pad with leading zeros ds = "0#{d}" if (d<10) ms = "0#{m}" if (m<10) dms = ds.to_s.concats("\u00B0", ms, "\u2032") # add º, ' symbols when :dms sec = (deg * 3600).round # convert degrees to seconds & round d = (sec / 3600).floor # get component deg/min/sec m = ((sec / 60) % 60).floor s = (sec % 60).round(dp) # pad with trailing zeros ds = d ms = m ss = s ds = "0#{d}" if (d < 100) # pad with leading zeros ds = "0#{ds}" if (d < 10) ms = "0#{m}" if (m < 10) ss = "0#{s}" if (s < 10) dms = ds.to_s.concats("\u00B0", ms, "\u2032", ss, "\u2033") # add º, ', " symbols end return dms end |