defmodule Microwaveprop.Geocoder do @moduledoc """ Thin wrapper around the Google Maps Geocoding API. Only used as a fallback when QRZ's own `` / `` fields are missing on a callsign record. """ @spec geocode(String.t()) :: {:ok, %{lat: float(), lon: float()}} | {:error, String.t()} def geocode(address) do Microwaveprop.Instrument.span([:geocoder, :geocode], %{}, fn -> case Req.get(client(), url: "/maps/api/geocode/json", params: [address: address, key: api_key()] ) do {:ok, %{status: 200, body: %{"status" => "OK", "results" => [first | _]}}} -> %{"geometry" => %{"location" => %{"lat" => lat, "lng" => lon}}} = first {:ok, %{lat: lat, lon: lon}} {:ok, %{status: 200, body: %{"status" => "ZERO_RESULTS"}}} -> {:error, "No results found"} {:ok, %{status: 200, body: %{"status" => status}}} -> {:error, "Geocoding failed: #{status}"} {:error, reason} -> {:error, "Geocoding request failed: #{inspect(reason)}"} end end) end defp client do config = Application.get_env(:microwaveprop, __MODULE__, []) [base_url: "https://maps.googleapis.com"] |> Req.new() |> Req.Request.register_options([:plug, :api_key]) |> Req.merge(config) end defp api_key do :microwaveprop |> Application.get_env(__MODULE__, []) |> Keyword.get(:api_key, "") end end