lib/ndfd/client/query.rb
require 'active_support/time'
require 'active_support/time_with_zone'
Time.zone ||= "UTC"
require 'ndfd/client/query/query_property'
require 'ndfd/client/query/selection_attributes'
require 'ndfd/client/query/query_utilities'
module NDFD
class Client
class Query
FORECAST_ELEMENTS = {
:maxt => "Maximum Temperature",
:mint => "Minimum Temperature",
:temp => "3 Hourly Temperature",
:dew => "Dewpoint Temperature",
:appt => "Apparent Temperature",
:pop12 => "12 Hour Probability of Precipitation",
:qpf => "Liquid Precipitation Amount",
:snow => "Snowfall Amount",
:sky => "Cloud Cover Amount",
:rh => "Relative Humidity",
:wspd => "Wind Speed",
:wdir => "Wind Direction",
:wx => "Weather",
:icons => "Weather Icons",
:waveh => "Wave Height",
:incw34 => "Probabilistic Tropical Cyclone Wind Speed >34 Knots (Incremental)",
:incw50 => "Probabilistic Tropical Cyclone Wind Speed >50 Knots (Incremental)",
:incw64 => "Probabilistic Tropical Cyclone Wind Speed >64 Knots (Incremental)",
:cumw34 => "Probabilistic Tropical Cyclone Wind Speed >34 Knots (Cumulative)",
:cumw50 => "Probabilistic Tropical Cyclone Wind Speed >50 Knots (Cumulative)",
:cumw64 => "Probabilistic Tropical Cyclone Wind Speed >64 Knots (Cumulative)",
:wgust => "Wind Gust",
:critfireo => "Fire Weather from Wind and Relative Humidity",
:dryfireo => "Fire Weather from Dry Thunderstorms",
:conhazo => "Convective Hazard Outlook",
:ptornado => "Probability of Tornadoes",
:phail => "Probability of Hail",
:ptstmwinds => "Probability of Damaging Thunderstorm Winds",
:pxtornado => "Probability of Extreme Tornadoes",
:pxhail => "Probability of Extreme Hail",
:pxtstmwinds => "Probability of Extreme Thunderstorm Winds",
:ptotsvrtstm => "Probability of Severe Thunderstorms",
:pxtotsvrtstm => "Probability of Extreme Severe Thunderstorms",
:tmpabv14d => "Probability of 8- To 14-Day Average Temperature Above Normal",
:tmpblw14d => "Probability of 8- To 14-Day Average Temperature Below Normal",
:tmpabv30d => "Probability of One-Month Average Temperature Above Normal",
:tmpblw30d => "Probability of One-Month Average Temperature Below Normal",
:tmpabv90d => "Probability of Three-Month Average Temperature Above Normal",
:tmpblw90d => "Probability of Three-Month Average Temperature Below Normal",
:prcpabv14d => "Probability of 8- To 14-Day Total Precipitation Above Median",
:prcpblw14d => "Probability of 8- To 14-Day Total Precipitation Below Median",
:prcpabv30d => "Probability of One-Month Total Precipitation Above Median",
:prcpblw30d => "Probability of One-Month Total Precipitation Below Median",
:prcpabv90d => "Probability of Three-Month Total Precipitation Above Median",
:prcpblw90d => "Probability of Three-Month Total Precipitation Below Median",
:precipa_r => "Real-time Mesoscale Analysis Precipitation",
:sky_r => "Real-time Mesoscale Analysis GOES Effective Cloud Amount",
:td_r => "Real-time Mesoscale Analysis Dewpoint Temperature",
:temp_r => "Real-time Mesoscale Analysis Temperature",
:wdir_r => "Real-time Mesoscale Analysis Wind Direction",
:wspd_r => "Real-time Mesoscale Analysis Wind Speed",
:wwa => "Watches, Warnings, and Advisories",
:iceaccum => "Ice Accumulation",
:maxrh => "Maximum Relative Humidity",
:minrh => "Minimum Relative Humidity"
}
attr_reader :soap_client, :select_attributes, :conditions
def initialize(soap_client, select_attributes = [])
@soap_client = soap_client
@select_attributes = select_attributes
@conditions = {}
end
def where(params)
conditions.merge!(params)
set_defaults_as_needed
self
end
def execute
raise NotImplementedError, "Must be implemented in subclass."
end
def validate
validate_selection_attributes
validate_conditions
end
class << self
def properties
@@properties ||= {}
end
def property(attr, options = {})
properties[self] ||= []
properties[self] << QueryProperty.new(attr, options)
end
def selection_attributes
@@selection_attributes ||= {}
end
def set_selection_attributes(*attrs)
selection_attributes[self] = SelectionAttributes.new(attrs)
end
end
protected
def available_selections
self.class.selection_attributes[self.class]
end
def set_defaults_as_needed
query_properties = self.class.properties[self.class]
return unless query_properties
query_properties.select(&:default).each do |query_property|
next if conditions.has_key?(query_property.name)
conditions.merge!(query_property.name => query_property.default)
end
end
def validate_selection_attributes
select_attributes.each do |attr|
available_selections && available_selections.valid?(attr)
end
end
def validate_conditions
query_properties = self.class.properties[self.class]
return unless query_properties
query_properties.each do |query_property|
query_property.valid?(conditions)
end
end
end
end
end
require 'ndfd/client/query/select_by_days_query'
require 'ndfd/client/query/select_coordinates_by_cities_query'
require 'ndfd/client/query/select_coordinates_by_zip_query'
require 'ndfd/client/query/select_corner_coordinates_query'
require 'ndfd/client/query/select_gridpoint_coordinates_query'
require 'ndfd/client/query/select_linepoint_coordinates_query'
require 'ndfd/client/query/select_square_coordinates_query'
require 'ndfd/client/query/select_query'