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 868 : const char *GetAttrAcronym(int i)
132 : {
133 868 : return GetAttrInfo(i) == nullptr ? nullptr
134 868 : : aoAttrInfos[i]->osAcronym.c_str();
135 : }
136 :
137 107776 : char GetAttrType(int i)
138 : {
139 107776 : 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 : 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 10073 : int GetCount()
242 : {
243 10073 : return nRecordCount;
244 : }
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 364 : int GetOptionFlags()
340 : {
341 364 : return nOptionFlags;
342 : }
343 :
344 : int Open(int bTestOpen);
345 : void Close();
346 :
347 490 : DDFModule *GetModule()
348 : {
349 490 : return poModule;
350 : }
351 :
352 : const char *GetDSNM()
353 : {
354 : return pszDSNM;
355 : }
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 */
|