概述
矢量切片通常作为从 GeoJSON 转换的静态文件分发(.pbf 文件的分发)。尽管从性能和服务器成本方面来看,这是最好的方法,但它存在一些典型问题。
- 转换成本很高(尤其是行星级,当瓷砖数量巨大时)。
- 我不擅长添加/删除/更新数据
这就是为什么能够从数据库动态地提供切片如此重要的原因。但是,这种方法也存在性能等问题,因此您需要仔细考虑使用哪种方法以及为什么。
PostGIS 是 FOSS4G 世界的数据库。有几个应用程序可以从 PostGIS 表中动态提供矢量图块。
一个主要区别是 martin 和 pg_tileserv 使用 PostGIS ST_AsMVT 函数,而其他函数则不使用。因为 martin 和 pg_tileserv 是比其他的更新的实现。
本文比较了 tegola、martint 和 pg_tileserv。
配置 PostGIS + 矢量切片服务器
PostgreSQL
启动 PostgreSQL 并使用 Docker 插入数据。
(以下以 docker-compose.yml 格式写入,恕不另行通知)
postgis:
image: kartoza/postgis:12.4
environment:
- POSTGRES_USER=docker
- POSTGRES_PASS=docker
- POSTGRES_DB=postgres
ports:
- "5432:5432"
volumes:
- postgis-data:/var/lib/postgresql
- ./postgres:/usr/src/app
networks:
- default
healthcheck:
test: [ "CMD-SHELL", "pg_isready" ]
interval: 10s
timeout: 5s
retries: 5
启动 PostgreSQL...
docker-compose up -d postgis
接下来,输入数据。这一次,我使用了geofabrik 的关东建筑和道路数据。
wget https://download.geofabrik.de/asia/japan/kanto-latest-free.shp.zip
unzip kanto-latest-free.shp.zip
ogr2ogr PG:postgresql://docker:docker@localhost:5432/postgres gis_osm_roads_free_1.shp
ogr2ogr PG:postgresql://docker:docker@localhost:5432/postgres gis_osm_buildings_a_free_1.shp -nlt MultiPolygon
输入完成。
SELECT * FROM gis_osm_roads_free_1 LIMIT 10;
SELECT * FROM gis_osm_buildings_a_free_1 LIMIT 10;
之后,我们将设置以矢量瓦片的形式分发关东建筑和道路数据。
泰戈拉
tegola:
image: gospatial/tegola
ports:
- "8080:8080"
depends_on:
postgis:
condition: service_healthy
volumes:
- ./tegola:/opt/tegola_config
command: --config /opt/tegola_config/config.toml serve
networks:
- default
tegola 使用 config.toml 配置文件。根据此配置文件中的定义将 PostgreSQL 表分发为矢量切片。
# /tegola/config.toml
[webserver]
port = ":8080"
CORSAllowedOrigin = "*"
# register data providers
[[providers]]
name = "japan" # provider name is referenced from map layers (required)
type = "postgis" # the type of data provider. currently only supports postgis (required)
host = "postgis" # postgis database host (required)
port = 5432 # postgis database port (required)
database = "postgres" # postgis database name (required)
user = "docker" # postgis database user (required)
password = "docker" # postgis database password (required)
srid = 4326 # The default srid for this provider. If not provided it will be WebMercator (3857)
[[providers.layers]]
name = "roads"
geometry_fieldname = "wkb_geometry"
id_fieldname = "ogc_fid"
tablename = "gis_osm_roads_free_1"
[[providers.layers]]
name = "buildings"
geometry_fieldname = "wkb_geometry"
id_fieldname = "ogc_fid"
tablename = "gis_osm_buildings_a_free_1"
[[maps]]
name = "japan"
center = [139.72120, 35.73273, 11.0] # set the center of the map so the user is auto navigated to Bonn
[[maps.layers]]
provider_layer = "japan.buildings"
min_zoom = 5
max_zoom = 20
[[maps.layers]]
provider_layer = "japan.roads"
min_zoom = 5
max_zoom = 20
这些设置将以http://localhost:8080/maps/japan/{z}/{x}/{y}.vector.pbf 的形式提供矢量切片。
马丁
martin:
image: urbica/martin
restart: unless-stopped
ports:
- 3000:3000
depends_on:
postgis:
condition: service_healthy
networks:
- default
volumes:
- ./martin:/opt/martin_config
command: martin --config /opt/martin_config/config.yaml
martin 还使用了一个类似于 tegola 的配置文件。
# The socket address to bind [default: 0.0.0.0:3000]
listen_addresses: '0.0.0.0:3000'
# Database connection string
connection_string: 'postgres://docker:docker@postgis/postgres'
# Maximum connections pool size [default: 20]
pool_size: 20
# Connection keep alive timeout [default: 75]
keep_alive: 75
# Number of web server workers
worker_processes: 8
# If a spatial table has SRID 0, then this default SRID will be used as a fallback
default_srid: 4326
# Enable watch mode
watch: false
# Trust invalid certificates. This introduces significant vulnerabilities, and should only be used as a last resort.
danger_accept_invalid_certs: true
# Associative arrays of table sources
table_sources:
public.buildings:
# Table source id (required)
id: public.gis_osm_buildings_a_free_1
# Table schema (required)
schema: public
# Table name (required)
table: gis_osm_buildings_a_free_1
# Geometry SRID (required)
srid: 4326
# Geometry column name (required)
geometry_column: wkb_geometry
# Feature id column name
id_column: ogc_fid
# An integer specifying the minimum zoom level
minzoom: 0
# An integer specifying the maximum zoom level. MUST be >= minzoom
maxzoom: 30
# The maximum extent of available map tiles. Bounds MUST define an area
# covered by all zoom levels. The bounds are represented in WGS:84
# latitude and longitude values, in the order left, bottom, right, top.
# Values may be integers or floating point numbers.
bounds: [-180.0, -90.0, 180.0, 90.0]
# Tile extent in tile coordinate space
extent: 4096
# Buffer distance in tile coordinate space to optionally clip geometries
buffer: 64
# Boolean to control if geometries should be clipped or encoded as is
clip_geom: true
# Geometry type
geometry_type: GEOMETRY
# List of columns, that should be encoded as tile properties (required)
properties:
ogc_fid: integer
name: string
fclass: string
public.roads:
id: public.gis_osm_roads_free_1
schema: public
table: gis_osm_roads_free_1
srid: 4326
geometry_column: wkb_geometry
id_column: ogc_fid
minzoom: 0
maxzoom: 30
bounds: [-180.0, -90.0, 180.0, 90.0]
extent: 4096
buffer: 64
clip_geom: true
geometry_type: GEOMETRY
properties:
ogc_fid: integer
name: string
fclass: string
maxspeed: smallint
矢量切片在http://localhost:3000/public.roads,public.buildings/{z}/{x}/{y}.pbf 提供。
pg_tileserv
pg_tileserv:
image: pramsey/pg_tileserv
container_name: pg_tileserv
environment:
- DATABASE_URL=postgres://docker:docker@postgis/postgres
depends_on:
- postgis
ports:
- 7800:7800
值得注意的是,pg_tileserv 可以零配置启动,并自动将 PostgreSQL 表作为矢量切片提供服务。
矢量切片在http://localhost:7800/public.gis_osm_buildings_a_free_1,public.gis_osm_roads_free_1/{z}/{x}/{y}.vector.pbf 提供。
比较
现在让我们启动矢量切片服务器。
docker-compose up
在 QGIS 中,您可以像这样添加矢量切片图层:
- 矢量切片中的“新通用连接”
- 显示有数据的区域
- 添加矢量切片图层
所有三层看起来都完全相同(尽管颜色会自动设置)。这是很自然的,因为它们都引用相同的数据(PostgreSQL 表)。但是,您会发现 martin 和 pg_tileserv 的响应速度比 tegola 快得多。
导致性能差异的原因是什么?
不知道 tegola 和 martin/pg_tileserv 的具体实现区别,但是 martin/pg_tileserv 使用的是
ST_AsMVT,我觉得这个函数可能更快。据我所见,
ST_AsMVT是在 2018 年实施的,并且似乎在 2019 年提高了它的性能。https://www.crunchydata.com/blog/waiting-for-postgis-3-st_asmvt-performance
(貌似最新的tegola支持
ST_AsMVT,但是错误无法解决)此外,martin 显然比 pg_tileserv 快。我不知道为什么,但一个原因可能是 martin 是用 Rust 编写的,并且在 Actix 上运行,这是一个快速的 Web 服务器。
结论
- Martin 是最快的 PostGIS 矢量切片服务器
- 接下来是pg_tileserv,零配置,非常好用
- 只要您在本地运行它们,它们就相当快,但您可能需要调整平铺缩放级别。
源代码
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308628196.html