tree-geocoder
A command line tool and library for geocoding based on the TREE traversal approach over GeoNames and OSMNames data. The tool matches GeoNames and OSMNames entities using either prefix or suffix-based approaches. To foster interoperability, data entities are modeled using a JSON-LD seralization based on the GeoNames Ontology and the OpenStreetMap Vocabulary respectively.
Prefix-based geocoding means that, querying for gent
will result in entities like Geonames's Gent
, Gentinnes
, Gentbrugge
and OSM's Gent
, Genté
, Gentil
etc. On the other hand, suffix-based geocoding for terdam
will result in entities such as Rotterdam
, Amsterdam
, Achterdam
and also fuzzy matched results like Overdam
and Veerdam
.
The tool assigns a score
to every matched entity based on the Sørensen–Dice coefficient, which is calculated using the string-similarity
library.
Results can be obtained as soon as possible in a streaming and unsorted way using the --streaming
option (see example below) or can be awaited for a complete answer that will be sorted by score
.
Furthermore, this tool supports filtering options based on the minimum accepted score (e.g., --minScore 0.7
) and entity properties (e.g., only entities that represent administrative regions: --filter "geonames:featureClass geonames:A, osm:boundary osm:Administrative"
) .
Requirements
This tool requires Node.js v12.x or superior.
Geographic coverage
Up until now, we support the following countries to perform geocoding queries:
- Prefix queries: Austria, Belgium, Denmark, France, Germany, Great Britain, Greece, Italy, Luxembourg, Spain, Switzerland, The Netherlands and USA.
- Suffix queries: Belgium, France and The Netherlands.
Command line interface
Install it:
npm install -g tree-geocoder
Use the help option -h
to see what are the possible uses:
tree-geocoder -hUsage: tree-geocoder [options] <query> Options: --maxResults, <maxResults> Maximum amount of desired results --minScore <minScore> Minimum accepted score
Use it for a prefix-based geocoding query:
tree-geocoder --mode prefix --maxResults 5 your_query
Use it for a suffix-based geocoding query:
tree-geocoder --maxResults 10 your_query
Get results in a streaming way and pipe them into other applications:
tree-geocoder --streaming your_query | other_awesome_application
Filter results based on entity properties and string similarity. In this example we filter to have only streets and roads (of all kinds) having a score
of 0.6 or higher:
tree-geocoder --minScore 0.6 --filter "geonames:featureClass geonames:R, osm:highway '*'" your_query
A more specific filter for only GeoNames water streams and OSM residential roads in France:
tree-geocoder --filter "geonames:featureCode geonames:H.STM, geonames:countryCode geonames:FR, osm:highway osm:Residential, osm:hasTag 'addr:country=FR'" your_query
Refer to the documentation of Geonames classes and OSM tags for more information on what is possible in the filtering option.
As an example on how the results of a query look see the following query for entbru
which will include the following:
tree-geocoder entbru[ , ...]
Library
This tool can be used both in the backend (Node.js) and in the browser by means of a tool such as Webpack.
Install it in your project npm install tree-geocoder
.
The TreeGeocoder
class exposes the AsyncGenerator function geocode()
, which can be used as follows:
Use it synchronously and get sorted (by score
) results:
const TreeGeocoder = ; { const tgc = ; const opts = query: "your_query" minScore: 06 // Optional. Values between 0 and 1 (higher means more similar) maxResults: 10 // Optional mode: "prefix" // Or don't define to get suffix-based results filter: // Optional. Define the predicate-object pairs that will be matched against each type of entity "https://w3id.org/openstreetmap/terms#": // Rules for OSM entities "https://w3id.org/openstreetmap/terms#highway": "https://w3id.org/openstreetmap/terms#Motorway" "https://w3id.org/openstreetmap/terms#hasTag": "addr:country=BE" "http://www.geonames.org/ontology#": // Rules for GeoNames entities "http://www.geonames.org/ontology#featureClass": "http://www.geonames.org/ontology#P" "http://www.geonames.org/ontology#countryCode": "http://www.geonames.org/ontology#BE" ; const results = await tgcnextvalue; console;} ;
Or consume it as a stream and get (unsorted) results as soon as possible:
const TreeGeocoder = ; { const tgc = ; const opts = query: "your_query" minScore: 06 // Optional. Values between 0 and 1 (higher means more similar) maxResults: 100 // Optional streaming: true filter: // Optional. Define the predicate-object pairs that will be matched against each type of entity "https://w3id.org/openstreetmap/terms#": // Rules for OSM entities "https://w3id.org/openstreetmap/terms#highway": "https://w3id.org/openstreetmap/terms#Motorway" "https://w3id.org/openstreetmap/terms#hasTag": "addr:country=BE" "http://www.geonames.org/ontology#": // Rules for GeoNames entities "http://www.geonames.org/ontology#featureClass": "http://www.geonames.org/ontology#P" "http://www.geonames.org/ontology#countryCode": "http://www.geonames.org/ontology#BE" ; for await const result of tgc console; } ;