LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/s57 - ogrs57layer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 109 116 94.0 %
Date: 2024-11-25 13:07:18 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  S-57 Translator
       4             :  * Purpose:  Implements OGRS57Layer class.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1999, Frank Warmerdam
       9             :  * Copyright (c) 2009-2014, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_conv.h"
      15             : #include "cpl_string.h"
      16             : #include "ogr_s57.h"
      17             : 
      18             : /************************************************************************/
      19             : /*                            OGRS57Layer()                             */
      20             : /*                                                                      */
      21             : /*      Note that the OGRS57Layer assumes ownership of the passed       */
      22             : /*      OGRFeatureDefn object.                                          */
      23             : /************************************************************************/
      24             : 
      25        5402 : OGRS57Layer::OGRS57Layer(OGRS57DataSource *poDSIn, OGRFeatureDefn *poDefnIn,
      26        5402 :                          int nFeatureCountIn, int nOBJLIn)
      27             :     : poDS(poDSIn), poFeatureDefn(poDefnIn), nCurrentModule(-1),
      28             :       nRCNM(100),  // Default to feature.
      29        5402 :       nOBJL(nOBJLIn), nNextFEIndex(0), nFeatureCount(nFeatureCountIn)
      30             : {
      31        5402 :     SetDescription(poFeatureDefn->GetName());
      32        5402 :     if (poFeatureDefn->GetGeomFieldCount() > 0)
      33       10442 :         poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(
      34        5221 :             poDS->DSGetSpatialRef());
      35             : 
      36        5402 :     if (EQUAL(poDefnIn->GetName(), OGRN_VI))
      37          21 :         nRCNM = RCNM_VI;
      38        5381 :     else if (EQUAL(poDefnIn->GetName(), OGRN_VC))
      39          21 :         nRCNM = RCNM_VC;
      40        5360 :     else if (EQUAL(poDefnIn->GetName(), OGRN_VE))
      41          21 :         nRCNM = RCNM_VE;
      42        5339 :     else if (EQUAL(poDefnIn->GetName(), OGRN_VF))
      43          21 :         nRCNM = RCNM_VF;
      44        5318 :     else if (EQUAL(poDefnIn->GetName(), "DSID"))
      45          37 :         nRCNM = RCNM_DSID;
      46             :     // Leave as feature.
      47        5402 : }
      48             : 
      49             : /************************************************************************/
      50             : /*                           ~OGRS57Layer()                           */
      51             : /************************************************************************/
      52             : 
      53       10804 : OGRS57Layer::~OGRS57Layer()
      54             : 
      55             : {
      56        5402 :     if (m_nFeaturesRead > 0)
      57             :     {
      58          98 :         CPLDebug("S57", "%d features read on layer '%s'.",
      59          49 :                  static_cast<int>(m_nFeaturesRead), poFeatureDefn->GetName());
      60             :     }
      61             : 
      62        5402 :     poFeatureDefn->Release();
      63       10804 : }
      64             : 
      65             : /************************************************************************/
      66             : /*                            ResetReading()                            */
      67             : /************************************************************************/
      68             : 
      69        1093 : void OGRS57Layer::ResetReading()
      70             : 
      71             : {
      72        1093 :     nNextFEIndex = 0;
      73        1093 :     nCurrentModule = -1;
      74        1093 : }
      75             : 
      76             : /************************************************************************/
      77             : /*                      GetNextUnfilteredFeature()                      */
      78             : /************************************************************************/
      79             : 
      80        2010 : OGRFeature *OGRS57Layer::GetNextUnfilteredFeature()
      81             : 
      82             : {
      83             :     /* -------------------------------------------------------------------- */
      84             :     /*      Are we out of modules to request features from?                 */
      85             :     /* -------------------------------------------------------------------- */
      86        2010 :     if (nCurrentModule >= poDS->GetModuleCount())
      87         361 :         return nullptr;
      88             : 
      89             :     /* -------------------------------------------------------------------- */
      90             :     /*      Set the current position on the current module and fetch a      */
      91             :     /*      feature.                                                        */
      92             :     /* -------------------------------------------------------------------- */
      93        1649 :     S57Reader *poReader = poDS->GetModule(nCurrentModule);
      94        1649 :     OGRFeature *poFeature = nullptr;
      95             : 
      96        1649 :     if (poReader != nullptr)
      97             :     {
      98        1159 :         poReader->SetNextFEIndex(nNextFEIndex, nRCNM);
      99        1159 :         poFeature = poReader->ReadNextFeature(poFeatureDefn);
     100        1159 :         nNextFEIndex = poReader->GetNextFEIndex(nRCNM);
     101             :     }
     102             : 
     103             :     /* -------------------------------------------------------------------- */
     104             :     /*      If we didn't get a feature we need to move onto the next file.  */
     105             :     /* -------------------------------------------------------------------- */
     106        1649 :     if (poFeature == nullptr)
     107             :     {
     108         838 :         nCurrentModule++;
     109         838 :         poReader = poDS->GetModule(nCurrentModule);
     110             : 
     111         838 :         if (poReader != nullptr && poReader->GetModule() == nullptr)
     112             :         {
     113           0 :             if (!poReader->Open(FALSE))
     114           0 :                 return nullptr;
     115             :         }
     116             : 
     117         838 :         return GetNextUnfilteredFeature();
     118             :     }
     119             :     else
     120             :     {
     121         811 :         m_nFeaturesRead++;
     122         811 :         if (poFeature->GetGeometryRef() != nullptr)
     123         772 :             poFeature->GetGeometryRef()->assignSpatialReference(
     124         772 :                 GetSpatialRef());
     125             :     }
     126             : 
     127         811 :     return poFeature;
     128             : }
     129             : 
     130             : /************************************************************************/
     131             : /*                           GetNextFeature()                           */
     132             : /************************************************************************/
     133             : 
     134         945 : OGRFeature *OGRS57Layer::GetNextFeature()
     135             : 
     136             : {
     137         945 :     OGRFeature *poFeature = nullptr;
     138             : 
     139             :     /* -------------------------------------------------------------------- */
     140             :     /*      Read features till we find one that satisfies our current       */
     141             :     /*      spatial criteria.                                               */
     142             :     /* -------------------------------------------------------------------- */
     143             :     while (true)
     144             :     {
     145        1172 :         poFeature = GetNextUnfilteredFeature();
     146        1172 :         if (poFeature == nullptr)
     147         361 :             break;
     148             : 
     149        1853 :         if ((m_poFilterGeom == nullptr ||
     150        1528 :              FilterGeometry(poFeature->GetGeometryRef())) &&
     151         717 :             (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
     152         584 :             break;
     153             : 
     154         227 :         delete poFeature;
     155             :     }
     156             : 
     157         945 :     return poFeature;
     158             : }
     159             : 
     160             : /************************************************************************/
     161             : /*                           TestCapability()                           */
     162             : /************************************************************************/
     163             : 
     164         759 : int OGRS57Layer::TestCapability(const char *pszCap)
     165             : 
     166             : {
     167         759 :     if (EQUAL(pszCap, OLCRandomRead))
     168           0 :         return false;
     169             : 
     170         759 :     if (EQUAL(pszCap, OLCSequentialWrite))
     171          13 :         return true;
     172             : 
     173         746 :     if (EQUAL(pszCap, OLCRandomWrite))
     174          13 :         return false;
     175             : 
     176         733 :     if (EQUAL(pszCap, OLCFastFeatureCount))
     177         231 :         return !(
     178         231 :             m_poFilterGeom != nullptr || m_poAttrQuery != nullptr ||
     179         157 :             nFeatureCount == -1 ||
     180         144 :             (EQUAL(poFeatureDefn->GetName(), "SOUNDG") &&
     181          12 :              poDS->GetModule(0) != nullptr &&
     182         243 :              (poDS->GetModule(0)->GetOptionFlags() & S57M_SPLIT_MULTIPOINT)));
     183             : 
     184         502 :     if (EQUAL(pszCap, OLCFastGetExtent))
     185             :     {
     186          24 :         OGREnvelope oEnvelope;
     187             : 
     188          24 :         return GetExtent(&oEnvelope, FALSE) == OGRERR_NONE;
     189             :     }
     190             : 
     191         478 :     if (EQUAL(pszCap, OLCFastSpatialFilter))
     192           0 :         return false;
     193             : 
     194         478 :     if (EQUAL(pszCap, OLCStringsAsUTF8))
     195             :     {
     196         306 :         return poDS->GetModule(0) != nullptr &&
     197         306 :                (poDS->GetModule(0)->GetOptionFlags() & S57M_RECODE_BY_DSSI);
     198             :     }
     199             : 
     200         325 :     if (EQUAL(pszCap, OLCZGeometries))
     201          39 :         return true;
     202             : 
     203         286 :     return false;
     204             : }
     205             : 
     206             : /************************************************************************/
     207             : /*                             GetExtent()                              */
     208             : /************************************************************************/
     209             : 
     210          73 : OGRErr OGRS57Layer::GetExtent(OGREnvelope *psExtent, int bForce)
     211             : 
     212             : {
     213          73 :     if (GetGeomType() == wkbNone)
     214           1 :         return OGRERR_FAILURE;
     215             : 
     216          72 :     return poDS->GetDSExtent(psExtent, bForce);
     217             : }
     218             : 
     219             : /************************************************************************/
     220             : /*                          GetFeatureCount()                           */
     221             : /************************************************************************/
     222         231 : GIntBig OGRS57Layer::GetFeatureCount(int bForce)
     223             : {
     224             : 
     225         231 :     if (!TestCapability(OLCFastFeatureCount))
     226          87 :         return OGRLayer::GetFeatureCount(bForce);
     227             : 
     228         144 :     return nFeatureCount;
     229             : }
     230             : 
     231             : /************************************************************************/
     232             : /*                             GetFeature()                             */
     233             : /************************************************************************/
     234             : 
     235          64 : OGRFeature *OGRS57Layer::GetFeature(GIntBig nFeatureId)
     236             : 
     237             : {
     238          64 :     S57Reader *poReader = poDS->GetModule(0);  // not multi-reader aware
     239             : 
     240          64 :     if (poReader != nullptr && nFeatureId <= INT_MAX)
     241             :     {
     242             :         OGRFeature *poFeature =
     243          51 :             poReader->ReadFeature(static_cast<int>(nFeatureId), poFeatureDefn);
     244             : 
     245          51 :         if (poFeature != nullptr && poFeature->GetGeometryRef() != nullptr)
     246          24 :             poFeature->GetGeometryRef()->assignSpatialReference(
     247          24 :                 GetSpatialRef());
     248          51 :         return poFeature;
     249             :     }
     250             : 
     251          13 :     return nullptr;
     252             : }
     253             : 
     254             : /************************************************************************/
     255             : /*                           ICreateFeature()                            */
     256             : /************************************************************************/
     257             : 
     258         118 : OGRErr OGRS57Layer::ICreateFeature(OGRFeature *poFeature)
     259             : 
     260             : {
     261             :     /* -------------------------------------------------------------------- */
     262             :     /*      Set RCNM if not already set.                                    */
     263             :     /* -------------------------------------------------------------------- */
     264         118 :     const int iRCNMFld = poFeature->GetFieldIndex("RCNM");
     265             : 
     266         118 :     if (iRCNMFld != -1)
     267             :     {
     268          94 :         if (!poFeature->IsFieldSetAndNotNull(iRCNMFld))
     269           0 :             poFeature->SetField(iRCNMFld, nRCNM);
     270             :         else
     271             :         {
     272          94 :             CPLAssert(poFeature->GetFieldAsInteger(iRCNMFld) == nRCNM);
     273             :         }
     274             :     }
     275             : 
     276             :     /* -------------------------------------------------------------------- */
     277             :     /*      Set OBJL if not already set.                                    */
     278             :     /* -------------------------------------------------------------------- */
     279         118 :     if (nOBJL != -1)
     280             :     {
     281          24 :         const int iOBJLFld = poFeature->GetFieldIndex("OBJL");
     282             : 
     283          24 :         if (!poFeature->IsFieldSetAndNotNull(iOBJLFld))
     284           0 :             poFeature->SetField(iOBJLFld, nOBJL);
     285             :         else
     286             :         {
     287          24 :             CPLAssert(poFeature->GetFieldAsInteger(iOBJLFld) == nOBJL);
     288             :         }
     289             :     }
     290             : 
     291             :     /* -------------------------------------------------------------------- */
     292             :     /*      Create the isolated node feature.                               */
     293             :     /* -------------------------------------------------------------------- */
     294         118 :     if (poDS->GetWriter()->WriteCompleteFeature(poFeature))
     295         118 :         return OGRERR_NONE;
     296             : 
     297           0 :     return OGRERR_FAILURE;
     298             : }

Generated by: LCOV version 1.14