1 /******************************************************************************
2 *
3 * Project: PDF Translator
4 * Purpose: Implements OGRPDFDataSource class
5 * Author: Even Rouault, even dot rouault at spatialys.com
6 *
7 ******************************************************************************
8 * Copyright (c) 2012, Even Rouault <even dot rouault at spatialys.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 ****************************************************************************/
28
29 #include "gdal_pdf.h"
30
31 CPL_CVSID("$Id: ogrpdflayer.cpp 9c1c4c56303c06d9e18dbfd9412dab3ce58f3f03 2020-05-28 14:16:15 +0200 Even Rouault $")
32
33 #ifdef HAVE_PDF_READ_SUPPORT
34
35 /************************************************************************/
36 /* OGRPDFLayer() */
37 /************************************************************************/
38
OGRPDFLayer(PDFDataset * poDSIn,const char * pszName,OGRSpatialReference * poSRS,OGRwkbGeometryType eGeomType)39 OGRPDFLayer::OGRPDFLayer( PDFDataset* poDSIn,
40 const char * pszName,
41 OGRSpatialReference *poSRS,
42 OGRwkbGeometryType eGeomType ) :
43 OGRMemLayer(pszName, poSRS, eGeomType ),
44 poDS(poDSIn),
45 bGeomTypeSet(FALSE),
46 bGeomTypeMixed(FALSE)
47 {}
48
49 /************************************************************************/
50 /* Fill() */
51 /************************************************************************/
52
Fill(GDALPDFArray * poArray)53 void OGRPDFLayer::Fill( GDALPDFArray* poArray )
54 {
55 for(int i=0;i<poArray->GetLength();i++)
56 {
57 GDALPDFObject* poFeatureObj = poArray->Get(i);
58 if (poFeatureObj == nullptr ||
59 poFeatureObj->GetType() != PDFObjectType_Dictionary)
60 continue;
61
62 GDALPDFObject* poA = poFeatureObj->GetDictionary()->Get("A");
63 if (!(poA != nullptr && poA->GetType() == PDFObjectType_Dictionary))
64 continue;
65
66 // P is supposed to be required in A, but past GDAL versions could
67 // generate features without attributes without a P array
68 GDALPDFObject* poP = poA->GetDictionary()->Get("P");
69 GDALPDFArray* poPArray = nullptr;
70 if (poP != nullptr && poP->GetType() == PDFObjectType_Array)
71 poPArray = poP->GetArray();
72 else
73 poP = nullptr;
74
75 GDALPDFObject* poK = poFeatureObj->GetDictionary()->Get("K");
76 int nK = -1;
77 if (poK != nullptr && poK->GetType() == PDFObjectType_Int)
78 nK = poK->GetInt();
79
80 if( poP )
81 {
82 for(int j = 0;j<poPArray->GetLength();j++)
83 {
84 GDALPDFObject* poKV = poPArray->Get(j);
85 if (poKV && poKV->GetType() == PDFObjectType_Dictionary)
86 {
87 GDALPDFObject* poN = poKV->GetDictionary()->Get("N");
88 GDALPDFObject* poV = poKV->GetDictionary()->Get("V");
89 if (poN != nullptr && poN->GetType() == PDFObjectType_String &&
90 poV != nullptr)
91 {
92 int nIdx = GetLayerDefn()->GetFieldIndex( poN->GetString().c_str() );
93 OGRFieldType eType = OFTString;
94 if (poV->GetType() == PDFObjectType_Int)
95 eType = OFTInteger;
96 else if (poV->GetType() == PDFObjectType_Real)
97 eType = OFTReal;
98 if (nIdx < 0)
99 {
100 OGRFieldDefn oField(poN->GetString().c_str(), eType);
101 CreateField(&oField);
102 }
103 else if (GetLayerDefn()->GetFieldDefn(nIdx)->GetType() != eType &&
104 GetLayerDefn()->GetFieldDefn(nIdx)->GetType() != OFTString)
105 {
106 OGRFieldDefn oField(poN->GetString().c_str(), OFTString);
107 AlterFieldDefn( nIdx, &oField, ALTER_TYPE_FLAG );
108 }
109 }
110 }
111 }
112 }
113
114 OGRFeature* poFeature = new OGRFeature(GetLayerDefn());
115 if( poPArray )
116 {
117 for(int j = 0;j<poPArray->GetLength();j++)
118 {
119 GDALPDFObject* poKV = poPArray->Get(j);
120 if (poKV && poKV->GetType() == PDFObjectType_Dictionary)
121 {
122 GDALPDFObject* poN = poKV->GetDictionary()->Get("N");
123 GDALPDFObject* poV = poKV->GetDictionary()->Get("V");
124 if (poN != nullptr && poN->GetType() == PDFObjectType_String &&
125 poV != nullptr)
126 {
127 if (poV->GetType() == PDFObjectType_String)
128 poFeature->SetField(poN->GetString().c_str(), poV->GetString().c_str());
129 else if (poV->GetType() == PDFObjectType_Int)
130 poFeature->SetField(poN->GetString().c_str(), poV->GetInt());
131 else if (poV->GetType() == PDFObjectType_Real)
132 poFeature->SetField(poN->GetString().c_str(), poV->GetReal());
133 }
134 }
135 }
136 }
137
138 if (nK >= 0)
139 {
140 OGRGeometry* poGeom = poDS->GetGeometryFromMCID(nK);
141 if (poGeom)
142 {
143 poGeom->assignSpatialReference(GetSpatialRef());
144 poFeature->SetGeometry(poGeom);
145 }
146 }
147
148 OGRGeometry* poGeom = poFeature->GetGeometryRef();
149 if( !bGeomTypeMixed && poGeom != nullptr )
150 {
151 if (!bGeomTypeSet)
152 {
153 bGeomTypeSet = TRUE;
154 GetLayerDefn()->SetGeomType(poGeom->getGeometryType());
155 }
156 else if (GetLayerDefn()->GetGeomType() != poGeom->getGeometryType())
157 {
158 bGeomTypeMixed = TRUE;
159 GetLayerDefn()->SetGeomType(wkbUnknown);
160 }
161 }
162 ICreateFeature(poFeature);
163
164 delete poFeature;
165 }
166 }
167
168 /************************************************************************/
169 /* TestCapability() */
170 /************************************************************************/
171
TestCapability(const char * pszCap)172 int OGRPDFLayer::TestCapability( const char * pszCap )
173
174 {
175 if( EQUAL(pszCap,OLCStringsAsUTF8) )
176 return TRUE;
177 else
178 return OGRMemLayer::TestCapability(pszCap);
179 }
180
181 #endif /* HAVE_PDF_READ_SUPPORT */
182
183 /************************************************************************/
184 /* OGRPDFWritableLayer() */
185 /************************************************************************/
186
OGRPDFWritableLayer(PDFWritableVectorDataset * poDSIn,const char * pszName,OGRSpatialReference * poSRS,OGRwkbGeometryType eGeomType)187 OGRPDFWritableLayer::OGRPDFWritableLayer( PDFWritableVectorDataset* poDSIn,
188 const char * pszName,
189 OGRSpatialReference *poSRS,
190 OGRwkbGeometryType eGeomType ) :
191 OGRMemLayer(pszName, poSRS, eGeomType ),
192 poDS(poDSIn)
193 {}
194
195 /************************************************************************/
196 /* ICreateFeature() */
197 /************************************************************************/
198
ICreateFeature(OGRFeature * poFeature)199 OGRErr OGRPDFWritableLayer::ICreateFeature( OGRFeature *poFeature )
200 {
201 poDS->SetModified();
202 return OGRMemLayer::ICreateFeature(poFeature);
203 }
204
205 /************************************************************************/
206 /* TestCapability() */
207 /************************************************************************/
208
TestCapability(const char * pszCap)209 int OGRPDFWritableLayer::TestCapability( const char * pszCap )
210
211 {
212 if( EQUAL(pszCap,OLCStringsAsUTF8) )
213 return TRUE;
214 else
215 return OGRMemLayer::TestCapability(pszCap);
216 }
217