{"id":15017620,"url":"https://github.com/nigelhorne/geo-coder-free","last_synced_at":"2025-04-09T19:42:31.501Z","repository":{"id":56834488,"uuid":"106314515","full_name":"nigelhorne/Geo-Coder-Free","owner":"nigelhorne","description":"Provides a geocoding functionality using free databases","archived":false,"fork":false,"pushed_at":"2025-04-04T21:10:58.000Z","size":43383,"stargazers_count":9,"open_issues_count":3,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-04T22:23:49.665Z","etag":null,"topics":["geocoder","geocoding","geonames","maxmind","openaddresses","perl","perl-module","perl5","perl5-module","whosonfirst"],"latest_commit_sha":null,"homepage":"https://geocode.nigelhorne.com","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nigelhorne.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["https://www.paypal.com/paypalme/bandsman"]}},"created_at":"2017-10-09T17:34:53.000Z","updated_at":"2025-04-04T21:11:01.000Z","dependencies_parsed_at":"2023-10-15T16:40:33.595Z","dependency_job_id":"a3bc36b6-839c-45f8-9701-1e5d91da1564","html_url":"https://github.com/nigelhorne/Geo-Coder-Free","commit_stats":{"total_commits":1046,"total_committers":7,"mean_commits":"149.42857142857142","dds":0.09369024856596553,"last_synced_commit":"26f502e5ea2ebbacac4ac9ffd003313ffc6f82b2"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nigelhorne%2FGeo-Coder-Free","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nigelhorne%2FGeo-Coder-Free/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nigelhorne%2FGeo-Coder-Free/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nigelhorne%2FGeo-Coder-Free/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nigelhorne","download_url":"https://codeload.github.com/nigelhorne/Geo-Coder-Free/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248101135,"owners_count":21047910,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["geocoder","geocoding","geonames","maxmind","openaddresses","perl","perl-module","perl5","perl5-module","whosonfirst"],"created_at":"2024-09-24T19:50:45.921Z","updated_at":"2025-04-09T19:42:31.494Z","avatar_url":"https://github.com/nigelhorne.png","language":"Perl","funding_links":["https://www.paypal.com/paypalme/bandsman"],"categories":[],"sub_categories":[],"readme":"Geo-Coder-Free\n==============\n\n[![Actions States](https://img.shields.io/github/actions/workflow/status/nigelhorne/geo-coder-free/test.yml?branch=master)](https://github.com/nigelhorne/Geo-Coder-Free/actions)\n[![Appveyor status](https://ci.appveyor.com/api/projects/status/8nk00o0rietskf29/branch/master?svg=true)](https://ci.appveyor.com/project/nigelhorne/geo-coder-free-4onbr/branch/master)\n[![Coveralls Status](https://coveralls.io/repos/github/nigelhorne/Geo-Coder-Free/badge.svg?branch=master)](https://coveralls.io/github/nigelhorne/Geo-Coder-Free?branch=master)\n[![CPAN](https://img.shields.io/cpan/v/Geo-Coder-Free.svg)](http://search.cpan.org/~nhorne/Geo-Coder-Free/)\n[![Kritika Analysis Status](https://kritika.io/users/nigelhorne/repos/4097424524111879/heads/master/status.svg)](https://kritika.io/users/nigelhorne/repos/4097424524111879/heads/master/)\n[![Kwalitee](https://cpants.cpanauthors.org/dist/Geo-Coder-Free.png)](http://cpants.cpanauthors.org/dist/Geo-Coder-Free)\n[![Travis Status](https://travis-ci.org/nigelhorne/Geo-Coder-Free.svg?branch=master)](https://travis-ci.org/nigelhorne/Geo-Coder-Free)\n\n# NAME\n\nGeo::Coder::Free - Provides a Geo-Coding functionality using free databases\n\n# VERSION\n\nVersion 0.39\n\n# DESCRIPTION\n\n`Geo::Coder::Free` translates addresses into latitude and longitude coordinates using a local `SQLite` database built from free databases such as\n[https://spelunker.whosonfirst.org/](https://spelunker.whosonfirst.org/),\n[https://maxmind.com](https://maxmind.com),\n[https://github.com/dr5hn/countries-states-cities-database](https://github.com/dr5hn/countries-states-cities-database),\n[https://openaddresses.io/](https://openaddresses.io/), and\n[https://openstreetmap.org](https://openstreetmap.org).\nThe module is designed to be flexible,\nimporting the data into the database,\nand supporting both command-line and programmatic usage.\nThe module includes methods for geocoding (translating addresses to coordinates) and reverse geocoding (translating coordinates to addresses),\nthough the latter is not fully implemented.\nIt also provides utilities for handling common address formats and abbreviations,\nand it includes a sample CGI script for a web-based geocoding service.\nThe module is intended for use in applications requiring geocoding without relying on paid or rate-limited online services,\nand it supports customization through environment variables and optional database downloads.\n\nThe cgi-bin directory contains a simple DIY Geo-Coding website.\n\n    cgi-bin/page.fcgi page=query q=1600+Pennsylvania+Avenue+NW+Washington+DC+USA\n\nThe sample website is currently down while I look for a new host.\nWhen it's back up you will be able to use this to test it.\n\n    curl 'https://geocode.nigelhorne.com/cgi-bin/page.fcgi?page=query\u0026q=1600+Pennsylvania+Avenue+NW+Washington+DC+USA'\n\n# SYNOPSIS\n\n    use Geo::Coder::Free;\n\n    my $geo_coder = Geo::Coder::Free-\u003enew();\n    my $location = $geo_coder-\u003egeocode(location =\u003e 'Ramsgate, Kent, UK');\n\n    print 'Latitude: ', $location-\u003elat(), \"\\n\";\n    print 'Longitude: ', $location-\u003elong(), \"\\n\";\n\n    # Use a local download of http://results.openaddresses.io/ and https://www.whosonfirst.org/\n    my $openaddr_geo_coder = Geo::Coder::Free-\u003enew(openaddr =\u003e $ENV{'OPENADDR_HOME'});\n    $location = $openaddr_geo_coder-\u003egeocode(location =\u003e '1600 Pennsylvania Avenue NW, Washington DC, USA');\n\n    print 'Latitude: ', $location-\u003elat(), \"\\n\";\n    print 'Longitude: ', $location-\u003elong(), \"\\n\";\n\n# METHODS\n\n## new\n\n    $geo_coder = Geo::Coder::Free-\u003enew();\n\nTakes one optional parameter, openaddr, which is the base directory of\nthe OpenAddresses data from [http://results.openaddresses.io](http://results.openaddresses.io),\nand Who's On First data from [https://whosonfirst.org](https://whosonfirst.org).\n\nTakes one optional parameter, directory,\nwhich tells the object where to find the MaxMind and GeoNames files admin1db,\nadmin2.db and cities.\\[sql|csv.gz\\].\nIf that parameter isn't given,\nthe module will attempt to find the databases,\nbut that can't be guaranteed to work.\n\n## geocode\n\n    $location = $geo_coder-\u003egeocode(location =\u003e $location);\n\n    print 'Latitude: ', $location-\u003e{'latitude'}, \"\\n\";\n    print 'Longitude: ', $location-\u003e{'longitude'}, \"\\n\";\n\n    # TODO:\n    # @locations = $geo_coder-\u003egeocode('Portland, USA');\n    # diag 'There are Portlands in ', join (', ', map { $_-\u003e{'state'} } @locations);\n\n    # Note that this yields many false positives and isn't useable yet\n    my @matches = $geo_coder-\u003egeocode(scantext =\u003e 'arbitrary text', region =\u003e 'US');\n\n    @matches = $geo_coder-\u003egeocode(scantext =\u003e 'arbitrary text', region =\u003e 'GB', ignore_words =\u003e [ 'foo', 'bar' ]);\n\n## reverse\\_geocode\n\n    $location = $geocoder-\u003ereverse_geocode(latlng =\u003e '37.778907,-122.39732');\n\nTo be done.\n\n## ua\n\nDoes nothing, here for compatibility with other Geo-Coders\n\n## run\n\nYou can also run this module from the command line:\n\n    perl lib/Geo/Coder/Free.pm 1600 Pennsylvania Avenue NW, Washington DC\n\n# GETTING STARTED\n\nTo download, import and setup the local database,\nbefore running \"make\", but after running \"perl Makefile.PL\", run these instructions.\n\nOptionally set the environment variable OPENADDR\\_HOME to point to an empty directory and download the data from [http://results.openaddresses.io](http://results.openaddresses.io) into that directory; and\noptionally set the environment variable WHOSONFIRST\\_HOME to point to an empty directory and download the data using [https://github.com/nigelhorne/NJH-Snippets/blob/master/bin/wof-clone](https://github.com/nigelhorne/NJH-Snippets/blob/master/bin/wof-clone).\nThe script bin/download\\_databases (see below) will do those for you.\nYou do not need to download the MaxMind data, that will be downloaded automatically.\n\nYou will need to create the database used by Geo::Coder::Free.\n\nInstall [App::csv2sqlite](https://metacpan.org/pod/App%3A%3Acsv2sqlite) and [https://github.com/nigelhorne/NJH-Snippets](https://github.com/nigelhorne/NJH-Snippets).\nRun bin/create\\_sqlite - converts the Maxmind \"cities\" database from CSV to SQLite.\n\nTo use with MariaDB,\nset MARIADB\\_SERVER=\"$hostname;$port\" and\nMARIADB\\_USER=\"$user;$password\" (TODO: username/password should be asked for)\nThe code will use a database called geo\\_code\\_free which will be deleted\nif it exists.\n$user should only need to privileges to DROP, CREATE, SELECT, INSERT, CREATE and INDEX\non that database. If you've set DEBUG mode in createdatabase.PL, or are playing\nwith REPLACE instead of INSERT, you'll also need DELETE privileges - but non-developers\ndon't need to have that.\n\nOptional steps to download and install large databases.\nThis will take a long time and use a lot of disc space, be clear that this is what you want.\nIn the bin directory there are some helper scripts to do this.\nYou will need to tailor them to your set up, but that's not that hard as the\nscripts are trivial.\n\n1. `mkdir $WHOSONFIRST_HOME; cd $WHOSONFIRST_HOME` run wof-clone from NJH-Snippets.\n\n    This can take a long time because it contains lots of directories which filesystem drivers\n    seem to take a long time to navigate (at least my EXT4 and ZFS systems do).\n\n2. Install [https://github.com/dr5hn/countries-states-cities-database.git](https://github.com/dr5hn/countries-states-cities-database.git) into $DR5HN\\_HOME.\nThis data contains cities only,\nso it's not used if OSM\\_HOME is set,\nsince the latter is much more comprehensive.\nAlso, only Australia, Canada and the US is imported, as the UK data is difficult to parse.\n3. Run bin/download\\_databases - this will download the WhosOnFirst, Openaddr,\nOpen Street Map and dr5hn databases.\nCheck the values of OSM\\_HOME, OPENADDR\\_HOME,\nDR5HN\\_HOME and WHOSONFIRST\\_HOME within that script,\nyou may wish to change them.\nThe Makefile.PL file will download the MaxMind database for you, as that is not optional.\n4. Run bin/create\\_db - this creates the database used by G:C:F using the data you've just downloaded\nThe database is called openaddr.sql,\neven though it does include all of the above data.\nThat's historical before I added the WhosOnFirst database.\nThe names are a bit of a mess because of that.\nI should rename it to geo-coder-free.sql, even though it doesn't contain the Maxmind data.\n\nNow you're ready to run \"make\"\n(note that the download\\_databases script may have done that for you,\nbut you'll want to check).\n\nSee the comment at the start of createdatabase.PL for further reading.\n\n# MORE INFORMATION\n\nI've written a few Perl related Genealogy programs including gedcom ([https://github.com/nigelhorne/gedcom](https://github.com/nigelhorne/gedcom))\nand ged2site ([https://github.com/nigelhorne/ged2site](https://github.com/nigelhorne/ged2site)).\nOne of the things that these do is to check the validity of your family tree, and one of those tasks is to verify place-names.\nOf course places do change names and spelling becomes more consistent over the years, but the vast majority remain the same.\nEnough of a majority to computerise the verification.\nUnfortunately all of the on-line services have one problem or another - most either charge for large number of access, or throttle the number of look-ups.\nEven my modest tree, just over 2000 people, reaches those limits.\n\nThere are, however, a number of free databases that can be used, including MaxMind, GeoNames, OpenAddresses and WhosOnFirst.\nThe objective of [Geo::Coder::Free](https://metacpan.org/pod/Geo%3A%3ACoder%3A%3AFree) ([https://github.com/nigelhorne/Geo-Coder-Free](https://github.com/nigelhorne/Geo-Coder-Free))\nis to create a database of those databases and to create a search engine either through a local copy of the database or through an on-line website.\nBoth are in their early days, but I have examples which do surprisingly well.\n\nThe local copy of the database is built using the createdatabase.PL script which is bundled with G:C:F.\nThat script creates a single SQLite file from downloaded copies of the databases listed above, to create the database you will need\nto first install [App::csv2sqlite](https://metacpan.org/pod/App%3A%3Acsv2sqlite).\nIf REDIS\\_SERVER is set, the data are also stored on a Redis Server.\nRunning 'make' will download GeoNames and MaxMind, but OpenAddresses and WhosOnFirst need to be downloaded manually if you decide to use them - they are treated as optional by G:C:F.\n\nThe sample website at [https://geocode.nigelhorne.com/](https://geocode.nigelhorne.com/) is down at the moment while I look for a new host.\nThe source code for that site is included in the G:C:F distribution.\n\n# BUGS\n\nSome lookups fail at the moments, if you find one please file a bug report.\n\nThe MaxMind data only contains cities.\nThe OpenAddresses data doesn't cover the globe.\n\nCan't parse and handle \"London, England\".\n\nIt would be great to have a set-up wizard to create the database.\n\nThe various scripts in NJH-Snippets ought to be in this module.\n\n# SEE ALSO\n\n[https://openaddresses.io/](https://openaddresses.io/),\n[https://www.maxmind.com/en/home](https://www.maxmind.com/en/home),\n[https://www.geonames.org/](https://www.geonames.org/),\n[https://raw.githubusercontent.com/dr5hn/countries-states-cities-database/master/countries%2Bstates%2Bcities.json](https://raw.githubusercontent.com/dr5hn/countries-states-cities-database/master/countries%2Bstates%2Bcities.json),\n[https://www.whosonfirst.org/](https://www.whosonfirst.org/) and\n[https://github.com/nigelhorne/vwf](https://github.com/nigelhorne/vwf).\n\n[Geo::Coder::Free::Local](https://metacpan.org/pod/Geo%3A%3ACoder%3A%3AFree%3A%3ALocal),\n[Geo::Coder::Free::Maxmind](https://metacpan.org/pod/Geo%3A%3ACoder%3A%3AFree%3A%3AMaxmind),\n[Geo::Coder::Free::OpenAddresses](https://metacpan.org/pod/Geo%3A%3ACoder%3A%3AFree%3A%3AOpenAddresses).\n\nSee [Geo::Coder::Free::OpenAddresses](https://metacpan.org/pod/Geo%3A%3ACoder%3A%3AFree%3A%3AOpenAddresses) for instructions creating the SQLite database from\n[http://results.openaddresses.io/](http://results.openaddresses.io/).\n\n# AUTHOR\n\nNigel Horne, `\u003cnjh@bandsman.co.uk\u003e`\n\nThis library is free software; you can redistribute it and/or modify\nit under the same terms as Perl itself.\n\n# SUPPORT\n\nThis module is provided as-is without any warranty.\n\nYou can find documentation for this module with the perldoc command.\n\n    perldoc Geo::Coder::Free\n\nYou can also look for information at:\n\n- MetaCPAN\n\n    [https://metacpan.org/release/Geo-Coder-Free](https://metacpan.org/release/Geo-Coder-Free)\n\n- RT: CPAN's request tracker\n\n    [https://rt.cpan.org/NoAuth/Bugs.html?Dist=Geo-Coder-Free](https://rt.cpan.org/NoAuth/Bugs.html?Dist=Geo-Coder-Free)\n\n- CPANTS\n\n    [http://cpants.cpanauthors.org/dist/Geo-Coder-Free](http://cpants.cpanauthors.org/dist/Geo-Coder-Free)\n\n- CPAN Testers' Matrix\n\n    [http://matrix.cpantesters.org/?dist=Geo-Coder-Free](http://matrix.cpantesters.org/?dist=Geo-Coder-Free)\n\n- CPAN Testers Dependencies\n\n    [http://deps.cpantesters.org/?module=Geo::Coder::Free](http://deps.cpantesters.org/?module=Geo::Coder::Free)\n\n- Search CPAN\n\n    [http://search.cpan.org/dist/Geo-Coder-Free/](http://search.cpan.org/dist/Geo-Coder-Free/)\n\n# LICENSE AND COPYRIGHT\n\nCopyright 2017-2025 Nigel Horne.\n\nThe program code is released under the following licence: GPL for personal use on a single computer.\nAll other users (including Commercial, Charity, Educational, Government)\nmust apply in writing for a licence for use from Nigel Horne at \\`\u0026lt;njh at nigelhorne.com\u003e\\`.\n\nThis product uses GeoLite2 data created by MaxMind, available from\n[https://www.maxmind.com/en/home](https://www.maxmind.com/en/home). See their website for licensing information.\n\nThis product uses data from Who's on First.\nSee [https://github.com/whosonfirst-data/whosonfirst-data/blob/master/LICENSE.md](https://github.com/whosonfirst-data/whosonfirst-data/blob/master/LICENSE.md) for licensing information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnigelhorne%2Fgeo-coder-free","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnigelhorne%2Fgeo-coder-free","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnigelhorne%2Fgeo-coder-free/lists"}