Geo encoding a location Part 3
Project source code: https://github.com/antp/locations
GEO encoding an address
Before an address can be located, the user needs a mechanism to enter an address. A Phoenix LiveView UI is included in the project to enable the entering, editing, deletion and geolocating of an address.
Once a location is saved, the user can select the get Map
button to trigger the GEO location process.
This starts with a call to the location context Locations.get_map_for(location)
function. This delegates to the following module to perform the encoding.
defmodule Locations.Location.GetMapFor do
alias Locations.GeoEncode.{
Address,
Lookup,
Nominatim
}
def call(location) do
address = Address.build_address(location)
case Lookup.geoencode(address) do
{:ok, 200, response} ->
Nominatim.get_location(response)
other ->
other
end
end
end
The responsibilities of the three modules Address
, Lookup
and Nominatim
are simple and they cooperate to obtain the geographical information.
- The
Address
module, purely converts a location to a query string to be used by Nominatim. - The
Lookup
module queries the Nominatim service and on success converts the result from JSON to an elixir struct. - The
Nominatim
module, extracts the features from the data returned from the lookup stage.
Any errors are returned to the caller. In most cases this will be because the user has an error in the entered address.
The code for these modules can be found in lib\locations\geo_encode
.
By creating the struct:
%{
addr1: “Dinton Village Hall”,
addr2: “Upton Road”,
city: “Dinton”,
country: “Buckinghamshire”
postcode: “HP17 8UQ”,
country: “United Kingdom”
}
And passing it to locations.get_map_for
, the following is returned.
{:ok,
[
%{
"bbox" => [-0.8943214, 51.7903516, -0.8939829, 51.7905312],
"geometry" => %{
"coordinates" => [-0.8941397157675615, 51.7904389],
"type" => "Point"
},
"properties" => %{
"category" => "amenity",
"display_name" => "Dinton Village Hall, Upton Road, Dinton-with-Ford and Upton, Dinton, Buckinghamshire, South East, England, HP17 8UQ, United Kingdom",
"importance" => 1.1309999999999998,
"osm_id" => 602254458,
"osm_type" => "way",
"place_id" => 209962616,
"place_rank" => 30,
"type" => "community_centre"
},
"type" => "Feature"
}
]}
At this point no data is saved to the database. In this simple case, with only one location, there are no decisions to be made and the map with its location marker can be displayed. For multiple features, user interaction is required.
Next: How to display the map.