Packages

NioGoogleGeocoder is a collection of Elixir convenience functions to geocode a single, or list of, addresses. It also includes a function that automatically adds a geo location to an `Ecto.Changeset`.

Current section

Files

Jump to
nio_google_geocoder lib nio_google_geocoder.ex
Raw

lib/nio_google_geocoder.ex

defmodule NioGoogleGeocoder do
@moduledoc """
This module provides simple wrapper functions to request geocode information
from Google based on a single or list of addresses.
"""
@api_key Application.get_env(:nio_google_geocoder, :api_key) || nil
@url_endpoint "https://maps.googleapis.com/maps/api/geocode/json?"
@doc """
Returns a tuple or list of tuples of geocoding results
"""
def geocode(address) when is_binary(address) do
address
|> build_query(@api_key)
|> URI.encode
|> build_url
|> get
end
def geocode([]), do: []
def geocode([h|t]), do: [geocode(h) | geocode(t)]
def geocode(_), do: {:error, "Geocode requires a string or list of strings."}
# Joins the query params
defp build_query(address, nil), do: "address=" <> address
defp build_query(address, key), do: "address=" <> address <> "&key=" <> key
# Joins encoded query params to the base url
defp build_url(query), do: @url_endpoint <> query
# Executes the geocoding request and returns a tuple starting with :ok or :error
defp get(url) do
HTTPoison.start
case HTTPoison.get(url, [], []) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}}
->
case body |> Poison.decode! do
%{"results" => results, "status" => _}
-> {:ok, results}
%{"error_message" => message, "results" => _, "status" => status}
-> {:error, status <> ": " <> message}
end
{:error, %HTTPoison.Error{id: _, reason: error}}
-> {:error, error}
end
end
end