lib/barometer/query.rb in attack-barometer-0.1.0 vs lib/barometer/query.rb in attack-barometer-0.2.3

- old
+ new

@@ -29,24 +29,27 @@ def initialize(query=nil) @q = query self.analyze! end - # analyze the saved query to determine the format. for the format of - # :zipcode and :postalcode the country_code can also be set + # analyze the saved query to determine the format. def analyze! return unless @q if Barometer::Query.is_us_zipcode?(@q) @format = :zipcode + @country_code = Barometer::Query.format_to_country_code(@format) elsif Barometer::Query.is_canadian_postcode?(@q) @format = :postalcode + @country_code = Barometer::Query.format_to_country_code(@format) elsif Barometer::Query.is_coordinates?(@q) @format = :coordinates + elsif Barometer::Query.is_icao?(@q) + @format = :icao +# @country_code = Barometer::Query.icao_to_country_code(@q) else @format = :geocode end - @country_code = Barometer::Query.format_to_country_code(@format) end # take a list of acceptable (and ordered by preference) formats and convert # the current query (q) into the most preferred and acceptable format. as a # side effect of some conversions, the country_code might be known, then save it @@ -91,10 +94,11 @@ def zipcode?; @format == :zipcode; end def postalcode?; @format == :postalcode; end def coordinates?; @format == :coordinates; end def geocode?; @format == :geocode; end + def icao?; @format == :icao; end def self.is_us_zipcode?(query) us_zipcode_regex = /(^[0-9]{5}$)|(^[0-9]{5}-[0-9]{4}$)/ return !(query =~ us_zipcode_regex).nil? end @@ -110,16 +114,29 @@ def self.is_coordinates?(query) coordinates_regex = /^[-]?[0-9\.]+[,]{1}[-]?[0-9\.]+$/ return !(query =~ coordinates_regex).nil? end + def self.is_icao?(query) + # allow any 3 or 4 letter word ... unfortunately this means some locations + # (ie Utah, Goa, Kiev, etc) will be detected as ICAO. This won't matter for + # returning weather results ... it will just effect what happens to the query. + # For example, wunderground will accept :icao above :coordinates and :geocode, + # which means that a city like Kiev would normally get converted to :coordinates + # but in this case it will be detected as :icao so it will be passed as is. + # Currently, only wunderground accepts ICAO, and they process ICAO the same as a + # city name, so it doesn't matter. + icao_regex = /^[A-Za-z]{3,4}$/ + return !(query =~ icao_regex).nil? + end + # # CONVERTERS # # this will take all query formats and convert them to coordinates - # accepts- :zipcode, :postalcode, :geocode + # accepts- :zipcode, :postalcode, :geocode, :icao # returns- :coordinates # if the conversion fails, return nil def self.to_coordinates(query, format) country_code = self.format_to_country_code(format) geo = self.geocode(query, country_code) @@ -127,11 +144,11 @@ return nil unless geo && geo.longitude && geo.latitude ["#{geo.latitude},#{geo.longitude}", country_code, geo] end # this will take all query formats and convert them to coorinates - # accepts- :zipcode, :postalcode, :coordinates + # accepts- :zipcode, :postalcode, :coordinates, :icao # returns- :geocode def self.to_geocode(query, format) perform_geocode = false perform_geocode = true if self.has_geocode_key? @@ -141,12 +158,21 @@ country_code = self.format_to_country_code(format) if perform_geocode geo = self.geocode(query, country_code) country_code ||= geo.country_code if geo - return nil unless geo && geo.locality && geo.region && geo.country - return ["#{geo.locality}, #{geo.region}, #{geo.country}", country_code, geo] + # different formats have different acceptance criteria + q = nil + case format + when :icao + return nil unless geo && geo.address && geo.country + q = "#{geo.address}, #{geo.country}" + else + return nil unless geo && geo.locality && geo.region && geo.country + q = "#{geo.locality}, #{geo.region}, #{geo.country}" + end + return [q, country_code, geo] else # without geocoding, the best we can do is just make use the given query as # the query for the "geocode" format return [query, country_code, nil] end @@ -205,11 +231,10 @@ :output => "xml", :q => query }, :format => :xml )['kml']['Response'] - #puts location.inspect geo = Barometer::Geo.new(location) end def self.format_to_country_code(format) return nil unless format @@ -221,8 +246,32 @@ else country_code = nil end country_code end + + # todo, the fist letter in a 4-letter icao can designate country: + # c=canada + # k=usa + # etc... + # def self.icao_to_country_code(icao_code) + # return unless icao_code.is_a?(String) + # country_code = nil + # if icao_code.size == 4 + # case icao_code.first_letter + # when "C" + # country_code = "CA" + # when "K" + # country_code = "US" + # end + # if coutry_code.nil? + # case icao_code.first_two_letters + # when "ET" + # country_code = "GERMANY" + # end + # end + # end + # country_code + # end end end