Current section
Files
Jump to
Current section
Files
lib/what3words.ex
defmodule What3Words do
@moduledoc """
What3Words is the main module to interact with the w3w API.
It includes calls to the three current endpoints: `words_to_position/2`,
`position_to_words/2` and `languages/2`.
To use the What3Words API, be sure to have your API key set up in your `config.exs`:
config :what3words, key: "yourkey"
"""
@client Application.get_env(:what3words, :client, What3Words.Client)
import What3Words.Extractor
# Types
#######
@type lat :: float()
@type lng :: float()
@type w3w :: {String.t, String.t, String.t}
@type coords :: {lat, lng}
@spec words_to_position(w3w, Keyword.t) :: coords
@doc """
Translates a tuple of 3 words into a `{lat, lng}` tuple.
An optional `opts` keyword argument can be passed: the opts cited [in the w3w API documentation](http://developer.what3words.com/api) are supported, plus a `:raw` option is supported, for retrieving the whole response from the API.
iex> What3Words.words_to_position({"home", "index", "raft"})
{:ok, {40.723008, -74.199598}}
iex> What3Words.words_to_position({"home", "index", "raft"}, raw: true)
{:ok, %{language: "en", position: [40.723008, -74.199598], type: "3 words", words: ["home", "index", "raft"]}}
"""
def words_to_position(words, opts \\ []) do
words
|> make_path(opts)
|> @client.get!
|> extract(:coordinates, opts[:raw])
end
@spec position_to_words(coords, Keyword.t) :: w3w
@doc """
Translates a tuple `{lat, lng}` into a tuple of 3 words.
An optional `opts` keyword argument can be passed: the opts cited [in the w3w API documentation](http://developer.what3words.com/api) are supported, plus a `:raw` option is supported, for retrieving the whole response from the API.
iex> What3Words.position_to_words({40.723008, -74.199598})
{:ok, {"home", "index", "raft"}}
iex> What3Words.position_to_words({40.723008, -74.199598}, raw: true)
{:ok, %{language: "en", position: [40.723008, -74.199598], words: ["home", "index", "raft"]}}
"""
def position_to_words(coords, opts \\ []) do
coords
|> make_path(opts)
|> @client.get!
|> extract(:words, opts[:raw])
end
@spec languages(Keyword.t) :: [String.t]
@doc """
Retrieves all available languages from the w3w API.
An optional `opts` keyword argument can be passed: the opts cited [in the w3w API documentation](http://developer.what3words.com/api) are supported, plus a `:raw` option is supported, for retrieving the whole response from the API.
iex> What3Words.languages
{:ok, ["en", "fr"]}
iex> What3Words.languages(raw: true)
{:ok, %{languages: [%{"code" => "en", "name_display" => "English"}, %{"code" => "fr", "name_display" => "French"}]}}
"""
def languages(opts \\ []) do
opts
|> make_path
|> @client.get!
|> extract(:languages, opts[:raw])
end
@spec words_to_position!(w3w, Keyword.t) :: coords
def words_to_position!(words, opts \\ []) do
{:ok, result} = words_to_position(words, opts)
result
end
@spec position_to_words!(coords, Keyword.t) :: w3w
def position_to_words!(words, opts \\ []) do
{:ok, result} = position_to_words(words, opts)
result
end
@spec languages!(Keyword.t) :: [String.t]
def languages!(opts \\ []) do
{:ok, result} = languages(opts)
result
end
# Private implementation
########################
@api_token Application.get_env(:what3words, :key)
defp make_path({w1, w2, w3}, opts) do
[key: @api_token, string: "#{w1}.#{w2}.#{w3}"] |> do_make_path("w3w", opts)
end
defp make_path({lat, lng}, opts) do
[key: @api_token, position: "#{lat}, #{lng}"] |> do_make_path("position", opts)
end
defp make_path(opts) do
[key: @api_token] |> do_make_path("get-languages", opts)
end
defp do_make_path(query, path, opts) do
query = query |> Keyword.merge(opts) |> URI.encode_query
"/#{path}?#{query}"
end
end