Vector Tile(矢量瓦片)是现代 Web 地图中最核心的数据格式之一,本文主要用于替换OpenStreetMap自带的 png 瓦片服务,它具有比自带瓦片服务更好的扩展、更好的用户体验、更高的性能以及开发过程中更高的应用性。

一、数据处理

  1. 创建相关目录

    mkdir -p /var/www/html/osm/vector-tile && cd /var/www/html/osm/vector-tile
  2. 下载复制工具代码

    git clone https://github.com/openmaptiles/openmaptiles.git
  3. 准备数据文件

    cd openmaptiles && mkdir data && cp ../../china-latest.osm.pbf data
    
    mkdir -p data/natural_earth
    wget http://naciscdn.org/naturalearth/packages/natural_earth_vector.sqlite.zip -O /tmp/natural_earth_vector.sqlite.zip
    unzip /tmp/natural_earth_vector.sqlite.zip -d data/natural_earth
    
    mkdir -p data/water_polygons
    wget https://osmdata.openstreetmap.de/download/water-polygons-split-4326.zip -O /tmp/water-polygons-split-4326.zip
    unzip /tmp/water-polygons-split-4326.zip -d data/water_polygons
    
    mkdir -p data/lake_centerline
    wget https://github.com/lukasmartinelli/osm-lakelines/releases/download/v0.9/lake_centerline.geojson -O data/lake_centerline/lake_centerline.geojson
    
    
  4. 导入数据

    根据 OSM PBF 文件生成对应区域的 bbox(边界范围)文件,命令中的china-latest就是上面下载的文件名称,只不过去掉了.osm.pbf,所以注意保持一致

    make generate-bbox-file area=china-latest
    
  5. 修改配置文件.env
    MIN_ZOOM=0
    MAX_ZOOM=14
    BBOX=69.0450549,7.1975938,135.6776013,54.0115689
    增加
    DATA_DIR=/data

    BBOX 的值来自于cat data/china-latest.bbox,主要是避免生成全球的数据,那就太大了
  6. 编辑docker-compose.yml

    vi /var/www/html/osm/vector-tile/openmaptiles/docker-compose.yml

    找到import-data:增加

    volumes:
        - ./import:/import
        - ./import:/export
        - ./build:/mapping
        - ./build/sql:/sql
        - ./cache:/cache
        - ./style:/style
        - ./:/tileset
    
  7. Natural Earth

    make import-data
    
  8. 导入中国 OSM

    make import-osm
    
  9. 导入 SQL 图层

    make import-sql
    
  10. 生成 Vector Tile

    make generate-tiles-pg
    

二、安装 TileServer GL

  1. 创建相关目录

    mkdir /var/www/html/osm/vector-tile && cd /var/www/html/osm/vector-tile
    
  2. 下载样式到自定义目录

    mkdir styles/liberty
    wget https://raw.githubusercontent.com/maputnik/osm-liberty/gh-pages/style.json -O styles/liberty/style.json
    
  3. 复制系统自带的目录到自定义目录(如果不使用这个样式也可以不必这个操作)

    docker cp china-vector-server:/usr/src/app/node_modules/tileserver-gl-styles/styles/basic-preview /var/www/html/osm/vector-tile/styles/
    
  4. 更改配置

    vi /var/www/html/osm/vector-tile/openmaptiles/data/config.json

    内容如下:

    {
      "options": {
        "paths": {
          "root": "/data",
          "styles": "/styles"
        },
        "serveAllStyles": true
      },
    
      "styles": {
        "basic": {
          "style": "basic-preview/style.json"
        },
        "liberty": {
          "style": "liberty/style.json"
        }
      },
    
      "data": {
        "china": {
          "mbtiles": "china.mbtiles"
        }
      }
    }
    

    修改样式中的配置

    vi /var/www/html/osm/vector-tile/styles/basic-preview/style.json

    url改为mbtiles://china.mbtiles,如下:

    "sources":{
      "openmaptiles":{
        "type":"vector",
        "url":"mbtiles://china.mbtiles"
      }
    }
    

    修改样式中的配置

    vi /var/www/html/osm/vector-tile/styles/liberty/style.json

    同样将url改为mbtiles://china.mbtiles,如下:

    "sources": {
      "openmaptiles": {
        "type": "vector",
        "url": "mbtiles://china.mbtiles"
      },
      ...
    }
    
  5. 编辑docker-compose.yml

    vi /var/www/html/osm/vector-tile/docker-compose.yml

    内容如下

    services:
    
      tileserver:
        image: maptiler/tileserver-gl
        container_name: china-vector-server
        ports:
          - "9084:8080"
        volumes:
          - /var/www/html/osm/vector-tile/openmaptiles/data:/data
          - /var/www/html/osm/vector-tile/styles:/styles
        command:
          - --mbtiles
          - /data/china.mbtiles
          - --config
          - /data/config.json
  6. 运行

    cd /var/www/html/osm/vector-tile
    docker compose up -d
    
  7. 测试访问

    http://服务器IP:9084
    
    
  8. nginx 反向代理的时候注意下面这行

        location / {
            proxy_set_header    X-Real-IP               $remote_addr;
            proxy_set_header    X-Forwarded-For         $proxy_add_x_forwarded_for;
            proxy_set_header    HTTP_X_FORWARDED_FOR    $remote_addr;
    
            proxy_pass http://127.0.0.1:9084;
            proxy_set_header Host $host; # 注意加上这里
        }