我正在创建PDF格式的徒步旅行/步行地图。作为一个额外的功能,我使用地理空间测量字典向PDF添加了一个视区。这是为了将页面上的位置与实际的地理坐标联系起来。
我遵循https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/adobe_supplement_iso32000.pdf中的Adobe文档。在一个简单的场景中,这可以很好地工作: Acrobat在启用地理空间位置工具的情况下,显示鼠标位置的正确坐标。
由于一些与实际打印PDF相关的原因,我想在页面上旋转地图。根据我对PDF7规范文档的理解(第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发布于 2020-01-27 21:28:57
LPTS数组将GPTS中的地理点映射到相对于BBox定义的坐标系的视口角落。
对LPTS使用此值,将正确处理经度/经度: 0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0
左上角是(0,0),右下角是(1,1)。您的GPTS点按照(top,left),(top,right),(bottom,right),(bottom,right),(bottom,left)的顺序给出,所以LPTS数组是(0,0),(1,0),(1,1),(0,1)。
发布于 2020-02-08 20:59:12
上面的部分答案(它适用于这个例子)帮助我表达了一个通用的解决方案:
当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 ) } );
}https://stackoverflow.com/questions/59562254
复制相似问题