visgl / deck.gl

WebGL2 powered visualization framework
https://deck.gl
MIT License
12.08k stars 2.08k forks source link

RFC: TileJson #4930

Closed VictorVelarde closed 3 years ago

VictorVelarde commented 4 years ago

Hi!, I'm bringing here a RFC for a new feature around MVTLayer. I will use first the short template proposed in the issue, to add the main points, and then I'll add some more details in a comment.


Target Use case

This would help users to consume a standard for MVT tiles. This would also open a path for new features around MVT metadata

Proposed feature

A modification at MVTLayer data param, so it accepts a url with a tilejson endpoint

To Do List

VictorVelarde commented 4 years ago

And this is a bit more elaborated RFC. Eager to receive your feedback on it. Thx!


RFC: TileJson in MVTLayer, including metadata support

References:

Summary

This RFC proposes the addition of TileJSON support to the current MVTLayer (with some work on loaders.gl if necessary), including optional metadata such as TileStats extension

Motivation

deck.gl right now supports an MVTLayer connected to one or several url templates (with {x}, {y}, {z} placeholders). But there is another common approach to specify the MVT endpoints, through the use of a TileJSON. It is a de facto standard: a JSON format for describing map tilesets, with some metadata that can be pretty useful for managing the layer.

The TileJSON includes these params:

Adding TileJSON would ease the use of MVTLayer in some use cases. Supporting some of its optional params would also unlock several visualization features for the users, such as styles based on metadata.

TileJSON is also used in some other relevant tools and libraries, such as QGIS and tippecanoe

Options

A basic implementation on MVTLayer could look like this at API level:

let tileJsonEndpoint = "https://bq1.cartocdn.com/tilesjson?t=cartobq.maps.ais_tileset";
let mvt = new MVTLayer(data: tileJsonEndpoint);

Or and equivalent version built over an object

let mvt = new MVTLayer(
    data: {
        "tilejson": "2.2.0",
        "tiles": [
        "https://bq1.cartocdn.com/tile?y={y}&x={x}&z={z}&p=0_16_19257_19396_24574_24697_4000_1&t=cartobq.maps.nyc_taxi_points_demo_id"
    ],
        "tilestats": {
            ...someStats
        }
    }
);

Another approach could be a Composition Layer based on MVTLayer.

ibgreen commented 4 years ago

+1, tilejson support makes a lot of sense.

I assume some desired properties could be:

alasarr commented 4 years ago

@ibgreen tomorrow we'll post another RFC for a classifier with styles. We've thought something like this:

const colors = [
    [ 0, 0, 0, 0],
  [ 0, 255, 0, 0]
  [255, 0, 255, 0
]; 

let classifier;

new MVTLayer({
  data: 'https://abc.com/tileset?tilejson',

    getFillColor: (o) => {
        const bin = classifier.getBin(o.pop);
        return colors[bin];
    },
  onMetadata: (tilejson) => {
        classifier = new Classifier(tilejson.tilestats.layer[0], 'pop', 'quantiles', 3);
  }
});
kylebarron commented 4 years ago
  • tilestats: an "advanced param" with metadata about the layer's fields and statistics calculated from their values (field type, min / max values...)

To be rigorous, the TileJSON schema doesn't mention tilestats; it just happens to allow extra keys beyond what's defined: (I.e. additionalProperties: false doesn't appear in the TileJSON JSON Schema). I would caution against any implementation that expects tilestats to exist.

Adding TileJSON would ease the use of MVTLayer in some use cases

TileJSON is orthogonal to vector tiles. An implementation in deck.gl should be in the TileLayer, not the MVTLayer.

data: 'https://abc.com/tileset?tilejson'

It might be preferable to use a different prop, so that data refers only to urls that return data

TileJSON is also used in some other relevant tools and libraries, such as QGIS and tippecanoe

To be a bit pedantic: Tippecanoe doesn't export valid TileJSON, it just exports enough metadata such that a TileJSON can be formed from it.

alasarr commented 4 years ago

To be rigorous, the TileJSON schema doesn't mention tilestats; it just happens to allow extra keys beyond what's defined: (I.e. additionalProperties: false doesn't appear in the TileJSON JSON Schema). I would caution against any implementation that expects tilestats to exist.

It must only require the required fields in the standard. The stats are outside of the scope of this implementation, we just return the fetched tilejson on the callback. And it's on the user to use something out of the standard.

Thus, the implementation should work with a tilejson without a tilestats

TileJSON is orthogonal to vector tiles. An implementation in deck.gl should be in the TileLayer, not the MVTLayer.

Agree