NAME Net::API::Nominatim - Perl client for local or public OpenStreetMap Nominatim Geocoding service. Open source, unrestricted and free. VERSION Version 0.01 !NOMINATIM! Nominatim uses OpenStreetMap data to find locations on Earth by name and address (geocoding). It can also do the reverse, find an address for any location on the planet. Nominatim provides a public, free and un-restricted service, subject to fair usage, at https://nominatim.openstreetmap.org/ui/search.html?%3Cparams%3E for all of your geocoding needs. Most importantly, a Nominatim server can easily and in-expensively be installed locally if you intend to geocode heavily. The geocoding data Nominatim uses is open source, provided by OpenStreetMap . When you install Nominatim locally, you also install this geocoding data locally. The data is broken into different geographical locations so you can geocode for just your country, your continent or the whole planet without relying on the closely guarded data provided by the usual big Capitalist players. If you decide to install Nominatim locally for your own geocoding needs it is also worth to consider installing a Map Tile Server in order to provide your own maps! All the data open source, courtesy of OpenStreetMap . Have a look at this guide for how to completely break free and never again have to rely on the usual big Capitalist players. For local installations, Nominatim can be accessed via a UNIX socket. This should be the fastest method to geocode locally. Unless you have implemented intermediate caching. Alternatively, for local or public Nominatim service, you can make a simple HTTP/GET query. Remember, Capitalism is changing really fast, to the uglier, by the day. Right now it is very hungry. It will become even more so. As a matter of life or death, break away from it NOW. SYNOPSIS The current module provides functionality to query a Nominatim server, either via a local UNIX socket, if Nominatim is installed locally, or via HTTP/GET requests if you rely on the public Nominatim service. The Nominatim API is extensive. But the current module covers only basic forward and reverse geocoding queries only with search, reverse and status. Example usage: use Net::API::Nominatim; my $cparams = { 'server' => { 'url' => 'https://nominatim.openstreetmap.org', }, # optional debug 'debug' => { 'verbosity' => 666, }, # optional logger 'log' => { 'logger-file' => Mojo::Log->new, } }; my $client = Net::API::Nominatim->new($cparams); my $addresses = $client->search({ q => 'Leika', }); # we now have an ARRAY_REF of # Net::API::Nominatim::Model::Address objects back # these objects contain many useful things including # proper address, coordinates and bounding box! # Thank you OpenStreetMap! print $_->toString()."\n" for @$addresses; # or just get the JSON string back my $jsonresponse = $client->search({ q => 'Leika', 'want-json' => 1, }); # You can be more specific with a structured query my $addresses = $client->search({ street => 'Leika', city => 'Honolulu', # county, country, etc. }); # a structured query allows you to search for amenities my $addresses = $client->search({ amenity => 'restaurant', city => 'Honolulu', # county, country, etc. }); # Reverse geo-coding: from coordinates to address my $address = $client->reverse({ lon => '15.014879', # quote them, you never know with floats ... lat => '38.022967', }); # it returns a single Net::API::Nominatim::Model::Address object print $address->toString()."\n"; # server status print "alive!\n" if $client->status(); METHODS new() The constructor. The full list of arguments, provided as a hashref, is as follows: * server : a HASH_REF with one of these keys: * url : specify the Nominatim server URL, for example the public service is located at https://nominatim.openstreetmap.org/ui/search.html. * unix-socket : alternatively, if you have installed Nominatim locally, you may want to query it directly via its UNIX socket. This should then be the fullpath to the local UNIX socket (which must have the appropriate permissions for the current user). * log : a HASH_REF with one of these keys: * logger-file : a filename to log into, or, * logger-object : an already existing logger object which implements methods info(string), warn(string) and error(string). * lwpuseragent : only applicable if doing HTTP queries (and not UNIX socket). This is HASH_REF with some of these keys: * cookies-object : specify a cookies object for loading and saving session cookies, optional and most likely unused, * lwpuseragent-object : specify an already existing LWP::UserAgent object to use. WARNING: this object will have its UserAgent String altered to comply with Nominatim's usage policy which states it must be a string to identify the client. So, this will be our client's UserAgent String. If you intend to use the specified LWP::UserAgent object then save its agent string (my $oldstr = $ua-agent;>) and reload it later ($ua-agent($oldstr);>). * useragent-string : DO NOT SPECIFY your own UserAgent String PLEASE. There is already a default for this which identifies this current client uniquely. So, you do not need to set this. But if you wish to do so, then nobody stops you. The constructor will return undef on failure (but will not die). Caveat The user-specified HASH_REF of parameters into the constructor will be modified. Some fields will be added and some fields will be deleted. It would be ideal if it was cloned but since it can contain OBJECT references I find it difficult to tell Clone or Storable to skip cloning objects. search() It does free-form or structured address search. The full list of arguments, provided as a hashref, is as follows: * The search can be free-form or structured. In case of free-form search you need to specify only q as a free-form address string. In case of a structured search you must NOT specify q at all but specify some of the other fields as specified below. Note that all strings will be url-encoded internally, taking into account if are unicode'd, do not url-encode them yourself. * q : a free-form address string. It will be url-encoded when making the query so do not encode it yourself. * alternatively use some of these for a structured search: amenity, street, city, county, state, country, postalcode. See the structured search API for more details. * want-json : optionally, specify whether you want to have the raw server response back as a JSON string. This will save some time decoding the JSON into Net::API::Nominatim::Model::Address objects. * query-params : optionally specify extra query params to your search as a HASH_REF. See the Nominatim Search API for what these parameters can be. By default, you do not need to specify any of these extra parameters. It returns undef on communication failure. It returns back an ARRAY_REF of zero, one or more Net::API::Nominatim::Model::Address objects on success. Unless the option want-json was set to 1, in which case the return will be a JSON (array-of-hashes) string of results. Warning Do not mix free-form query parameter (q) with structured query parameters (e.g. street, country, etc.). A structured query can return many results depending on how specific it is. For example, if you specify only amenity=restaurant there can be hundreds of results but the public Nominatim service has a default limit of returning only 10 results with a hard-limit of 40. reverse() It does a reverse geocoding search. That is, it returns an address when coordinates are specified. The full list of arguments, provided as a hashref, is as follows: * lat : latitude * lon : longitude * want-json : optionally, specify whether you want to have the raw server response back as a JSON string. This will save some time decoding the JSON into Net::API::Nominatim::Model::Address objects. * query-params : optionally specify extra query params to your search as a HASH_REF. See the Nominatim Search API for what these parameters can be. By default, you do not need to specify any of these extra parameters. It returns undef on communication failure. It returns back a single Net::API::Nominatim::Model::Address object on success. Unless the option want-json was set to 1, in which case the return will be a JSON (hash) string of results. It differs from search() in that it returns a single address object and not an ARRAY_REF of objects. The returned JSON will be a hash containing a single address and not an array. TODO The Nominatim API contains a lot more "verbs" than the three implemented in this module. Feel free to provide implementations if you find any of those useful and they will be incorporated in this module. CAVEATS Queries can return many results depending on how specific they are, especially the structured query. For example, if you specify only amenity=restaurant there can be hundreds of results but the public Nominatim service has a default limit of returning only 10 results with a hard-limit of 40. This is specified in the Nominatim API under limit. RELATED OPEN SOURCE SOFTWARE First of all, OpenStreetMap data is freely available for downloading, for the whole planet or for specific geographical areas from GeoFabrik in the form of .osm.pbf files. This data is understood by Nominatim, the Map tile server and GeoDesk-Gol mentioned below. This data can also be inserted into a PostGIS database and make your own queries on it. I have already mentioned at the INTRODUCTION that it is quite easy and, definetely, not discouraged to host a Nominatim server locally. It will be totally self-sufficient in the sense that it will not need to access any external resources. All addresses for your geographical area or the whole planet are stored in a local PostGIS , powered by the amazing elephant-in-the-server-room PostgreSQL . Check for what resources are required though. For small geographical areas, resources are moderate. You can also host your own map tiles and serve your own high-quality maps without relying ever again on the big players. Have a look at the guide offered at Switch2osm for how you can get started with this, although the resources are bigger and assembling the toolchain is far more complicated than with Nominatim. Another open source project is GeoDesk and the command line query tool GeoDesk-Gol . This tool takes OpenStreetMap data for any geographical location, in the form of .osm.pbf files (see above on where to download them from) and constructs a portable file-based database (called Gol, as in scoring a goal!) which you can then enquire with the provided command line tool. There is no need to create a PostGIS database and insert data into it. The Gol file is all you need for doing queries like, find all restaurants in this neighbourhood, list all street names in this district, list all bus-stops, etc. It is pretty amazing and more so because it is portable, no database setup is required. Of course it is open source and kudos to their creator Clarisma, which by-the-way I am not affiliated in any way, just a fan. TESTING Basic testing (make test) does not require, and, will not attempt online access. It tests instantiating the client and the other auxiliary classes. Live testing needs network access to a public Nominatim server or a local installation of Nominatim. It comes in two flavours: make livetesturl : tests HTTP/GET queries to the public Nominatim server at https://nominatim.openstreetmap.org/ui/search.html. make livetestlocal : tests UNIX socket queries to a local Nominatim installation via its local UNIX socket whose path can be set in all the test files in directory xt/live/local-socket/ via the $sockpath variable, currently pointing to /run/nominatim/nominatim.sock. AUTHOR Andreas Hadjiprocopis, BUGS Please report any bugs or feature requests to bug-net-api-nominatim at rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-API-Nominatim. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. SUPPORT You can find documentation for this module with the perldoc command. perldoc Net::API::Nominatim You can also look for information at: * RT: CPAN's request tracker (report bugs here) https://rt.cpan.org/NoAuth/Bugs.html?Dist=Net-API-Nominatim * CPAN Ratings https://cpanratings.perl.org/d/Net-API-Nominatim * Search CPAN https://metacpan.org/release/Net-API-Nominatim ACKNOWLEDGEMENTS LICENSE AND COPYRIGHT This software is Copyright (c) 2025 by Andreas Hadjiprocopis. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible)