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