LCOV - code coverage report
Current view: top level - frmts/pdf - ogrpdflayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 97 109 89.0 %
Date: 2024-11-21 22:18:42 Functions: 8 8 100.0 %

          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             : }

Generated by: LCOV version 1.14