Changes for version 0.45 - 2026-10-15

  • Enhancements
    • Every Geo::Location::Point this distribution returns now carries geocoder, database, confidence and accuracy, so a caller can tell which distribution and which backend produced it, how good the match was and how precise the coordinate is. geocoder is new and additive, and the existing database values are unchanged for the consumers that match on them
    • Local, MaxMind and OpenAddresses each describe the match they actually made: an OpenAddresses geohash hit is an address and a hand-curated entry a locality, a Local match is graded from the columns that matched rather than the ones the call site offered, and a MaxMind cities row is a city or a region
    • Added provenance(), which returns the distribution, backend, confidence and accuracy of a result, as a list or, in scalar context, as a hashref. The backends' two spellings of database are reduced to one vocabulary there. It returns undef rather than guessing for something with no provenance to report, such as a plain hash handed on by another geocoder
    • Added Geo::Coder::Free::Provenance: the GEOCODER constant, the ACCURACY_LEVELS vocabulary and _accuracy_for(), so a backend describes a match without repeating the vocabulary. They live in a module of their own because Geo::Coder::Free::Utils is synced from VWF master, where a geocoder result has no provenance - an addition there would not survive the next sync
    • Requires Geo::Location::Point 0.16, which stores and returns false values: a confidence of 0 or an empty accuracy used to be discarded on write, so provenance could not have been reported honestly
  • Tests
    • t/unit.t: the API ledger gains the provenance states, and a new section runs the real MaxMind backend (the mock is restored first) to assert that a hit carries all four keys with an accuracy of city or region - a point the test built itself would prove nothing about the stamping
    • t/integration.t: the OpenAddresses path is now asserted end to end - the database lookup is stubbed at the seam _get() uses, so the stamping, the Storable round trip through the result cache and the thawed second lookup are all the code under test
    • t/consumer-contract.t: geocoder, database, confidence and accuracy are declared as guaranteed producer keys, so a backend that stops setting one of them fails here
    • t/bin.t: the skip for a run without OPENADDR_HOME covers the 26 tests the plan declares, not 28, so a configuration that skips the whole file no longer ends with 'Bad plan' and a non-zero exit
    • t/unit.t needs neither the downloaded databases nor an optional address parser: the MaxMind section answers the database lookups itself, Geo::libpostal and Geo::Address::Parser are hidden so that what a location string parses to cannot decide whether a documented state is reachable, and the column scan is driven with the components a dataset row really carries. Both of those were passing on a machine with the data and the parsers installed and failing in CI, which has neither

Documentation

Modules

Geocoding using free, locally-hosted databases
Site-independent configuration file for the Versatile Web Framework
driver for http://download.geonames.org/export/dump/admin1CodesASCII.txt
driver for http://download.geonames.org/export/dump/admin2Codes.txt
driver for https://www.maxmind.com/en/free-world-cities-database
driver for http://results.openaddresses.io/
interface to data from http://results.openaddresses.io/
Driver for /tmp/vwf.log
Geocode using user-curated local data
Provides a geocoding functionality using the MaxMind and GeoNames databases
The provenance keys that every Geo::Coder::Free result carries
Random subroutines for Geo::Coder::Free

Provides

in lib/Geo/Coder/Free/Allow.pm
in lib/Geo/Coder/Free/Display.pm
in lib/Geo/Coder/Free/Display/index.pm
in lib/Geo/Coder/Free/Display/meta_data.pm
in lib/Geo/Coder/Free/Display/query.pm