Geo encoding a location Part 2
Project source code: https://github.com/antp/locations
Project demo
This project will use OpenStreetMap Nominatim service to GEO encode addresses and OpenStreetMap via Leaflet.js to display multiple independent maps on a single.
It is always good to see a demonstration of the example project...
Creating the project
Create a Phoenix application, in this example, called locations with:
> mix phx.new locations —binary_id —live
The next step is to add geo_postgis
to the project, to enable the use of GIS functionality. This will allow queries to be run that will, for example, find all locations in the database within 50Km of an address.
Add geo_postgis. Full installation and configuration instructions can be found there, but in short:
Add it to your mix file.
{:geo_postgis, "~> 3.0"}
And run to get the dependency:
> mix reps.get
Add a migration called add postgis
with the following contents:
defmodule Location.Repo.Migrations.AddPostgis do
use Ecto.Migration
def up do
execute "CREATE EXTENSION IF NOT EXISTS postgis"
end
def down do
execute "DROP EXTENSION IF EXISTS postgis"
end
end
Then create a migration for the location table:
defmodule Location.Repo.Migrations.AddLocation do
use Ecto.Migration
def change do
create table(:locations, primary_key: false) do
add :id, :binary_id, primary_key: true
add :addr1, :string, null: false
add :addr2, :string, null: true
add :city, :string, null: false
add :county, :string, null: true
add :postcode, :string, null: false
add :country, :string, null: false
add :geo_error, :binary, null: true
add :geo_selected_id, :int8, null: true
add :geo_features, :jsonb, null: true
add :lat, :float, null: true
add :lon, :float, null: true
add :geolocation, :geometry, null: true
timestamps()
end
end
end
This will create the locations table. A location has two parts, the address and the geographical information.
In order to display a location symbol on a map, the latitude and longitude of the location must be known. This information is contained in the lat
and lon
fields above. This information is also encoded in the geographical field geolocation
. This field will be used in the GIS queries.
The features returned from locating an address are held in geo_features
. It is possible for an address to encode to several points, so there may be more than one feature. The geo_selected_id
contains the osm_id
of the currently selected feature by the user.
In the case of errors geo_error
will contain the error information.
Create the database and tables with:
>mix ecto.reset
The initial application and database is now setup.
Next: Encoding an address.