module FishingSites
Constants
- DEFAULT_MAX_KM
- QLD_LAT_RANGE
- QLD_LON_RANGE
Public Instance Methods
Source
# File lib/fishing_sites.rb, line 29 def find_port_by_name(location, sites:) needle = normalize_location(location) qld_sites = sites.select { |site| site["STATE_CODE"] == "QLD" } exact = qld_sites.find { |site| normalize_location(site["PORT_NAME"]) == needle } return port_hash(exact, match: :name) if exact starts_with = qld_sites.select { |site| normalize_location(site["PORT_NAME"]).start_with?(needle) } if starts_with.length == 1 return port_hash(starts_with.min_by { |site| site["PORT_NAME"].length }, match: :name) end return port_hash(starts_with.find { |site| normalize_location(site["PORT_NAME"]) == needle }, match: :name) if starts_with.any? includes = qld_sites.select { |site| normalize_location(site["PORT_NAME"]).include?(needle) } return port_hash(includes.min_by { |site| site["PORT_NAME"].length }, match: :name) if includes.length == 1 nil end
Source
# File lib/fishing_sites.rb, line 48 def nearest_port(coords, sites:, max_km: DEFAULT_MAX_KM) return nil unless coords candidates = sites.filter_map do |site| site_coords = site_coordinates(site) next unless site_coords distance_km = GeoLookup.distance_km(coords, site_coords) next if distance_km > max_km { site: site, distance_km: distance_km } end return nil if candidates.empty? best = candidates.min_by { |entry| entry[:distance_km] } port_hash(best[:site], match: :geo, distance_km: best[:distance_km].round(1)) end
Source
# File lib/fishing_sites.rb, line 19 def normalize_location(text) text.to_s.strip.downcase.gsub(/\s+/, " ") end
Source
# File lib/fishing_sites.rb, line 115 def port_hash(site, match:, matched_as: nil, distance_km: nil) return nil unless site { name: site["PORT_NAME"], aac: site["AAC"], timezone: site["TIME_ZONE"], state_code: site["STATE_CODE"], match: match, matched_as: matched_as, distance_km: distance_km }.compact end
Source
# File lib/fishing_sites.rb, line 102 def qld_coordinates?(coords) lat, lon = coords.map(&:to_f) QLD_LAT_RANGE.cover?(lat) && QLD_LON_RANGE.cover?(lon) end
Source
# File lib/fishing_sites.rb, line 83 def queensland_geocode?(result) return false unless result if result.respond_to?(:state_code) state = result.state_code.to_s.strip.upcase return true if state == "QLD" end if result.respond_to?(:state) state_name = result.state.to_s return true if state_name.match?(/queensland/i) end coords = GeoLookup.coordinates_for(result) return false unless coords qld_coordinates?(coords) end
Source
# File lib/fishing_sites.rb, line 23 def queensland_sites_from_json(data) payload = data.is_a?(String) ? JSON.parse(data) : data payload.fetch("features", []).map { |feature| feature["properties"] } .select { |properties| properties["STATE_CODE"] == "QLD" && properties["TYPE"] == "TIDE" } end
Source
# File lib/fishing_sites.rb, line 67 def resolve_port(location, sites:, geocode: nil, max_km: DEFAULT_MAX_KM) needle = normalize_location(location) named = find_port_by_name(needle, sites: sites) return named if named geocode_fn = geocode || ->(place) { GeoLookup.lookup_place(place) } result = geocode_fn.call(location) return nil unless queensland_geocode?(result) coords = GeoLookup.coordinates_for(result) nearest = nearest_port(coords, sites: sites, max_km: max_km) return nil unless nearest nearest.merge(match: :geo, matched_as: needle) end
Source
# File lib/fishing_sites.rb, line 107 def site_coordinates(site) lat = site["LAT"] lon = site["LON"] return nil if lat.nil? || lon.nil? [lat.to_f, lon.to_f] end