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

Generated by: LCOV version 1.14