PostGIS 矢量瓦片

news2024/11/25 0:21:20

title: PostGIS 矢量瓦片
date: 2023-08-07
author: ac
tags:

  • vector tile
    categories:
  • Database

Martin - 基于PostGIS的矢量瓦片服务器

1. 简介

目前流行的矢量瓦片的切图方案:

  • mapbox gl + tippecanoe :v2收费,tippecanoe是mapbox官方推荐的矢量瓦片静态生成工具 ,适用于大数据量场景,且不频繁更新的空间数据;
  • openlayers + geoserver :开源,使用geoserver的矢量瓦片扩展,增加矢量瓦片的输出格式;
  • maplibre+ Martin +postgis :开源,martin是矢量切片服务器,通过postgis的函数动态生成矢量瓦片。
  • maptiler:收费

mapbox v2 必须使用 access token 才能初始化 Map 对象。进行token计算,每月50000免费次数。

2. Martin

Martin是一个开源的PostGIS矢量切片服务器,可以从任何PostGIS表或视图中创建MVT矢量切片,也可以从 PMTile 和MBTile文件中动态生成矢量瓦片,是使用 Rust编写,针对切片速度和大流量进行了优化,是极快且轻量级的切片服务器。

2.1 安装

如果将Martin和PostgreSQL一起使用,PostGIS版本必须为v3.0+

Martin支持Linux、macOS、windows平台和docker环境,本例采用windows环境。先从github上下载martin-Windows-x86_64 。解压后会发现这两个exe:

─martin-Windows-x86_64
  ├─martin.exe
  └─mbtiles.exe

windows平台可以直接使用martin.exe来启动切片服务器,可以先在命令行查看一下参数:

D:\tools\vectorTileTool\martin-Windows-x86_64>martin.exe --help
Blazing fast and lightweight tile server with PostGIS, MBTiles, and PMTiles support

Usage: martin.exe [OPTIONS] [CONNECTION]...

Arguments:
  [CONNECTION]...  Connection strings, e.g. postgres://... or /path/to/files

Options:
  -c, --config <CONFIG>
          Path to config file. If set, no tile source-related parameters are allowed
      --save-config <SAVE_CONFIG>
          Save resulting config to a file or use "-" to print to stdout. By default, only print if sources are auto-detected
  -s, --sprite <SPRITE>
          Export a directory with SVG files as a sprite source. Can be specified multiple times
  -k, --keep-alive <KEEP_ALIVE>
          Connection keep alive timeout. [DEFAULT: 75]
  -l, --listen-addresses <LISTEN_ADDRESSES>
          The socket address to bind. [DEFAULT: 0.0.0.0:3000]
  -W, --workers <WORKERS>
          Number of web server workers
  -b, --disable-bounds
          Disable the automatic generation of bounds for spatial PG tables
      --ca-root-file <CA_ROOT_FILE>
          Loads trusted root certificates from a file. The file should contain a sequence of PEM-formatted CA certificates
  -d, --default-srid <DEFAULT_SRID>
          If a spatial PG table has SRID 0, then this default SRID will be used as a fallback
  -p, --pool-size <POOL_SIZE>
          Maximum connections pool size [DEFAULT: 20]
  -m, --max-feature-count <MAX_FEATURE_COUNT>
          Limit the number of features in a tile from a PG table source
  -h, --help
          Print help
  -V, --version
          Print version

2.2 使用

本例pg安装postgis是v3.3.3.1

martin连接pg可以用connection_string(命令行参数)和配置文件两种形式。

PostgreSQL连接字符串的形式:

# martin.exe postgresql://user:password@host/db
D:\tools\vectorTileTool\martin-Windows-x86_64>martin.exe postgresql://postgres:123@127.0.0.1:5433/postgres
[2023-08-08T03:50:11Z INFO  martin] Starting Martin v0.8.7
[2023-08-08T03:50:11Z INFO  martin] Config file is not specified, auto-detecting sources
[2023-08-08T03:50:11Z INFO  martin::pg::pool] Connecting to postgresql://postgres:123@127.0.0.1:5433/postgres
[2023-08-08T03:50:11Z INFO  martin::pg::configurator] Discovered source zhujiang_river from table public.zhujiang_river with geom column (MULTIPOLYGON, SRID=4326)
[2023-08-08T03:50:11Z INFO  martin] Use --save-config to save or print Martin configuration.
[2023-08-08T03:50:11Z INFO  martin] Martin has been started on 0.0.0.0:3000.
[2023-08-08T03:50:11Z INFO  martin] Use http://0.0.0.0:3000/catalog to get the list of available sources.

配置文件的形式 config.yaml:

# Connection keep alive timeout [default: 75]
keep_alive: 75

# The socket address to bind [default: 0.0.0.0:3000]
listen_addresses: '127.0.0.1:3000'

# Number of web server workers
worker_processes: 8
# Database configuration. This can also be a list of PG configs.
postgres:
  # Database connection string. You can use env vars too, for example:
  #   $DATABASE_URL
  #   ${DATABASE_URL:-postgresql://postgres@localhost/db}
  connection_string: 'postgresql://postgres@localhost:5433/postgres?sslmode=disable&user=postgres&password=123'
  
  # Same as PGSSLCERT for psql
  #ssl_cert: './postgresql.crt'
  # Same as PGSSLKEY for psql
  #ssl_key: './postgresql.key'
  # Same as PGSSLROOTCERT for psql
  #ssl_root_cert: './root.crt'

  #  If a spatial table has SRID 0, then this SRID will be used as a fallback
  default_srid: 4326

  # Maximum connections pool size [default: 20]
  pool_size: 20

  # Limit the number of table geo features included in a tile. Unlimited by default.
  max_feature_count: 1000

  # Control the automatic generation of bounds for spatial tables [default: false]
  # If enabled, it will spend some time on startup to compute geometry bounds.
  disable_bounds: false
D:\tools\vectorTileTool\martin-Windows-x86_64>martin.exe -c config.yaml
[2023-08-08T03:54:43Z INFO  martin] Starting Martin v0.8.7
[2023-08-08T03:54:43Z INFO  martin] Using config.yaml
[2023-08-08T03:54:43Z INFO  martin::pg::pool] Connecting to postgresql://postgres@localhost:5433/postgres?sslmode=disable&user=postgres&password=123
[2023-08-08T03:54:43Z INFO  martin::pg::configurator] Discovered source zhujiang_river from table public.zhujiang_river with geom column (MULTIPOLYGON, SRID=4326)
[2023-08-08T03:54:44Z INFO  martin] Use --save-config to save or print Martin configuration.
[2023-08-08T03:54:44Z INFO  martin] Martin has been started on 127.0.0.1:3000.
[2023-08-08T03:54:44Z INFO  martin] Use http://127.0.0.1:3000/catalog to get the list of available sources.

本例采用的是配置文件的形式启动服务器,服务地址是http://127.0.0.1:3000

从启动的日志可以看到Martin将所连接的pg库中的zhujiang_river表发布为数据源。

Martin 会将所有表发布为数据源(如果它们至少有一个几何列)。如果 SRID 为 0,则必须设置默认 SRID,否则该地理列/表将被忽略。所有非几何表列都将发布为矢量切片要素标签(属性)。

在这里插入图片描述

打开目录可以看到已发布的数据源:
在这里插入图片描述
在这里插入图片描述

数据表的元数据是符合TileJSON 3.0.0标准的JSON文件。

TileJSON是表示地图元数据的开放标准

2.3 mapbox

发布完数据源后,使用mapbox gl 来调用一下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/mapbox-gl@1.9.1/dist/mapbox-gl.js"></script>
    <link href="https://unpkg.com/mapbox-gl@1.9.1/dist/mapbox-gl.css"/>
    <style>
        #map{
            height: 100vh;
            width: 100%;
        }
    </style>
</head>
<body>
    <div id="map"></div>
    <script>
        
        const TIANDITU_URL = 'http://t0.tianditu.gov.cn';
        const tdtKey = "your_token";
        const tdtConfig = {
            code: 'tdt_img',
            name: '天地图影像',
            source: {
                type: 'raster',
                tiles: [
                    `${TIANDITU_URL}/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=${tdtKey}`
                ],
                tileSize: 256,
                minzoom: 0,
                maxzoom: 22
            },
            layer: {
                id: 'tdt-img-tiles',
                type: 'raster',
                minzoom: 0,
                maxzoom: 22,
                layout: { visibility: 'visible' }
            }
        }
        let map = new mapboxgl.Map({
            container:'map',
            style:{
                "version":8,
                "sources":{},
                "layers":[],
                glyphs: "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
            },
            center: [112.39747, 22.908823], // 广东
            zoom: 8, // starting zoom 地图初始的拉伸比例
            pitch: 0, // 地图的角度,不写默认是0,取值是0-85度,一般在3D中使用
            bearing: 0, // 地图的初始方向,值是北的逆时针度数,默认是0,即是正北
            antialias: true, // 抗锯齿,通过false关闭提升性能
            minZoom: 3,
            maxZoom: 17.36
        });
        map.on('load', () => {
            // 天地图底图加载
            addLayerConfig(tdtConfig);
            addMvt();
        });
        function addLayerConfig(layerConfig){
            const {code, source,layer} = layerConfig;
            map.addSource(code, source);
            const layerParams = {
                ...layer,
                source: code
            };
            // 添加图层
            map.addLayer(layerParams);
        }
        function addMvt(){
            map.addLayer({
                id: 'lines',
                type: 'fill',
                source: {
                    type: 'vector',
                    url: 'http://localhost:3000/zhujiang_river'
                },
                'source-layer': 'zhujiang_river',
                paint: {
                	'fill-color': 'red'
                }
            });
        }
    </script>
</body>
</html>

加载效果:

在这里插入图片描述

3.遇到的问题

局限性:只能连接一个pg库。

对于有分库的系统,可以使用Nginx来转发。

参考文章

[1] Martin https://martin.maplibre.org/

[2] Martin Tile Server Documentation https://maplibre.org/martin/installation.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/868251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C语言】结构体详解

现实生活中一个事物&#xff0c;会有许多属性连接起来。而C语言引入一种构造数据类型——结构体 将属于一个事物的多个数据组织起来以体现其内部联系。 一、结构体类型的定义 结构体类型 是一种 构造类型&#xff0c;它是由若干成员组成的&#xff0c;每个成员可以是一个基本…

python:使用geopandas和rasterio将矢量范围内的栅格值赋为0并重新输出

需求&#xff1a;有一个点shp文件和一个栅格&#xff0c;想要构建shp中每个点的缓冲区&#xff0c;并且缓冲区范围内的栅格值重新赋为0并输出新的tif文件 解决方法&#xff1a;使用python中的geopandas和rasterio中的掩膜操作实现 代码如下&#xff1a; import numpy as np …

数据结构(一):顺序表详解

在正式介绍顺序表之前&#xff0c;我们有必要先了解一个名词&#xff1a;线性表。 线性表&#xff1a; 线性表是&#xff0c;具有n个相同特性的数据元素的有限序列。常见的线性表&#xff1a;顺序表、链表、栈、队列、数组、字符串... 线性表在逻辑上是线性结构&#xff0c;但…

【验证码逆向专栏】最新某度旋转验证码 v2 逆向分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 本文章未…

使用requests如何实现自动登录

不知道大家有没有注意到&#xff0c;好多网站我们登录过后&#xff0c;在之后的某段时间内访问该网页时&#xff0c;不会给出请登录的提示&#xff0c;时间到期后就会提示请登录&#xff01;这样在使用爬虫访问网页时还要登录&#xff0c;打乱我们的节奏&#xff0c;那么如何使…

ISC 2023 大会成功举办,向量数据库公司 Zilliz 成大模型论坛焦点

近日,第十一届互联网安全大会(ISC 2023)在北京盛大开幕。大会由 ISC 互联网安全大会组委会、中国互联网协会、中国网络空间安全协会、全国工商联大数据运维(网络安全)委员会、中国人工智能学会、中国软件行业协会、中国企业联合会、360 互联网安全中心主办;中国通信企业协…

使用阿里云服务器部署和使用GitLab

本文阿里云百科分享使用阿里云服务器部署和使用GitLab&#xff0c;GitLab是Ruby开发的自托管的Git项目仓库&#xff0c;可通过Web界面访问公开的或者私人的项目。本教程介绍如何部署和使用GitLab。 目录 准备工作 部署GitLab环境 使用GitLab 登录GitLab 生成密钥对文件并…

HoloLens 2设备MR 应用交互设计

AR 眼镜实现了虚拟世界与现实世界的融合&#xff0c;完成屏幕的“跨越”&#xff0c;人机交互设计也从二维平面迈向三维世界。目前&#xff0c;MR 应用的人机交互界面仍然处于早期发展阶段&#xff0c;各种理念和方法仍处于逐步形成与应用阶段&#xff0c;低成本地完成使用者从…

记录一下Java实体转json字段顺序问题

特殊需求&#xff0c;和C交互他们那边要求字段顺序要和他们定义的一致(批框架) 如下&#xff1a; Data public class UserDto {private String name;private Integer age;private String addr; }未转换前打印&#xff1a; 转换后打印&#xff1a; 可以看到转换为json顺序打印…

第9届Python编程挑战赛北京赛区复赛真题剖析-2023年全国青少年信息素养大赛

[导读]&#xff1a;超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲&#xff0c;这是超平老师解读Python编程挑战赛系列的第16讲。 全国青少年信息素养大赛&#xff08;原全国青少年电子信息智能创新大赛&#xff09;是“世界机器人大会青少年机器人设计与…

Spring与Spring Bean

Spring 原理 它是一个全面的、企业应用开发一站式的解决方案&#xff0c;贯穿表现层、业务层、持久层。但是 Spring 仍然可 以和其他的框架无缝整合。 Spring 特点 轻量级 控制反转 面向切面 容器 框架集合 Spring 核心组件 Spring 总共有十几个组件核心容器(Spring core) S…

02.Deep Visual-Semantic Alignments for Generating Image Descriptions

目录 前言泛读摘要IntroductionRelated Work小结 精读Model3.1 学习对齐视觉与语言数据图片表征句子表征对齐目标损失函数解码文本片段对齐图像 MRNN生成描述优化 实验结论 代码 前言 本课程来自深度之眼《多模态》训练营&#xff0c;部分截图来自课程视频。 文章标题&#xf…

湘大 XTU OJ 1290 Alice and Bob 题解(非常详细):字符串 分类讨论 简单模拟

一、链接 1290 Alice and Bob 二、题目 题目描述 Alice和Bob玩剪刀-石头-布的游戏&#xff0c;请你写个程序判断一下比赛的结果。 输入 第一行是一个整数K&#xff0c;表示样例的个数。 以后每行两个单词&#xff0c;rock表示石头&#xff0c;paper表示布&#xff0c;scis…

ETL技术入门之ETLCloud初认识

首先ETL是什么&#xff1f; ETL代表“Extract, Transform, Load”&#xff0c;是一种用于数据集成和转换的过程。它在数据管理和分析中扮演着重要的角色。下面我们将分解每个步骤&#xff1a; Extract&#xff08;抽取&#xff09;&#xff1a; 这一步骤涉及从多个不同的数据源…

小说推文怎么做详细教程。小说推文项目拆解及分享

科思创业汇 大家好&#xff0c;这里是科思创业汇&#xff0c;一个轻资产创业孵化平台。赚钱的方式有很多种&#xff0c;我希望在科思创业汇能够给你带来最快乐的那一种&#xff01; 如何制作小说推文的详细教程&#xff01; 我做自媒体已经五年了&#xff0c;在自媒体行业也…

YOLOv5、YOLOv8改进:MobileViT:轻量通用且适合移动端的视觉Transformer

MobileViT: Light-weight, General-purpose, and Mobile-friendly Vision Transformer 论文&#xff1a;https://arxiv.org/abs/2110.02178 1简介 MobileviT是一个用于移动设备的轻量级通用可视化Transformer&#xff0c;据作者介绍&#xff0c;这是第一次基于轻量级CNN网络性…

CMake语法中的PUBLIC、PRIVATE、INTERFACE关键字含义

在CMake语法中&#xff0c;经常见到PUBLIC、PRIVATE、INTERFACE关键字&#xff0c;它们是什么意思呢&#xff1f;下面举例说明。 如上图,说明如下&#xff1a; RIVATE&#xff1a;私有的。生成 libhello-world.so时&#xff0c;只在 hello_world.c 中包含了 hello.h&#xff0…

C# 随机法求解线性规划问题 蒙特卡洛

线性规划问题: max3x12x2 x12x2<5 2x1x2<4 4x13x2<9 x1>0 x2>0 正确的结果:x11.5; x21, max z6.5 Random random1 new Random(DateTime.Now.Millisecond);Random random2 new Random(DateTime.Now.Millisecond*DateTime.Now.Millisecond);double max-9999,x1…

【electron】electron项目创建的方式:

文章目录 【1】npm init quick-start/electron&#xff08;推荐&#xff09;【2】 克隆仓库&#xff0c;快速启动【3】 通过脚手架搭建项目【4】 手动创建项目 【Electron官网】https://www.electronjs.org/zh/docs/latest/api/app 【1】npm init quick-start/electron&#xf…

六 动手学深度学习v2 ——权重衰退+dropout

1. 权重衰退 最常见的用来处理过拟合的方法 使用均方范数作为硬性限制 使用均方范数作为软性限制 总结&#xff1a; 正则化是处理过拟合的常用方法&#xff1a;在训练集的损失函数中加入惩罚项&#xff0c;以降低学习到的模型的复杂度。 保持模型简单的一个特别的选择是使用…