module BomLocationApi
BomLocationApi — resolve place names via BOM autocomplete API.
Constants
- CAPITAL_STATION_IDS
- STATE_API
Public Instance Methods
Source
# File lib/bom_location_api.rb, line 27 def autocomplete(name, fetch:) query = URI.encode_www_form_component(name.to_s.strip) data = BomApi.fetch_json("/locations/places/autocomplete?name=#{query}", fetch: fetch) data["candidates"] || [] end
Source
# File lib/bom_location_api.rb, line 70 def observation_station_id(candidates, place) CAPITAL_STATION_IDS[place["id"]] || candidates.find { |entry| entry["type"] == "bom_stn" && entry["name"].to_s.start_with?(place["name"]) }&.[]("id")&.to_i end
Source
# File lib/bom_location_api.rb, line 59 def pick_place(places, search_name, slug) return nil if places.empty? exact = places.find { |entry| entry["name"].casecmp?(search_name) } return exact if exact slug_name = slug.tr("-", " ") places.find { |entry| entry["name"].casecmp?(slug_name) } || places.first end
Source
# File lib/bom_location_api.rb, line 33 def resolve(location, state: nil, fetch:) parsed = BomForecast.parse_location(location) search_name = parsed[:slug].tr("-", " ") return nil if search_name.empty? state_key = state || parsed[:state] api_state = STATE_API[state_key] if state_key candidates = autocomplete(search_name, fetch: fetch) places = candidates.select { |entry| entry["type"] == "place" } places = places.select { |entry| entry["state"] == api_state } if api_state place = pick_place(places, search_name, parsed[:slug]) return nil unless place grid = place.dig("gridcells", "forecast") return nil unless grid && grid["x"] && grid["y"] { id: place["id"], name: place["name"], grid: grid, timezone: place["timezone"], station_id: observation_station_id(candidates, place) } end