Line data Source code
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 : #ifdef HAVE_PDF_READ_SUPPORT
32 :
33 : /************************************************************************/
34 : /* OGRPDFLayer() */
35 : /************************************************************************/
36 :
37 12 : OGRPDFLayer::OGRPDFLayer(PDFDataset *poDSIn, const char *pszName,
38 : OGRSpatialReference *poSRS,
39 12 : OGRwkbGeometryType eGeomType)
40 : : OGRMemLayer(pszName, poSRS, eGeomType), poDS(poDSIn), bGeomTypeSet(FALSE),
41 12 : bGeomTypeMixed(FALSE)
42 : {
43 12 : }
44 :
45 : /************************************************************************/
46 : /* Fill() */
47 : /************************************************************************/
48 :
49 6 : void OGRPDFLayer::Fill(GDALPDFArray *poArray)
50 : {
51 38 : for (int i = 0; i < poArray->GetLength(); i++)
52 : {
53 32 : GDALPDFObject *poFeatureObj = poArray->Get(i);
54 64 : if (poFeatureObj == nullptr ||
55 32 : poFeatureObj->GetType() != PDFObjectType_Dictionary)
56 0 : continue;
57 :
58 32 : GDALPDFObject *poA = poFeatureObj->GetDictionary()->Get("A");
59 32 : if (!(poA != nullptr && poA->GetType() == PDFObjectType_Dictionary))
60 0 : continue;
61 :
62 32 : auto poO = poA->GetDictionary()->Get("O");
63 64 : if (!(poO && poO->GetType() == PDFObjectType_Name &&
64 32 : poO->GetName() == "UserProperties"))
65 0 : continue;
66 :
67 : // P is supposed to be required in A, but past GDAL versions could
68 : // generate features without attributes without a P array
69 32 : GDALPDFObject *poP = poA->GetDictionary()->Get("P");
70 32 : GDALPDFArray *poPArray = nullptr;
71 32 : if (poP != nullptr && poP->GetType() == PDFObjectType_Array)
72 32 : poPArray = poP->GetArray();
73 : else
74 0 : poP = nullptr;
75 :
76 32 : GDALPDFObject *poK = poFeatureObj->GetDictionary()->Get("K");
77 32 : int nK = -1;
78 32 : if (poK != nullptr && poK->GetType() == PDFObjectType_Int)
79 32 : nK = poK->GetInt();
80 :
81 32 : if (poP)
82 : {
83 66 : for (int j = 0; j < poPArray->GetLength(); j++)
84 : {
85 34 : GDALPDFObject *poKV = poPArray->Get(j);
86 34 : if (poKV && poKV->GetType() == PDFObjectType_Dictionary)
87 : {
88 34 : GDALPDFObject *poN = poKV->GetDictionary()->Get("N");
89 34 : GDALPDFObject *poV = poKV->GetDictionary()->Get("V");
90 68 : if (poN != nullptr &&
91 34 : poN->GetType() == PDFObjectType_String &&
92 : poV != nullptr)
93 : {
94 68 : int nIdx = GetLayerDefn()->GetFieldIndex(
95 34 : poN->GetString().c_str());
96 34 : OGRFieldType eType = OFTString;
97 34 : if (poV->GetType() == PDFObjectType_Int)
98 17 : eType = OFTInteger;
99 17 : else if (poV->GetType() == PDFObjectType_Real)
100 1 : eType = OFTReal;
101 34 : if (nIdx < 0)
102 : {
103 12 : OGRFieldDefn oField(poN->GetString().c_str(),
104 24 : eType);
105 12 : CreateField(&oField);
106 : }
107 22 : else if (GetLayerDefn()
108 22 : ->GetFieldDefn(nIdx)
109 22 : ->GetType() != eType &&
110 0 : GetLayerDefn()
111 0 : ->GetFieldDefn(nIdx)
112 0 : ->GetType() != OFTString)
113 : {
114 0 : OGRFieldDefn oField(poN->GetString().c_str(),
115 0 : OFTString);
116 0 : AlterFieldDefn(nIdx, &oField, ALTER_TYPE_FLAG);
117 : }
118 : }
119 : }
120 : }
121 : }
122 :
123 32 : OGRFeature *poFeature = new OGRFeature(GetLayerDefn());
124 32 : if (poPArray)
125 : {
126 66 : for (int j = 0; j < poPArray->GetLength(); j++)
127 : {
128 34 : GDALPDFObject *poKV = poPArray->Get(j);
129 34 : if (poKV && poKV->GetType() == PDFObjectType_Dictionary)
130 : {
131 34 : GDALPDFObject *poN = poKV->GetDictionary()->Get("N");
132 34 : GDALPDFObject *poV = poKV->GetDictionary()->Get("V");
133 68 : if (poN != nullptr &&
134 34 : poN->GetType() == PDFObjectType_String &&
135 : poV != nullptr)
136 : {
137 34 : if (poV->GetType() == PDFObjectType_String)
138 16 : poFeature->SetField(poN->GetString().c_str(),
139 16 : poV->GetString().c_str());
140 18 : else if (poV->GetType() == PDFObjectType_Int)
141 17 : poFeature->SetField(poN->GetString().c_str(),
142 17 : poV->GetInt());
143 1 : else if (poV->GetType() == PDFObjectType_Real)
144 1 : poFeature->SetField(poN->GetString().c_str(),
145 1 : poV->GetReal());
146 : }
147 : }
148 : }
149 : }
150 :
151 32 : if (nK >= 0)
152 : {
153 32 : OGRGeometry *poGeom = poDS->GetGeometryFromMCID(nK);
154 32 : if (poGeom)
155 : {
156 31 : poGeom->assignSpatialReference(GetSpatialRef());
157 31 : poFeature->SetGeometry(poGeom);
158 : }
159 : }
160 :
161 32 : OGRGeometry *poGeom = poFeature->GetGeometryRef();
162 32 : if (!bGeomTypeMixed && poGeom != nullptr)
163 : {
164 17 : auto poLayerDefn = GetLayerDefn();
165 17 : if (!bGeomTypeSet)
166 : {
167 6 : bGeomTypeSet = TRUE;
168 12 : whileUnsealing(poLayerDefn)
169 6 : ->SetGeomType(poGeom->getGeometryType());
170 : }
171 11 : else if (poLayerDefn->GetGeomType() != poGeom->getGeometryType())
172 : {
173 3 : bGeomTypeMixed = TRUE;
174 3 : whileUnsealing(poLayerDefn)->SetGeomType(wkbUnknown);
175 : }
176 : }
177 32 : ICreateFeature(poFeature);
178 :
179 32 : delete poFeature;
180 : }
181 6 : }
182 :
183 : /************************************************************************/
184 : /* TestCapability() */
185 : /************************************************************************/
186 :
187 8 : int OGRPDFLayer::TestCapability(const char *pszCap)
188 :
189 : {
190 8 : if (EQUAL(pszCap, OLCStringsAsUTF8))
191 0 : return TRUE;
192 : else
193 8 : return OGRMemLayer::TestCapability(pszCap);
194 : }
195 :
196 : /************************************************************************/
197 : /* GetDataset() */
198 : /************************************************************************/
199 :
200 1 : GDALDataset *OGRPDFLayer::GetDataset()
201 : {
202 1 : return poDS;
203 : }
204 :
205 : #endif /* HAVE_PDF_READ_SUPPORT */
206 :
207 : /************************************************************************/
208 : /* OGRPDFWritableLayer() */
209 : /************************************************************************/
210 :
211 52 : OGRPDFWritableLayer::OGRPDFWritableLayer(PDFWritableVectorDataset *poDSIn,
212 : const char *pszName,
213 : OGRSpatialReference *poSRS,
214 52 : OGRwkbGeometryType eGeomType)
215 52 : : OGRMemLayer(pszName, poSRS, eGeomType), poDS(poDSIn)
216 : {
217 52 : }
218 :
219 : /************************************************************************/
220 : /* ICreateFeature() */
221 : /************************************************************************/
222 :
223 111 : OGRErr OGRPDFWritableLayer::ICreateFeature(OGRFeature *poFeature)
224 : {
225 111 : poDS->SetModified();
226 111 : return OGRMemLayer::ICreateFeature(poFeature);
227 : }
228 :
229 : /************************************************************************/
230 : /* TestCapability() */
231 : /************************************************************************/
232 :
233 102 : int OGRPDFWritableLayer::TestCapability(const char *pszCap)
234 :
235 : {
236 102 : if (EQUAL(pszCap, OLCStringsAsUTF8))
237 0 : return TRUE;
238 : else
239 102 : return OGRMemLayer::TestCapability(pszCap);
240 : }
241 :
242 : /************************************************************************/
243 : /* GetDataset() */
244 : /************************************************************************/
245 :
246 18 : GDALDataset *OGRPDFWritableLayer::GetDataset()
247 : {
248 18 : return poDS;
249 : }
|