PDF—地理空间PDF

司机简称

PDF

生成依赖项

无用于写支持,Poppler/PoDoFo/PDFium用于读支持

通过提取地理参考信息和栅格化数据,GDAL支持读取地理空间PDF文档。非地理空间PDF文档也将被驱动程序识别。

PDF文档可以从其他GDAL栅格数据集创建,OGR数据源也可以选择性地绘制在栅格层的顶部(参见OGR_ * 下节中的创建选项)。

驱动程序支持读取以两种现有方式之一编码的地理参考:根据OGC编码最佳实践,或根据ISO 32000的Adobe补充。

多页文档公开为子数据集,即文档的一页中的一个子数据集。

驱动程序功能

Supports CreateCopy()

This driver supports the GDALDriver::CreateCopy() operation

Supports Georeferencing

This driver supports georeferencing

Supports VirtualIO

This driver supports virtual I/O operations (/vsimem/, etc.)

矢量支持

PDF vector 文档页

元数据

neatline(对于OGC最佳实践)或bounding box(Adobe样式)将报告为neatline元数据项,以便以后可以用作翘曲算法的剪切线。

XMP元数据可以从文件中提取,并作为XML原始内容存储在XML:XMP元数据域中。

其他元数据(如USGS Topo PDF中的元数据)可以从文件中提取,并将作为XML原始内容存储在嵌入的元数据域中。

配置选项

  • GDAL_PDF_DPI :通过指定栅格化的DPI(默认值为150)来控制栅格的尺寸。驱动程序将努力从一些PDF文件中包含的特定元数据项或PDF中的栅格图像(在简单的情况下)猜测DPI值。

  • GDAL_PDF_NEATLINE :要选择的基线的名称(仅适用于地理空间PDF,根据OGC最佳实践编码)。对于USGS Topo PDF,默认为“Map Layers”。如果找不到,覆盖面积最大的那条小潮线。

  • GDAL_USER_PWD :受保护PDF的用户密码。

  • GDAL_PDF_RENDERING_OPTIONS :矢量、栅格和以逗号分隔的文本的组合,用于选择是否应呈现矢量、栅格或文本特征。如果未指定该选项,则渲染所有功能(Poppler和PDFium)。

  • GDAL_PDF_BANDS =3或4:PDF是否应呈现为RGB(3)或RGBA(4)图像。默认值将取决于使用的PDF呈现(Poppler vs PDFium)和PDF文件中找到的内容(如果识别出具有透明度的图像,则将使用4)。选择3个波段时,将使用白色背景。

  • GDAL_PDF_LAYERS =要打开的层列表(逗号分隔)(或“全部”打开所有层)。可以通过查询图层元数据域来获取图层名。指定此选项时,将关闭未显式列出的层(Poppler和PDFium)。

  • GDAL_PDF_LAYERS_OFF =要关闭的层列表(逗号分隔)。图层名可以通过查询图层元数据域(Poppler和PDFium)获得。

  • GDAL_PDF_LAUNDER_LAYER_NAMES =YES/NO:(GDAL>=3.1)可以设置为NO,以避免在LAYERS metadata domain中报告的层名称,或作为要“清洗”的向量部分的OGR层。

打开选项

以上配置选项也可作为打开选项使用。

  • RENDERING_OPTIONS = [RASTER,VECTOR,TEXT / RASTER,VECTOR / RASTER,TEXT / RASTER / VECTOR,TEXT / VECTOR / TEXT] :与GDAL_PDF_RENDERING_OPTIONS配置选项相同

  • DPI =值:与GDAL_PDF_DPI配置选项相同

  • USER_PWD =密码:与GDAL_USER_PWD配置选项相同

  • PDF_LIB = [POPPLER/PODOFO/PDFIUM] :仅适用于具有多个后端的生成。

  • LAYERS =字符串:要打开的层列表(逗号分隔)。与GDAL_PDF_LAYERS配置选项相同

  • GDAL_PDF_LAYERS_OFF =字符串:要关闭的层列表(逗号分隔)。与GDAL_PDF_LAYERS_OFF配置选项相同

  • BANDS =3或4。与GDAL_PDF_BANDS配置选项相同

  • NEATLINE =直线名称。与GDAL_PDF_NEATLINE配置选项相同

层元数据域

当根据Poppler或PDFium编译GDAL时,可以查询LAYERS元数据域以检索可以打开或关闭的层名称。这有助于了解要为 GDAL_PDF_LAYERSGDAL_PDF_LAYERS_OFF 配置选项。

例如:

$ gdalinfo ../autotest/gdrivers/data/adobe_style_geospatial.pdf -mdd LAYERS

Driver: PDF/Geospatial PDF
Files: ../autotest/gdrivers/data/adobe_style_geospatial.pdf
[...]
Metadata (LAYERS):
  LAYER_00_NAME=New_Data_Frame
  LAYER_01_NAME=New_Data_Frame.Graticule
  LAYER_02_NAME=Layers
  LAYER_03_NAME=Layers.Measured_Grid
  LAYER_04_NAME=Layers.Graticule
[...]

$ gdal_translate ../autotest/gdrivers/data/adobe_style_geospatial.pdf out.tif --config GDAL_PDF_LAYERS_OFF "New_Data_Frame"

限制

打开PDF文档(以获取地理参考)很快,但在第一次访问栅格块时,整个页面将被栅格化(使用Poppler),这可能是一个缓慢的操作。

注意:GDAL PDF驱动程序将定期平铺的一些仅栅格的PDF文件(例如一些USGS GeoPDF文件)公开为平铺数据集,并且可以使用任何后端进行渲染。

目前,驱动程序中只映射了OGC最佳实践规范中可用的一些可能基准。未识别的基准将被视为基于WGS84椭球体。

对于页面中包含多条细线的文档(插图),将从面积最大的插图(根据屏幕点)中提取地理参考。

创建问题

PDF文档可以从其他GDAL栅格数据集创建,这些数据集有1个波段(灰度或带颜色表)、3个波段(RGB)或4个波段(RGBA)。

默认情况下,将根据ISO32000规范编写地理参考信息。也可以根据OGC最佳实践惯例编写(但仅限于少数数据和投影类型)。

注意:PDF写支持不需要链接到任何后端。

创建选项

  • [COMPRESS=[NONE/DEFLATE/JPEG/JPEG2000]] :设置用于栅格数据的压缩。默认为“放气”。

  • [STREAM_COMPRESS=[NONE/DEFLATE]] :设置用于流对象(矢量几何体、JavaScript内容)的压缩。默认为“放气”。

  • DPI=value :设置要使用的DPI。默认值为72。可以自动调整为更高的值,以便页面维度不超过Acrobat允许的最大值14400(以用户单位为单位)。

  • WRITE_USERUNIT=YES/NO :(GDAL>=2.2)是否应在文件中记录从DPI(UserUnit=DPI/72.0)计算的UserUnit设置。当记录UserUnit时,GDAL在读取时识别的栅格大小(以像素为单位)与源栅格保持相同。当没有记录用户单元时,打印的大小将取决于DPI值。如果未设置此参数,但指定了DPI,则它将默认为NO(以便打印大小取决于DPI值)。如果未设置此参数且未指定DPI,则将记录用户单位(以便GDAL在读取时识别的栅格大小(以像素为单位)与源栅格保持相同)。

  • [PREDICTOR=[1/2]] :仅用于放气压缩。可以设置为2以使用水平预测器,该预测器可以使文件变小(但并非总是如此!)。默认为1。

  • [JPEG_QUALITY=[1-100]] :使用JPEG压缩时设置JPEG质量。值100表示最佳质量(最小压缩),值1表示最差质量(最佳压缩)。默认值为75。

  • [JPEG2000_DRIVER=[JP2KAK/JP2ECW/JP2OpenJPEG/JPEG2000]] :设置要使用的JPEG2000驱动程序。如果未指定,将在上一个列表中搜索它。

  • TILED=YES :默认情况下创建单块文件。此选项可用于强制创建平铺的PDF文件。

  • BLOCKXSIZE=n :设置平铺宽度,默认值为256。

  • BLOCKYSIZE=n :设置平铺高度,默认值为256。

  • CLIPPING_EXTENT=xmin,ymin,xmax,ymax :设置主源数据集和可选额外栅格的剪裁范围。坐标以数据集的SRS为单位表示。如果未指定,则剪裁范围将设置为主源数据集的范围。

  • LAYER_NAME=name :放置栅格的图层的名称。如果指定,栅格将被放置到一个可以在PDF阅读器的“图层树”中切换/取消切换的图层中。

  • EXTRA_RASTERS=dataset_ids :要插入页面的地理参考栅格的逗号分隔列表。这些栅格显示在主源栅格的顶部。必须在同一投影中对它们进行地理参考,如果指定了剪裁范围,则会将它们剪裁为剪裁范围(否则将剪裁到主源栅格的范围)。

  • EXTRA_RASTERS_LAYER_NAME=dataset_names :在额外栅格中指定的每个栅格名称的逗号分隔列表。如果指定,每个额外的栅格将被放置到一个图层中,该图层使用指定的值命名,可以在PDF阅读器的“图层树”中切换/取消切换。如果未指定,所有多余的栅格将放置在默认层中。

  • EXTRA_STREAM=content :在图像之后绘制的PDF内容流,通常用于添加一些文本。它可以引用14种标准的PDF类型1字体(省略连字符),如/FTimesRoman,/FTimesBold,/FHelvetica,/FCourierOblique。。。,在这种情况下,将插入所需的资源字典。

  • [EXTRA_IMAGES=image_file_name,x,y,scale[,link=some_url] (possibly repeated)] :要作为额外内容插入到页中的(未地理引用的)图像列表。这对插入徽标、图例等很有用。。。x和y是从页面左下角开始的用户单位,定位点是图像左下角的像素。比例是放大倍数(如果不确定,请使用1)。如果指定了link=some_url,则图像将是可选的,其选择将导致在指定的url上打开web浏览器。

  • EXTRA_LAYER_NAME=name :放置用extra_流或extra_图像指定的额外内容的层的名称。如果指定,额外的内容将被放置到一个可以在PDF阅读器的“层树”中切换/取消切换的层中。

  • MARGIN/LEFT_MARGIN/RIGHT_MARGIN/TOP_MARGIN/BOTTOM_MARGIN=value :以用户单位表示的图像周围的边距。

  • [GEO_ENCODING=[NONE/ISO32000/OGC_BP/BOTH]] :设置要使用的地理编码方法。默认为ISO32000。

  • NEATLINE=polygon_definition_in_wkt :设置要使用的最小行。

  • [XMP=[NONE/xml_xmp_content]] :默认情况下,如果源数据集在“xml:XMP”元数据域中有数据,则此数据将复制到输出PDF,除非此选项设置为“无”。XMP xml字符串也可以直接设置为此选项。

  • [WRITE_INFO=[YES/NO]] :默认情况下,作者、创建者、创建日期、关键字、生产者、主题和标题信息将从源数据集中的相应元数据项写入PDF信息块,如果未设置,则从相应的创建选项写入PDF信息块。如果此选项设置为“否”,则不会写入任何信息。

  • AUTHORCREATORCREATION_DATEKEYWORDSPRODUCERSUBJECTTITLE :可以写入PDF信息块的元数据。注意:创建日期的值格式必须为D:YYYYMMDDHHmmSSOHH'mm'(例如,2012年11月22日的D:20121122132447+02'00'为13:24:47 GMT+02)(请参见 PDF Reference, version 1.7 ,第160页)

  • OGR_DATASOURCE=name :要显示在栅格层顶部的OGR数据源的名称。

  • OGR_DISPLAY_FIELD=name :字段的名称(与OGR层定义中的字段名称匹配),用于生成出现在知名PDF查看器的“模型树”UI组件中的功能的标签。例如,如果OGR层有一个名为“ID”的字段,则可以将其用作该选项的值:“模型树”中的要素将根据其“ID”字段的值进行标记。如果未指定,将使用顺序通用标签(“特性1”、“特性2”等)。

  • OGR_DISPLAY_LAYER_NAMES=names :要在“模型树”中为OGR层显示的名称的逗号分隔列表。此选项用于提供自定义名称,而不是在未指定此选项时使用的OGR层名称。指定时,名称的数量应与数据源中OGR层的数量相同(例如,按ogrinfo列出时的显示顺序)。

  • OGR_WRITE_ATTRIBUTES=YES/NO :是否写入OGR功能的属性。默认为“是”

  • OGR_LINK_FIELD=name :要使用的字段名称(与OGR层定义中的字段名称匹配),以使单击OGR功能打开由字段值指定的URL上的web浏览器。

  • OFF_LAYERS=names :最初应隐藏的图层名的逗号分隔列表。默认情况下,所有层都可见。图层名可以来自图层名(主栅格图层名)、附加栅格图层名、附加栅格图层名和OGR图层显示名。

  • EXCLUSIVE_LAYERS=names :以逗号分隔的图层名称列表,以便一次只能看到其中一个图层。这是图形用户界面中单选按钮的行为。图层名称可以来自图层名称(主栅格图层名称)、附加栅格图层名称、附加图层名称和OGR显示图层名称。

  • JAVASCRIPT=script :要在文档打开时运行的Javascript内容。见 Acrobat(R) JavaScript Scripting Reference .

  • JAVASCRIPT_FILE=script_filename :要在文档打开时嵌入和运行的Javascript文件的名称。见 Acrobat(R) JavaScript Scripting Reference .

  • COMPOSITION_FILE=xml_filename :(GDAL>=3.0)请参见下面的段落“从XML组合文件创建PDF文件”

更新现有文件

可以在更新模式下打开现有的PDF文件(无论是否使用GDAL创建),以便设置或更新以下元素:

  • Geotransform和关联的投影(使用SetGeoTransform()和SetProjection())

  • GCPs(使用SetGCPs())

  • Neatline(带SetMetadataItem(“Neatline”,多边形定义,在wkt中))

  • 信息对象的内容(带有SetMetadataItem(key,value),其中key是AUTHOR、CREATOR、CREATIONu DATE、KEYWORDS、PRODUCER、SUBJECT和TITLE之一)

  • xml:XMP元数据(带有SetMetadata(md,“xml:XMP”))

对于geotransform或GCPs,默认使用的地理编码方法是ISO32000。通过将GDAL_PDF_GEO_编码配置选项设置为OGC_BP,可以选择OGC_BP。

更新的元素将按照PDF规范中描述的增量更新方法写入文件末尾。

从XML合成文件创建PDF文件(GDAL>=3.0)

可以从描述PDF组成的XML文件生成PDF文件:

  • 页数

  • 图层树,具有可见性状态,排除组

  • 定义或每页0、1或多个地理参考区域

  • 由栅格、矢量或标签组成的页面内容

GDALCreate()API必须与width=height=bands=0和datatype=GDT_Unknown一起使用,COMPOSITION_文件必须是单个创建选项。

The XML schema against which the composition file must validate is pdfcomposition.xsd

如何使用API的示例:

char** papszOptions = CSLSetNameValue(nullptr, "COMPOSITION_FILE", "the.xml");
GDALDataset* ds = GDALCreate("the.pdf", 0, 0, 0, GDT_Unknown, papszOptions);
// return a non-null (fake) dataset in case of success, nullptr otherwise.
GDALClose(ds);
CSLDestroy(papszOptions);

A sample Python script gdal_create_pdf.py is also available. Starting with GDAL 3.2, the gdal_create utility can also be used.

组合XML文件的示例:

<PDFComposition>
    <Metadata>
        <Author>Even</Author>
    </Metadata>

    <LayerTree displayOnlyOnVisiblePages="true">
        <Layer id="l1" name="Satellite imagery"/>
        <Layer id="l2" name="OSM data">
            <Layer id="l2.1" name="Roads" initiallyVisible="false"/>
            <Layer id="l2.2" name="Buildings" mutuallyExclusiveGroupId="group1">
                <Layer id="l2.2.text" name="Buildings name"/>
            </Layer>
            <Layer id="l2.3" name="Cadastral parcels" mutuallyExclusiveGroupId="group1"/>
        </Layer>
    </LayerTree>

    <Page id="page_1">
        <DPI>72</DPI>
        <Width>10</Width>
        <Height>15</Height>
        <Georeferencing id="georeferenced">
            <SRS dataAxisToSRSAxisMapping="2,1">EPSG:4326</SRS>
            <BoundingBox x1="1" y1="1" x2="9" y2="14"/>
            <BoundingPolygon>POLYGON((1 1,9 1,9 14,1 14,1 1))</BoundingPolygon>
            <ControlPoint x="1"  y="1"  GeoY="48"  GeoX="2"/>
            <ControlPoint x="1"  y="14" GeoY="49"  GeoX="2"/>
            <ControlPoint x="9"  y="1"  GeoY="49"  GeoX="3"/>
            <ControlPoint x="9"  y="14" GeoY="48"  GeoX="3"/>
        </Georeferencing>

        <Content>
            <IfLayerOn layerId="l1">
                <!-- image drawn, and stretched to (x1,y1)->(x2,y2), without reading its georeferencing -->
                <Raster dataset="satellite.png" x1="1" y1="1" x2="9" y2="14"/>
            </IfLayerOn>
            <IfLayerOn layerId="l2">
                <IfLayerOn layerId="l2.1">
                    <Raster dataset="roads.jpg" x1="1" y1="1" x2="9" y2="14"/>
                    <!-- vector drawn with coordinates in PDF coordinate space -->
                    <Vector dataset="roads_pdf_units.shp" layer="roads_pdf_units" visible="false">
                        <LogicalStructure displayLayerName="Roads" fieldToDisplay="road_name"/>>
                    </Vector>
                </IfLayerOn>
                <IfLayerOn layerId="l2.2">
                    <!-- image drawn by taking into account its georeferencing -->
                    <Raster dataset="buildings.tif" georeferencingId="georeferenced"/>
                    <IfLayerOn layerId="l2.2.text">
                        <!-- vector drawn by taking into account its georeferenced coordinates -->
                        <VectorLabel dataset="labels.shp" layer="labels" georeferencingId="georeferenced">
                        </VectorLabel>
                    </IfLayerOn>
                </IfLayerOn>
                <IfLayerOn layerId="l2.3">
                    <PDF dataset="parcels.pdf">
                        <Blending function="Normal" opacity="0.7"/>
                    </PDF>
                </IfLayerOn>
            </IfLayerOn>
        </Content>
    </Page>

    <Page id="page_2">
        <DPI>72</DPI>
        <Width>10</Width>
        <Height>15</Height>
        <Content>
        </Content>
    </Page>

    <Outline>
        <OutlineItem name="turn only layer 'Satellite imagery' on, and switch to fullscreen" italic="true" bold="true">
            <Actions>
                <SetAllLayersStateAction visible="false"/>
                <SetLayerStateAction visible="true" layerId="l1"/>
                <JavascriptAction>app.fs.isFullScreen = true;</JavascriptAction>
            </Actions>
        </OutlineItem>
        <OutlineItem name="Page 1" pageId="page_1">
            <OutlineItem name="Important feature !">
                <Actions>
                    <GotoPageAction pageId="page_1" x1="1" y1="2" x2="3" y2="4"/>
                </Actions>
            </OutlineItem>
        </OutlineItem>
        <OutlineItem name="Page 2" pageId="page_2"/>
    </Outline>

</PDFComposition>

生成依赖项

对于读支持,必须针对以下库之一构建GDAL:

  • Poppler (GPL许可)

  • PoDoFo (LGPL许可)

  • PDFium (新的BSD许可证,自gdal2.1.0以来受支持)

注意:也可以根据以上几个库的组合进行构建。PDFium将优先于Poppler使用,它本身优先于PoDoFo使用。

Unix生成

相关的配置选项是--with poppler,-with podofo,-with podofo lib和--with podofo extra lib以供测试。

从GDAL 2.1.0开始,--使用pdfium,--使用pdfium lib,--使用pdfium extra lib进行测试和--enable pdf插件也可用。

波普勒

LbPopFube本身必须配置为-DeababyununLeLayApIIAbIIHiHeals= =,以便XPDF C++头文件可用。注意:PopFuxC++ API不稳定,因此驱动程序编译可能会失败,因为使用过旧版本或过期的版本。

PoDoFo

作为部分替代方案,可以针对libpodofo编译PDF驱动程序,以避免libpoppler依赖性。这足以得到地理参考和矢量信息。但是,为了获得图像,poppler发行版附带的pdftoppm实用程序必须在系统路径中可用。临时文件将在由以下配置选项确定的目录中生成:CPL_TMPDIR、TMPDIR或TEMP(按此顺序)。如果未定义,则将使用当前目录。成功测试的版本是libpodofo 0.8.4、0.9.1和0.9.3。重要提示:强烈建议不要使用PoDoFo 0.9.0,因为它可能会由于PoDoFo中的错误而导致GDAL崩溃。

PDFium

使用PDFium作为后端允许访问栅格、矢量、地理参考和其他元数据。PDFium后端还支持任意概览,以实现快速缩小。

只有GDAL版本与PDFium的静态版本进行了测试。构建PDFium可能很有挑战性,必须使用特定的构建来正确地使用GDAL。

With GDAL >= 3.5

The scripts in the https://github.com/rouault/pdfium_build_gdal_3_5 repository must be used to build a patched version of PDFium.

With GDAL 3.4

The scripts in the https://github.com/rouault/pdfium_build_gdal_3_4 repository must be used to build a patched version of PDFium.

With GDAL 3.2 and 3.3

中的脚本 https://github.com/rouault/pdfium_build_gdal_3_2 _必须使用存储库来构建PDFium的修补版本。

使用GDAL 3.1.x

中的脚本 https://github.com/rouault/pdfium_build_gdal_3_1 _必须使用存储库来构建PDFium的修补版本。

GDAL>=2.2.0且<3.1时

A PDFium forked version for simpler builds 可用(对于Windows,专用的 win_gdal_build 建议使用分支)。一个 build repository 提供了一些脚本,这些脚本可以用作为Linux/MacOSX/Windows构建PDFium的模板。这些分叉版本消除了对V8 JavaScript引擎的依赖性,并且还进行了一些更改,以避免在Linux上与libjpeg和libopenjpeg发生符号冲突。将PDF驱动程序构建为GDAL插件也是避免此类问题的一种方法。PDFIUM构建需要一个C++ 11兼容编译器,以及构建PDAUM的GDAL本身。成功测试的版本是GCC 4.7.0(以前的版本不兼容)和Visual Studio 12/VS2013。

实例

  • 从两个栅格(主栅格和另一个栅格)创建PDF,以便主栅格最初显示,并且以独占方式显示:

    gdal_translate -of PDF main_raster.tif my.pdf -co LAYER_NAME=main_raster
                   -co EXTRA_RASTERS=another_raster.tif -co EXTRA_RASTERS_LAYER_NAME=another_raster
                   -co OFF_LAYERS=another_raster -co EXCLUSIVE_LAYERS=main_raster,another_raster
    
  • 使用一些JavaScript创建PDF:

    gdal_translate -of PDF my.tif my.pdf -co JAVASCRIPT_FILE=script.js
    

    其中script.js是:

    button = app.alert({cMsg: 'This file was generated by GDAL. Do you want to visit its website ?', cTitle: 'Question', nIcon:2, nType:2});
    if (button == 4) app.launchURL('http://gdal.org/');
    

也见

PDF vector 文档页

规格:

库:

样品: