ExNominatim updated: now configurable for your Elixir application

ExNominatim updated: now configurable for your Elixir application

26 July, 2024 3 min read
software, programming, Elixir, package, release, OpenStreetMap, Nominatim, API

ExNominatim v1.1.1 has just been published on Hex alongside its updated documentation . Given the significant Quality-of-Life improvements of this version, I have retired the previous package versions on Hex.

There is now a new ExNominatim.Report module with functions for processing the output of responses into more user-friendly structures and “atomizing” any bitstring keys of maps/structs therein. This is enabled by default and can be switched off independently by setting either or both keywords :process, :atomize to false in the endpoint functions.

There are also various improvements to the DX here and there, such as being able to properly validate setting the value of 0/1 fields to false/true. I have implemented validation of a couple remaining fields, too.

Most importantly, since v1.1.0, ExNominatim features application configurability: it takes into account your overarching Elixir application’s configuration, as defined using the Elixir.Config module. For example, in the config/config.exs file of a Phoenix app named MyApp, you can define default values such as these:

config :my_app, MyApp.ExNominatim,
all: [
  base_url: "http://localhost:8080",
  force: true,
  format: "json",
  process: true,
  atomize: true
],
search: [format: "geocodejson", force: false],
reverse: [namedetails: true],
lookup: [],
details: [],
status: [format: "json"]

The configuration above has the following effects:

  • Requests to all endpoints will use the self-hosted Nominatim API instance at port 8080 of localhost, accessible over HTTP.
  • Request parameter validation errors (valid?: false in the request parameters struct) will be ignored for requests to all endpoints, except for requests to the /search endpoint.
  • Unless requested otherwise in opts, requests to the /search endpoint will return data in GeocodeJSON format (instead of the default jsonv2).
  • Requests to the /reverse endpoint will set :namedetails to true (unless otherwise set in opts during the request).
  • Requests to the /status endpoint will return JSON instead of the default text (HTTP status code 200 and text OK or HTTP status 500 and a detailed error message).
  • The responses from all endpoints will be processed automatically using ExNominatim.Report.process/1, and any maps and contents thereof (or map contents of structs’s keys) will be converted from bitstring keys to atom keys using ExNominatim.Report.atomize/1 (this is the default anyway).

Here’s the preference order:

  • The default values for :base_url and :force across all endpoints are the public Nominatim API server’s URL and false, respectively.
  • Any keyword-value pairs set in the :all list override these defaults and are applied automatically in requests to all endpoints.
  • Any keyword-value pairs set in the list of a specific endpoint override any values defined in the :all list and are applied automatically in requests to that endpoint.
  • Anything you set in opts overrides all the above.

At any moment you can use ExNominatim.get_config/0 to see the current configuration.

This is a significant upgrade that IMHO deprecates any use of ExOpenStreetMap. The package may see updates in the future. In particular, I intend to implement built-in caching using Cachex, both to aid package users to satisfy the Usage Policy of the public Nominatim API out of the box and to provide an easy way to cache geolocation responses that really don’t change that often (or ever).