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-05-03 15:49:35 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             :  * 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             : }

Generated by: LCOV version 1.14