Revision history for Geo-Coder-Free
0.47 Fri Oct 16 09:34:18 PM EDT 2026
[ Enhancements ]
- Added geocode_many(), the loop a batch caller writes around geocode()
It takes an arrayref of locations and answers with one entry
per distinct value - the point it resolved to, or undef - plus lookups (how many values were
looked up), resolved and unresolved (which add up to the number of distinct values) and
unresolved_values (the values that produced nothing, in the order they were first seen, which
is what a caller records as tried-and-failed instead of retrying them on every request). A
value repeated in the batch is one lookup, so a column holding the same handful of places
thousands of times costs the handful; a value the module refuses before any backend is touched
- a bare number, the empty string, undef, a reference - costs no lookup at all and is counted
unresolved, so the count a caller caps its work by is the number of backends asked. An undef
is the empty string and shares its entry; region and on_error are handed to every lookup and
mean there what they mean in geocode(), croak by default; and a backend exception is still an
exception. The four keys the answer carries besides the values are reserved, and a value
spelled like one is refused by name rather than overwriting a count. A batch of no values
answers with counts of zero
- The token filter in _find_word_ngrams() asks the shared location rule what a bare number
is instead of spelling the rule out again with its own regex. The answer is the same for
every token that can reach it - the text is trimmed and its whitespace collapsed before the
split, so no empty token can arise - and the rule is now answered in one place (below)
- The databases Makefile.PL downloads are fetched with LWP::Simple again, and LWP::Simple::WithCache is
no longer used to fetch them. That module swaps in a caching user agent whose request($request,
$file) answers a cache hit, or a 304, straight out of the cache and never writes $file, so
getstore() answered 200 and left nothing behind: on any machine whose cache had been warmed by an
earlier install no database was fetched at all, while perl Makefile.PL reported "Looks good" and
make succeeded. The failure arrived much later, as "gunzip: cities.csv.gz: No such file or
directory" from createdatabase.PL and a failing t/locales.t, so an install that should have worked
did not work rather than losing a feature. HTTP::Cache::Transparent, which caches the file it is
asked for, is still used when it is installed
- Makefile.PL checks the files it downloaded rather than the status codes: after wait_all_children()
every destination is looked for in the parent, because a download that fails in a forked child dies
with that child and the parent never saw it - which is how the missing databases went unnoticed. A
download that didn't arrive is named by URL and file and stops the build, under AUTOMATED_TESTING
it is a warning instead, since a smoker cannot fix the network and the tests that need those files
skip, and a build with NO_NETWORK_TESTING says that it is fetching nothing rather than doing it
quietly
- createdatabase.PL no longer runs bin/create_sqlite when cities.csv.gz is absent. db2sql gunzips
that file, so without it the step could only print the gzip error and blame sqlite3 ("perhaps you
don't have sqlite3 installed") for a file that was never downloaded; it now names the file that is
missing and carries on, cities.sql being optional
[ Tests ]
- t/unit.t: the API ledger gains the geocode_many states (the map and the counts, the
distinct-value reduction, the region pass-through, the default croak and its message, an undef
cell, the reserved key, an empty batch, both calling conventions, the usage errors and a
backend that dies), and a subtest drives them against a backend that is asked once per call and
answers per location
- t/edge_cases.t: section 9d runs a 401-row column holding four distinct values to hold "one
lookup per distinct value" to two backend calls rather than 397, and a column of nothing but
unusable values to zero lookups at all - the backend is mocked to die if it is called for one
- t/location-rule.t: the location rule is written out in one file and no other. It scans every
module under lib/, every script under bin/ and every program under cgi-bin/ for the rule's
question as source text - a negated digit class or an anchored all-digits test - and fails
naming the file, the line, the sub and the spelling, so a renamed copy of _valid_location(),
or the guard typed straight into a caller, is caught as well as a second copy of the sub.
POD, comments and anything after __END__/__DATA__ are masked, since prose that describes the
rule is not a copy of it, and regexes that merely resemble it (a postcode, a coordinate,
/^\d/, /\d+=\d+/) are not reported. The scan is run first on source whose answer is known,
so it is shown to tell the rule from code that merely uses digits. Sites that ask one of
those questions about something that is not a location - the CGI test number, a cache
configuration value - are listed with their reason, and an exemption that no longer names a
site fails too, so the table cannot outlive the code it was written for
- t/vwf-sync.t says what the sync will do with each block of local code instead of only that it
is not the master's. A block is a run of consecutive local lines; each line is compared with
the master's lines in the same passage on the words it holds (identifiers and numbers,
punctuation and whitespace ignored), and a line sharing at least half its words with one of
them is that line in an older revision, which the sync will replace - the master's revision is
printed beside ours - while a line sharing that much with none of them is code the master has
never had, which the sync will discard. A line that could be either is reported as local code,
the reading that sends the reader to look at their own code, and each file's report ends with
the two totals. The tracked files are unchanged and still fail the test; the difference is in
the report, where Display.pm's local %blacklist hash now stands apart from the die() beside it
(the master's croak() in an older revision) and Utils.pm's @EXPORT line is shown with the
master's shorter list rather than as an addition of ours. The comparison is run on source
whose answer is known as well - a changed line beside an added subroutine, a reworded line, and
a local line whose neighbour is an unrelated upstream change - so a report that has lost the
distinction fails there first
- t/locales.t: the geographic subtests skip when the MaxMind databases are absent instead of failing.
Those lookups need admin1.db and admin2.db, which Makefile.PL downloads, and a build that was never
given them cannot answer the calls at all - the backend croaks "Can't find a file called 'admin1'"
- so a machine with OPENADDR_HOME set and no downloaded data to go with it failed five subtests,
and with them the install. The skip names the files that are missing, as t/maxmind.t names the
database it needs
- Added t/downloads.t: the fetch path in Makefile.PL is held to asking LWP::Simple, to waiting for the
children that do the downloading and to looking for the file that arrived rather than at the status
code, since a download that doesn't happen is invisible in the build and turns up later as a test
failing for want of a database
- t/bin.t drives the CGI's index and meta_data pages, not just the query page, and checks what they
render rather than only the coordinates the query page resolves. The landing page is asked for the
title and description its stub configuration gives it and for the form that starts a search; the
status page for the site title it was configured with, the domain it was answered for and the
figures it counts. Those figures are the log the pages keep - one entry per visit, and a page
records the visit it serves - so the test writes a log of its own making (CGI::Info::logdir()
honours LOGDIR) and asserts the counts rendered from it, the four visitor types at two web visits,
one mobile, three search engines and no robots, header row and all. The domain is named
(SERVER_NAME) rather than taken from the host, and the log the status page counts is written after
the landing page has been served, since serving it is itself a visit. Both pages render templates
this distribution ships - the query page's own template is not one of them, query.txt ships empty,
which is why its answer is only in the log - so their output is the page, and it is asserted as
such. bin/testcgibin gained tests 5 and 6 to drive them
- t/bin.t asserts the site's answer to a client it will not serve, and its answer to one it will.
The same query is asked twice, from the same address and with the same everything else, by a
client whose user agent Geo::Coder::Free::Allow blacklists (bin/testcgibin test 7) and by one
whose agent is an ordinary browser's (test 8): the first is answered with a 403 and the
plain-text block page and is not given the position, the second is served the position and gets
no block page. The refusal is read back out of the access log as well - the row the page
writes for it carries the reason the user-agent blacklist gave ('zgrab is blacklisted'), which
no other layer of the page's access control produces, plus the 403 and the address that was
refused - so what is asserted is that layer refusing the client and not the account being
written by something else in the stack. The log every run writes is written into the test's
own directory now (LOGDIR, for all the runs rather than only those that read it back) and the
page's temporary directory is the test's too (TMPDIR), so the throttle that counts requests is
this run's rather than one that carries the count over from the last, and no run leaves an
access log or a throttle outside the temporary directory. The file also points its diagnostics
at STDOUT: Log::WarnDie, which the pages need installed, takes STDERR over, and a test's
diagnostics go there by default, so before this every failure in t/bin.t was reported as a test
name with no detail to say what the page had answered instead
0.46 Thu Oct 15 09:06:24 PM EDT 2026
[ Enhancements ]
- Added valid_location(), which answers whether a string is a location at all: the rule geocode()
applies before it touches a backend, made public. A caller working down a spreadsheet column can
skip a row whose value is a bare number, or empty, instead of catching the croak that would
otherwise end the run. The regex it replaces was private to this module, so no caller could
pre-filter with the module's own rule
- geocode() takes on_error => 'croak' (the default, and the behaviour every existing caller already
has) or 'undef'. 'undef' returns undef - an empty list in list context - for the two documented
input errors, invalid_location and invalid_scantext, and for nothing else: a backend that throws
still throws, because nothing is wrapped in an eval, and a call with neither a location nor a
scantext is still a usage croak. An on_error with any other value is refused by name rather than
ignored, so a caller who misspells it does not ship a batch job that dies on its first bad row
- Geo::Coder::Free::Provenance reads the accuracy vocabulary from Geo::Location::Point instead of
keeping a second copy of it. The levels a backend reports and the levels a point accepts are now
one list - Geo::Location::Point::ACCURACY_LEVELS(), re-exported as Provenance's ACCURACY_LEVELS -
so a level added to one cannot go missing from the other, and the prerequisite is Geo::Location::Point
0.18, which is the version that defines it. t/accuracy-vocabulary.t asserts the two names are the
same list, that a point accepts every level in it and refuses one outside it, and that every level
_accuracy_for() can derive from the fields a backend matches on is one of them
[ Tests ]
- t/consumer-contract.t: the declaration now accounts for every accessor Geo::Location::Point
documents, and the checker (Test-Consumer-Contract 0.02) fails when the value object gains an
accessor that is in none of the declaration's lists. geocoder, database, confidence and
accuracy are named as accessors a consumer may read off a result, country, city and state as
documented accessors only some results carry, and new, AUTOLOAD and ACCURACY_LEVELS as
documented but not slots of one result. The four provenance accessors and the three attribute
accessors had been absent from the declaration since they were added to the value object, which
is the drift the new direction of the check is for
0.45 Thu Oct 15 01:23:24 PM EDT 2026
[ 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
0.44 Thu Oct 15 10:22:42 AM EDT 2026
[ Tests ]
- Use Test::Log::Abstraction
- Added t/consumer-contract.t: the reader/producer contract for the Geo::Location::Point this dist returns. It checks that each backend still sets
the keys the contract claims, and that every registered consumer in the workspace reads only the keys every backend guarantees - reading a key that
only one backend sets is undef for the others, which is how a caller silently takes the wrong branch. A consumer that is not registered fails the
discovery test, so the check cannot go stale
0.43 Fri Aug 14 08:24:12 PM EDT 2026
[ Enhancements ]
- _normalize rewritten with split to eliminate O(N³) catastrophic backtracking from (.+)\s+(.+)\s+(.+)
- _find_gb_addresses commas now mandatory between parts to prevent exponential backtracking on comma-free text
- _find_us_addresses and _find_ca_addresses converted all capturing groups to non-capturing (only $& used)
- _find_us_addresses and _find_ca_addresses street name pattern bounded to prevent lazy-quantifier O(N²) expansion
- _normalize_args now croaks on odd-count argument lists longer than 1 (closes logic gap M7)
- wantarray tautologies in reverse_geocode eliminated (M8)
- scantext ignore_words passed by reference instead of copying the full hash each call
- %admin2cache_rev added as inverse of %admin2cache, replacing O(N) value scan with O(1) lookup in _prepare
[ Tests ]
- Added new tests
t/logic-reducer.t: new test file with partition-based proofs for all M-series reductions
t/unit.t: new black-box unit test file covering every public API of Geo::Coder::Free, Local, OpenAddresses, and Utils; uses Test::Mockingbird to mock MaxMind, Test::Returns for schema validation, and an API ledger to guarantee all documented states are exercised
t/integration.t: new end-to-end integration test file covering cross-module workflows; tests backend delegation chain, alternatives singleton, concurrency isolation, clone shallow-copy semantics, scantext memoisation, round-trip geocode/reverse, distance calculations, OA known_locations, MaxMind admin cache invariants, optional Geo::libpostal dep, and USA/US normalisation
t/edge_cases.t: new destructive/boundary/security test file; covers distance() boundary coordinates, undef/non-numeric/out-of-range inputs, cache hostile configs, purely numeric geocode rejection (M7 regression), SQL/shell/newline injection payloads, global variable isolation, and ReDoS regression tests for _normalize(), _find_gb_addresses(), and the OA city-name pattern
t/path.t: new CFG path-coverage test file; maps every unique execution path in GCF::new/geocode/reverse_geocode, Local::geocode/reverse_geocode/_search/_find_geographic_centres/_to_two_letter_state, and the shared helpers _normalize_args/_normalize/_abbreviate/_find_word_ngrams; 97 subtests covering all dispatch branches, guard exits, confidence levels, and mock-contamination hygiene
t/transaction.t: new transaction-flow/lifecycle test file; 18 subtests covering Local cache write-through, geocode idempotency, scantext miss memoization, OA exception propagation (no silent swallow), OA→Local delegation chain, all-miss recovery, one-shot __DATA__ lifecycle, alternatives map re-geocode cycle, geocode→reverse round-trip, USA/US normalization idempotency, lazy backend creation, clone shallow-copy state boundary (shared references visible across both sides), and object usability after mid-chain failure
0.42 Fri Jul 10 11:48:02 EDT 2026
Try Geo::Address::Parser before libpostal() as that uses less memory
createdatabase.PL - borough parent lookup now uses locality_id from hierarchy to skip intermediate boroughs
createdatabase.PL - File::Find glob fallback replaced with a pre-built ID->path index, eliminating per-miss tree scans
createdatabase.PL - fix WhosonFirst index building regex broken by no_chdir => 1
createdatabase.PL - catch XML parse errors in corrupt OSM files and continue to next file
createdatabase.PL - eval scope narrowed to re-throw non-XML exceptions (business-logic die was silently swallowed)
createdatabase.PL - XML::LibXML::Reader constructor moved inside eval so reader-open failures skip the file
createdatabase.PL - $inserts reset per OSM file to prevent cross-file flush accounting errors
createdatabase.PL - fix warn inside eval calling ->document->toString(1) which could throw on corrupt documents
createdatabase.PL - fix operator precedence in DEBUG&DEBUG_GET_WOF && $filename debug print
createdatabase.PL - add -f guard to WhosonFirst index builder to skip directories matching *.geojson pattern
Local: Added _find_geographic_centres to add towns to the database where more than 3 places are known
Improve handling of Australian states
Ensure known_places are all loaded
Don't put spaces in digest, helps to find known_places match
Added test dashboard
Updated from upstream VWF
Openstreetmap now uses PBF files
createdatabase.PL - l1_cache is now an LRU cache
0.41 Mon Jul 7 13:45:41 EDT 2025
Use Object::Configure
Attempt improvement on EXT4
No need to clone Geo::Location::Point objects
0.40 Wed Jun 11 07:32:17 EDT 2025
Improved the support for Berkeley DB databases
Don't use IO::AIO on Windows
Ensure CGI::Info doesn't attempt to read from stdin
Run if Parallel::ForkManager isn't installed
Use Params::Get in new()
0.39 Thu Mar 20 12:40:51 EDT 2025
Use Geo::Hash to store in the database (results in over 10% size reduction)
Improve US address parser to include NW as in "Pennsylvania Ave. NW"
Handle arrays that are only one element in size
Refactor scantext, using a complex regex and other technologies
Latest upstream changes from VWF
Use Geo::Hash, reduces SQLite file size by over 10%
Makefile.PL: Download the files in parallel
0.38 Wed Jan 22 08:37:22 EST 2025
Latest as_string return code and Utils.pm from VWF
Added t/30-basics, t/config.t, t/utils.t and t/display.t
geocode(): croak when input is just a set of numbers
Local: Replace linear search with a hash search
Local: Create a cache
Maxmind: Create a cache
scantext: set the location field to the string that was matched
0.37 Wed Oct 23 10:09:54 EDT 2024
Allow new() to take HASH ref
Slight speed improvements in Local.pm
Support CircleCI
Fix testing on a NO_NETWORK_TESTING system
Port to Haiku
Added the -f flag to createdatabase.PL to force building
the database, e.g. after running wof_update
DR5HN now puts JSON in its own directory
0.36 Fri Jul 5 08:56:52 EDT 2024
Handle wide characters
Latest VWF
Added "exact" to OpenAddresses.pm
Local.pm - remove empty fields
Install bin/address_lookup
Set lng as well as long in the output
0.35 Wed Mar 6 20:48:43 EST 2024
Fix scantext.t when OSM is installed
Fix openaddr.t test for not/there
Rework the GETTING STARTED section of the POD
Trying different databases since the creation of a database in SQLite
eats a lot of RAM
Added mysql support in createdatabase - TODO add support to DB.pm
Added BUILDMODE to optionally only import from one large database
Fix usage message in DB.pm
Added more data cleanup to createdatabase.PL
Use Database::Abstraction
Rework key - for me saved about 1/3 of the database size
0.34 Mon Nov 6 16:53:43 EST 2023
Latest DB.pm from NJH-Snippets
Latest Display.pm from VWF
Use HEAD not master to get the list of files
MaxMind.pm: Try hard to support whatever API that the user wants to use
0.33 Mon 6 Nov 08:31:27 EST 2023
Calling new on a local object now returns a clone rather than setting the defaults in the new object
Some support for reverse_geocode
Added Redis as a prerequisite if REDIS_SERVER is set
Latest DB.pm from NJH-Snippets
Change the mode of the cachedir to 2755
Free.pm/Local.pm: Try hard to support whatever API that the user wants to use
Local.pm: if libpostal fails, try code without
Put the README file into the GETTING STARTED section of the POD
0.32 Wed Jun 21 20:31:01 EDT 2023
Set NA rather than fail on smokers without L:P:https
It's OK to install modules on Github Actions
Reduce the number of calls to libpostal in Local.pm
Only use XML::LibXML::Reader when needed
0.31 Fri Mar 24 17:30:06 EDT 2023
Calling new on an object now returns a clone rather than setting the defaults in the new object
Port to Solaris
Local.pm doesn't contain states/provinces' locations, so quick return on search for those
Use JSON::MaybeXS instead of JSON
Fix truncate
Use perl shell rather than CPAN to install missing modules
Move temporary downloads to their own directory to stop them being installed
Some local matches in US missed in the quick lookup
Die, rather than warn, if the openaddr database can't be opened
0.30 Wed Mar 9 09:47:33 EST 2022
Fix treating "30 Cross Street" as "30 X St"
Latest DB.pm from VWF
Improved handling of house numbers in Local.pm
0.29 Thu Nov 26 14:19:56 EST 2020
Started work on importing data from OpenStreetMaps
using planet.osm.bz2 files in $OSM_HOME
More work to reduce the number of Maxmind results
Removed some false positives in Local.pm
Import US and Canadian data from
https://github.com/dr5hn/countries-states-cities-database.git
set DR5HN_HOME to where you clone it
0.28 Fri Oct 16 21:51:27 EDT 2020
Fixed the manifest
Don't return all the matches in a state/county/province
0.27.1 Thu Oct 15 11:08:18 EDT 2020
Fix https://github.com/nigelhorne/Geo-Coder-Free/issues/47
0.27 Fri Oct 9 20:44:09 EDT 2020
Local.pm: Call _normalize when libpostal is installed
Install LWP::Simple and LWP::Protocol::https if needed
0.26 Thu Oct 8 19:47:45 EDT 2020
Create the MaxMind database directory to download to
Use Geo::Coder::Abbreviations
0.25 Wed Sep 30 22:33:06 EDT 2020
Maxmind: Improved handling of full state names in the US
0.24 Mon Jun 15 11:50:14 EDT 2020
Deal with
https://github.com/apache/commons-csv/commit/914f2c41557bdd3dcde8d10d6f128fa3bb307b11
Makefile.PL: used to not download any file if it exists, now it
will download the file if it's older than a week
0.23 Sat May 16 22:16:30 EDT 2020
WhosOnFirst: Use raw geojson files from GitHub
Don't store items in MaxMind cache when there are more than one match,
it was causing some subsequent searches to fail
Sanity check to MaxMind records
Don't look up where we've already failed to find a location
Save database in Redis server as well if REDIS_SERVER is set
Fixed reverse_geocode in Local.pm for UK addresses
Fixed reverse_geocode in Local.pm when you know the name but not the
number
0.22 Sat 12 Oct 15:14:01 EDT 2019
When looking up Tyne and Wear, also lookup Borough of North Tyneside
Make createdatabase.PL and openaddress.pm agree on how to handle St. Louis, MO
0.21 Tue 16 Jul 20:58:06 EDT 2019
Remove errant debug statement
0.20 Sun 14 Jul 22:52:42 EDT 2019
reverse_geocode starts locally then zooms out a bit
Fix copy and paste error into Local.pm from OpenAddresses.pm
0.19 Wed 17 Apr 17:25:55 EDT 2019
Added reverse_geocode support to MaxMind and Local
0.18 Wed 20 Mar 17:00:52 EDT 2019
Added Geo::Coder::Free::Local
Now return Geo::Location::Point object
0.17 Sat 23 Feb 17:21:41 EST 2019
Maxmind download of worldcitiespop.txt has been removed
0.16 Tue Jan 1 17:57:37 EST 2019
Import GeoName's allCountries data
Remember L:E:AddressParser objects to speed up parsing. RT#127814
Fix uninitialized variable
Error if G:S:P can't extract a state name
0.15 Thu Nov 15 21:10:51 EST 2018
Added alternatives table, for when a place could be listed elsewhere
Support lookups of British counties e.g. 'Kent, England'
0.14 Fri Sep 7 16:07:39 EDT 2018
Work on fixing http://www.cpantesters.org/cpan/report/6b68841a-8cc6-11e8-98d5-bb14e5798fec
Re-enable Lingua::EN::AddressParse usage and prefer over Geo::libpostal
Don't store cities and location names in the database
0.13 Fri Jul 20 16:48:58 EDT 2018
Fix handling of cities with spaces in them
Fix Canadian provinces - everything was going in AB
Improved handling of "LANE"
0.12 Tue Jun 19 09:02:28 EDT 2018
Fix "RESTAURANT" insert where street is known but not number
Improved searches when Geo::Libpostal is not installed
Improved handling of un-normalized input
Removed duplicate code
Add current country on web interface
Added bin/address_lookup
No need to give openaddr argument to new() if OPENADDR_HOME is set
0.11 Fri Jun 8 17:27:55 EDT 2018
Started work on scantext support
Fixed some calls in list mode which returned a scalar
Many WOF records were not being imported
Only fall back to Geo::StreetAddress::US as last resort
Don't include NULL fields in the JSON output
Better at finding venues when libpostal is not installed
Tighten OpenAddresses validation
0.10 Fri 11 May 18:30:54 EDT 2018
Street numbers were not being indexed
Add data that I know with the GPS program on my phone
Support "DR" for "Drive"
Import GB data from whosonfirst.org data
Maxmind - no longer croak for bad args
0.09 Tue Apr 17 21:34:01 EDT 2018
Consolidated date in createdatabase
Load Australian data
Added basic Australian search (town, state, country)
Removed the OLDCODE
0.08 Sun Apr 15 11:49:55 EDT 2018
Download admin1 and admin2 directly from MaxMind
Download cities.sql from geocode.nigelhorne.com
0.07 Tue Apr 3 07:40:46 EDT 2018
Stash results in cache, workaround for very slow libpostal load
(minutes!!) on scaleway machines
Fix search for just state/province
Added the run method
0.06 Thu Mar 29 09:12:56 EDT 2018
Fix Github issue 14
Updated to latest MaxMind databases
Started support for a local copy of results.openaddresses.io
Fixed Canadian lookups
Match a street even if the house number isn't known
Started geocoder website - see cgi-bin
0.05 Sun Jan 28 17:33:33 EST 2018
Fix http://www.cpantesters.org/cpan/report/b10c956b-6bf9-1014-9a47-dc46d49c4260
Allow known peculiarities to be found
Improve handling of US lookups
Added DISTINCT when only wanting one row
0.04 Thu Oct 26 22:05:54 EDT 2017
Fix throw in http://www.cpantesters.org/cpan/report/ab86a142-b8d9-11e7-a1cf-bb670eaac09d
Various speedups
Fixed uninitialized variable
Fix http://www.cpantesters.org/cpan/report/26e07a7e-b9e9-11e7-a1cf-bb670eaac09d
0.03 Sun Oct 22 10:46:22 EDT 2017
Fixed spelling mistake
0.02 Sun Oct 22 10:31:35 EDT 2017
Mention that reverse isn't supported
Added createdatabase.PL
Added ua
0.01 Sun 15 Oct 14:24:23 EDT 2017
First Version
Keyboard Shortcuts
Global
s
Focus search bar
?
Bring up this help dialog
GitHub
gp
Go to pull requests
gi
Go to GitHub issues (only if GitHub is preferred repository)