LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/vfk - ogrvfklayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 72 83 86.7 %
Date: 2024-11-21 22:18:42 Functions: 10 10 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements OGRVFKLayer class.
       5             :  * Author:   Martin Landa, landa.martin gmail.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2009-2010, Martin Landa <landa.martin gmail.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "ogr_vfk.h"
      14             : #include "cpl_conv.h"
      15             : #include "cpl_string.h"
      16             : 
      17             : /*!
      18             :   \brief OGRVFKLayer constructor
      19             : 
      20             :   \param pszName layer name
      21             :   \param poSRSIn spatial reference
      22             :   \param eReqType WKB geometry type
      23             :   \param poDSIn  data source where to register OGR layer
      24             : */
      25         976 : OGRVFKLayer::OGRVFKLayer(const char *pszName, OGRSpatialReference *poSRSIn,
      26         976 :                          OGRwkbGeometryType eReqType, OGRVFKDataSource *poDSIn)
      27         976 :     : poSRS(poSRSIn == nullptr ? new OGRSpatialReference() : poSRSIn->Clone()),
      28         976 :       poFeatureDefn(new OGRFeatureDefn(pszName)),
      29        2928 :       poDataBlock(poDSIn->GetReader()->GetDataBlock(pszName)), m_iNextFeature(0)
      30             : {
      31         976 :     poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
      32             : 
      33         976 :     if (poSRSIn == nullptr)
      34             :     {
      35             :         // Default is S-JTSK (EPSG: 5514).
      36         976 :         if (poSRS->importFromEPSG(5514) != OGRERR_NONE)
      37             :         {
      38           0 :             delete poSRS;
      39           0 :             poSRS = nullptr;
      40             :         }
      41             :     }
      42             : 
      43         976 :     SetDescription(poFeatureDefn->GetName());
      44         976 :     poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
      45             : 
      46         976 :     poFeatureDefn->Reference();
      47         976 :     poFeatureDefn->SetGeomType(eReqType);
      48         976 : }
      49             : 
      50             : /*!
      51             :   \brief OGRVFKLayer() destructor
      52             : */
      53        1952 : OGRVFKLayer::~OGRVFKLayer()
      54             : {
      55         976 :     if (poFeatureDefn)
      56         976 :         poFeatureDefn->Release();
      57             : 
      58         976 :     if (poSRS)
      59         976 :         poSRS->Release();
      60        1952 : }
      61             : 
      62             : /*!
      63             :   \brief Test capability (random access, etc.)
      64             : 
      65             :   \param pszCap capability name
      66             : */
      67           2 : int OGRVFKLayer::TestCapability(const char *pszCap)
      68             : {
      69           2 :     if (EQUAL(pszCap, OLCRandomRead))
      70             :     {
      71           0 :         return TRUE; /* ? */
      72             :     }
      73           2 :     if (EQUAL(pszCap, OLCStringsAsUTF8))
      74             :     {
      75           2 :         return TRUE;
      76             :     }
      77             : 
      78           0 :     return FALSE;
      79             : }
      80             : 
      81             : /*!
      82             :   \brief Reset reading
      83             : 
      84             :   \todo To be implemented
      85             : */
      86           7 : void OGRVFKLayer::ResetReading()
      87             : {
      88           7 :     m_iNextFeature = 0;
      89           7 :     poDataBlock->ResetReading();
      90           7 : }
      91             : 
      92             : /*!
      93             :   \brief Get geometry from VFKFeature
      94             : 
      95             :   \param poVfkFeature pointer to VFKFeature
      96             : 
      97             :   \return pointer to OGRGeometry or NULL on error
      98             : */
      99          31 : const OGRGeometry *OGRVFKLayer::GetGeometry(IVFKFeature *poVfkFeature)
     100             : {
     101          31 :     return poVfkFeature->GetGeometry();
     102             : }
     103             : 
     104             : /*!
     105             :   \brief Get feature count
     106             : 
     107             :   This method overwrites OGRLayer::GetFeatureCount(),
     108             : 
     109             :   \param bForce skip (return -1)
     110             : 
     111             :   \return number of features
     112             : */
     113           3 : GIntBig OGRVFKLayer::GetFeatureCount(CPL_UNUSED int bForce)
     114             : {
     115             :     /* note that 'nfeatures' is 0 when data are not read from DB */
     116           3 :     int nfeatures = (int)poDataBlock->GetFeatureCount();
     117           3 :     if (m_poFilterGeom || m_poAttrQuery || nfeatures < 1)
     118             :     {
     119             :         /* force real feature count */
     120           0 :         nfeatures = (int)OGRLayer::GetFeatureCount();
     121             :     }
     122             : 
     123           3 :     CPLDebug("OGR-VFK", "OGRVFKLayer::GetFeatureCount(): name=%s -> n=%d",
     124           3 :              GetName(), nfeatures);
     125             : 
     126           3 :     return nfeatures;
     127             : }
     128             : 
     129             : /*!
     130             :   \brief Get next feature
     131             : 
     132             :   \return pointer to OGRFeature instance
     133             : */
     134           9 : OGRFeature *OGRVFKLayer::GetNextFeature()
     135             : {
     136             :     /* loop till we find and translate a feature meeting all our
     137             :        requirements
     138             :     */
     139           9 :     if (m_iNextFeature < 1 && m_poFilterGeom == nullptr &&
     140           6 :         m_poAttrQuery == nullptr)
     141             :     {
     142             :         /* sequential feature properties access only supported when no
     143             :         filter enabled */
     144           4 :         poDataBlock->LoadProperties();
     145             :     }
     146             :     while (true)
     147             :     {
     148          33 :         IVFKFeature *poVFKFeature = poDataBlock->GetNextFeature();
     149          33 :         if (!poVFKFeature)
     150             :         {
     151             :             /* clean loaded feature properties for a next run */
     152           3 :             poDataBlock->CleanProperties();
     153           3 :             return nullptr;
     154             :         }
     155             : 
     156             :         /* skip feature with unknown geometry type */
     157          30 :         if (poVFKFeature->GetGeometryType() == wkbUnknown)
     158           0 :             continue;
     159             : 
     160          30 :         OGRFeature *poOGRFeature = GetFeature(poVFKFeature);
     161          30 :         if (poOGRFeature)
     162           6 :             return poOGRFeature;
     163          24 :     }
     164             : }
     165             : 
     166             : /*!
     167             :   \brief Get feature by fid
     168             : 
     169             :   \param nFID feature id (-1 for next)
     170             : 
     171             :   \return pointer to OGRFeature or NULL not found
     172             : */
     173           1 : OGRFeature *OGRVFKLayer::GetFeature(GIntBig nFID)
     174             : {
     175           1 :     IVFKFeature *poVFKFeature = poDataBlock->GetFeature(nFID);
     176             : 
     177           1 :     if (!poVFKFeature)
     178           0 :         return nullptr;
     179             : 
     180             :     /* clean loaded feature properties (sequential access not
     181             :        finished) */
     182           1 :     if (m_iNextFeature > 0)
     183             :     {
     184           0 :         ResetReading();
     185           0 :         poDataBlock->CleanProperties();
     186             :     }
     187             : 
     188           1 :     CPLAssert(nFID == poVFKFeature->GetFID());
     189           1 :     CPLDebug("OGR-VFK", "OGRVFKLayer::GetFeature(): name=%s fid=" CPL_FRMT_GIB,
     190           1 :              GetName(), nFID);
     191             : 
     192           1 :     return GetFeature(poVFKFeature);
     193             : }
     194             : 
     195             : /*!
     196             :   \brief Get feature (private)
     197             : 
     198             :   \return pointer to OGRFeature or NULL not found
     199             : */
     200          31 : OGRFeature *OGRVFKLayer::GetFeature(IVFKFeature *poVFKFeature)
     201             : {
     202             :     /* skip feature with unknown geometry type */
     203          31 :     if (poVFKFeature->GetGeometryType() == wkbUnknown)
     204           0 :         return nullptr;
     205             : 
     206             :     /* get features geometry */
     207          31 :     const OGRGeometry *poGeomRef = GetGeometry(poVFKFeature);
     208             : 
     209             :     /* does it satisfy the spatial query, if there is one? */
     210          31 :     if (m_poFilterGeom != nullptr && poGeomRef && !FilterGeometry(poGeomRef))
     211             :     {
     212           0 :         return nullptr;
     213             :     }
     214             : 
     215             :     /* convert the whole feature into an OGRFeature */
     216          31 :     OGRFeature *poOGRFeature = new OGRFeature(GetLayerDefn());
     217          31 :     poOGRFeature->SetFID(poVFKFeature->GetFID());
     218          31 :     poVFKFeature->LoadProperties(poOGRFeature);
     219             : 
     220             :     /* test against the attribute query */
     221          31 :     if (m_poAttrQuery != nullptr && !m_poAttrQuery->Evaluate(poOGRFeature))
     222             :     {
     223          24 :         delete poOGRFeature;
     224          24 :         return nullptr;
     225             :     }
     226             : 
     227           7 :     if (poGeomRef)
     228             :     {
     229           7 :         auto poGeom = poGeomRef->clone();
     230           7 :         poGeom->assignSpatialReference(poSRS);
     231           7 :         poOGRFeature->SetGeometryDirectly(poGeom);
     232             :     }
     233             : 
     234           7 :     m_iNextFeature++;
     235             : 
     236           7 :     return poOGRFeature;
     237             : }

Generated by: LCOV version 1.14