创建旋转的地理空间PDF

问题描述 投票:0回答:2

我正在创建PDF远足/步行地图。作为一项附加功能,我使用地理空间测量字典将视口添加到PDF。这是为了将页面上的位置与实际的地理坐标相关联。

我遵循https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/adobe_supplement_iso32000.pdf中的Adobe文档。在一个简单的场景中,它可以很好地工作:启用了地理空间定位工具的Acrobat,可以显示鼠标位置的正确坐标。

由于与实际打印PDF有关的某些原因,我想旋转页面上的地图。根据对PDF 7规范文档的了解(第8.8节),我要做的就是在地图视口词典的BBox中提供一个旋转的主对角线。这就是我要做的。 (除了旋转图像)

在地图的旋转版本中,Acrobat可以正确识别矩形的主要对角线。但是,对于其他两个角,则交换了地理(纬度/经度)和几何(x,y)坐标之间的关系。

有人知道我的PDF文件出了什么问题吗?直立的示例为https://mdedoes.home.xs4all.nl/maarssen-25000.pdf,旋转的示例为https://mdedoes.home.xs4all.nl/maarssen-25000-r.pdf

为了完整起见,我列出了该页面视口的所有清单。 (使用PDFBox从实际文件中提取)

 VP[0].Name=n:Maarssen
 VP[0].BBox[0]=f:42.5197
 VP[0].BBox[1]=f:552.7559
 VP[0].BBox[2]=f:325.98428
 VP[0].BBox[3]=f:42.5197
 VP[0].Measure:o.Bounds[0]=f:0.0
 VP[0].Measure:o.Bounds[1]=f:0.0
 VP[0].Measure:o.Bounds[2]=f:0.0
 VP[0].Measure:o.Bounds[3]=f:1.0
 VP[0].Measure:o.Bounds[4]=f:1.0
 VP[0].Measure:o.Bounds[5]=f:1.0
 VP[0].Measure:o.Bounds[6]=f:1.0
 VP[0].Measure:o.Bounds[7]=f:0.0
 VP[0].Measure:o.GCS:o.Type=n:GEOGCS
 VP[0].Measure:o.GCS:o.EPSG=i:4289
 VP[0].Measure:o.GCS:o.WKT=s:GEOGCS["Amersfoort", Etc
 VP[0].Measure:o.DCS:o.Type=n:PROJCS
 VP[0].Measure:o.DCS:o.EPSG=i:28992
 VP[0].Measure:o.DCS:o.WKT=s:PROJCS["Amersfoort / RD New", Etc
 VP[0].Measure:o.GPTS[0]=f:52.151005
 VP[0].Measure:o.GPTS[1]=f:4.9930854
 VP[0].Measure:o.GPTS[2]=f:52.173477
 VP[0].Measure:o.GPTS[3]=f:4.9928865
 VP[0].Measure:o.GPTS[4]=f:52.17368
 VP[0].Measure:o.GPTS[5]=f:5.0586777
 VP[0].Measure:o.GPTS[6]=f:52.151207
 VP[0].Measure:o.GPTS[7]=f:5.058843
 VP[0].Measure:o.LPTS[0]=f:0.0
 VP[0].Measure:o.LPTS[1]=f:0.0
 VP[0].Measure:o.LPTS[2]=f:0.0
 VP[0].Measure:o.LPTS[3]=f:1.0
 VP[0].Measure:o.LPTS[4]=f:1.0
 VP[0].Measure:o.LPTS[5]=f:1.0
 VP[0].Measure:o.LPTS[6]=f:1.0
 VP[0].Measure:o.LPTS[7]=f:0.0
 VP[0].Measure:o.PDU[0]=s:M
 VP[0].Measure:o.PDU[1]=s:SQM
 VP[0].Measure:o.PDU[2]=s:DEG
 VP[0].Measure:o.Subtype=n:GEO
 VP[0].Measure:o.Type=n:Viewport
pdf geospatial measurement
2个回答
1
投票

LPTS数组将GPTS中的地理点相对于BBox定义的坐标系映射到视口的角。

将此值用于LPTS,纬度/经度将被正确处理:[0.0 0.0 1.0 0.0 1.0 1.0 1.0 0.0 1.0]

左上角为(0,0),右下角为(1,1)。您的GPTS点的顺序为(顶部,左侧),(顶部,右侧),(底部,右侧),(底部,左侧),因此LPTS数组为(0,0),(1,0),(1 ,1),(0,1)。


0
投票

上面的部分答案(适用于示例)帮助我提出了一个一般的解决方案:

[GPTS以顺时针顺序位于地图矩形的角上时,LPTS的顺序取决于旋转角度。对于90度奇数倍的旋转,LPTS沿逆时针方向旋转。对于偶数倍,LPTS都是顺时针顺序。

可能,代码片段最容易理解:

// Emit GPTS
private static COSArray gpts( GeospatialPdfViewport mapViewport ) {

    Coordinate[] coordinates= new Coordinate[] {
            mapViewport.getGeographicLowerLeft(),
            mapViewport.getGeographicUpperLeft(),
            mapViewport.getGeographicUpperRight(),
            mapViewport.getGeographicLowerRight(),
    };

    COSArray pts= new COSArray();

    for ( Coordinate c: coordinates ) {
        // Lat(y)-Lon(x) rather than Lon-Lat
        pts.add( new COSFloat( (float)c.y ) );
        pts.add( new COSFloat( (float)c.x ) );
    }

    return pts;
}

/**
 * @param odd True for 90 or 270 degrees; False for 0 or 180 degrees
 * @return an LPTS array. The contents depend on the angle of rotation of the viewport
 */
private static COSArray lpts( boolean odd ) {

    if  ( odd ) {
        return toCOSArray( new Coordinate[] {
                new Coordinate( 0, 0 ),
                new Coordinate( 1, 0 ),
                new Coordinate( 1, 1 ),
                new Coordinate( 0, 1 ),             
        } );
    } else {
        return toCOSArray( new Coordinate[] {
                new Coordinate( 0, 0 ),
                new Coordinate( 0, 1 ),             
                new Coordinate( 1, 1 ),
                new Coordinate( 1, 0 ),             
        } );
    }
}

// Emit Bounds
private static COSArray bounds() {
    return toCOSArray( new Coordinate[] {
            new Coordinate( 0, 0 ),
            new Coordinate( 0, 1 ),
            new Coordinate( 1, 1 ),
            new Coordinate( 1, 0 ) } );
}
© www.soinside.com 2019 - 2024. All rights reserved.