Coverage Report

Created: 2025-06-09 08:44

/src/gdal/ogr/ogrsf_frmts/s57/s57.h
Line
Count
Source (jump to first uncovered line)
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
0
#define EMPTY_NUMBER_MARKER 2147483641 /* MAXINT-6 */
29
30
/* -------------------------------------------------------------------- */
31
/*      Various option strings.                                         */
32
/* -------------------------------------------------------------------- */
33
1.01k
#define S57O_UPDATES "UPDATES"
34
1.51k
#define S57O_LNAM_REFS "LNAM_REFS"
35
1.01k
#define S57O_SPLIT_MULTIPOINT "SPLIT_MULTIPOINT"
36
1.01k
#define S57O_ADD_SOUNDG_DEPTH "ADD_SOUNDG_DEPTH"
37
1.01k
#define S57O_PRESERVE_EMPTY_NUMBERS "PRESERVE_EMPTY_NUMBERS"
38
1.44k
#define S57O_RETURN_PRIMITIVES "RETURN_PRIMITIVES"
39
1.01k
#define S57O_RETURN_LINKAGES "RETURN_LINKAGES"
40
1.44k
#define S57O_RETURN_DSID "RETURN_DSID"
41
1.01k
#define S57O_RECODE_BY_DSSI "RECODE_BY_DSSI"
42
1.01k
#define S57O_LIST_AS_STRING "LIST_AS_STRING"
43
44
822
#define S57M_UPDATES 0x01
45
15.3k
#define S57M_LNAM_REFS 0x02
46
13.6k
#define S57M_SPLIT_MULTIPOINT 0x04
47
1.01k
#define S57M_ADD_SOUNDG_DEPTH 0x08
48
506
#define S57M_PRESERVE_EMPTY_NUMBERS 0x10
49
14.4k
#define S57M_RETURN_PRIMITIVES 0x20
50
15.3k
#define S57M_RETURN_LINKAGES 0x40
51
94.8k
#define S57M_RETURN_DSID 0x80
52
506
#define S57M_RECODE_BY_DSSI 0x100
53
506
#define S57M_LIST_AS_STRING 0x200
54
55
/* -------------------------------------------------------------------- */
56
/*      RCNM values.                                                    */
57
/* -------------------------------------------------------------------- */
58
59
#define RCNM_FE 100 /* Feature record */
60
61
31.7k
#define RCNM_VI 110 /* Isolated Node */
62
30.8k
#define RCNM_VC 120 /* Connected Node */
63
30.6k
#define RCNM_VE 130 /* Edge */
64
30.5k
#define RCNM_VF 140 /* Face */
65
66
30.9k
#define RCNM_DSID 10
67
68
0
#define OGRN_VI "IsolatedNode"
69
0
#define OGRN_VC "ConnectedNode"
70
0
#define OGRN_VE "Edge"
71
0
#define OGRN_VF "Face"
72
73
/* -------------------------------------------------------------------- */
74
/*      FRID PRIM values.                                               */
75
/* -------------------------------------------------------------------- */
76
721k
#define PRIM_P 1 /* point feature */
77
706k
#define PRIM_L 2 /* line feature */
78
695k
#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
0
    {
127
0
        return GetAttrInfo(i) == nullptr ? nullptr
128
0
                                         : aoAttrInfos[i]->osName.c_str();
129
0
    }
130
131
    const char *GetAttrAcronym(int i)
132
0
    {
133
0
        return GetAttrInfo(i) == nullptr ? nullptr
134
0
                                         : aoAttrInfos[i]->osAcronym.c_str();
135
0
    }
136
137
    char GetAttrType(int i)
138
0
    {
139
0
        return GetAttrInfo(i) == nullptr ? '\0' : aoAttrInfos[i]->chType;
140
0
    }
141
142
0
#define SAT_ENUM 'E'
143
0
#define SAT_LIST 'L'
144
0
#define SAT_FLOAT 'F'
145
0
#define SAT_INT 'I'
146
0
#define SAT_CODE_STRING 'A'
147
0
#define SAT_FREE_TEXT 'S'
148
149
    char GetAttrClass(int i)
150
0
    {
151
0
        return GetAttrInfo(i) == nullptr ? '\0' : aoAttrInfos[i]->chClass;
152
0
    }
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
    bool Rewind()
182
0
    {
183
0
        return SelectClassByIndex(0);
184
0
    }
185
186
    bool NextClass()
187
0
    {
188
0
        return SelectClassByIndex(iCurrentClass + 1);
189
0
    }
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
typedef struct
208
{
209
    int nKey;
210
    DDFRecord *poRecord;
211
    void *pClientData;
212
} DDFIndexedRecord;
213
214
class CPL_DLL DDFRecordIndex
215
{
216
    bool bSorted;
217
218
    int nRecordCount;
219
    int nRecordMax;
220
221
    int nLastObjlPos;  // Added for FindRecordByObjl().
222
    int nLastObjl;     // Added for FindRecordByObjl().
223
224
    DDFIndexedRecord *pasRecords;
225
226
    void Sort();
227
228
  public:
229
    DDFRecordIndex();
230
    ~DDFRecordIndex();
231
232
    void AddRecord(int nKey, DDFRecord *);
233
    bool RemoveRecord(int nKey);
234
235
    DDFRecord *FindRecord(int nKey);
236
237
    DDFRecord *FindRecordByObjl(int nObjl);  // Added for FindRecordByObjl().
238
239
    void Clear();
240
241
    int GetCount()
242
2.32M
    {
243
2.32M
        return nRecordCount;
244
2.32M
    }
245
246
    DDFRecord *GetByIndex(int i);
247
    void *GetClientInfoByIndex(int i);
248
    void SetClientInfoByIndex(int i, void *pClientInfo);
249
};
250
251
/************************************************************************/
252
/*                              S57Reader                               */
253
/************************************************************************/
254
255
class CPL_DLL S57Reader
256
{
257
    S57ClassRegistrar *poRegistrar;
258
    S57ClassContentExplorer *poClassContentExplorer;
259
260
    int nFDefnCount;
261
    OGRFeatureDefn **papoFDefnList;
262
263
    std::vector<OGRFeatureDefn *> apoFDefnByOBJL;
264
265
    char *pszModuleName;
266
    char *pszDSNM;
267
268
    DDFModule *poModule;
269
270
    int nCOMF; /* Coordinate multiplier */
271
    int nSOMF; /* Vertical (sounding) multiplier */
272
273
    bool bFileIngested;
274
    DDFRecordIndex oVI_Index;
275
    DDFRecordIndex oVC_Index;
276
    DDFRecordIndex oVE_Index;
277
    DDFRecordIndex oVF_Index;
278
279
    int nNextVIIndex;
280
    int nNextVCIndex;
281
    int nNextVEIndex;
282
    int nNextVFIndex;
283
284
    int nNextFEIndex;
285
    DDFRecordIndex oFE_Index;
286
287
    int nNextDSIDIndex;
288
    DDFRecord *poDSIDRecord;
289
    DDFRecord *poDSPMRecord;
290
    std::string m_osEDTNUpdate;
291
    std::string m_osUPDNUpdate;
292
    std::string m_osISDTUpdate;
293
294
    char **papszOptions;
295
296
    int nOptionFlags;
297
298
    int iPointOffset;
299
    OGRFeature *poMultiPoint;
300
301
    int Aall;                // see RecodeByDSSI() function
302
    int Nall;                // see RecodeByDSSI() function
303
    bool needAallNallSetup;  // see RecodeByDSSI() function
304
305
    void ClearPendingMultiPoint();
306
    OGRFeature *NextPendingMultiPoint();
307
308
    OGRFeature *AssembleFeature(DDFRecord *, OGRFeatureDefn *);
309
310
    void ApplyObjectClassAttributes(DDFRecord *, OGRFeature *);
311
    static void GenerateLNAMAndRefs(DDFRecord *, OGRFeature *);
312
    void GenerateFSPTAttributes(DDFRecord *, OGRFeature *);
313
314
    void AssembleSoundingGeometry(DDFRecord *, OGRFeature *);
315
    // cppcheck-suppress functionStatic
316
    void AssemblePointGeometry(DDFRecord *, OGRFeature *);
317
    void AssembleLineGeometry(DDFRecord *, OGRFeature *);
318
    void AssembleAreaGeometry(const DDFRecord *, OGRFeature *);
319
320
    bool FetchPoint(int, int, double *, double *, double * = nullptr);
321
    bool FetchLine(DDFRecord *, int, int, OGRLineString *);
322
323
    OGRFeatureDefn *FindFDefn(DDFRecord *);
324
    int ParseName(const DDFField *, int = 0, int * = nullptr);
325
326
    // cppcheck-suppress functionStatic
327
    bool ApplyRecordUpdate(DDFRecord *, DDFRecord *);
328
329
    bool bMissingWarningIssued;
330
    bool bAttrWarningIssued;
331
332
  public:
333
    explicit S57Reader(const char *);
334
    ~S57Reader();
335
336
    void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
337
    bool SetOptions(char **);
338
339
    int GetOptionFlags()
340
1.71k
    {
341
1.71k
        return nOptionFlags;
342
1.71k
    }
343
344
    int Open(int bTestOpen);
345
    void Close();
346
347
    DDFModule *GetModule()
348
2.14k
    {
349
2.14k
        return poModule;
350
2.14k
    }
351
352
    const char *GetDSNM()
353
0
    {
354
0
        return pszDSNM;
355
0
    }
356
357
    bool Ingest();
358
    bool ApplyUpdates(DDFModule *);
359
    bool FindAndApplyUpdates(const char *pszPath = nullptr);
360
361
    void Rewind();
362
    OGRFeature *ReadNextFeature(OGRFeatureDefn * = nullptr);
363
    OGRFeature *ReadFeature(int nFID, OGRFeatureDefn * = nullptr);
364
    OGRFeature *ReadVector(int nFID, int nRCNM);
365
    OGRFeature *ReadDSID();
366
367
    int GetNextFEIndex(int nRCNM = 100);
368
    void SetNextFEIndex(int nNewIndex, int nRCNM = 100);
369
370
    void AddFeatureDefn(OGRFeatureDefn *);
371
372
    bool CollectClassList(std::vector<int> &anClassCount);
373
374
    OGRErr GetExtent(OGREnvelope *psExtent, int bForce);
375
376
    char *RecodeByDSSI(const char *SourceString, bool LookAtAALL_NALL);
377
};
378
379
/************************************************************************/
380
/*                              S57Writer                               */
381
/************************************************************************/
382
383
class CPL_DLL S57Writer
384
{
385
  public:
386
    static const int nDEFAULT_EXPP = 1;
387
    static const int nDEFAULT_INTU = 4;
388
    static const int nDEFAULT_AGEN = 540;
389
390
    static const int nDEFAULT_HDAT = 2;
391
    static const int nDEFAULT_VDAT = 7;
392
    static const int nDEFAULT_SDAT = 23;
393
    static const int nDEFAULT_CSCL = 52000;
394
    static const int nDEFAULT_COMF = 10000000;
395
    static const int nDEFAULT_SOMF = 10;
396
397
    S57Writer();
398
    ~S57Writer();
399
400
    void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
401
    bool CreateS57File(const char *pszFilename);
402
    bool Close();
403
404
    bool WriteGeometry(DDFRecord *, int, const double *, const double *,
405
                       const double *);
406
    bool WriteATTF(DDFRecord *, OGRFeature *);
407
    bool WritePrimitive(OGRFeature *poFeature);
408
    bool WriteCompleteFeature(OGRFeature *poFeature);
409
    bool WriteDSID(int nEXPP = nDEFAULT_EXPP, int nINTU = nDEFAULT_INTU,
410
                   const char *pszDSNM = nullptr, const char *pszEDTN = nullptr,
411
                   const char *pszUPDN = nullptr, const char *pszUADT = nullptr,
412
                   const char *pszISDT = nullptr, const char *pszSTED = nullptr,
413
                   int nAGEN = nDEFAULT_AGEN, const char *pszCOMT = nullptr,
414
                   int nAALL = 0, int nNALL = 0, int nNOMR = 0, int nNOGR = 0,
415
                   int nNOLR = 0, int nNOIN = 0, int nNOCN = 0, int nNOED = 0);
416
    bool WriteDSPM(int nHDAT = nDEFAULT_HDAT, int nVDAT = nDEFAULT_VDAT,
417
                   int nSDAT = nDEFAULT_SDAT, int nCSCL = nDEFAULT_CSCL,
418
                   int nCOMF = nDEFAULT_COMF, int nSOMF = nDEFAULT_SOMF);
419
420
    // semi-private - for sophisticated writers.
421
    DDFRecord *MakeRecord();
422
    DDFModule *poModule;
423
424
  private:
425
    int nNext0001Index;
426
    S57ClassRegistrar *poRegistrar;
427
    S57ClassContentExplorer *poClassContentExplorer;
428
429
    int m_nCOMF; /* Coordinate multiplier */
430
    int m_nSOMF; /* Vertical (sounding) multiplier */
431
};
432
433
/* -------------------------------------------------------------------- */
434
/*      Functions to create OGRFeatureDefns.                            */
435
/* -------------------------------------------------------------------- */
436
void CPL_DLL S57GenerateStandardAttributes(OGRFeatureDefn *, int);
437
OGRFeatureDefn CPL_DLL *S57GenerateGeomFeatureDefn(OGRwkbGeometryType, int);
438
OGRFeatureDefn CPL_DLL *
439
S57GenerateObjectClassDefn(S57ClassRegistrar *,
440
                           S57ClassContentExplorer *poClassContentExplorer, int,
441
                           int);
442
OGRFeatureDefn CPL_DLL *S57GenerateVectorPrimitiveFeatureDefn(int, int);
443
OGRFeatureDefn CPL_DLL *S57GenerateDSIDFeatureDefn(void);
444
445
#endif /* ndef S57_H_INCLUDED */