visgl / deck.gl

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

[Feat] PMTile Support #8615

Closed james-willis closed 8 months ago

james-willis commented 8 months ago

Target Use Case

PMTiles is an up and coming cloud native file format for serving MVTs from block storage. Being able to render these tiles in deck.gl would simplify stories of generating and serving tiles out of block storage, where writing large numbers of mvt files would be time and cost prohibitive.

I would be interested in implementing once there is consensus on the interface and any implementation details.

Proposal

I'm not sure if it would be more appropriate as a feature of the existing MVTLayer or as its own PMTLayer:

MVTLayer:

new MVTLayer({
  data: 'https://mySite.com/myTiles.pmtiles',
});

PMTLayer:

new PMTLayer({
  data: 'https://mySite.com/myTiles.pmtiles',
});
james-willis commented 8 months ago

I see this is a duplicate: https://github.com/visgl/deck.gl/discussions/7861

james-willis commented 8 months ago

Already possible using @deck.gl-community/layers:

import {TileSourceLayer} from '@deck.gl-community/layers';
import {PMTilesSource} from '@loaders.gl/pmtiles';

const PMTileLayer = new TileSourceLayer({
  tileSource: new PMTilesSource({url: 'http://website.tld/myTiles.pmtiles'}),
});
cboettig commented 6 months ago

@james-willis that's fantastic, thanks! Is it possible to use this directly from pydeck? Haven't seen any pydeck examples and am struggling with the syntax. :pray:

sheecegardezi commented 1 day ago

A pure JavaScript example using svelte:

<script>
    import {Deck} from '@deck.gl/core';
    import {TileSourceLayer} from '@deck.gl-community/layers';
    import {PMTilesSource} from '@loaders.gl/pmtiles';
    import {onMount} from "svelte";
    import {createDataSource} from '@loaders.gl/core';
    import {MVTSource, TableTileSource} from '@loaders.gl/mvt';

    const INITIAL_VIEW_STATE = {
        longitude: -122.4,
        latitude: 37.74,
        zoom: 2,
        minZoom: 1,
        maxZoom: 20,
        pitch: 0,
        bearing: 0
    };

    const data_urls = [
        "https://c.tile.openstreetmap.org",
        "https://c.tile.openstreetmap.org/{z}/{x}/{y}.png",
        "https://4sq-studio-public.s3.us-west-2.amazonaws.com/pmtiles-test/161727fe-7952-4e57-aa05-850b3086b0b2.pmtiles",
        "https://r2-public.protomaps.com/protomaps-sample-datasets/nz-buildings-v3.pmtiles",
        "https://r2-public.protomaps.com/protomaps-sample-datasets/terrarium_z9.pmtiles"
    ]

    let selected_data_url = $state(data_urls[1])  # <- change index to itrate though different datasets

    let map = $state();
    onMount(() => {
        let tileSource = createDataSource(
            selected_data_url,
            [PMTilesSource, MVTSource], {}
        )

        const tileLayer = new TileSourceLayer({ tileSource });

        map = new Deck({
            canvas: "deck-canvas",
            initialViewState: INITIAL_VIEW_STATE,
            controller: true,
            layers: [
                tileLayer
            ]
        });
    })
</script>
<canvas id="deck-canvas"></canvas>