You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在地理空间PDF的UTM坐标位置插入指定文本?

解决地理空间PDF中UTM坐标转页面坐标插入文本的问题

核心思路

要在UTM坐标对应位置插入文本,关键是将UTM坐标转换成PDF页面的点坐标——这需要先从地理空间PDF中提取地理参考信息,再通过坐标映射公式计算出对应的页面位置,最后替换你现有代码中的固定坐标即可。

步骤1:提取PDF的地理空间元数据

地理空间PDF会存储页面的地理范围(比如UTM坐标系下的左下角、右上角坐标)和页面尺寸信息,我们可以通过PyPDF2或pdfplumber提取:

import pdfplumber
from PyPDF2 import PdfReader

# 获取页面尺寸(单位:点pt)
with pdfplumber.open("geo.pdf") as pdf:
    page = pdf.pages[0]
    page_width = page.width
    page_height = page.height

# 获取UTM范围信息
reader = PdfReader("geo.pdf")
page_dict = reader.pages[0].get_object()
utm_min_x, utm_min_y = None, None
utm_max_x, utm_max_y = None, None

# 读取PDF中的地理参考元数据(常见存储路径)
if "/PieceInfo" in page_dict:
    adobe_info = page_dict["/PieceInfo"].get("/Adobe", {})
    dc_info = adobe_info.get("/DC", {}).get("/Subtype", {}).get("/Geo", {})
    ll = dc_info.get("/LL", [])  # 左下角UTM坐标
    ur = dc_info.get("/UR", [])  # 右上角UTM坐标
    if len(ll) == 2 and len(ur) == 2:
        utm_min_x, utm_min_y = ll[0], ll[1]
        utm_max_x, utm_max_y = ur[0], ur[1]

步骤2:UTM坐标转PDF页面坐标

PDF的坐标原点在页面左下角,Y轴向上;而UTM坐标系的Y轴通常向北递增,所以需要反转Y轴映射。转换公式如下:

  • 页面X坐标 = ((目标UTM X - utm_min_x) / (utm_max_x - utm_min_x)) * page_width
  • 页面Y坐标 = ((utm_max_y - 目标UTM Y) / (utm_max_y - utm_min_y)) * page_height

代码实现:

# 替换为你的目标UTM坐标
target_utm_x = 123456.789
target_utm_y = 987654.321

if all([utm_min_x, utm_min_y, utm_max_x, utm_max_y]):
    page_x = ((target_utm_x - utm_min_x) / (utm_max_x - utm_min_x)) * page_width
    page_y = ((utm_max_y - target_utm_y) / (utm_max_y - utm_min_y)) * page_height
else:
    raise ValueError("无法从PDF中提取地理参考信息,请确认PDF为标准地理空间PDF")

步骤3:修改原代码插入文本

将计算好的页面坐标替换原代码中的固定值,完整代码如下:

import io
from reportlab.pdfgen import canvas
from PyPDF2 import PdfReader, PdfWriter
import pdfplumber

# 1. 提取地理参考和页面尺寸
with pdfplumber.open("geo.pdf") as pdf:
    page = pdf.pages[0]
    page_width = page.width
    page_height = page.height

reader = PdfReader("geo.pdf")
page_dict = reader.pages[0].get_object()
utm_min_x, utm_min_y = None, None
utm_max_x, utm_max_y = None, None

if "/PieceInfo" in page_dict:
    adobe_info = page_dict["/PieceInfo"].get("/Adobe", {})
    dc_info = adobe_info.get("/DC", {}).get("/Subtype", {}).get("/Geo", {})
    ll = dc_info.get("/LL", [])
    ur = dc_info.get("/UR", [])
    if len(ll) == 2 and len(ur) == 2:
        utm_min_x, utm_min_y = ll[0], ll[1]
        utm_max_x, utm_max_y = ur[0], ur[1]

# 替换为你的目标UTM坐标
target_utm_x = 123456.789
target_utm_y = 987654.321

# 2. 转换坐标
if all([utm_min_x, utm_min_y, utm_max_x, utm_max_y]):
    page_x = ((target_utm_x - utm_min_x) / (utm_max_x - utm_min_x)) * page_width
    page_y = ((utm_max_y - target_utm_y) / (utm_max_y - utm_min_y)) * page_height
else:
    raise ValueError("无法从PDF中提取地理参考信息,请确认PDF为标准地理空间PDF")

# 3. 插入文本并合并PDF
input_pdf = PdfReader(open('geo.pdf', 'rb'))

buffer = io.BytesIO()
c = canvas.Canvas(buffer)
c.drawString(page_x, page_y, "Hello, World!")
c.save()
buffer.seek(0)

text_pdf = PdfReader(buffer)

output_pdf = PdfWriter()
for i in range(len(input_pdf.pages)):
    page = input_pdf.pages[i]
    if i == 0:
        page.merge_page(text_pdf.pages[0])
    output_pdf.add_page(page)

with open('output.pdf', 'wb') as f:
    output_pdf.write(f)

注意事项

  • 如果上述代码无法提取地理信息,可以尝试用PyMuPDF(fitz),它对地理PDF的支持更完善:
    import fitz
    doc = fitz.open("geo.pdf")
    page = doc[0]
    geo = page.get_geo()
    # 用geo.transform_point(x, y)直接转换坐标,x/y为UTM坐标
    
  • 确保你的UTM坐标的zone和基准面(如WGS84)与PDF的地理参考完全一致,否则转换结果会偏移。
  • 若PDF页面有旋转,需先处理页面旋转再计算坐标。

内容的提问来源于stack exchange,提问作者timp bill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 01:22:02