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 : // cppcheck-suppress functionStatic
312 : void GenerateLNAMAndRefs(DDFRecord *, OGRFeature *);
313 : void GenerateFSPTAttributes(DDFRecord *, OGRFeature *);
314 :
315 : void AssembleSoundingGeometry(DDFRecord *, OGRFeature *);
316 : // cppcheck-suppress functionStatic
317 : void AssemblePointGeometry(DDFRecord *, OGRFeature *);
318 : void AssembleLineGeometry(DDFRecord *, OGRFeature *);
319 : void AssembleAreaGeometry(DDFRecord *, OGRFeature *);
320 :
321 : bool FetchPoint(int, int, double *, double *, double * = nullptr);
322 : bool FetchLine(DDFRecord *, int, int, OGRLineString *);
323 :
324 : OGRFeatureDefn *FindFDefn(DDFRecord *);
325 : int ParseName(DDFField *, int = 0, int * = nullptr);
326 :
327 : // cppcheck-suppress functionStatic
328 : bool ApplyRecordUpdate(DDFRecord *, DDFRecord *);
329 :
330 : bool bMissingWarningIssued;
331 : bool bAttrWarningIssued;
332 :
333 : public:
334 : explicit S57Reader(const char *);
335 : ~S57Reader();
336 :
337 : void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
338 : bool SetOptions(char **);
339 :
340 364 : int GetOptionFlags()
341 : {
342 364 : return nOptionFlags;
343 : }
344 :
345 : int Open(int bTestOpen);
346 : void Close();
347 :
348 490 : DDFModule *GetModule()
349 : {
350 490 : return poModule;
351 : }
352 :
353 : const char *GetDSNM()
354 : {
355 : return pszDSNM;
356 : }
357 :
358 : bool Ingest();
359 : bool ApplyUpdates(DDFModule *);
360 : bool FindAndApplyUpdates(const char *pszPath = nullptr);
361 :
362 : void Rewind();
363 : OGRFeature *ReadNextFeature(OGRFeatureDefn * = nullptr);
364 : OGRFeature *ReadFeature(int nFID, OGRFeatureDefn * = nullptr);
365 : OGRFeature *ReadVector(int nFID, int nRCNM);
366 : OGRFeature *ReadDSID();
367 :
368 : int GetNextFEIndex(int nRCNM = 100);
369 : void SetNextFEIndex(int nNewIndex, int nRCNM = 100);
370 :
371 : void AddFeatureDefn(OGRFeatureDefn *);
372 :
373 : bool CollectClassList(std::vector<int> &anClassCount);
374 :
375 : OGRErr GetExtent(OGREnvelope *psExtent, int bForce);
376 :
377 : char *RecodeByDSSI(const char *SourceString, bool LookAtAALL_NALL);
378 : };
379 :
380 : /************************************************************************/
381 : /* S57Writer */
382 : /************************************************************************/
383 :
384 : class CPL_DLL S57Writer
385 : {
386 : public:
387 : static const int nDEFAULT_EXPP = 1;
388 : static const int nDEFAULT_INTU = 4;
389 : static const int nDEFAULT_AGEN = 540;
390 :
391 : static const int nDEFAULT_HDAT = 2;
392 : static const int nDEFAULT_VDAT = 7;
393 : static const int nDEFAULT_SDAT = 23;
394 : static const int nDEFAULT_CSCL = 52000;
395 : static const int nDEFAULT_COMF = 10000000;
396 : static const int nDEFAULT_SOMF = 10;
397 :
398 : S57Writer();
399 : ~S57Writer();
400 :
401 : void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
402 : bool CreateS57File(const char *pszFilename);
403 : bool Close();
404 :
405 : bool WriteGeometry(DDFRecord *, int, const double *, const double *,
406 : const double *);
407 : bool WriteATTF(DDFRecord *, OGRFeature *);
408 : bool WritePrimitive(OGRFeature *poFeature);
409 : bool WriteCompleteFeature(OGRFeature *poFeature);
410 : bool WriteDSID(int nEXPP = nDEFAULT_EXPP, int nINTU = nDEFAULT_INTU,
411 : const char *pszDSNM = nullptr, const char *pszEDTN = nullptr,
412 : const char *pszUPDN = nullptr, const char *pszUADT = nullptr,
413 : const char *pszISDT = nullptr, const char *pszSTED = nullptr,
414 : int nAGEN = nDEFAULT_AGEN, const char *pszCOMT = nullptr,
415 : int nAALL = 0, int nNALL = 0, int nNOMR = 0, int nNOGR = 0,
416 : int nNOLR = 0, int nNOIN = 0, int nNOCN = 0, int nNOED = 0);
417 : bool WriteDSPM(int nHDAT = nDEFAULT_HDAT, int nVDAT = nDEFAULT_VDAT,
418 : int nSDAT = nDEFAULT_SDAT, int nCSCL = nDEFAULT_CSCL,
419 : int nCOMF = nDEFAULT_COMF, int nSOMF = nDEFAULT_SOMF);
420 :
421 : // semi-private - for sophisticated writers.
422 : DDFRecord *MakeRecord();
423 : DDFModule *poModule;
424 :
425 : private:
426 : int nNext0001Index;
427 : S57ClassRegistrar *poRegistrar;
428 : S57ClassContentExplorer *poClassContentExplorer;
429 :
430 : int m_nCOMF; /* Coordinate multiplier */
431 : int m_nSOMF; /* Vertical (sounding) multiplier */
432 : };
433 :
434 : /* -------------------------------------------------------------------- */
435 : /* Functions to create OGRFeatureDefns. */
436 : /* -------------------------------------------------------------------- */
437 : void CPL_DLL S57GenerateStandardAttributes(OGRFeatureDefn *, int);
438 : OGRFeatureDefn CPL_DLL *S57GenerateGeomFeatureDefn(OGRwkbGeometryType, int);
439 : OGRFeatureDefn CPL_DLL *
440 : S57GenerateObjectClassDefn(S57ClassRegistrar *,
441 : S57ClassContentExplorer *poClassContentExplorer, int,
442 : int);
443 : OGRFeatureDefn CPL_DLL *S57GenerateVectorPrimitiveFeatureDefn(int, int);
444 : OGRFeatureDefn CPL_DLL *S57GenerateDSIDFeatureDefn(void);
445 :
446 : #endif /* ndef S57_H_INCLUDED */
|