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 */
|