【问题标题】:How to serve multiple .pbf files instead of .mbtiles with TileServer-GL or OpenMapTiles server as vector tiles into Google Maps with Deck.GL MVTLayer?如何使用 TileServer-GL 或 OpenMapTiles 服务器将多个 .pbf 文件而不是 .mbtiles 作为矢量切片提供到使用 Deck.GL MVTLayer 的 Google 地图中?
【发布时间】:2024-05-29 13:20:02
【问题描述】:

总结

我有 .geojson 文件并想将它们(使用tippecanoe / geobuf / 其他)转换为 .mbtiles 或 .pbf 文件,以将它们作为来自服务器的矢量切片 (TileServer-GL / OpenMapTiles /其他矢量切片服务器)使用 Deck.GLMVTLayer 进入 Google 地图。

预期结果:

  1. 能够从 TileServer-GL .pbf 文件而不是 .mbtiles 文件提供服务。
  2. 能够从 TileServer-GL 提供文件夹中的多个 .mbtiles(或 .pbf)文件,而无需使用特定的 .mbtiles 文件显式启动它。

实际结果:

  1. 如下所述,我正在使用带有 Deck.GL MVTLayer integration 的 Google Maps 和矢量平铺来提供来自 TileServer-GL 的特定 .mbtiles 文件,作为形状或点的集合。
  2. 什么都没做。

我的尝试

const map = new google.maps.Map(document.getElementById('container'), {
        center: { lat: 51.47, lng: 0.45 },
        zoom: 10
    });
const deckOverlay = new deck.GoogleMapsOverlay({
        layers: [
            new deck.MVTLayer({
                //working               
                data: `http://localhost:8080/data/SA1_2016-AU-tippecanoe/{z}/{x}/{y}.pbf`,
                //expected, but server NOT starting
                //data: `http://localhost:8080/data/SA1_2016-AU-geobuf/{z}/{x}/{y}.pbf`,

                minZoom: 0,
                maxZoom: 23,
                getLineColor: [1, 1, 1],
                getFillColor: [0, 153, 76],
                pickable: true,
                autoHighlight: true,
                onClick: info => info.object && console.log('onClick', info.object)
            })
        ]
    });
deckOverlay.setMap(map);

我从 Docker 运行 TileServer-GL,从包含数据文件的文件夹:

docker run --rm -it -v ${pwd}:/data -p 8080:80 maptiler/tileserver-gl --verbose --mbtiles SA1_2016-AU-tippecanoe.mbtiles

在 Docker 中,我通过 tippecanoe 将 .geojson 文件转换为 .mbtiles 文件。但是,对于更大的文件,转换似乎需要一些时间。 我在 aprox 中获得了一个 890 MB 的 .mbtiles 文件。 60 分钟从一个 45 MB 的 .geojson 文件,包含 57k 个功能。

docker run -it --rm -v ${pwd}:/data tippecanoe:latest tippecanoe --output=/data/SA1_2016-AU-tippecanoe.mbtiles /data/SA1_2016-AU.geojson

我设法通过 geobuf (json2geobuf) 更快地将 .geojson 文件直接转换为 .pbf 文件。 我在 aprox 中获得了一个 32 MB 的 .pbf 文件。 45 MB .geojson 文件的 37 秒,包含 57k 个特征。

json2geobuf SA1_2016-AU.geojson > SA1_2016-AU-geobuf.pbf

但是,我似乎无法直接从 TileServer-GL 和 OpenMapTiles-Server 提供 .pbf 文件。


我试过了

docker run --rm -it -v ${pwd}:/data -p 8080:80 maptiler/tileserver-gl --verbose --mbtiles SA1_2016-AU-geobuf.pbf

但是 TileServer-GL 没有启动并且我正在获取

ERROR: Metadata missing in the MBTiles.
       Make sure SA1_2016-AU-geobuf.pbf is valid MBTiles

我也尝试在本地创建 config.json 文件后重新运行

docker run --rm -it -v ${pwd}:/data -p 8080:80 maptiler/tileserver-gl --verbose --mbtiles SA1_2016-AU-geobuf.pbf
docker run --rm -it -v ${pwd}:/data -p 8080:80 maptiler/tileserver-gl --verbose SA1_2016-AU-geobuf.pbf

config.json

{
  "options": {
    "paths": {
      "root": "/usr/src/app/node_modules/tileserver-gl-styles",
      "fonts": "fonts",
      "styles": "styles",
      "mbtiles": "/data"
    }
  },
  "styles": {},
  "data": {
    "SA1_2016-AU-geobuf": {
      "mbtiles": "SA1_2016-AU-geobuf.pbf"
    }
  }
}

但是 TileServer-GL 没有启动并且我正在获取

SQLITE_NOTADB: file is not a database

在 OpenMapTiles 服务器上,我什至不知道如何指定输入文件 (reference):

docker run --rm -it -v ${pwd}:/data -p 8080:80 klokantech/openmaptiles-server

我的问题

  1. 如何使用 TileServer-GL 或 OpenMapTiles 服务器直接提供 .pbf 文件而不是 .mbtiles 文件?
  2. 如何使用 TileServer-GL 提供文件夹中的所有文件 (.mbtiles),而无需使用特定的 .mbtiles 文件docker ... maptiler/tileserver-gl --mbtiles some-file.mbtiles 明确启动它?

【问题讨论】:

    标签: google-maps mbtiles deck.gl vector-tiles tileserver-gl


    【解决方案1】:

    Geobuf pbf 不是平铺数据集,而是与 geojson (https://github.com/mapbox/geobuf/blob/master/README.md#geobuf) 相比更小更紧凑的二进制形式。您仍然需要通过tippecanoe 运行该geobuf,以在z/x/y 平铺方案中创建mbtiles 或pbf 目录(https://github.com/mapbox/tippecanoe#input-files-and-layer-names)。

    如果您使用tippecanoe-json-tool input.geojson > output_nd.geojson 将该geojson 转换为ndjson,您会看到使用tippecanoe 的运行时间要快得多,并利用-P 标志将output_nd.geojson 并行处理为mbtiles。如果tippecanoe 的输入是geobuf 文件(https://github.com/mapbox/tippecanoe#parallel-processing-of-input),则默认情况下也会启用tippecanoe 并行处理。使用 ndjson 文件的简单tippecanoe cmd 将是tippecanoe -t /dev/shm -o output.mbtiles -P -Z 1 -z 12 --drop-smallest-as-needed output_nd.geojson

    对于 tileserver-gl,您可以根据需要提供任意数量的 mbtiles 文件,但您需要提供自己的 config.json,将其挂载到容器 -v ${pwd}/config:/config,并使用 --config 标志显式调用它在你的docker run cmd中。

    如下所示的简单 shell 脚本可以更精细地控制样式(如果使用自定义样式)、字体(如果使用自定义字体)、精灵(如果使用自定义 sprite)以及您的数据和配置文件。

    #!/usr/bin/env bash
    
    TILESERVER_HOME=/tileserver-gl
    
    DATA_DIR=${TILESERVER_HOME}/mbtiles/
    CONFIG_DIR=${TILESERVER_HOME}/config/
    STYLE_DIR=${TILESERVER_HOME}/styles/
    SPRITES_DIR=${TILESERVER_HOME}/sprites/
    FONT_DIR=${TILESERVER_HOME}/fonts/
    
    docker stop tileserver-gl && docker rm tileserver-gl
    
    docker run --log-driver json-file --log-opt compress=true --log-opt max-size=100m --log-opt max-file=3 -d --name tileserver-gl --restart=always -v ${SPRITES_DIR}:/sprites -v ${DATA_DIR}:/data -v ${STYLE_DIR}:/styles -v ${FONT_DIR}:/fonts -v ${CONFIG_DIR}:/config -p 0.0.0.0:8080:80 maptiler/tileserver-gl:latest --verbose --config /config/config.json
    

    与上述 docker cmd 一起列出多个 mbtiles 文件的示例 config.json。

    {
        "options": {
            "paths": {
                "root": "",
                "fonts": "../fonts",
                "mbtiles": "../data",
                "styles": "../styles",
                "sprites": "../sprites"
            }
        },
        "data": {
            "STREETS": {
                "mbtiles": "STREETS.mbtiles"
            },
            "LANDMASS": {
                "mbtiles": "LANDMASS.mbtiles"
            },
            "CONTOUR": {
                "mbtiles": "CONTOUR.mbtiles"
            },
            "HILLSHADE": {
                "mbtiles": "HILLSHADE.mbtiles"
            },
            "OSM": {
                "mbtiles": "OSM.mbtiles"
            }
        },
        "styles": {
            "STREETS": {
                "style": "STREETS/style.json",
                "serve_data": true,
                "serve_rendered": true,
                "tilejson": {
                    "format": "png",
                    "bounds": [
                        -120,
                        -50,
                        160,
                        80
                    ]
                }
            },
            "OSM-POSITRON": {
                "style": "OSM-POSITRON/style.json",
                "serve_data": true,
                "serve_rendered": true,
                "tilejson": {
                    "format": "png",
                    "bounds": [
                        4.3026,
                        48.6085,
                        4.42742,
                        48.707
                    ]
                }
            }
        }
    }
    

    【讨论】: