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 207 : OGRPDFLayer::OGRPDFLayer(PDFDataset *poDSIn, const char *pszName, 22 : OGRSpatialReference *poSRS, 23 207 : OGRwkbGeometryType eGeomType) 24 : : OGRMemLayer(pszName, poSRS, eGeomType), poDS(poDSIn), bGeomTypeSet(FALSE), 25 207 : bGeomTypeMixed(FALSE) 26 : { 27 207 : } 28 : 29 : /************************************************************************/ 30 : /* Fill() */ 31 : /************************************************************************/ 32 : 33 8 : void OGRPDFLayer::Fill(GDALPDFArray *poArray) 34 : { 35 70 : for (int i = 0; i < poArray->GetLength(); i++) 36 : { 37 62 : GDALPDFObject *poFeatureObj = poArray->Get(i); 38 124 : if (poFeatureObj == nullptr || 39 62 : poFeatureObj->GetType() != PDFObjectType_Dictionary) 40 0 : continue; 41 : 42 62 : GDALPDFObject *poA = poFeatureObj->GetDictionary()->Get("A"); 43 62 : if (!(poA != nullptr && poA->GetType() == PDFObjectType_Dictionary)) 44 0 : continue; 45 : 46 62 : auto poO = poA->GetDictionary()->Get("O"); 47 124 : if (!(poO && poO->GetType() == PDFObjectType_Name && 48 62 : 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 62 : GDALPDFObject *poP = poA->GetDictionary()->Get("P"); 54 62 : GDALPDFArray *poPArray = nullptr; 55 62 : if (poP != nullptr && poP->GetType() == PDFObjectType_Array) 56 62 : poPArray = poP->GetArray(); 57 : else 58 0 : poP = nullptr; 59 : 60 62 : GDALPDFObject *poK = poFeatureObj->GetDictionary()->Get("K"); 61 62 : int nK = -1; 62 62 : if (poK != nullptr && poK->GetType() == PDFObjectType_Int) 63 62 : nK = poK->GetInt(); 64 : 65 62 : if (poP) 66 : { 67 108 : for (int j = 0; j < poPArray->GetLength(); j++) 68 : { 69 46 : GDALPDFObject *poKV = poPArray->Get(j); 70 46 : if (poKV && poKV->GetType() == PDFObjectType_Dictionary) 71 : { 72 46 : GDALPDFObject *poN = poKV->GetDictionary()->Get("N"); 73 46 : GDALPDFObject *poV = poKV->GetDictionary()->Get("V"); 74 92 : if (poN != nullptr && 75 46 : poN->GetType() == PDFObjectType_String && 76 : poV != nullptr) 77 : { 78 92 : int nIdx = GetLayerDefn()->GetFieldIndex( 79 46 : poN->GetString().c_str()); 80 46 : OGRFieldType eType = OFTString; 81 46 : if (poV->GetType() == PDFObjectType_Int) 82 19 : eType = OFTInteger; 83 27 : else if (poV->GetType() == PDFObjectType_Real) 84 3 : eType = OFTReal; 85 46 : if (nIdx < 0) 86 : { 87 20 : OGRFieldDefn oField(poN->GetString().c_str(), 88 40 : eType); 89 20 : CreateField(&oField); 90 : } 91 26 : else if (GetLayerDefn() 92 26 : ->GetFieldDefn(nIdx) 93 26 : ->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 62 : OGRFeature *poFeature = new OGRFeature(GetLayerDefn()); 108 62 : if (poPArray) 109 : { 110 108 : for (int j = 0; j < poPArray->GetLength(); j++) 111 : { 112 46 : GDALPDFObject *poKV = poPArray->Get(j); 113 46 : if (poKV && poKV->GetType() == PDFObjectType_Dictionary) 114 : { 115 46 : GDALPDFObject *poN = poKV->GetDictionary()->Get("N"); 116 46 : GDALPDFObject *poV = poKV->GetDictionary()->Get("V"); 117 92 : if (poN != nullptr && 118 46 : poN->GetType() == PDFObjectType_String && 119 : poV != nullptr) 120 : { 121 46 : if (poV->GetType() == PDFObjectType_String) 122 24 : poFeature->SetField(poN->GetString().c_str(), 123 24 : poV->GetString().c_str()); 124 22 : else if (poV->GetType() == PDFObjectType_Int) 125 19 : poFeature->SetField(poN->GetString().c_str(), 126 19 : poV->GetInt()); 127 3 : else if (poV->GetType() == PDFObjectType_Real) 128 3 : poFeature->SetField(poN->GetString().c_str(), 129 3 : poV->GetReal()); 130 : } 131 : } 132 : } 133 : } 134 : 135 62 : if (nK >= 0) 136 : { 137 62 : OGRGeometry *poGeom = poDS->GetGeometryFromMCID(nK); 138 62 : if (poGeom) 139 : { 140 59 : poGeom->assignSpatialReference(GetSpatialRef()); 141 59 : poFeature->SetGeometry(poGeom); 142 : } 143 : } 144 : 145 62 : OGRGeometry *poGeom = poFeature->GetGeometryRef(); 146 62 : if (!bGeomTypeMixed && poGeom != nullptr) 147 : { 148 21 : auto poLayerDefn = GetLayerDefn(); 149 21 : if (!bGeomTypeSet) 150 : { 151 8 : bGeomTypeSet = TRUE; 152 16 : whileUnsealing(poLayerDefn) 153 8 : ->SetGeomType(poGeom->getGeometryType()); 154 : } 155 13 : else if (poLayerDefn->GetGeomType() != poGeom->getGeometryType()) 156 : { 157 5 : bGeomTypeMixed = TRUE; 158 5 : whileUnsealing(poLayerDefn)->SetGeomType(wkbUnknown); 159 : } 160 : } 161 62 : ICreateFeature(poFeature); 162 : 163 62 : delete poFeature; 164 : } 165 8 : } 166 : 167 : /************************************************************************/ 168 : /* TestCapability() */ 169 : /************************************************************************/ 170 : 171 150 : int OGRPDFLayer::TestCapability(const char *pszCap) 172 : 173 : { 174 150 : if (EQUAL(pszCap, OLCStringsAsUTF8)) 175 0 : return TRUE; 176 : else 177 150 : 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 56 : OGRPDFWritableLayer::OGRPDFWritableLayer(PDFWritableVectorDataset *poDSIn, 196 : const char *pszName, 197 : OGRSpatialReference *poSRS, 198 56 : OGRwkbGeometryType eGeomType) 199 56 : : OGRMemLayer(pszName, poSRS, eGeomType), poDS(poDSIn) 200 : { 201 56 : } 202 : 203 : /************************************************************************/ 204 : /* ICreateFeature() */ 205 : /************************************************************************/ 206 : 207 171 : OGRErr OGRPDFWritableLayer::ICreateFeature(OGRFeature *poFeature) 208 : { 209 171 : poDS->SetModified(); 210 171 : return OGRMemLayer::ICreateFeature(poFeature); 211 : } 212 : 213 : /************************************************************************/ 214 : /* TestCapability() */ 215 : /************************************************************************/ 216 : 217 110 : int OGRPDFWritableLayer::TestCapability(const char *pszCap) 218 : 219 : { 220 110 : if (EQUAL(pszCap, OLCStringsAsUTF8)) 221 0 : return TRUE; 222 : else 223 110 : return OGRMemLayer::TestCapability(pszCap); 224 : } 225 : 226 : /************************************************************************/ 227 : /* GetDataset() */ 228 : /************************************************************************/ 229 : 230 22 : GDALDataset *OGRPDFWritableLayer::GetDataset() 231 : { 232 22 : return poDS; 233 : }