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-04-28 18:08:58 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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #include "cpl_conv.h"
      31             : #include "cpl_string.h"
      32             : #include "ogr_s57.h"
      33             : 
      34             : /************************************************************************/
      35             : /*                            OGRS57Layer()                             */
      36             : /*                                                                      */
      37             : /*      Note that the OGRS57Layer assumes ownership of the passed       */
      38             : /*      OGRFeatureDefn object.                                          */
      39             : /************************************************************************/
      40             : 
      41        5402 : OGRS57Layer::OGRS57Layer(OGRS57DataSource *poDSIn, OGRFeatureDefn *poDefnIn,
      42        5402 :                          int nFeatureCountIn, int nOBJLIn)
      43             :     : poDS(poDSIn), poFeatureDefn(poDefnIn), nCurrentModule(-1),
      44             :       nRCNM(100),  // Default to feature.
      45        5402 :       nOBJL(nOBJLIn), nNextFEIndex(0), nFeatureCount(nFeatureCountIn)
      46             : {
      47        5402 :     SetDescription(poFeatureDefn->GetName());
      48        5402 :     if (poFeatureDefn->GetGeomFieldCount() > 0)
      49       10442 :         poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(
      50        5221 :             poDS->DSGetSpatialRef());
      51             : 
      52        5402 :     if (EQUAL(poDefnIn->GetName(), OGRN_VI))
      53          21 :         nRCNM = RCNM_VI;
      54        5381 :     else if (EQUAL(poDefnIn->GetName(), OGRN_VC))
      55          21 :         nRCNM = RCNM_VC;
      56        5360 :     else if (EQUAL(poDefnIn->GetName(), OGRN_VE))
      57          21 :         nRCNM = RCNM_VE;
      58        5339 :     else if (EQUAL(poDefnIn->GetName(), OGRN_VF))
      59          21 :         nRCNM = RCNM_VF;
      60        5318 :     else if (EQUAL(poDefnIn->GetName(), "DSID"))
      61          37 :         nRCNM = RCNM_DSID;
      62             :     // Leave as feature.
      63        5402 : }
      64             : 
      65             : /************************************************************************/
      66             : /*                           ~OGRS57Layer()                           */
      67             : /************************************************************************/
      68             : 
      69       10804 : OGRS57Layer::~OGRS57Layer()
      70             : 
      71             : {
      72        5402 :     if (m_nFeaturesRead > 0)
      73             :     {
      74          98 :         CPLDebug("S57", "%d features read on layer '%s'.",
      75          49 :                  static_cast<int>(m_nFeaturesRead), poFeatureDefn->GetName());
      76             :     }
      77             : 
      78        5402 :     poFeatureDefn->Release();
      79       10804 : }
      80             : 
      81             : /************************************************************************/
      82             : /*                            ResetReading()                            */
      83             : /************************************************************************/
      84             : 
      85        1093 : void OGRS57Layer::ResetReading()
      86             : 
      87             : {
      88        1093 :     nNextFEIndex = 0;
      89        1093 :     nCurrentModule = -1;
      90        1093 : }
      91             : 
      92             : /************************************************************************/
      93             : /*                      GetNextUnfilteredFeature()                      */
      94             : /************************************************************************/
      95             : 
      96        2010 : OGRFeature *OGRS57Layer::GetNextUnfilteredFeature()
      97             : 
      98             : {
      99             :     /* -------------------------------------------------------------------- */
     100             :     /*      Are we out of modules to request features from?                 */
     101             :     /* -------------------------------------------------------------------- */
     102        2010 :     if (nCurrentModule >= poDS->GetModuleCount())
     103         361 :         return nullptr;
     104             : 
     105             :     /* -------------------------------------------------------------------- */
     106             :     /*      Set the current position on the current module and fetch a      */
     107             :     /*      feature.                                                        */
     108             :     /* -------------------------------------------------------------------- */
     109        1649 :     S57Reader *poReader = poDS->GetModule(nCurrentModule);
     110        1649 :     OGRFeature *poFeature = nullptr;
     111             : 
     112        1649 :     if (poReader != nullptr)
     113             :     {
     114        1159 :         poReader->SetNextFEIndex(nNextFEIndex, nRCNM);
     115        1159 :         poFeature = poReader->ReadNextFeature(poFeatureDefn);
     116        1159 :         nNextFEIndex = poReader->GetNextFEIndex(nRCNM);
     117             :     }
     118             : 
     119             :     /* -------------------------------------------------------------------- */
     120             :     /*      If we didn't get a feature we need to move onto the next file.  */
     121             :     /* -------------------------------------------------------------------- */
     122        1649 :     if (poFeature == nullptr)
     123             :     {
     124         838 :         nCurrentModule++;
     125         838 :         poReader = poDS->GetModule(nCurrentModule);
     126             : 
     127         838 :         if (poReader != nullptr && poReader->GetModule() == nullptr)
     128             :         {
     129           0 :             if (!poReader->Open(FALSE))
     130           0 :                 return nullptr;
     131             :         }
     132             : 
     133         838 :         return GetNextUnfilteredFeature();
     134             :     }
     135             :     else
     136             :     {
     137         811 :         m_nFeaturesRead++;
     138         811 :         if (poFeature->GetGeometryRef() != nullptr)
     139         772 :             poFeature->GetGeometryRef()->assignSpatialReference(
     140         772 :                 GetSpatialRef());
     141             :     }
     142             : 
     143         811 :     return poFeature;
     144             : }
     145             : 
     146             : /************************************************************************/
     147             : /*                           GetNextFeature()                           */
     148             : /************************************************************************/
     149             : 
     150         945 : OGRFeature *OGRS57Layer::GetNextFeature()
     151             : 
     152             : {
     153         945 :     OGRFeature *poFeature = nullptr;
     154             : 
     155             :     /* -------------------------------------------------------------------- */
     156             :     /*      Read features till we find one that satisfies our current       */
     157             :     /*      spatial criteria.                                               */
     158             :     /* -------------------------------------------------------------------- */
     159             :     while (true)
     160             :     {
     161        1172 :         poFeature = GetNextUnfilteredFeature();
     162        1172 :         if (poFeature == nullptr)
     163         361 :             break;
     164             : 
     165        1853 :         if ((m_poFilterGeom == nullptr ||
     166        1528 :              FilterGeometry(poFeature->GetGeometryRef())) &&
     167         717 :             (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
     168         584 :             break;
     169             : 
     170         227 :         delete poFeature;
     171             :     }
     172             : 
     173         945 :     return poFeature;
     174             : }
     175             : 
     176             : /************************************************************************/
     177             : /*                           TestCapability()                           */
     178             : /************************************************************************/
     179             : 
     180         759 : int OGRS57Layer::TestCapability(const char *pszCap)
     181             : 
     182             : {
     183         759 :     if (EQUAL(pszCap, OLCRandomRead))
     184           0 :         return false;
     185             : 
     186         759 :     if (EQUAL(pszCap, OLCSequentialWrite))
     187          13 :         return true;
     188             : 
     189         746 :     if (EQUAL(pszCap, OLCRandomWrite))
     190          13 :         return false;
     191             : 
     192         733 :     if (EQUAL(pszCap, OLCFastFeatureCount))
     193         231 :         return !(
     194         231 :             m_poFilterGeom != nullptr || m_poAttrQuery != nullptr ||
     195         157 :             nFeatureCount == -1 ||
     196         144 :             (EQUAL(poFeatureDefn->GetName(), "SOUNDG") &&
     197          12 :              poDS->GetModule(0) != nullptr &&
     198         243 :              (poDS->GetModule(0)->GetOptionFlags() & S57M_SPLIT_MULTIPOINT)));
     199             : 
     200         502 :     if (EQUAL(pszCap, OLCFastGetExtent))
     201             :     {
     202          24 :         OGREnvelope oEnvelope;
     203             : 
     204          24 :         return GetExtent(&oEnvelope, FALSE) == OGRERR_NONE;
     205             :     }
     206             : 
     207         478 :     if (EQUAL(pszCap, OLCFastSpatialFilter))
     208           0 :         return false;
     209             : 
     210         478 :     if (EQUAL(pszCap, OLCStringsAsUTF8))
     211             :     {
     212         306 :         return poDS->GetModule(0) != nullptr &&
     213         306 :                (poDS->GetModule(0)->GetOptionFlags() & S57M_RECODE_BY_DSSI);
     214             :     }
     215             : 
     216         325 :     if (EQUAL(pszCap, OLCZGeometries))
     217          39 :         return true;
     218             : 
     219         286 :     return false;
     220             : }
     221             : 
     222             : /************************************************************************/
     223             : /*                             GetExtent()                              */
     224             : /************************************************************************/
     225             : 
     226          73 : OGRErr OGRS57Layer::GetExtent(OGREnvelope *psExtent, int bForce)
     227             : 
     228             : {
     229          73 :     if (GetGeomType() == wkbNone)
     230           1 :         return OGRERR_FAILURE;
     231             : 
     232          72 :     return poDS->GetDSExtent(psExtent, bForce);
     233             : }
     234             : 
     235             : /************************************************************************/
     236             : /*                          GetFeatureCount()                           */
     237             : /************************************************************************/
     238         231 : GIntBig OGRS57Layer::GetFeatureCount(int bForce)
     239             : {
     240             : 
     241         231 :     if (!TestCapability(OLCFastFeatureCount))
     242          87 :         return OGRLayer::GetFeatureCount(bForce);
     243             : 
     244         144 :     return nFeatureCount;
     245             : }
     246             : 
     247             : /************************************************************************/
     248             : /*                             GetFeature()                             */
     249             : /************************************************************************/
     250             : 
     251          64 : OGRFeature *OGRS57Layer::GetFeature(GIntBig nFeatureId)
     252             : 
     253             : {
     254          64 :     S57Reader *poReader = poDS->GetModule(0);  // not multi-reader aware
     255             : 
     256          64 :     if (poReader != nullptr && nFeatureId <= INT_MAX)
     257             :     {
     258             :         OGRFeature *poFeature =
     259          51 :             poReader->ReadFeature(static_cast<int>(nFeatureId), poFeatureDefn);
     260             : 
     261          51 :         if (poFeature != nullptr && poFeature->GetGeometryRef() != nullptr)
     262          24 :             poFeature->GetGeometryRef()->assignSpatialReference(
     263          24 :                 GetSpatialRef());
     264          51 :         return poFeature;
     265             :     }
     266             : 
     267          13 :     return nullptr;
     268             : }
     269             : 
     270             : /************************************************************************/
     271             : /*                           ICreateFeature()                            */
     272             : /************************************************************************/
     273             : 
     274         118 : OGRErr OGRS57Layer::ICreateFeature(OGRFeature *poFeature)
     275             : 
     276             : {
     277             :     /* -------------------------------------------------------------------- */
     278             :     /*      Set RCNM if not already set.                                    */
     279             :     /* -------------------------------------------------------------------- */
     280         118 :     const int iRCNMFld = poFeature->GetFieldIndex("RCNM");
     281             : 
     282         118 :     if (iRCNMFld != -1)
     283             :     {
     284          94 :         if (!poFeature->IsFieldSetAndNotNull(iRCNMFld))
     285           0 :             poFeature->SetField(iRCNMFld, nRCNM);
     286             :         else
     287             :         {
     288          94 :             CPLAssert(poFeature->GetFieldAsInteger(iRCNMFld) == nRCNM);
     289             :         }
     290             :     }
     291             : 
     292             :     /* -------------------------------------------------------------------- */
     293             :     /*      Set OBJL if not already set.                                    */
     294             :     /* -------------------------------------------------------------------- */
     295         118 :     if (nOBJL != -1)
     296             :     {
     297          24 :         const int iOBJLFld = poFeature->GetFieldIndex("OBJL");
     298             : 
     299          24 :         if (!poFeature->IsFieldSetAndNotNull(iOBJLFld))
     300           0 :             poFeature->SetField(iOBJLFld, nOBJL);
     301             :         else
     302             :         {
     303          24 :             CPLAssert(poFeature->GetFieldAsInteger(iOBJLFld) == nOBJL);
     304             :         }
     305             :     }
     306             : 
     307             :     /* -------------------------------------------------------------------- */
     308             :     /*      Create the isolated node feature.                               */
     309             :     /* -------------------------------------------------------------------- */
     310         118 :     if (poDS->GetWriter()->WriteCompleteFeature(poFeature))
     311         118 :         return OGRERR_NONE;
     312             : 
     313           0 :     return OGRERR_FAILURE;
     314             : }

Generated by: LCOV version 1.14