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 : 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 : DDFIndexedRecord *pasRecords;
222 :
223 : void Sort();
224 :
225 : public:
226 : DDFRecordIndex();
227 : ~DDFRecordIndex();
228 :
229 : void AddRecord(int nKey, DDFRecord *);
230 : bool RemoveRecord(int nKey);
231 :
232 : DDFRecord *FindRecord(int nKey);
233 :
234 : void Clear();
235 :
236 347781 : int GetCount()
237 : {
238 347781 : return nRecordCount;
239 : }
240 :
241 : DDFRecord *GetByIndex(int i);
242 : void *GetClientInfoByIndex(int i);
243 : void SetClientInfoByIndex(int i, void *pClientInfo);
244 : };
245 :
246 : /************************************************************************/
247 : /* S57Reader */
248 : /************************************************************************/
249 :
250 : class CPL_DLL S57Reader
251 : {
252 : S57ClassRegistrar *poRegistrar;
253 : S57ClassContentExplorer *poClassContentExplorer;
254 :
255 : int nFDefnCount;
256 : OGRFeatureDefn **papoFDefnList;
257 :
258 : std::vector<OGRFeatureDefn *> apoFDefnByOBJL;
259 :
260 : char *pszModuleName;
261 : char *pszDSNM;
262 :
263 : DDFModule *poModule;
264 :
265 : int nCOMF; /* Coordinate multiplier */
266 : int nSOMF; /* Vertical (sounding) multiplier */
267 :
268 : bool bFileIngested;
269 : DDFRecordIndex oVI_Index;
270 : DDFRecordIndex oVC_Index;
271 : DDFRecordIndex oVE_Index;
272 : DDFRecordIndex oVF_Index;
273 :
274 : int nNextVIIndex;
275 : int nNextVCIndex;
276 : int nNextVEIndex;
277 : int nNextVFIndex;
278 :
279 : int nNextFEIndex;
280 : DDFRecordIndex oFE_Index;
281 :
282 : int nNextDSIDIndex;
283 : DDFRecord *poDSIDRecord;
284 : DDFRecord *poDSPMRecord;
285 : std::string m_osEDTNUpdate;
286 : std::string m_osUPDNUpdate;
287 : std::string m_osISDTUpdate;
288 :
289 : char **papszOptions;
290 :
291 : int nOptionFlags;
292 :
293 : int iPointOffset;
294 : OGRFeature *poMultiPoint;
295 :
296 : int Aall; // see RecodeByDSSI() function
297 : int Nall; // see RecodeByDSSI() function
298 : bool needAallNallSetup; // see RecodeByDSSI() function
299 :
300 : void ClearPendingMultiPoint();
301 : OGRFeature *NextPendingMultiPoint();
302 :
303 : OGRFeature *AssembleFeature(DDFRecord *, OGRFeatureDefn *);
304 :
305 : void ApplyObjectClassAttributes(DDFRecord *, OGRFeature *);
306 : static void GenerateLNAMAndRefs(DDFRecord *, OGRFeature *);
307 : void GenerateFSPTAttributes(DDFRecord *, OGRFeature *);
308 :
309 : void AssembleSoundingGeometry(DDFRecord *, OGRFeature *);
310 : // cppcheck-suppress functionStatic
311 : void AssemblePointGeometry(DDFRecord *, OGRFeature *);
312 : bool AssembleLineGeometry(DDFRecord *, OGRFeature *);
313 : void AssembleAreaGeometry(const DDFRecord *, OGRFeature *);
314 :
315 : bool FetchPoint(int, int, double *, double *, double * = nullptr);
316 : bool FetchLine(DDFRecord *, int, int, OGRLineString *);
317 :
318 : OGRFeatureDefn *FindFDefn(DDFRecord *);
319 : int ParseName(const DDFField *, int = 0, int * = nullptr);
320 :
321 : // cppcheck-suppress functionStatic
322 : bool ApplyRecordUpdate(DDFRecord *, DDFRecord *);
323 :
324 : bool bMissingWarningIssued;
325 : bool bAttrWarningIssued;
326 :
327 : public:
328 : explicit S57Reader(const char *);
329 : ~S57Reader();
330 :
331 : void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
332 : bool SetOptions(CSLConstList);
333 :
334 474 : int GetOptionFlags()
335 : {
336 474 : return nOptionFlags;
337 : }
338 :
339 : int Open(int bTestOpen);
340 : void Close();
341 :
342 563 : DDFModule *GetModule()
343 : {
344 563 : return poModule;
345 : }
346 :
347 : const char *GetDSNM()
348 : {
349 : return pszDSNM;
350 : }
351 :
352 : bool Ingest();
353 : bool ApplyUpdates(DDFModule *);
354 : bool FindAndApplyUpdates(const char *pszPath = nullptr);
355 :
356 : void Rewind();
357 : OGRFeature *ReadNextFeature(OGRFeatureDefn * = nullptr);
358 : OGRFeature *ReadFeature(int nFID, OGRFeatureDefn * = nullptr);
359 : OGRFeature *ReadVector(int nFID, int nRCNM);
360 : OGRFeature *ReadDSID();
361 :
362 : int GetNextFEIndex(int nRCNM = 100);
363 : void SetNextFEIndex(int nNewIndex, int nRCNM = 100);
364 :
365 : void AddFeatureDefn(OGRFeatureDefn *);
366 :
367 : bool CollectClassList(std::vector<int> &anClassCount);
368 :
369 : OGRErr GetExtent(OGREnvelope *psExtent, int bForce);
370 :
371 : char *RecodeByDSSI(const char *SourceString, bool LookAtAALL_NALL);
372 : };
373 :
374 : /************************************************************************/
375 : /* S57Writer */
376 : /************************************************************************/
377 :
378 : class CPL_DLL S57Writer
379 : {
380 : public:
381 : static const int nDEFAULT_EXPP = 1;
382 : static const int nDEFAULT_INTU = 4;
383 : static const int nDEFAULT_AGEN = 540;
384 :
385 : static const int nDEFAULT_HDAT = 2;
386 : static const int nDEFAULT_VDAT = 7;
387 : static const int nDEFAULT_SDAT = 23;
388 : static const int nDEFAULT_CSCL = 52000;
389 : static const int nDEFAULT_COMF = 10000000;
390 : static const int nDEFAULT_SOMF = 10;
391 :
392 : S57Writer();
393 : ~S57Writer();
394 :
395 : void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
396 : bool CreateS57File(const char *pszFilename);
397 : bool Close();
398 :
399 : bool WriteGeometry(DDFRecord *, int, const double *, const double *,
400 : const double *);
401 : bool WriteATTF(DDFRecord *, OGRFeature *);
402 : bool WritePrimitive(OGRFeature *poFeature);
403 : bool WriteCompleteFeature(OGRFeature *poFeature);
404 : bool WriteDSID(int nEXPP = nDEFAULT_EXPP, int nINTU = nDEFAULT_INTU,
405 : const char *pszDSNM = nullptr, const char *pszEDTN = nullptr,
406 : const char *pszUPDN = nullptr, const char *pszUADT = nullptr,
407 : const char *pszISDT = nullptr, const char *pszSTED = nullptr,
408 : int nAGEN = nDEFAULT_AGEN, const char *pszCOMT = nullptr,
409 : int nAALL = 0, int nNALL = 0, int nNOMR = 0, int nNOGR = 0,
410 : int nNOLR = 0, int nNOIN = 0, int nNOCN = 0, int nNOED = 0);
411 : bool WriteDSPM(int nHDAT = nDEFAULT_HDAT, int nVDAT = nDEFAULT_VDAT,
412 : int nSDAT = nDEFAULT_SDAT, int nCSCL = nDEFAULT_CSCL,
413 : int nCOMF = nDEFAULT_COMF, int nSOMF = nDEFAULT_SOMF);
414 :
415 : // semi-private - for sophisticated writers.
416 : DDFRecord *MakeRecord();
417 : DDFModule *poModule;
418 :
419 : private:
420 : int nNext0001Index;
421 : S57ClassRegistrar *poRegistrar;
422 : S57ClassContentExplorer *poClassContentExplorer;
423 :
424 : int m_nCOMF; /* Coordinate multiplier */
425 : int m_nSOMF; /* Vertical (sounding) multiplier */
426 : };
427 :
428 : /* -------------------------------------------------------------------- */
429 : /* Functions to create OGRFeatureDefns. */
430 : /* -------------------------------------------------------------------- */
431 : void CPL_DLL S57GenerateStandardAttributes(OGRFeatureDefn *, int);
432 : OGRFeatureDefn CPL_DLL *S57GenerateGeomFeatureDefn(OGRwkbGeometryType, int);
433 : OGRFeatureDefn CPL_DLL *
434 : S57GenerateObjectClassDefn(S57ClassRegistrar *,
435 : S57ClassContentExplorer *poClassContentExplorer, int,
436 : int);
437 : OGRFeatureDefn CPL_DLL *S57GenerateVectorPrimitiveFeatureDefn(int, int);
438 : OGRFeatureDefn CPL_DLL *S57GenerateDSIDFeatureDefn(void);
439 :
440 : #endif /* ndef S57_H_INCLUDED */
|