require 'sugar-high/numeric' module GeoUnitExt ::GeoUnits.units.each do |unit_type| define_method "#{unit_type}_to" do |unit| unit = GeoUnits.normalized(unit) self.to_f * GeoUnits::Maps::Meters.from_unit[unit_type] * GeoUnits::Maps::Meters.to_unit[unit] end end include NumberDslExt # from sugar-high def to_rad GeoUnits::Converter.to_rad self end alias_method :to_radians, :to_rad alias_method :degrees_to_rad, :to_radians alias_method :deg_to_rad, :to_radians end class Numeric include GeoUnitExt include ::GeoUnits::Numeric include ::GeoUnits::Numeric::Dms include ::GeoUnits::Numeric::Normalizer end class String def parse_dms options = {} GeoUnits::Converter::Dms.parse_dms self, options end def to_lng self.match(/[E|W]/) ? self.to_i : nil end def to_lat self.match(/[N|S]/) ? self.to_i : nil end end class Array def to_dms direction = nil lng, lat = extract_coords(direction) res = direction == :lat_lng ? [lat.to_lat_dms, lng.to_lng_dms] : [lng.to_lng_dms, lat.to_lat_dms] res.join(', ') end def parse_dms direction = nil lng, lat = extract_coords(direction) direction == :lat_lng ? [lat.parse_dms, lng.parse_dms] : [lng.parse_dms, lat.parse_dms] end protected def extract_coords direction = nil direction ||= GeoUnits.default_coords_order unless [:lng_lat, :lat_lng].include? direction raise ArgumentError, "Direction must be either :lng_lat or :lat_lng, was: #{direction}. You can also set the default direction via GeoUnits#default_direction=" end lat_index = direction == :reverse ? 0 : 1 lng_index = direction == :reverse ? 1 : 0 lat = self.to_lat if self.respond_to?(:to_lat) lat ||= self[lat_index] if self[lat_index].respond_to?(:to_lat) && self[lat_index].to_lat lat ||= self[lng_index] if self[lng_index].respond_to?(:to_lat) && self[lng_index].to_lat lat ||= self[lat_index] lng = self.to_lng if self.respond_to?(:to_lng) lng ||= self[lng_index] if self[lng_index].respond_to?(:to_lng) && self[lng_index].to_lng lng ||= self[lat_index] if self[lat_index].respond_to?(:to_lng) && self[lat_index].to_lng lng ||= self[lng_index] [lng, lat] end end