详细介绍:识别含地理信息的 PDF作为底图在 Mapbox GL项目中使用

news/2025/11/7 22:29:02/文章来源:https://www.cnblogs.com/slgkaifa/p/19201067

详细介绍:识别含地理信息的 PDF作为底图在 Mapbox GL项目中使用

文章目录

    • 一、先判断:这个 PDF 是不是“地理 PDF”(GeoPDF / geospatial PDF)
    • 二、常用工具(推荐顺序)
    • 三、把 GeoPDF 转为 GeoTIFF(最可靠的处理路径)
    • 四、重投影 / 裁剪(按需要)
    • 五、生成地图切片(用于 Web 地图,Leaflet/Mapbox)
    • 六、在常见环境中使用该底图
    • 七、Python 自动化(示例脚本)
    • 八、关于 GeoPDF 的特定说明与陷阱
    • 九、快速常见命令汇总(便于复制粘贴)
    • 十、实操建议(顺序与调优)

整套可执行流程:从识别含地理信息的 PDF(GeoPDF / geospatial PDF)、提取/转换为常用栅格(GeoTIFF)、必要时重投影、生成地图切片,最后把它作为底图在 Mapbox GL 等中使用。

一、先判断:这个 PDF 是不是“地理 PDF”(GeoPDF / geospatial PDF)

地理信息在 PDF 中常见形式:

  • GeoPDF / Geospatial PDF(像 Avenza/TerraGo 导出的 PDF)内嵌了地理坐标(GCPs / affine / CRS)。

  • 或者 PDF 只是普通地图图像,坐标信息记录在旁的元数据/说明里(这种情况需手动配准)。

检查命令(推荐)

gdalinfo your_map.pdf

输出会告诉你:

  • 是否识别为 Driver: PDF;

  • 是否有 Metadata 中的 CRS 信息或 Corner coordinates / GCPs;

  • 是否有内嵌 raster bands。

如果 gdalinfo 能看到 corner coordinates 或 GCPs,那么 GDAL 能直接处理。

二、常用工具(推荐顺序)

  • GDAL(必须) —— gdalinfo, gdal_translate, gdalwarp, gdal2tiles.py。适用于批处理与脚本化。

  • QGIS —— 直接拖入 GeoPDF,预览与栅格化;可作为最终查看。

  • ArcGIS / ArcMap / ArcGIS Pro —— 可直接加载 GeoPDF(Pro 支持更好),或使用“导出为 TIFF”。

  • Avenza/ TerraGo —— 专业 GeoPDF 工具(查看/测量),非必需。

  • Python(osgeo.gdal) —— 自动化工作流与微调。

三、把 GeoPDF 转为 GeoTIFF(最可靠的处理路径)

  1. 查看信息(确认是否含坐标)
gdalinfo -stats your_map.pdf

重点看:

Driver: PDF、Size、Coordinate System 或 Corner Coordinates、GCPs。

  1. 若 PDF 内嵌 geotransform(可直接转换)

直接用 gdal_translate:

gdal_translate -of GTiff your_map.pdf output.tif

若 PDF 有多页或多个图层,指定子dataset:

gdalinfo your_map.pdf  # 看 subdatasets 列表
gdal_translate -of GTiff "PDF:your_map.pdf:page=1" page1.tif
  1. 若 PDF 提供 GCPs(而不是直接 geo transform),需在转换时保留 GCPs,再用 gdalwarp 变换为栅格 GeoTIFF
# 保留 GCPs 的 GeoTIFF(可能无地理变换但包含 GCPs)
gdal_translate -of GTiff your_map.pdf tmp_gcp.tif
# 使用 gdalwarp 以 GCPs 计算并生成地理化的 TIFF(指定目标 CRS)
gdalwarp -t_srs "EPSG:4326" tmp_gcp.tif output_geotiff.tif

说明:如果 GCPs 在别的 CRS,先查看 gdalinfo 的 GCP projection,然后在 gdalwarp 中指定 -t_srs 或 -s_srs。

  1. 若 PDF 不含任何地理信息(普通图像)

需要人工配准(QGIS 的“栅格 → 地理配准器”或 ArcMap 的 “Georeferencing”),或通过已知 control points 生成 worldfile,再用 gdal_translate -a_ullr/-a_srs 指定四角坐标。

示例(已知四角经纬度):

gdal_translate -of GTiff -a_ullr lon_left_upper lat_left_upper lon_right_lower lat_right_lower -a_srs EPSG:4326 input.png output_geotiff.tif

四、重投影 / 裁剪(按需要)

把 GeoTIFF 转到项目用的 CRS(例如 Web Mercator / EPSG:3857):

gdalwarp -t_srs EPSG:3857 output_geotiff.tif output_3857.tif

按边界裁剪:

gdalwarp -te minX minY maxX maxY -te_srs EPSG:4326 input.tif cropped.tif

五、生成地图切片(用于 Web 地图,Leaflet/Mapbox)

若你要在 Leaflet / Mapbox GL 中作为底图,通常将 GeoTIFF 切成瓦片(XYZ 或 MBTiles):

使用 gdal2tiles(生成 XYZ 目录)

gdal2tiles.py -z 0-18 -w none output_3857.tif tiles_dir/

这会生成 tiles_dir/{z}/{x}/{y}.png,可通过简单静态服务器提供。

生成 MBTiles(推荐用于离线与 Mapbox)

使用 gdal_translate 到 VRT 然后 gdal2tiles 或用 gdal_translate -of MBTILES(GDAL 支持 MBTiles 输出):

gdal_translate -of MBTILES output_3857.tif output.mbtiles

或用 TileMill、tippecanoe 等工具进一步打包。

六、在常见环境中使用该底图

  1. 在 QGIS 中

直接 Layer → Add Layer → Add Raster Layer,选择 output_geotiff.tif。

或:Layer → Add XYZ Tiles 指向你的 tiles 服务器 URL(如 http://localhost:8000/{z}/{x}/{y}.png)加载切片。

  1. 在 Leaflet(页面示例)

HTML/JS 示例(加载 XYZ 瓦片):

var map = L.map('map').setView([24.0, 54.5], 8);
L.tileLayer('http://your-server/tiles/{z}/{x}/{y}.png', {attribution: 'GeoPDF map'
}).addTo(map);

若你有 GeoTIFF 并想直接显示(不切片),可以用 leaflet-geotiff
将 GeoTIFF 转为 canvas 并叠加。

  1. 在 Mapbox GL JS

Mapbox GL 需要切片或 raster source:

map.addSource('pdfBase', {type: 'raster',tiles: ['http://your-server/tiles/{z}/{x}/{y}.png'],tileSize: 256
});
map.addLayer({ id: 'pdfBaseLayer', type: 'raster', source: 'pdfBase' }, 'waterway-label');
  1. ArcGIS Desktop / Pro
  • ArcMap/Pro 可直接 Add Data 加载 GeoPDF/GeoTIFF(Pro 对 GeoPDF 支持更好)。

  • 亦可将 GeoTIFF 发布为 ArcGIS Server 服务或矢量叠加。

七、Python 自动化(示例脚本)

下面给出一个 GDAL-Python 示例:自动检测 PDF、转为 GeoTIFF、重投影并生成 tiles(简化版)。

from osgeo import gdal
import subprocess, os
pdf = r"your_map.pdf"
tif = r"output.tif"
tif_3857 = r"output_3857.tif"
tiles_dir = r"tiles"
# 1. 查看 info
print(gdal.Info(pdf))
# 2. translate
gdal.Translate(tif, pdf)
# 3. warp to web mercator
gdal.Warp(tif_3857, tif, dstSRS='EPSG:3857')
# 4. generate tiles using gdal2tiles (system call)
subprocess.check_call(["gdal2tiles.py", "-z", "5-18", "--processes", "4", tif_3857, tiles_dir])
print("tiles generated at", tiles_dir)

注意:若 gdal.Info(pdf) 未显示 corner coordinates,可能需要人工配准或检查 subdatasets。

八、关于 GeoPDF 的特定说明与陷阱

  1. GeoPDF 多页/多图层:gdalinfo 会列出 subdatasets,可能要指定 PDF:your.pdf:page=1。

  2. 矢量注记 vs 栅格图层:PDF 中的矢量文本或注记可能在转 raster 时变模糊或丢失,可在高 DPI 下 rasterize(GDAL 支持 -r 和 -tr)。

  3. 分辨率(DPI)问题:导出时控制像素尺寸/分辨率,保证细节。gdal_translate -outsize 或用 -r 指定重采样。

  4. 坐标系识别失败:某些 GeoPDF 把 GCP 存在非标准字段,需要使用 TerraGo/Avenza 查看原始投影信息并手工设置 -a_srs。

  5. 大文件与内存:对大幅面地图,先用 gdalwarp -co TILED=YES -co COMPRESS=DEFLATE 压缩,再切片。

九、快速常见命令汇总(便于复制粘贴)

检查 PDF:

gdalinfo your_map.pdf

转 GeoTIFF(默认页):

gdal_translate -of GTiff "PDF:your_map.pdf:page=1" page1.tif

若含 GCPs,生成地理化的 GeoTIFF:

gdal_translate your_map.pdf tmp_gcp.tif
gdalwarp -t_srs EPSG:4326 tmp_gcp.tif output_geo.tif

重投影到 WebMercator:

gdalwarp -t_srs EPSG:3857 output_geo.tif output_3857.tif

生成 XYZ 瓦片:

gdal2tiles.py -z 0-18 -w none output_3857.tif tiles/

直接输出 MBTiles:

gdal_translate -of MBTILES output_3857.tif output.mbtiles

十、实操建议(顺序与调优)

  • 先 gdalinfo 看信息;若看到 corner coordinates → 优先用 gdal_translate。

  • 若 gdalinfo 没有坐标 → 在 QGIS 用地理配准器做 control points,再导出 GeoTIFF。

  • 找到合适的分辨率(DPI)再 rasterize;细节小的地图用更高 DPI。

  • 若要 web 展示 → 生成 tiles 并用静态服务器(nginx)或直接用本地 python -m http.server 测试。

  • 若要在移动端离线查看 → 生成 MBTiles,使用 Mapbox/Leaflet 的 MBTiles 插件或移动端 SDK。

在这里插入图片描述


“人的一生会经历很多痛苦,但回头想想,都是传奇”。


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

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

相关文章

2024 暑期模拟赛 #6

100 + 20 + 60 + 0 = 180, Rank 1/6.逆天模拟赛。题的质量是挺好的,但是你 要不只给最后一个点的大样例 要不只给第一个点的大样例 要不直接不给大样例 什么意思,甚至还有个大样例由若干个 ਰ 字符和 ਱ 字符构成,足…

使用CSS和GSAP创建3D滚动驱动文本动画

本教程详细讲解如何使用CSS、GSAP和ScrollTrigger插件创建三种高性能3D滚动文本动画效果,包括圆柱体、双圆环和隧道动画,涵盖数学计算、响应式设计和性能优化。使用CSS和GSAP创建3D滚动驱动文本动画 本教程将指导您使…

Apifox接口测试工具简介 - 努力-

Apifox接口测试工具简介Apifox简介。一、Apifox介绍 介绍:Apifox是一款集成了Api文档、Api调试、Api Mock、Api测试的一体化协作平台。 作用:接口文档管理、接口请求测试、Mock服务。 官网: https://apifox.com/ 二…

Windows 10 家庭版启用组策略编辑器

Windows 10 家庭版启用组策略编辑器 问题描述 在Windows 10/11家庭版中,运行gpedit.msc(组策略编辑器)时,系统提示“Windows 找不到文件 gpedit.msc”,无法打开组策略编辑器。 原因 Windows家庭版系统默认未预装组…

MySQL 基础架构(一):SQL语句的执行之旅

MySQL 采用经典的分层架构设计,整体可分为 Server 层和存储引擎层两大部分。这种设计实现了核心功能与存储实现的分离,为不同类型的应用场景提供了灵活的存储方案。MySQL系列文章 你是否好奇过,一条看似简单的SQL查…

顺序表练习题

​1. 设顺序表中的元素递增有序,编写一个算法,将元素x插入顺序表L中的适当位置,以保持该顺序表的有序性。 void sortInsert(List *l,int x){//假设表是有序的if(l->length==MAXSIZE)exit(1);//表已满,无法插入f…

关于一种计算递归次数题的思路

代码如下 要求计算最后输出的count的结果 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int count = 0; int fib(int a) {count++;if (a == 0)return 1;else if (a == 1)return 2;elsereturn fib(a - 1) …

前端框架深度解析:Vue 从入门到实战,掌握渐进式开发核心 - 实践

前端框架深度解析:Vue 从入门到实战,掌握渐进式开发核心 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "…

CF2162G

定义一棵树大小为 \(n\) 的树的权值是:\(S = \sum\limits_{(u, v) \in E} (u \cdot v)\),给定 \(n\),构造一棵权值为完全平方数的树。 \(n \le 2 \times 10^5\)尝试让 \(u\) 固定,那就是菊花图,此时 \(S = u(\fra…

题解:lo6878 生不逢时

写这篇题解的时候回酒店电脑崩了直接没了,也算是照应标题生不逢时了…… 牛牛题。 题意:给定正整数 n, m 和 n 个区间,第 i 个区间为 \([l _ i, r _ i]\),保证 \(0 \leq l_i \leq r_i < 2^m\)。 对于非负整数 \…

【UEGamePlay】- 3C篇(三) : 角色 (二)

前言 上篇文章我们大体梳理了角色相关的移动/旋转框架逻辑,并且初步筛选了我们

stapter WP笔记

很喜欢的靶机,有效暴露了自己的不足,里面的兔子洞基本上全部踩了一遍,所以写一下这篇wp兼笔记 感想:打靶很多时候是反直觉的,有的时候不能基于感觉,或者说觉得概率很小就不去尝试,它是一个严谨的,纯粹理性的过…

【51单片机】【protues仿真】基于51单片机全自动洗衣机系统 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

定金单专题

一、系统中的定金单,支付方式和账户是一一对应的。 二、定金单的支付方式,再Payment method grouping里面是以Card形式出现的,否则定金单的支付找不到对应的支付方式。 三、在系统中下定金单。

练习上传

这是一级标题 MPE教程 这是二级标题 这是三级标题 这会是 斜体 的文字 这会是 斜体 的文字 这会是 粗体 的文字 这会是 粗体 的文字 你也 组合 这些符号 这个文字将会被横线删除 无序列表Item 1 Item 2Item 2a Item 2b…

uniapp修改原生导航栏样式、加图标、加文字、加点击事件 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

CITP——更适合约束接口的CRTP变式 - CLimber

在C++中,前人已经提出了多种约束接口的方式。其中,CRTP不妨是一个适用于低标准且不需要性能的静态多态设计方式。但CRTP无法约束构造函数,实现过程涉及静态转换,代码复杂。为此,我们提出了CRTP的变式——**CITP**…

函数的可变参数传参

一.前言 可变参数传参是C语言的一种高级用法。二. 用法示例 求任意个 int 类型数据的平均值。点击查看代码 double avg_int(int count, ...) {va_list ap; /* 2. 声明参数列表变量 */int sum = 0;va…

P12366 [蓝桥杯 2022 省 Python B] 数位排序

将数字与数位和捆绑(使用结构体或元组)放入数组或列表,以数位和为关键字排序,最后输出第 m 个数。 #include<stdio.h> #include<algorithm> using namespace std; const int MAXN=1e6+7; struct Node{…

重组蛋白表达技术|HEK293细胞蛋白表达|高效重组蛋白生产服务

一、表达系统的技术特性与选择策略 哺乳动物细胞表达系统以其卓越的翻译后修饰能力成为复杂蛋白表达的首选方案。其中,HEK293细胞凭借高转染效率和快速生长特性,在瞬时表达中表现优异;而CHO细胞则因其在悬浮培养中的…