LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/s57 - ogrs57datasource.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 181 219 82.6 %
Date: 2024-04-28 18:08:58 Functions: 11 12 91.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  S-57 Translator
       4             :  * Purpose:  Implements OGRS57DataSource class
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1999, Frank Warmerdam
       9             :  * Copyright (c) 2010-2013, 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             : #include <algorithm>
      35             : #include <set>
      36             : 
      37             : /************************************************************************/
      38             : /*                          OGRS57DataSource()                          */
      39             : /************************************************************************/
      40             : 
      41          56 : OGRS57DataSource::OGRS57DataSource(char **papszOpenOptionsIn)
      42             :     : pszName(nullptr), nLayers(0), papoLayers(nullptr),
      43          56 :       poSpatialRef(new OGRSpatialReference()), papszOptions(nullptr),
      44             :       nModules(0), papoModules(nullptr), poWriter(nullptr),
      45         112 :       poClassContentExplorer(nullptr), bExtentsSet(false)
      46             : {
      47          56 :     poSpatialRef->SetWellKnownGeogCS("WGS84");
      48          56 :     poSpatialRef->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
      49             : 
      50             :     /* -------------------------------------------------------------------- */
      51             :     /*      Allow initialization of options from the environment.           */
      52             :     /* -------------------------------------------------------------------- */
      53          56 :     const char *pszOptString = CPLGetConfigOption("OGR_S57_OPTIONS", nullptr);
      54             : 
      55          56 :     if (pszOptString != nullptr)
      56             :     {
      57           4 :         papszOptions =
      58           4 :             CSLTokenizeStringComplex(pszOptString, ",", FALSE, FALSE);
      59             : 
      60           4 :         if (papszOptions && *papszOptions)
      61             :         {
      62           4 :             CPLDebug("S57", "The following S57 options are being set:");
      63           4 :             char **papszCurOption = papszOptions;
      64          16 :             while (*papszCurOption)
      65          12 :                 CPLDebug("S57", "    %s", *papszCurOption++);
      66             :         }
      67             :     }
      68             : 
      69             :     /* -------------------------------------------------------------------- */
      70             :     /*      And from open options.                                          */
      71             :     /* -------------------------------------------------------------------- */
      72          57 :     for (char **papszIter = papszOpenOptionsIn; papszIter && *papszIter;
      73             :          ++papszIter)
      74             :     {
      75           1 :         char *pszKey = nullptr;
      76           1 :         const char *pszValue = CPLParseNameValue(*papszIter, &pszKey);
      77           1 :         if (pszKey && pszValue)
      78             :         {
      79           1 :             papszOptions = CSLSetNameValue(papszOptions, pszKey, pszValue);
      80             :         }
      81           1 :         CPLFree(pszKey);
      82             :     }
      83          56 : }
      84             : 
      85             : /************************************************************************/
      86             : /*                         ~OGRS57DataSource()                          */
      87             : /************************************************************************/
      88             : 
      89         112 : OGRS57DataSource::~OGRS57DataSource()
      90             : 
      91             : {
      92        5458 :     for (int i = 0; i < nLayers; i++)
      93        5402 :         delete papoLayers[i];
      94             : 
      95          56 :     CPLFree(papoLayers);
      96             : 
      97          93 :     for (int i = 0; i < nModules; i++)
      98          37 :         delete papoModules[i];
      99          56 :     CPLFree(papoModules);
     100             : 
     101          56 :     CPLFree(pszName);
     102             : 
     103          56 :     CSLDestroy(papszOptions);
     104             : 
     105          56 :     poSpatialRef->Release();
     106             : 
     107          56 :     if (poWriter != nullptr)
     108             :     {
     109          19 :         poWriter->Close();
     110          19 :         delete poWriter;
     111             :     }
     112          56 :     delete poClassContentExplorer;
     113         112 : }
     114             : 
     115             : /************************************************************************/
     116             : /*                           SetOptionList()                            */
     117             : /************************************************************************/
     118             : 
     119           0 : void OGRS57DataSource::SetOptionList(char **papszNewOptions)
     120             : 
     121             : {
     122           0 :     CSLDestroy(papszOptions);
     123           0 :     papszOptions = CSLDuplicate(papszNewOptions);
     124           0 : }
     125             : 
     126             : /************************************************************************/
     127             : /*                             GetOption()                              */
     128             : /************************************************************************/
     129             : 
     130         451 : const char *OGRS57DataSource::GetOption(const char *pszOption)
     131             : 
     132             : {
     133         451 :     return CSLFetchNameValue(papszOptions, pszOption);
     134             : }
     135             : 
     136             : /************************************************************************/
     137             : /*                           TestCapability()                           */
     138             : /************************************************************************/
     139             : 
     140          73 : int OGRS57DataSource::TestCapability(const char *pszCap)
     141             : 
     142             : {
     143          73 :     if (EQUAL(pszCap, ODsCZGeometries))
     144          26 :         return true;
     145             : 
     146          47 :     return false;
     147             : }
     148             : 
     149             : /************************************************************************/
     150             : /*                                Open()                                */
     151             : /************************************************************************/
     152             : 
     153          37 : int OGRS57DataSource::Open(const char *pszFilename)
     154             : 
     155             : {
     156          37 :     pszName = CPLStrdup(pszFilename);
     157             : 
     158             :     /* -------------------------------------------------------------------- */
     159             :     /*      Setup reader options.                                           */
     160             :     /* -------------------------------------------------------------------- */
     161          37 :     char **papszReaderOptions = nullptr;
     162             : 
     163          37 :     if (GetOption(S57O_LNAM_REFS) == nullptr)
     164             :         papszReaderOptions =
     165          35 :             CSLSetNameValue(papszReaderOptions, S57O_LNAM_REFS, "ON");
     166             :     else
     167           2 :         papszReaderOptions = CSLSetNameValue(papszReaderOptions, S57O_LNAM_REFS,
     168             :                                              GetOption(S57O_LNAM_REFS));
     169             : 
     170          37 :     if (GetOption(S57O_UPDATES) != nullptr)
     171           0 :         papszReaderOptions = CSLSetNameValue(papszReaderOptions, S57O_UPDATES,
     172             :                                              GetOption(S57O_UPDATES));
     173             : 
     174          37 :     if (GetOption(S57O_SPLIT_MULTIPOINT) != nullptr)
     175             :         papszReaderOptions =
     176           0 :             CSLSetNameValue(papszReaderOptions, S57O_SPLIT_MULTIPOINT,
     177             :                             GetOption(S57O_SPLIT_MULTIPOINT));
     178             : 
     179          37 :     if (GetOption(S57O_ADD_SOUNDG_DEPTH) != nullptr)
     180             :         papszReaderOptions =
     181           0 :             CSLSetNameValue(papszReaderOptions, S57O_ADD_SOUNDG_DEPTH,
     182             :                             GetOption(S57O_ADD_SOUNDG_DEPTH));
     183             : 
     184          37 :     if (GetOption(S57O_PRESERVE_EMPTY_NUMBERS) != nullptr)
     185             :         papszReaderOptions =
     186           0 :             CSLSetNameValue(papszReaderOptions, S57O_PRESERVE_EMPTY_NUMBERS,
     187             :                             GetOption(S57O_PRESERVE_EMPTY_NUMBERS));
     188             : 
     189          37 :     if (GetOption(S57O_RETURN_PRIMITIVES) != nullptr)
     190             :         papszReaderOptions =
     191           3 :             CSLSetNameValue(papszReaderOptions, S57O_RETURN_PRIMITIVES,
     192             :                             GetOption(S57O_RETURN_PRIMITIVES));
     193             : 
     194          37 :     if (GetOption(S57O_RETURN_LINKAGES) != nullptr)
     195             :         papszReaderOptions =
     196           2 :             CSLSetNameValue(papszReaderOptions, S57O_RETURN_LINKAGES,
     197             :                             GetOption(S57O_RETURN_LINKAGES));
     198             : 
     199          37 :     if (GetOption(S57O_RETURN_DSID) != nullptr)
     200           0 :         papszReaderOptions = CSLSetNameValue(
     201             :             papszReaderOptions, S57O_RETURN_DSID, GetOption(S57O_RETURN_DSID));
     202             : 
     203          37 :     if (GetOption(S57O_RECODE_BY_DSSI) != nullptr)
     204             :         papszReaderOptions =
     205           0 :             CSLSetNameValue(papszReaderOptions, S57O_RECODE_BY_DSSI,
     206             :                             GetOption(S57O_RECODE_BY_DSSI));
     207             : 
     208          37 :     if (GetOption(S57O_LIST_AS_STRING) != nullptr)
     209             :         papszReaderOptions =
     210           0 :             CSLSetNameValue(papszReaderOptions, S57O_LIST_AS_STRING,
     211             :                             GetOption(S57O_LIST_AS_STRING));
     212             : 
     213          37 :     S57Reader *poModule = new S57Reader(pszFilename);
     214          37 :     bool bRet = poModule->SetOptions(papszReaderOptions);
     215          37 :     CSLDestroy(papszReaderOptions);
     216             : 
     217          37 :     if (!bRet)
     218             :     {
     219           0 :         delete poModule;
     220           0 :         return FALSE;
     221             :     }
     222             : 
     223             :     /* -------------------------------------------------------------------- */
     224             :     /*      Try opening.                                                    */
     225             :     /*                                                                      */
     226             :     /*      Eventually this should check for catalogs, and if found         */
     227             :     /*      instantiate a whole series of modules.                          */
     228             :     /* -------------------------------------------------------------------- */
     229          37 :     if (!poModule->Open(TRUE))
     230             :     {
     231           0 :         delete poModule;
     232             : 
     233           0 :         return FALSE;
     234             :     }
     235             : 
     236          37 :     bool bSuccess = true;
     237             : 
     238          37 :     nModules = 1;
     239          37 :     papoModules = static_cast<S57Reader **>(CPLMalloc(sizeof(void *)));
     240          37 :     papoModules[0] = poModule;
     241             : 
     242             :     /* -------------------------------------------------------------------- */
     243             :     /*      Add the header layers if they are called for.                   */
     244             :     /* -------------------------------------------------------------------- */
     245          37 :     if (GetOption(S57O_RETURN_DSID) == nullptr ||
     246           0 :         CPLTestBool(GetOption(S57O_RETURN_DSID)))
     247             :     {
     248          37 :         OGRFeatureDefn *poDefn = S57GenerateDSIDFeatureDefn();
     249          37 :         AddLayer(new OGRS57Layer(this, poDefn));
     250             :     }
     251             : 
     252             :     /* -------------------------------------------------------------------- */
     253             :     /*      Add the primitive layers if they are called for.                */
     254             :     /* -------------------------------------------------------------------- */
     255          37 :     if (GetOption(S57O_RETURN_PRIMITIVES) != nullptr)
     256             :     {
     257           3 :         OGRFeatureDefn *poDefn = S57GenerateVectorPrimitiveFeatureDefn(
     258             :             RCNM_VI, poModule->GetOptionFlags());
     259           3 :         AddLayer(new OGRS57Layer(this, poDefn));
     260             : 
     261           3 :         poDefn = S57GenerateVectorPrimitiveFeatureDefn(
     262             :             RCNM_VC, poModule->GetOptionFlags());
     263           3 :         AddLayer(new OGRS57Layer(this, poDefn));
     264             : 
     265           3 :         poDefn = S57GenerateVectorPrimitiveFeatureDefn(
     266             :             RCNM_VE, poModule->GetOptionFlags());
     267           3 :         AddLayer(new OGRS57Layer(this, poDefn));
     268             : 
     269           3 :         poDefn = S57GenerateVectorPrimitiveFeatureDefn(
     270             :             RCNM_VF, poModule->GetOptionFlags());
     271           3 :         AddLayer(new OGRS57Layer(this, poDefn));
     272             :     }
     273             : 
     274             :     /* -------------------------------------------------------------------- */
     275             :     /*      Initialize a layer for each type of geometry.  Eventually       */
     276             :     /*      we will do this by object class.                                */
     277             :     /* -------------------------------------------------------------------- */
     278          37 :     if (OGRS57Driver::GetS57Registrar() == nullptr)
     279             :     {
     280             :         OGRFeatureDefn *poDefn =
     281           0 :             S57GenerateGeomFeatureDefn(wkbPoint, poModule->GetOptionFlags());
     282           0 :         AddLayer(new OGRS57Layer(this, poDefn));
     283             : 
     284           0 :         poDefn = S57GenerateGeomFeatureDefn(wkbLineString,
     285             :                                             poModule->GetOptionFlags());
     286           0 :         AddLayer(new OGRS57Layer(this, poDefn));
     287             : 
     288             :         poDefn =
     289           0 :             S57GenerateGeomFeatureDefn(wkbPolygon, poModule->GetOptionFlags());
     290           0 :         AddLayer(new OGRS57Layer(this, poDefn));
     291             : 
     292             :         poDefn =
     293           0 :             S57GenerateGeomFeatureDefn(wkbNone, poModule->GetOptionFlags());
     294           0 :         AddLayer(new OGRS57Layer(this, poDefn));
     295             :     }
     296             : 
     297             :     /* -------------------------------------------------------------------- */
     298             :     /*      Initialize a feature definition for each class that actually    */
     299             :     /*      occurs in the dataset.                                          */
     300             :     /* -------------------------------------------------------------------- */
     301             :     else
     302             :     {
     303          37 :         poClassContentExplorer =
     304          37 :             new S57ClassContentExplorer(OGRS57Driver::GetS57Registrar());
     305             : 
     306          74 :         for (int iModule = 0; iModule < nModules; iModule++)
     307          37 :             papoModules[iModule]->SetClassBased(OGRS57Driver::GetS57Registrar(),
     308             :                                                 poClassContentExplorer);
     309             : 
     310          74 :         std::vector<int> anClassCount;
     311             : 
     312          74 :         for (int iModule = 0; iModule < nModules; iModule++)
     313             :         {
     314          74 :             bSuccess &= CPL_TO_BOOL(
     315          37 :                 papoModules[iModule]->CollectClassList(anClassCount));
     316             :         }
     317             : 
     318          37 :         bool bGeneric = false;
     319             : 
     320       22197 :         for (unsigned int iClass = 0; iClass < anClassCount.size(); iClass++)
     321             :         {
     322       22160 :             if (anClassCount[iClass] > 0)
     323             :             {
     324         187 :                 OGRFeatureDefn *poDefn = S57GenerateObjectClassDefn(
     325             :                     OGRS57Driver::GetS57Registrar(), poClassContentExplorer,
     326             :                     iClass, poModule->GetOptionFlags());
     327             : 
     328         187 :                 if (poDefn != nullptr)
     329         187 :                     AddLayer(
     330         187 :                         new OGRS57Layer(this, poDefn, anClassCount[iClass]));
     331             :                 else
     332             :                 {
     333           0 :                     bGeneric = true;
     334           0 :                     CPLDebug("S57", "Unable to find definition for OBJL=%d\n",
     335             :                              iClass);
     336             :                 }
     337             :             }
     338             :         }
     339             : 
     340          37 :         if (bGeneric)
     341             :         {
     342           0 :             OGRFeatureDefn *poDefn = S57GenerateGeomFeatureDefn(
     343             :                 wkbUnknown, poModule->GetOptionFlags());
     344           0 :             AddLayer(new OGRS57Layer(this, poDefn));
     345             :         }
     346             :     }
     347             : 
     348             :     /* -------------------------------------------------------------------- */
     349             :     /*      Attach the layer definitions to each of the readers.            */
     350             :     /* -------------------------------------------------------------------- */
     351          74 :     for (int iModule = 0; iModule < nModules; iModule++)
     352             :     {
     353         273 :         for (int iLayer = 0; iLayer < nLayers; iLayer++)
     354             :         {
     355         236 :             papoModules[iModule]->AddFeatureDefn(
     356         236 :                 papoLayers[iLayer]->GetLayerDefn());
     357             :         }
     358             :     }
     359             : 
     360          37 :     return bSuccess;
     361             : }
     362             : 
     363             : /************************************************************************/
     364             : /*                              GetLayer()                              */
     365             : /************************************************************************/
     366             : 
     367        4255 : OGRLayer *OGRS57DataSource::GetLayer(int iLayer)
     368             : 
     369             : {
     370        4255 :     if (iLayer < 0 || iLayer >= nLayers)
     371           2 :         return nullptr;
     372             : 
     373        4253 :     return papoLayers[iLayer];
     374             : }
     375             : 
     376             : /************************************************************************/
     377             : /*                              AddLayer()                              */
     378             : /************************************************************************/
     379             : 
     380        5402 : void OGRS57DataSource::AddLayer(OGRS57Layer *poNewLayer)
     381             : 
     382             : {
     383       10804 :     papoLayers = static_cast<OGRS57Layer **>(
     384        5402 :         CPLRealloc(papoLayers, sizeof(void *) * ++nLayers));
     385             : 
     386        5402 :     papoLayers[nLayers - 1] = poNewLayer;
     387        5402 : }
     388             : 
     389             : /************************************************************************/
     390             : /*                             GetModule()                              */
     391             : /************************************************************************/
     392             : 
     393        2881 : S57Reader *OGRS57DataSource::GetModule(int i)
     394             : 
     395             : {
     396        2881 :     if (i < 0 || i >= nModules)
     397         838 :         return nullptr;
     398             : 
     399        2043 :     return papoModules[i];
     400             : }
     401             : 
     402             : /************************************************************************/
     403             : /*                            GetDSExtent()                             */
     404             : /************************************************************************/
     405             : 
     406          72 : OGRErr OGRS57DataSource::GetDSExtent(OGREnvelope *psExtent, int bForce)
     407             : 
     408             : {
     409             :     /* -------------------------------------------------------------------- */
     410             :     /*      If we have it, return it immediately.                           */
     411             :     /* -------------------------------------------------------------------- */
     412          72 :     if (bExtentsSet)
     413             :     {
     414          71 :         *psExtent = oExtents;
     415          71 :         return OGRERR_NONE;
     416             :     }
     417             : 
     418           1 :     if (nModules == 0)
     419           0 :         return OGRERR_FAILURE;
     420             : 
     421             :     /* -------------------------------------------------------------------- */
     422             :     /*      Otherwise try asking each of the readers for it.                */
     423             :     /* -------------------------------------------------------------------- */
     424           2 :     for (int iModule = 0; iModule < nModules; iModule++)
     425             :     {
     426           1 :         OGREnvelope oModuleEnvelope;
     427             : 
     428           1 :         OGRErr eErr = papoModules[iModule]->GetExtent(&oModuleEnvelope, bForce);
     429           1 :         if (eErr != OGRERR_NONE)
     430           0 :             return eErr;
     431             : 
     432           1 :         if (iModule == 0)
     433           1 :             oExtents = oModuleEnvelope;
     434             :         else
     435             :         {
     436           0 :             oExtents.MinX = std::min(oExtents.MinX, oModuleEnvelope.MinX);
     437           0 :             oExtents.MaxX = std::max(oExtents.MaxX, oModuleEnvelope.MaxX);
     438           0 :             oExtents.MinY = std::min(oExtents.MinY, oModuleEnvelope.MinY);
     439           0 :             oExtents.MaxX = std::max(oExtents.MaxY, oModuleEnvelope.MaxY);
     440             :         }
     441             :     }
     442             : 
     443           1 :     *psExtent = oExtents;
     444           1 :     bExtentsSet = true;
     445             : 
     446           1 :     return OGRERR_NONE;
     447             : }
     448             : 
     449             : /************************************************************************/
     450             : /*                               Create()                               */
     451             : /*                                                                      */
     452             : /*      Create a new S57 file, and represent it as a datasource.        */
     453             : /************************************************************************/
     454             : 
     455          19 : int OGRS57DataSource::Create(const char *pszFilename, char **papszOptionsIn)
     456             : {
     457             :     /* -------------------------------------------------------------------- */
     458             :     /*      Instantiate the class registrar if possible.                    */
     459             :     /* -------------------------------------------------------------------- */
     460          19 :     if (OGRS57Driver::GetS57Registrar() == nullptr)
     461             :     {
     462           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     463             :                  "Unable to load s57objectclasses.csv.  Unable to continue.");
     464           0 :         return FALSE;
     465             :     }
     466             : 
     467             :     /* -------------------------------------------------------------------- */
     468             :     /*      Create the S-57 file with definition record.                    */
     469             :     /* -------------------------------------------------------------------- */
     470          19 :     poWriter = new S57Writer();
     471             : 
     472          19 :     if (!poWriter->CreateS57File(pszFilename))
     473           1 :         return FALSE;
     474             : 
     475          18 :     poClassContentExplorer =
     476          18 :         new S57ClassContentExplorer(OGRS57Driver::GetS57Registrar());
     477             : 
     478          18 :     poWriter->SetClassBased(OGRS57Driver::GetS57Registrar(),
     479             :                             poClassContentExplorer);
     480          18 :     pszName = CPLStrdup(pszFilename);
     481             : 
     482             :     /* -------------------------------------------------------------------- */
     483             :     /*      Add the primitive layers if they are called for.                */
     484             :     /* -------------------------------------------------------------------- */
     485          18 :     int nOptionFlags = S57M_RETURN_LINKAGES | S57M_LNAM_REFS;
     486             : 
     487             :     OGRFeatureDefn *poDefn =
     488          18 :         S57GenerateVectorPrimitiveFeatureDefn(RCNM_VI, nOptionFlags);
     489          18 :     AddLayer(new OGRS57Layer(this, poDefn));
     490             : 
     491          18 :     poDefn = S57GenerateVectorPrimitiveFeatureDefn(RCNM_VC, nOptionFlags);
     492          18 :     AddLayer(new OGRS57Layer(this, poDefn));
     493             : 
     494          18 :     poDefn = S57GenerateVectorPrimitiveFeatureDefn(RCNM_VE, nOptionFlags);
     495          18 :     AddLayer(new OGRS57Layer(this, poDefn));
     496             : 
     497          18 :     poDefn = S57GenerateVectorPrimitiveFeatureDefn(RCNM_VF, nOptionFlags);
     498          18 :     AddLayer(new OGRS57Layer(this, poDefn));
     499             : 
     500             :     /* -------------------------------------------------------------------- */
     501             :     /*      Initialize a feature definition for each object class.          */
     502             :     /* -------------------------------------------------------------------- */
     503          18 :     poClassContentExplorer->Rewind();
     504          18 :     std::set<int> aoSetOBJL;
     505        5112 :     while (poClassContentExplorer->NextClass())
     506             :     {
     507        5094 :         const int nOBJL = poClassContentExplorer->GetOBJL();
     508             :         // Detect potential duplicates in the classes
     509        5094 :         if (aoSetOBJL.find(nOBJL) != aoSetOBJL.end())
     510             :         {
     511           0 :             CPLDebug("S57", "OBJL %d already registered!", nOBJL);
     512           0 :             continue;
     513             :         }
     514        5094 :         aoSetOBJL.insert(nOBJL);
     515        5094 :         poDefn = S57GenerateObjectClassDefn(OGRS57Driver::GetS57Registrar(),
     516             :                                             poClassContentExplorer, nOBJL,
     517             :                                             nOptionFlags);
     518             : 
     519        5094 :         AddLayer(new OGRS57Layer(this, poDefn, 0, nOBJL));
     520             :     }
     521             : 
     522             :     /* -------------------------------------------------------------------- */
     523             :     /*      Write out "header" records.                                     */
     524             :     /* -------------------------------------------------------------------- */
     525             :     int nEXPP =
     526          18 :         atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_EXPP",
     527             :                                   CPLSPrintf("%d", S57Writer::nDEFAULT_EXPP)));
     528             :     int nINTU =
     529          18 :         atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_INTU",
     530             :                                   CPLSPrintf("%d", S57Writer::nDEFAULT_INTU)));
     531          18 :     const char *pszEDTN = CSLFetchNameValue(papszOptionsIn, "S57_EDTN");
     532          18 :     const char *pszUPDN = CSLFetchNameValue(papszOptionsIn, "S57_UPDN");
     533          18 :     const char *pszUADT = CSLFetchNameValue(papszOptionsIn, "S57_UADT");
     534          18 :     const char *pszISDT = CSLFetchNameValue(papszOptionsIn, "S57_ISDT");
     535          18 :     const char *pszSTED = CSLFetchNameValue(papszOptionsIn, "S57_STED");
     536             :     int nAGEN =
     537          18 :         atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_AGEN",
     538             :                                   CPLSPrintf("%d", S57Writer::nDEFAULT_AGEN)));
     539          18 :     const char *pszCOMT = CSLFetchNameValue(papszOptionsIn, "S57_COMT");
     540          18 :     int nAALL = atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_AALL", "0"));
     541          18 :     int nNALL = atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_NALL", "0"));
     542          18 :     int nNOMR = atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_NOMR", "0"));
     543          18 :     int nNOGR = atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_NOGR", "0"));
     544          18 :     int nNOLR = atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_NOLR", "0"));
     545          18 :     int nNOIN = atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_NOIN", "0"));
     546          18 :     int nNOCN = atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_NOCN", "0"));
     547          18 :     int nNOED = atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_NOED", "0"));
     548          18 :     poWriter->WriteDSID(nEXPP, nINTU, CPLGetFilename(pszFilename), pszEDTN,
     549             :                         pszUPDN, pszUADT, pszISDT, pszSTED, nAGEN, pszCOMT,
     550             :                         nAALL, nNALL, nNOMR, nNOGR, nNOLR, nNOIN, nNOCN, nNOED);
     551             : 
     552             :     int nHDAT =
     553          18 :         atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_HDAT",
     554             :                                   CPLSPrintf("%d", S57Writer::nDEFAULT_HDAT)));
     555             :     int nVDAT =
     556          18 :         atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_VDAT",
     557             :                                   CPLSPrintf("%d", S57Writer::nDEFAULT_VDAT)));
     558             :     int nSDAT =
     559          18 :         atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_SDAT",
     560             :                                   CPLSPrintf("%d", S57Writer::nDEFAULT_SDAT)));
     561             :     int nCSCL =
     562          18 :         atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_CSCL",
     563             :                                   CPLSPrintf("%d", S57Writer::nDEFAULT_CSCL)));
     564             :     int nCOMF =
     565          18 :         atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_COMF",
     566             :                                   CPLSPrintf("%d", S57Writer::nDEFAULT_COMF)));
     567             :     int nSOMF =
     568          18 :         atoi(CSLFetchNameValueDef(papszOptionsIn, "S57_SOMF",
     569             :                                   CPLSPrintf("%d", S57Writer::nDEFAULT_SOMF)));
     570          18 :     poWriter->WriteDSPM(nHDAT, nVDAT, nSDAT, nCSCL, nCOMF, nSOMF);
     571             : 
     572          18 :     return TRUE;
     573             : }

Generated by: LCOV version 1.14