LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/s57 - s57.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 16 16 100.0 %
Date: 2026-04-19 18:43:50 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  S-57 Translator
       4             :  * Purpose:  Declarations for S-57 translator not including the
       5             :  *           binding onto OGRLayer/DataSource/Driver which are found in
       6             :  *           ogr_s57.h.
       7             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8             :  *
       9             :  ******************************************************************************
      10             :  * Copyright (c) 1999, Frank Warmerdam
      11             :  * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com>
      12             :  *
      13             :  * SPDX-License-Identifier: MIT
      14             :  ****************************************************************************/
      15             : 
      16             : #ifndef S57_H_INCLUDED
      17             : #define S57_H_INCLUDED
      18             : 
      19             : #include <string>
      20             : #include <vector>
      21             : #include "ogr_feature.h"
      22             : #include "iso8211.h"
      23             : 
      24             : class S57Reader;
      25             : 
      26             : char **S57FileCollector(const char *pszDataset);
      27             : 
      28             : #define EMPTY_NUMBER_MARKER 2147483641 /* MAXINT-6 */
      29             : 
      30             : /* -------------------------------------------------------------------- */
      31             : /*      Various option strings.                                         */
      32             : /* -------------------------------------------------------------------- */
      33             : #define S57O_UPDATES "UPDATES"
      34             : #define S57O_LNAM_REFS "LNAM_REFS"
      35             : #define S57O_SPLIT_MULTIPOINT "SPLIT_MULTIPOINT"
      36             : #define S57O_ADD_SOUNDG_DEPTH "ADD_SOUNDG_DEPTH"
      37             : #define S57O_PRESERVE_EMPTY_NUMBERS "PRESERVE_EMPTY_NUMBERS"
      38             : #define S57O_RETURN_PRIMITIVES "RETURN_PRIMITIVES"
      39             : #define S57O_RETURN_LINKAGES "RETURN_LINKAGES"
      40             : #define S57O_RETURN_DSID "RETURN_DSID"
      41             : #define S57O_RECODE_BY_DSSI "RECODE_BY_DSSI"
      42             : #define S57O_LIST_AS_STRING "LIST_AS_STRING"
      43             : 
      44             : #define S57M_UPDATES 0x01
      45             : #define S57M_LNAM_REFS 0x02
      46             : #define S57M_SPLIT_MULTIPOINT 0x04
      47             : #define S57M_ADD_SOUNDG_DEPTH 0x08
      48             : #define S57M_PRESERVE_EMPTY_NUMBERS 0x10
      49             : #define S57M_RETURN_PRIMITIVES 0x20
      50             : #define S57M_RETURN_LINKAGES 0x40
      51             : #define S57M_RETURN_DSID 0x80
      52             : #define S57M_RECODE_BY_DSSI 0x100
      53             : #define S57M_LIST_AS_STRING 0x200
      54             : 
      55             : /* -------------------------------------------------------------------- */
      56             : /*      RCNM values.                                                    */
      57             : /* -------------------------------------------------------------------- */
      58             : 
      59             : #define RCNM_FE 100 /* Feature record */
      60             : 
      61             : #define RCNM_VI 110 /* Isolated Node */
      62             : #define RCNM_VC 120 /* Connected Node */
      63             : #define RCNM_VE 130 /* Edge */
      64             : #define RCNM_VF 140 /* Face */
      65             : 
      66             : #define RCNM_DSID 10
      67             : 
      68             : #define OGRN_VI "IsolatedNode"
      69             : #define OGRN_VC "ConnectedNode"
      70             : #define OGRN_VE "Edge"
      71             : #define OGRN_VF "Face"
      72             : 
      73             : /* -------------------------------------------------------------------- */
      74             : /*      FRID PRIM values.                                               */
      75             : /* -------------------------------------------------------------------- */
      76             : #define PRIM_P 1 /* point feature */
      77             : #define PRIM_L 2 /* line feature */
      78             : #define PRIM_A 3 /* area feature */
      79             : #define PRIM_N 4 /* non-spatial feature  */
      80             : 
      81             : /************************************************************************/
      82             : /*                          S57ClassRegistrar                           */
      83             : /************************************************************************/
      84             : 
      85             : class S57ClassContentExplorer;
      86             : 
      87             : class CPL_DLL S57AttrInfo
      88             : {
      89             :   public:
      90             :     CPLString osName;
      91             :     CPLString osAcronym;
      92             :     char chType;
      93             :     char chClass;
      94             : };
      95             : 
      96             : class CPL_DLL S57ClassRegistrar
      97             : {
      98             :     friend class S57ClassContentExplorer;
      99             : 
     100             :     // Class information:
     101             :     int nClasses;
     102             :     CPLStringList apszClassesInfo;
     103             : 
     104             :     // Attribute Information:
     105             :     int nAttrCount;
     106             :     std::vector<S57AttrInfo *> aoAttrInfos;
     107             :     std::vector<int> anAttrIndex;  // sorted by acronym.
     108             : 
     109             :     static bool FindFile(const char *pszTarget, const char *pszDirectory,
     110             :                          bool bReportErr, VSILFILE **fp);
     111             : 
     112             :     const char *ReadLine(VSILFILE *fp);
     113             :     char **papszNextLine;
     114             : 
     115             :   public:
     116             :     S57ClassRegistrar();
     117             :     ~S57ClassRegistrar();
     118             : 
     119             :     bool LoadInfo(const char *, const char *, bool);
     120             : 
     121             :     // attribute table methods.
     122             :     // int         GetMaxAttrIndex() { return nAttrMax; }
     123             :     const S57AttrInfo *GetAttrInfo(int i);
     124             : 
     125             :     const char *GetAttrName(int i)
     126             :     {
     127             :         return GetAttrInfo(i) == nullptr ? nullptr
     128             :                                          : aoAttrInfos[i]->osName.c_str();
     129             :     }
     130             : 
     131       22791 :     const char *GetAttrAcronym(int i)
     132             :     {
     133       22791 :         return GetAttrInfo(i) == nullptr ? nullptr
     134       22791 :                                          : aoAttrInfos[i]->osAcronym.c_str();
     135             :     }
     136             : 
     137      110047 :     char GetAttrType(int i)
     138             :     {
     139      110047 :         return GetAttrInfo(i) == nullptr ? '\0' : aoAttrInfos[i]->chType;
     140             :     }
     141             : 
     142             : #define SAT_ENUM 'E'
     143             : #define SAT_LIST 'L'
     144             : #define SAT_FLOAT 'F'
     145             : #define SAT_INT 'I'
     146             : #define SAT_CODE_STRING 'A'
     147             : #define SAT_FREE_TEXT 'S'
     148             : 
     149             :     char GetAttrClass(int i)
     150             :     {
     151             :         return GetAttrInfo(i) == nullptr ? '\0' : aoAttrInfos[i]->chClass;
     152             :     }
     153             : 
     154             :     int FindAttrByAcronym(const char *);
     155             : };
     156             : 
     157             : /************************************************************************/
     158             : /*                       S57ClassContentExplorer                        */
     159             : /************************************************************************/
     160             : 
     161             : class S57ClassContentExplorer
     162             : {
     163             :     S57ClassRegistrar *poRegistrar;
     164             : 
     165             :     char ***papapszClassesFields;
     166             : 
     167             :     int iCurrentClass;
     168             : 
     169             :     char **papszCurrentFields;
     170             : 
     171             :     char **papszTempResult;
     172             : 
     173             :   public:
     174             :     explicit S57ClassContentExplorer(S57ClassRegistrar *poRegistrar);
     175             :     ~S57ClassContentExplorer();
     176             : 
     177             :     bool SelectClassByIndex(int);
     178             :     bool SelectClass(int);
     179             :     bool SelectClass(const char *);
     180             : 
     181          18 :     bool Rewind()
     182             :     {
     183          18 :         return SelectClassByIndex(0);
     184             :     }
     185             : 
     186        5112 :     bool NextClass()
     187             :     {
     188        5112 :         return SelectClassByIndex(iCurrentClass + 1);
     189             :     }
     190             : 
     191             :     int GetOBJL();
     192             :     const char *GetDescription() const;
     193             :     const char *GetAcronym() const;
     194             : 
     195             :     char **GetAttributeList(const char * = nullptr);
     196             : 
     197             :     char GetClassCode() const;
     198             :     char **GetPrimitives();
     199             : };
     200             : 
     201             : /************************************************************************/
     202             : /*                            DDFRecordIndex                            */
     203             : /*                                                                      */
     204             : /*      Maintain an index of DDF records based on an integer key.       */
     205             : /************************************************************************/
     206             : 
     207             : struct DDFIndexedRecord
     208             : {
     209             :     int nKey = 0;
     210             :     std::unique_ptr<DDFRecord> poRecord;
     211             :     const void *pClientData = nullptr;
     212             : };
     213             : 
     214         195 : class CPL_DLL DDFRecordIndex
     215             : {
     216             :     mutable bool bSorted = false;
     217             :     mutable std::vector<DDFIndexedRecord> asRecords{};
     218             : 
     219             :     void Sort() const;
     220             : 
     221             :     DDFRecordIndex(const DDFRecordIndex &) = delete;
     222             :     DDFRecordIndex &operator=(const DDFRecordIndex &) = delete;
     223             :     DDFRecordIndex(DDFRecordIndex &&) = delete;
     224             :     DDFRecordIndex &operator=(DDFRecordIndex &&) = delete;
     225             : 
     226             :   public:
     227             :     DDFRecordIndex();
     228             :     ~DDFRecordIndex();
     229             : 
     230             :     void AddRecord(int nKey, std::unique_ptr<DDFRecord> poRecord);
     231             :     bool RemoveRecord(int nKey);
     232             : 
     233             :     DDFRecord *FindRecord(int nKey) const;
     234             : 
     235             :     void Clear();
     236             : 
     237      709503 :     int GetCount() const
     238             :     {
     239      709503 :         return static_cast<int>(asRecords.size());
     240             :     }
     241             : 
     242             :     const DDFRecord *GetByIndex(int i) const;
     243             :     const void *GetClientInfoByIndex(int i) const;
     244             :     void SetClientInfoByIndex(int i, const void *pClientInfo);
     245             : };
     246             : 
     247             : /************************************************************************/
     248             : /*                              S57Reader                               */
     249             : /************************************************************************/
     250             : 
     251             : class CPL_DLL S57Reader
     252             : {
     253             :     S57ClassRegistrar *poRegistrar = nullptr;
     254             :     S57ClassContentExplorer *poClassContentExplorer = nullptr;
     255             : 
     256             :     int nFDefnCount = 0;
     257             :     OGRFeatureDefn **papoFDefnList = nullptr;
     258             : 
     259             :     std::vector<OGRFeatureDefn *> apoFDefnByOBJL{};
     260             : 
     261             :     char *pszModuleName = nullptr;
     262             :     char *pszDSNM = nullptr;
     263             : 
     264             :     std::unique_ptr<DDFModule> poModule{};
     265             : 
     266             :     int nCOMF = 1000000; /* Coordinate multiplier */
     267             :     int nSOMF = 10;      /* Vertical (sounding) multiplier */
     268             : 
     269             :     bool bFileIngested = false;
     270             :     DDFRecordIndex oVI_Index{};
     271             :     DDFRecordIndex oVC_Index{};
     272             :     DDFRecordIndex oVE_Index{};
     273             :     DDFRecordIndex oVF_Index{};
     274             : 
     275             :     int nNextVIIndex = 0;
     276             :     int nNextVCIndex = 0;
     277             :     int nNextVEIndex = 0;
     278             :     int nNextVFIndex = 0;
     279             : 
     280             :     int nNextFEIndex = 0;
     281             :     DDFRecordIndex oFE_Index{};
     282             : 
     283             :     int nNextDSIDIndex = 0;
     284             :     std::unique_ptr<DDFRecord> poDSIDRecord{};
     285             :     std::unique_ptr<DDFRecord> poDSPMRecord{};
     286             :     std::string m_osEDTNUpdate{};
     287             :     std::string m_osUPDNUpdate{};
     288             :     std::string m_osISDTUpdate{};
     289             : 
     290             :     char **papszOptions = nullptr;
     291             : 
     292             :     int nOptionFlags = S57M_UPDATES;
     293             : 
     294             :     int iPointOffset = 0;
     295             :     std::unique_ptr<OGRFeature> poMultiPoint{};
     296             : 
     297             :     int Aall = 0;                   // see RecodeByDSSI() function
     298             :     int Nall = 0;                   // see RecodeByDSSI() function
     299             :     bool needAallNallSetup = true;  // see RecodeByDSSI() function
     300             : 
     301             :     void ClearPendingMultiPoint();
     302             :     OGRFeature *NextPendingMultiPoint();
     303             : 
     304             :     OGRFeature *AssembleFeature(const DDFRecord *, OGRFeatureDefn *);
     305             : 
     306             :     void ApplyObjectClassAttributes(const DDFRecord *, OGRFeature *);
     307             :     static void GenerateLNAMAndRefs(const DDFRecord *, OGRFeature *);
     308             :     void GenerateFSPTAttributes(const DDFRecord *, OGRFeature *);
     309             : 
     310             :     void AssembleSoundingGeometry(const DDFRecord *, OGRFeature *);
     311             :     // cppcheck-suppress functionStatic
     312             :     void AssemblePointGeometry(const DDFRecord *, OGRFeature *);
     313             :     bool AssembleLineGeometry(const DDFRecord *, OGRFeature *);
     314             :     void AssembleAreaGeometry(const DDFRecord *, OGRFeature *);
     315             : 
     316             :     bool FetchPoint(int, int, double *, double *, double * = nullptr);
     317             :     bool FetchLine(const DDFRecord *, int, int, OGRLineString *);
     318             : 
     319             :     const OGRFeatureDefn *FindFDefn(const DDFRecord *);
     320             :     int ParseName(const DDFField *, int = 0, int * = nullptr);
     321             : 
     322             :     // cppcheck-suppress functionStatic
     323             :     bool ApplyRecordUpdate(DDFRecord *, DDFRecord *);
     324             : 
     325             :     bool bMissingWarningIssued = false;
     326             :     bool bAttrWarningIssued = false;
     327             : 
     328             :   public:
     329             :     explicit S57Reader(const char *);
     330             :     ~S57Reader();
     331             : 
     332             :     void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
     333             :     bool SetOptions(CSLConstList);
     334             : 
     335         474 :     int GetOptionFlags()
     336             :     {
     337         474 :         return nOptionFlags;
     338             :     }
     339             : 
     340             :     int Open(int bTestOpen);
     341             :     void Close();
     342             : 
     343         563 :     DDFModule *GetModule()
     344             :     {
     345         563 :         return poModule.get();
     346             :     }
     347             : 
     348             :     const char *GetDSNM()
     349             :     {
     350             :         return pszDSNM;
     351             :     }
     352             : 
     353             :     bool Ingest();
     354             :     bool ApplyUpdates(DDFModule *);
     355             :     bool FindAndApplyUpdates(const char *pszPath = nullptr);
     356             : 
     357             :     void Rewind();
     358             :     OGRFeature *ReadNextFeature(OGRFeatureDefn * = nullptr);
     359             :     OGRFeature *ReadFeature(int nFID, OGRFeatureDefn * = nullptr);
     360             :     OGRFeature *ReadVector(int nFID, int nRCNM);
     361             :     OGRFeature *ReadDSID();
     362             : 
     363             :     int GetNextFEIndex(int nRCNM = 100);
     364             :     void SetNextFEIndex(int nNewIndex, int nRCNM = 100);
     365             : 
     366             :     void AddFeatureDefn(OGRFeatureDefn *);
     367             : 
     368             :     bool CollectClassList(std::vector<int> &anClassCount);
     369             : 
     370             :     OGRErr GetExtent(OGREnvelope *psExtent, int bForce);
     371             : 
     372             :     char *RecodeByDSSI(const char *SourceString, bool LookAtAALL_NALL);
     373             : };
     374             : 
     375             : /************************************************************************/
     376             : /*                              S57Writer                               */
     377             : /************************************************************************/
     378             : 
     379             : class CPL_DLL S57Writer
     380             : {
     381             :   public:
     382             :     static const int nDEFAULT_EXPP = 1;
     383             :     static const int nDEFAULT_INTU = 4;
     384             :     static const int nDEFAULT_AGEN = 540;
     385             : 
     386             :     static const int nDEFAULT_HDAT = 2;
     387             :     static const int nDEFAULT_VDAT = 7;
     388             :     static const int nDEFAULT_SDAT = 23;
     389             :     static const int nDEFAULT_CSCL = 52000;
     390             :     static const int nDEFAULT_COMF = 10000000;
     391             :     static const int nDEFAULT_SOMF = 10;
     392             : 
     393             :     S57Writer();
     394             :     ~S57Writer();
     395             : 
     396             :     void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
     397             :     bool CreateS57File(const char *pszFilename);
     398             :     bool Close();
     399             : 
     400             :     bool WriteGeometry(DDFRecord *, int, const double *, const double *,
     401             :                        const double *);
     402             :     bool WriteATTF(DDFRecord *, OGRFeature *);
     403             :     bool WritePrimitive(OGRFeature *poFeature);
     404             :     bool WriteCompleteFeature(OGRFeature *poFeature);
     405             :     bool WriteDSID(int nEXPP = nDEFAULT_EXPP, int nINTU = nDEFAULT_INTU,
     406             :                    const char *pszDSNM = nullptr, const char *pszEDTN = nullptr,
     407             :                    const char *pszUPDN = nullptr, const char *pszUADT = nullptr,
     408             :                    const char *pszISDT = nullptr, const char *pszSTED = nullptr,
     409             :                    int nAGEN = nDEFAULT_AGEN, const char *pszCOMT = nullptr,
     410             :                    int nAALL = 0, int nNALL = 0, int nNOMR = 0, int nNOGR = 0,
     411             :                    int nNOLR = 0, int nNOIN = 0, int nNOCN = 0, int nNOED = 0);
     412             :     bool WriteDSPM(int nHDAT = nDEFAULT_HDAT, int nVDAT = nDEFAULT_VDAT,
     413             :                    int nSDAT = nDEFAULT_SDAT, int nCSCL = nDEFAULT_CSCL,
     414             :                    int nCOMF = nDEFAULT_COMF, int nSOMF = nDEFAULT_SOMF);
     415             : 
     416             :     // semi-private - for sophisticated writers.
     417             :     DDFRecord *MakeRecord();
     418             :     DDFModule *poModule;
     419             : 
     420             :   private:
     421             :     int nNext0001Index;
     422             :     S57ClassRegistrar *poRegistrar;
     423             :     S57ClassContentExplorer *poClassContentExplorer;
     424             : 
     425             :     int m_nCOMF; /* Coordinate multiplier */
     426             :     int m_nSOMF; /* Vertical (sounding) multiplier */
     427             : };
     428             : 
     429             : /* -------------------------------------------------------------------- */
     430             : /*      Functions to create OGRFeatureDefns.                            */
     431             : /* -------------------------------------------------------------------- */
     432             : void CPL_DLL S57GenerateStandardAttributes(OGRFeatureDefn *, int);
     433             : OGRFeatureDefn CPL_DLL *S57GenerateGeomFeatureDefn(OGRwkbGeometryType, int);
     434             : OGRFeatureDefn CPL_DLL *
     435             : S57GenerateObjectClassDefn(S57ClassRegistrar *,
     436             :                            S57ClassContentExplorer *poClassContentExplorer, int,
     437             :                            int);
     438             : OGRFeatureDefn CPL_DLL *S57GenerateVectorPrimitiveFeatureDefn(int, int);
     439             : OGRFeatureDefn CPL_DLL *S57GenerateDSIDFeatureDefn(void);
     440             : 
     441             : #endif /* ndef S57_H_INCLUDED */

Generated by: LCOV version 1.14