@@ -93,11 +93,7 @@ defmodule Mobilizon.Service.Geospatial.Addok do
|
||||
if is_nil(value), do: url, else: do_add_parameter(url, key, value)
|
||||
end
|
||||
|
||||
@spec do_add_parameter(String.t(), :coords | :type, %{lat: float, lon: float} | :administrative) ::
|
||||
String.t()
|
||||
defp do_add_parameter(url, :coords, coords),
|
||||
do: "#{url}&lat=#{coords.lat}&lon=#{coords.lon}"
|
||||
|
||||
@spec do_add_parameter(String.t(), :type, :administrative | atom()) :: String.t()
|
||||
defp do_add_parameter(url, :type, :administrative),
|
||||
do: "#{url}&type=municipality"
|
||||
|
||||
|
||||
@@ -31,16 +31,18 @@ defmodule Mobilizon.Service.Geospatial.GoogleMaps do
|
||||
@doc """
|
||||
Google Maps implementation for `c:Mobilizon.Service.Geospatial.Provider.geocode/3`.
|
||||
"""
|
||||
@spec geocode(String.t(), keyword()) :: list(Address.t()) | no_return
|
||||
@spec geocode(float(), float(), keyword()) :: list(Address.t())
|
||||
def geocode(lon, lat, options \\ []) do
|
||||
url = build_url(:geocode, %{lon: lon, lat: lat}, options)
|
||||
|
||||
Logger.debug("Asking Google Maps for reverse geocode with #{url}")
|
||||
|
||||
with {:ok, %{status: 200, body: body}} <- GeospatialClient.get(url),
|
||||
%{"results" => results, "status" => "OK"} <- body do
|
||||
Enum.map(results, fn entry -> process_data(entry, options) end)
|
||||
else
|
||||
%Tesla.Env{status: 200, body: body} = GeospatialClient.get!(url)
|
||||
|
||||
case body do
|
||||
%{"results" => results, "status" => "OK"} ->
|
||||
Enum.map(results, &process_data(&1, options))
|
||||
|
||||
%{"status" => "REQUEST_DENIED", "error_message" => error_message} ->
|
||||
raise ArgumentError, message: to_string(error_message)
|
||||
end
|
||||
@@ -50,16 +52,18 @@ defmodule Mobilizon.Service.Geospatial.GoogleMaps do
|
||||
@doc """
|
||||
Google Maps implementation for `c:Mobilizon.Service.Geospatial.Provider.search/2`.
|
||||
"""
|
||||
@spec search(String.t(), keyword()) :: list(Address.t()) | no_return
|
||||
@spec search(String.t(), keyword()) :: list(Address.t())
|
||||
def search(q, options \\ []) do
|
||||
url = build_url(:search, %{q: q}, options)
|
||||
|
||||
Logger.debug("Asking Google Maps for addresses with #{url}")
|
||||
|
||||
with {:ok, %{status: 200, body: body}} <- GeospatialClient.get(url),
|
||||
%{"results" => results, "status" => "OK"} <- body do
|
||||
results |> Enum.map(fn entry -> process_data(entry, options) end)
|
||||
else
|
||||
%Tesla.Env{status: 200, body: body} = GeospatialClient.get!(url)
|
||||
|
||||
case body do
|
||||
%{"results" => results, "status" => "OK"} ->
|
||||
results |> Enum.map(fn entry -> process_data(entry, options) end)
|
||||
|
||||
%{"status" => "REQUEST_DENIED", "error_message" => error_message} ->
|
||||
raise ArgumentError, message: to_string(error_message)
|
||||
|
||||
@@ -68,7 +72,7 @@ defmodule Mobilizon.Service.Geospatial.GoogleMaps do
|
||||
end
|
||||
end
|
||||
|
||||
@spec build_url(atom(), map(), list()) :: String.t() | no_return
|
||||
@spec build_url(:search | :geocode, map(), list()) :: String.t() | no_return
|
||||
defp build_url(method, args, options) do
|
||||
limit = Keyword.get(options, :limit, 10)
|
||||
lang = Keyword.get(options, :lang, "en")
|
||||
@@ -97,6 +101,7 @@ defmodule Mobilizon.Service.Geospatial.GoogleMaps do
|
||||
URI.encode(uri)
|
||||
end
|
||||
|
||||
@spec process_data(map(), Keyword.t()) :: Address.t()
|
||||
defp process_data(
|
||||
%{
|
||||
"formatted_address" => description,
|
||||
@@ -148,16 +153,18 @@ defmodule Mobilizon.Service.Geospatial.GoogleMaps do
|
||||
end
|
||||
end
|
||||
|
||||
@spec do_fetch_place_details(String.t() | nil, Keyword.t()) :: String.t() | no_return
|
||||
@spec do_fetch_place_details(String.t() | nil, Keyword.t()) :: String.t() | nil
|
||||
defp do_fetch_place_details(place_id, options) do
|
||||
url = build_url(:place_details, %{place_id: place_id}, options)
|
||||
|
||||
Logger.debug("Asking Google Maps for details with #{url}")
|
||||
|
||||
with {:ok, %{status: 200, body: body}} <- GeospatialClient.get(url),
|
||||
%{"result" => %{"name" => name}, "status" => "OK"} <- body do
|
||||
name
|
||||
else
|
||||
%Tesla.Env{status: 200, body: body} = GeospatialClient.get!(url)
|
||||
|
||||
case body do
|
||||
%{"result" => %{"name" => name}, "status" => "OK"} ->
|
||||
name
|
||||
|
||||
%{"status" => "REQUEST_DENIED", "error_message" => error_message} ->
|
||||
raise ArgumentError, message: to_string(error_message)
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ defmodule Mobilizon.Service.Geospatial.Provider do
|
||||
%Address{}
|
||||
"""
|
||||
@callback geocode(longitude :: number, latitude :: number, options :: keyword) ::
|
||||
[Address.t()] | {:error, atom()}
|
||||
[Address.t()]
|
||||
|
||||
@doc """
|
||||
Search for an address
|
||||
@@ -63,23 +63,21 @@ defmodule Mobilizon.Service.Geospatial.Provider do
|
||||
iex> search("10 rue Jangot")
|
||||
%Address{}
|
||||
"""
|
||||
@callback search(address :: String.t(), options :: keyword) :: [Address.t()] | {:error, atom()}
|
||||
@callback search(address :: String.t(), options :: keyword) :: [Address.t()]
|
||||
|
||||
@doc """
|
||||
Returns a `Geo.Point` for given coordinates
|
||||
"""
|
||||
@spec coordinates([number | String.t()], number) :: Geo.Point.t() | nil
|
||||
def coordinates(coords, srid \\ 4326)
|
||||
|
||||
def coordinates([x, y], srid) when is_number(x) and is_number(y) do
|
||||
%Geo.Point{coordinates: {x, y}, srid: srid}
|
||||
@spec coordinates([number | String.t()]) :: Geo.Point.t() | nil
|
||||
def coordinates([x, y]) when is_number(x) and is_number(y) do
|
||||
%Geo.Point{coordinates: {x, y}, srid: 4326}
|
||||
end
|
||||
|
||||
def coordinates([x, y], srid) when is_binary(x) and is_binary(y) do
|
||||
%Geo.Point{coordinates: {String.to_float(x), String.to_float(y)}, srid: srid}
|
||||
def coordinates([x, y]) when is_binary(x) and is_binary(y) do
|
||||
%Geo.Point{coordinates: {String.to_float(x), String.to_float(y)}, srid: 4326}
|
||||
end
|
||||
|
||||
def coordinates(_, _), do: nil
|
||||
def coordinates(_), do: nil
|
||||
|
||||
@spec endpoint(atom()) :: String.t()
|
||||
def endpoint(provider) do
|
||||
|
||||
Reference in New Issue
Block a user