An open API service indexing awesome lists of open source software.

https://github.com/mmomtchev/query-mvt

Query features from remote MVT tiles by location
https://github.com/mmomtchev/query-mvt

Last synced: 6 months ago
JSON representation

Query features from remote MVT tiles by location

Awesome Lists containing this project

README

          

# query-mvt

Query map features nearest to a given point from a remote MVT vector tiles layer

[![License: ISC](https://img.shields.io/github/license/mmomtchev/query-mvt)](https://github.com/mmomtchev/query-mvt/blob/master/LICENSE)
[![Node.js CI](https://github.com/mmomtchev/query-mvt/actions/workflows/node.js.yml/badge.svg)](https://github.com/mmomtchev/query-mvt/actions/workflows/node.js.yml)[![codecov](https://codecov.io/gh/mmomtchev/query-mvt/branch/main/graph/badge.svg?token=oT28J2XMYB)](https://codecov.io/gh/mmomtchev/query-mvt)

`query-mvt` allows you query remote vector tile sets for features. Its main advantage is that it does not require any special access or server-side software as it mimics the behavior of a web browser displaying the map.

It works both in Node.js and in the browser. It supports all vector mapping services that use MVT/PBF files and can adapt to different projections and tileset extents.

# Usage

```shell
npm i query-mvt
```

Vector tile sets created by GDAL and a few other tools come with a de-facto standard `metadata.json` that allows `query-mvt` to automatically acquire all the needed parameters (such as map projects, tile grid and size, world bounds):

## with `metadata.json`

```js
import * as queryMVT from 'query-mvt';

// Automatically imports the layer metadata
// (EPSG:4326 with world coverage in this case)
queryMVT.acquire('https://velivole.b-cdn.net/tiles/place/2/metadata.json')
.then((metadata) => queryMVT.search({
url: 'https://velivole.b-cdn.net/tiles/place/2/{z}/{x}/{y}.pbf',
lon: 6.220432,
lat: 45.779170,
metadata
}))
.then((result) => {
assert.strictEqual(result.feature.properties['n'], 'Doussard');
assert.closeTo(result.distance, 0.34, 0.1);
})
```

## raw MVT tiles

Most commercial public mapping services such as Qwant do not have a `metadata.json` but tend to use the same `EPSG:3857` projection (aka Web Mercator) and world bounds:

```js
import * as queryMVT from 'query-mvt';

// Configure manually the layer metadata
// (EPSG:3857 with world coverage in this case)
queryMVT.search({
url: 'https://tiles.qwant.com/default/{z}/{x}/{y}',
lon: 2.348942,
lat: 48.853289,
// You can filter the results
filter: (f) => f.properties['class'] === 'city',
maxFeatures: 20,
maxRadius: 10,
metadata: queryMVT.constants.EPSG3857
})
.then((results) => {
assert.strictEqual(results[0].feature.properties['class'], 'city');
assert.strictEqual(results[0].feature.properties['name'], 'Paris');
assert.closeTo(results[0].distance, 0.04, 0.1);
})
```

## CLI

A stand-alone CLI version exists as well:

```shell
# Query the nearest village near 45.779° N : 6.22° E
query-mvt 45.779 6.22 -f class=village
```

## API

#### Table of Contents

* [Result](#result)
* [Properties](#properties)
* [distance](#distance)
* [feature](#feature)
* [acquire](#acquire)
* [Parameters](#parameters)
* [search](#search)
* [Parameters](#parameters-1)

### Result

Type: {distance: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), feature: turf.Feature}

#### Properties

* `distance` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)**
* `feature` **turf.Feature**

#### distance

Distance in km

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### feature

Feature (turf.js and GeoJSON compatible)

Type: turf.Feature

### acquire

#### Parameters

* `url` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** URL of a GDAL-style metadata.json
* `fetchOpts` **RequestInit?** optional fetch options (AbortController, authorization headers...)

Returns **MVTMetadata**

### search

#### Parameters

* `opts` **Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), any>** options

* `opts.url` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Openlayers-style URL template for requesting tiles, must contain {x}, {y} and {z}
* `opts.metadata` **MVTMetadata?** optional GDAL-style metadata.json, may be empty for world-wide EPSG:3857 tilesets
* `opts.lon` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** longitude
* `opts.lat` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** latitude
* `opts.queue` **Queue?** optional shared Queue to be used for limiting concurrency, @default Queue(8,0)
* `opts.maxFeatures` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** optional number of features to return, @default 1
* `opts.maxRadius` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** optional maximum radius in km to search in, @default 10
* `opts.fetchOpts` **RequestInit?** optional fetch options (AbortController, authorization headers...)
* `opts.dedupe` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** dedupe the returned features (as the text will usually stretch across several tiles)

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Result](#result)>>**