webgis之制作地图切片方法(三) —— tippecanoe

相关文章

《webgis之制作地图切片方法(一) —— QGIS》
《webgis之制作地图切片方法(二) —— gdal2tiles.py》

前言
本文介绍Mapbox开源的一个非常强大的矢量切片工具应用 —— tippecanoe。通过该工具可以将geojson格式的数据切片成 xyz 形式的矢量切片 或者 mbtiles 格式的矢量切片。本文将介绍该工具简单应用方式,并通过 MapboxGL 预览切片。

  • 环境
    macOS、tippecanoe、express、MapboxGL
  • 工具安装
    本实验是macOS环境,win系统使用可以装个ubuntu虚拟机,具体方式可以参考官网。
$ brew install tippecanoe

制作切片

更多配置项参考官网。

1. 制作mbtiles 切片

配置项 含义
-zg 自动选择最大的maxZoom,平衡性能
-o 输出文件
custome.json 切片的文件,仅支持geojson,根据实际情况写
tippecanoe -zg -o custom.bmtiles custom.json 

2. 制作xyz切片(pbf)

(1)不压缩的pbf 切片

配置项 含义
-z maxZoom,最大的切片层级
-Z minZoom,最小的切片层级
-pC 不压缩文件(gzip)
-e 输出文件夹
custome.json 切片的文件,仅支持geojson,根据实际情况写
tippecanoe -z10 -Z0 -pC -e xyz custom.json
  • 切片结果如下:
    webgis之制作地图切片方法(三) —— tippecanoe_第1张图片
  • MapboxGL加载切片

未压缩的切片放在服务器中以静态文件服务的形式发布,可以使用MapboxGL直接调用。

<html>

<head>
    <title>Mapbox Demotitle>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <link href="https://api.mapbox.com/mapbox-gl-js/v2.13.0/mapbox-gl.css" rel="stylesheet">
    <script src="https://api.mapbox.com/mapbox-gl-js/v2.13.0/mapbox-gl.js">script>
head>

<body>
    <div id="map" style="width: 100vw; height: 100vh">div>
body>
<script type="text/javascript">

    // Get a mapbox API access token
    mapboxgl.accessToken = 'token';

    // Initialize mapbox map
    const map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/mapbox/dark-v11',
        center: [22.324219, 42.423322],
        zoom: 4,
    });

    map.on('load', () => {

        map.addSource('myvct', {
            type: 'vector',
            tiles: ['http://localhost:3000/geoserver/{z}/{x}/{y}.pbf']
        })
        map.addLayer({
            id: 'mylayer',
            source: 'myvct',
            "source-layer": 'custom',
            type: 'fill',
            paint: {
                "fill-color": '#0080ff',
                'fill-opacity': 0.5
            }
        })
    });
script>

html>
  • 渲染效果
    webgis之制作地图切片方法(三) —— tippecanoe_第2张图片
    (2)gzip压缩的pbf切片
    gzip压缩是默认的切片方式,其中有一点点坑,切片集不能在像未压缩那样简单粗暴的扔到服务器调用就行,如何使用往下看吧。
  • 切片命令
tippecanoe -z10 -Z0 -e xyz custom.json
  • 问题
    将切片结果,仍然像上文那样去使用时,客户端报错了message : "Unimplemented type: 3",这个问题官方也有提到 issues,由此官网也对这个做了补充描述。
  • 解决方法
    解决方法很简单,只需要在请求切片返回头参数Response Headers加参数 Content-Encoding: gzip 就可以了。实现目的的方式多种多样,本实验使用 express 实现地图服务支持。服务端关键代码如下:
const express = require("express");
const fs = require("fs");
const path = require("path");

const app = express();
const port = 3000;

// 自定义跨域中间件
const allowCors = function (req, res, next) {
  res.header("Access-Control-Allow-Origin", req.headers.origin);
  res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
  res.header("Access-Control-Allow-Headers", "Content-Type");
  res.header("Access-Control-Allow-Credentials", "true");
  next();
};
app.use(allowCors); //使用跨域中间件

// pbf 矢量切片请求接口
app.get("/geoserver/:z/:x/:y", (req, res) => {
  const { z, x, y } = req.params;

  // 读取pbf文件
  const pbfFilePath = `./zipxyz/${z}/${x}/${y}`

  if(fs.existsSync(pbfFilePath)){
    const file = fs.createReadStream(pbfFilePath);
    // 根据pbf文件是否压缩设置相应头
    res.setHeader("Content-Encoding", "gzip");
  
    /**
     * some program block.
     */
  
    file.pipe(res);
  }
});

app.listen(port, () => {
  console.log(`server on ${port}`);
});

  • 效果
    webgis之制作地图切片方法(三) —— tippecanoe_第3张图片

你可能感兴趣的:(Mapboxgl,GIS,Nodejs,javascript,node.js)