0.3.2 • Published 4 years ago

tree-geocoder v0.3.2

Weekly downloads
11
License
MIT
Repository
github
Last release
4 years ago

tree-geocoder

npm

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 -h
Usage: tree-geocoder [options] <query>

Options:
  --maxResults, <maxResults>  Maximum amount of desired results
  --minScore <minScore>       Minimum accepted score (based on Dice's coefficient) for matched results (value between 0 and 1)
  --mode, <mode>              Select "prefix" or "suffix" for specific matching mode. Suffix-based matching will be done by default
  --filter, <filter>          Enter "predicate object" pairs (within double quotes and separated by comma) that would be matched over found entities. E.g., "geonames:featureClass geonames:A, osm:boundary osm:Administrative, osm:hasTag 'addr:country=BE'"
  --streaming                 Get streaming results. Sorting by string similarity cannot be guaranteed with streaming results
  -h, --help                  display help for command

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
[
  {
      "@id": "http://www.openstreetmap.org/way/7523153",
      "https://w3id.org/openstreetmap/terms#name": "Meentbrug",
      "score": 0.7692307692307693,
      "https://w3id.org/openstreetmap/terms#highway": "https://w3id.org/openstreetmap/terms#Unclassified",
      "http://www.w3.org/2003/01/geo/wgs84_pos#lat": 5.19221665E1,
      "http://www.w3.org/2003/01/geo/wgs84_pos#long": 4.4825865E0,
      "http://www.opengis.net/ont/geosparql#asWKT": "POINT (4.4825865 51.9221665)",
      "https://w3id.org/openstreetmap/terms#hasTag": "addr:country=NL",
      "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": "https://w3id.org/openstreetmap/terms#Way"
  },
  {
      "@id": "https://sws.geonames.org/2797652",
      "http://www.geonames.org/ontology#countryCode": "http://www.geonames.org/ontology#BE",
      "score": 0.7142857142857143,
      "http://www.geonames.org/ontology#featureClass": "http://www.geonames.org/ontology#P",
      "http://www.geonames.org/ontology#featureCode": "http://www.geonames.org/ontology#P.PPL",
      "http://www.geonames.org/ontology#name": "Gentbrugge",
      "http://www.opengis.net/ont/geosparql#asWKT": "POINT (3.76509 51.03692)",
      "http://www.w3.org/2000/01/rdf-schema#isDefinedBy": "https://sws.geonames.org/2797652/about.rdf",
      "http://www.w3.org/2003/01/geo/wgs84_pos#lat": 5.103692E1,
      "http://www.w3.org/2003/01/geo/wgs84_pos#long": 3.76509E0,
      "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": "http://www.geonames.org/ontology#Feature"
  }
  ...
]

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 = require("tree-geocoder");

async function runQuery() {
    const tgc = new TreeGeocoder();
    const opts = {
        query: "your_query",
        minScore: 0.6 // 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 tgc.geocode(opts).next()).value;
    console.log(results);
}

runQuery();

Or consume it as a stream and get (unsorted) results as soon as possible:

const TreeGeocoder = require("tree-geocoder");

async function runQuery() {
    const tgc = new TreeGeocoder();
    const opts = {
        query: "your_query",
        minScore: 0.6, // 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.geocode(opts)) {
        console.log(result);
    }
}

runQuery();
0.3.2

4 years ago

0.3.1

4 years ago

0.3.0

4 years ago

0.2.2

4 years ago

0.2.1

4 years ago

0.2.0

4 years ago

0.1.1

4 years ago

0.1.0

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago