Line data Source code
1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Project: S-57 Translator
5 : * Purpose: Declarations for S-57 translator not including the
6 : * binding onto OGRLayer/DataSource/Driver which are found in
7 : * ogr_s57.h.
8 : * Author: Frank Warmerdam, warmerdam@pobox.com
9 : *
10 : ******************************************************************************
11 : * Copyright (c) 1999, Frank Warmerdam
12 : * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com>
13 : *
14 : * SPDX-License-Identifier: MIT
15 : ****************************************************************************/
16 :
17 : #ifndef S57_H_INCLUDED
18 : #define S57_H_INCLUDED
19 :
20 : #include <string>
21 : #include <vector>
22 : #include "ogr_feature.h"
23 : #include "iso8211.h"
24 :
25 : class S57Reader;
26 :
27 : char **S57FileCollector(const char *pszDataset);
28 :
29 : #define EMPTY_NUMBER_MARKER 2147483641 /* MAXINT-6 */
30 :
31 : /* -------------------------------------------------------------------- */
32 : /* Various option strings. */
33 : /* -------------------------------------------------------------------- */
34 : #define S57O_UPDATES "UPDATES"
35 : #define S57O_LNAM_REFS "LNAM_REFS"
36 : #define S57O_SPLIT_MULTIPOINT "SPLIT_MULTIPOINT"
37 : #define S57O_ADD_SOUNDG_DEPTH "ADD_SOUNDG_DEPTH"
38 : #define S57O_PRESERVE_EMPTY_NUMBERS "PRESERVE_EMPTY_NUMBERS"
39 : #define S57O_RETURN_PRIMITIVES "RETURN_PRIMITIVES"
40 : #define S57O_RETURN_LINKAGES "RETURN_LINKAGES"
41 : #define S57O_RETURN_DSID "RETURN_DSID"
42 : #define S57O_RECODE_BY_DSSI "RECODE_BY_DSSI"
43 : #define S57O_LIST_AS_STRING "LIST_AS_STRING"
44 :
45 : #define S57M_UPDATES 0x01
46 : #define S57M_LNAM_REFS 0x02
47 : #define S57M_SPLIT_MULTIPOINT 0x04
48 : #define S57M_ADD_SOUNDG_DEPTH 0x08
49 : #define S57M_PRESERVE_EMPTY_NUMBERS 0x10
50 : #define S57M_RETURN_PRIMITIVES 0x20
51 : #define S57M_RETURN_LINKAGES 0x40
52 : #define S57M_RETURN_DSID 0x80
53 : #define S57M_RECODE_BY_DSSI 0x100
54 : #define S57M_LIST_AS_STRING 0x200
55 :
56 : /* -------------------------------------------------------------------- */
57 : /* RCNM values. */
58 : /* -------------------------------------------------------------------- */
59 :
60 : #define RCNM_FE 100 /* Feature record */
61 :
62 : #define RCNM_VI 110 /* Isolated Node */
63 : #define RCNM_VC 120 /* Connected Node */
64 : #define RCNM_VE 130 /* Edge */
65 : #define RCNM_VF 140 /* Face */
66 :
67 : #define RCNM_DSID 10
68 :
69 : #define OGRN_VI "IsolatedNode"
70 : #define OGRN_VC "ConnectedNode"
71 : #define OGRN_VE "Edge"
72 : #define OGRN_VF "Face"
73 :
74 : /* -------------------------------------------------------------------- */
75 : /* FRID PRIM values. */
76 : /* -------------------------------------------------------------------- */
77 : #define PRIM_P 1 /* point feature */
78 : #define PRIM_L 2 /* line feature */
79 : #define PRIM_A 3 /* area feature */
80 : #define PRIM_N 4 /* non-spatial feature */
81 :
82 : /************************************************************************/
83 : /* S57ClassRegistrar */
84 : /************************************************************************/
85 :
86 : class S57ClassContentExplorer;
87 :
88 : class CPL_DLL S57AttrInfo
89 : {
90 : public:
91 : CPLString osName;
92 : CPLString osAcronym;
93 : char chType;
94 : char chClass;
95 : };
96 :
97 : class CPL_DLL S57ClassRegistrar
98 : {
99 : friend class S57ClassContentExplorer;
100 :
101 : // Class information:
102 : int nClasses;
103 : CPLStringList apszClassesInfo;
104 :
105 : // Attribute Information:
106 : int nAttrCount;
107 : std::vector<S57AttrInfo *> aoAttrInfos;
108 : std::vector<int> anAttrIndex; // sorted by acronym.
109 :
110 : static bool FindFile(const char *pszTarget, const char *pszDirectory,
111 : bool bReportErr, VSILFILE **fp);
112 :
113 : const char *ReadLine(VSILFILE *fp);
114 : char **papszNextLine;
115 :
116 : public:
117 : S57ClassRegistrar();
118 : ~S57ClassRegistrar();
119 :
120 : bool LoadInfo(const char *, const char *, bool);
121 :
122 : // attribute table methods.
123 : // int GetMaxAttrIndex() { return nAttrMax; }
124 : const S57AttrInfo *GetAttrInfo(int i);
125 :
126 : const char *GetAttrName(int i)
127 : {
128 : return GetAttrInfo(i) == nullptr ? nullptr
129 : : aoAttrInfos[i]->osName.c_str();
130 : }
131 :
132 868 : const char *GetAttrAcronym(int i)
133 : {
134 868 : return GetAttrInfo(i) == nullptr ? nullptr
135 868 : : aoAttrInfos[i]->osAcronym.c_str();
136 : }
137 :
138 107776 : char GetAttrType(int i)
139 : {
140 107776 : return GetAttrInfo(i) == nullptr ? '\0' : aoAttrInfos[i]->chType;
141 : }
142 :
143 : #define SAT_ENUM 'E'
144 : #define SAT_LIST 'L'
145 : #define SAT_FLOAT 'F'
146 : #define SAT_INT 'I'
147 : #define SAT_CODE_STRING 'A'
148 : #define SAT_FREE_TEXT 'S'
149 :
150 : char GetAttrClass(int i)
151 : {
152 : return GetAttrInfo(i) == nullptr ? '\0' : aoAttrInfos[i]->chClass;
153 : }
154 :
155 : int FindAttrByAcronym(const char *);
156 : };
157 :
158 : /************************************************************************/
159 : /* S57ClassContentExplorer */
160 : /************************************************************************/
161 :
162 : class S57ClassContentExplorer
163 : {
164 : S57ClassRegistrar *poRegistrar;
165 :
166 : char ***papapszClassesFields;
167 :
168 : int iCurrentClass;
169 :
170 : char **papszCurrentFields;
171 :
172 : char **papszTempResult;
173 :
174 : public:
175 : explicit S57ClassContentExplorer(S57ClassRegistrar *poRegistrar);
176 : ~S57ClassContentExplorer();
177 :
178 : bool SelectClassByIndex(int);
179 : bool SelectClass(int);
180 : bool SelectClass(const char *);
181 :
182 18 : bool Rewind()
183 : {
184 18 : return SelectClassByIndex(0);
185 : }
186 :
187 5112 : bool NextClass()
188 : {
189 5112 : return SelectClassByIndex(iCurrentClass + 1);
190 : }
191 :
192 : int GetOBJL();
193 : const char *GetDescription() const;
194 : const char *GetAcronym() const;
195 :
196 : char **GetAttributeList(const char * = nullptr);
197 :
198 : char GetClassCode() const;
199 : char **GetPrimitives();
200 : };
201 :
202 : /************************************************************************/
203 : /* DDFRecordIndex */
204 : /* */
205 : /* Maintain an index of DDF records based on an integer key. */
206 : /************************************************************************/
207 :
208 : typedef struct
209 : {
210 : int nKey;
211 : DDFRecord *poRecord;
212 : void *pClientData;
213 : } DDFIndexedRecord;
214 :
215 : class CPL_DLL DDFRecordIndex
216 : {
217 : bool bSorted;
218 :
219 : int nRecordCount;
220 : int nRecordMax;
221 :
222 : int nLastObjlPos; // Added for FindRecordByObjl().
223 : int nLastObjl; // Added for FindRecordByObjl().
224 :
225 : DDFIndexedRecord *pasRecords;
226 :
227 : void Sort();
228 :
229 : public:
230 : DDFRecordIndex();
231 : ~DDFRecordIndex();
232 :
233 : void AddRecord(int nKey, DDFRecord *);
234 : bool RemoveRecord(int nKey);
235 :
236 : DDFRecord *FindRecord(int nKey);
237 :
238 : DDFRecord *FindRecordByObjl(int nObjl); // Added for FindRecordByObjl().
239 :
240 : void Clear();
241 :
242 10073 : int GetCount()
243 : {
244 10073 : return nRecordCount;
245 : }
246 :
247 : DDFRecord *GetByIndex(int i);
248 : void *GetClientInfoByIndex(int i);
249 : void SetClientInfoByIndex(int i, void *pClientInfo);
250 : };
251 :
252 : /************************************************************************/
253 : /* S57Reader */
254 : /************************************************************************/
255 :
256 : class CPL_DLL S57Reader
257 : {
258 : S57ClassRegistrar *poRegistrar;
259 : S57ClassContentExplorer *poClassContentExplorer;
260 :
261 : int nFDefnCount;
262 : OGRFeatureDefn **papoFDefnList;
263 :
264 : std::vector<OGRFeatureDefn *> apoFDefnByOBJL;
265 :
266 : char *pszModuleName;
267 : char *pszDSNM;
268 :
269 : DDFModule *poModule;
270 :
271 : int nCOMF; /* Coordinate multiplier */
272 : int nSOMF; /* Vertical (sounding) multiplier */
273 :
274 : bool bFileIngested;
275 : DDFRecordIndex oVI_Index;
276 : DDFRecordIndex oVC_Index;
277 : DDFRecordIndex oVE_Index;
278 : DDFRecordIndex oVF_Index;
279 :
280 : int nNextVIIndex;
281 : int nNextVCIndex;
282 : int nNextVEIndex;
283 : int nNextVFIndex;
284 :
285 : int nNextFEIndex;
286 : DDFRecordIndex oFE_Index;
287 :
288 : int nNextDSIDIndex;
289 : DDFRecord *poDSIDRecord;
290 : DDFRecord *poDSPMRecord;
291 : std::string m_osEDTNUpdate;
292 : std::string m_osUPDNUpdate;
293 : std::string m_osISDTUpdate;
294 :
295 : char **papszOptions;
296 :
297 : int nOptionFlags;
298 :
299 : int iPointOffset;
300 : OGRFeature *poMultiPoint;
301 :
302 : int Aall; // see RecodeByDSSI() function
303 : int Nall; // see RecodeByDSSI() function
304 : bool needAallNallSetup; // see RecodeByDSSI() function
305 :
306 : void ClearPendingMultiPoint();
307 : OGRFeature *NextPendingMultiPoint();
308 :
309 : OGRFeature *AssembleFeature(DDFRecord *, OGRFeatureDefn *);
310 :
311 : void ApplyObjectClassAttributes(DDFRecord *, OGRFeature *);
312 : // cppcheck-suppress functionStatic
313 : void GenerateLNAMAndRefs(DDFRecord *, OGRFeature *);
314 : void GenerateFSPTAttributes(DDFRecord *, OGRFeature *);
315 :
316 : void AssembleSoundingGeometry(DDFRecord *, OGRFeature *);
317 : // cppcheck-suppress functionStatic
318 : void AssemblePointGeometry(DDFRecord *, OGRFeature *);
319 : void AssembleLineGeometry(DDFRecord *, OGRFeature *);
320 : void AssembleAreaGeometry(DDFRecord *, OGRFeature *);
321 :
322 : bool FetchPoint(int, int, double *, double *, double * = nullptr);
323 : bool FetchLine(DDFRecord *, int, int, OGRLineString *);
324 :
325 : OGRFeatureDefn *FindFDefn(DDFRecord *);
326 : int ParseName(DDFField *, int = 0, int * = nullptr);
327 :
328 : // cppcheck-suppress functionStatic
329 : bool ApplyRecordUpdate(DDFRecord *, DDFRecord *);
330 :
331 : bool bMissingWarningIssued;
332 : bool bAttrWarningIssued;
333 :
334 : public:
335 : explicit S57Reader(const char *);
336 : ~S57Reader();
337 :
338 : void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
339 : bool SetOptions(char **);
340 :
341 364 : int GetOptionFlags()
342 : {
343 364 : return nOptionFlags;
344 : }
345 :
346 : int Open(int bTestOpen);
347 : void Close();
348 :
349 490 : DDFModule *GetModule()
350 : {
351 490 : return poModule;
352 : }
353 :
354 : const char *GetDSNM()
355 : {
356 : return pszDSNM;
357 : }
358 :
359 : bool Ingest();
360 : bool ApplyUpdates(DDFModule *);
361 : bool FindAndApplyUpdates(const char *pszPath = nullptr);
362 :
363 : void Rewind();
364 : OGRFeature *ReadNextFeature(OGRFeatureDefn * = nullptr);
365 : OGRFeature *ReadFeature(int nFID, OGRFeatureDefn * = nullptr);
366 : OGRFeature *ReadVector(int nFID, int nRCNM);
367 : OGRFeature *ReadDSID();
368 :
369 : int GetNextFEIndex(int nRCNM = 100);
370 : void SetNextFEIndex(int nNewIndex, int nRCNM = 100);
371 :
372 : void AddFeatureDefn(OGRFeatureDefn *);
373 :
374 : bool CollectClassList(std::vector<int> &anClassCount);
375 :
376 : OGRErr GetExtent(OGREnvelope *psExtent, int bForce);
377 :
378 : char *RecodeByDSSI(const char *SourceString, bool LookAtAALL_NALL);
379 : };
380 :
381 : /************************************************************************/
382 : /* S57Writer */
383 : /************************************************************************/
384 :
385 : class CPL_DLL S57Writer
386 : {
387 : public:
388 : static const int nDEFAULT_EXPP = 1;
389 : static const int nDEFAULT_INTU = 4;
390 : static const int nDEFAULT_AGEN = 540;
391 :
392 : static const int nDEFAULT_HDAT = 2;
393 : static const int nDEFAULT_VDAT = 7;
394 : static const int nDEFAULT_SDAT = 23;
395 : static const int nDEFAULT_CSCL = 52000;
396 : static const int nDEFAULT_COMF = 10000000;
397 : static const int nDEFAULT_SOMF = 10;
398 :
399 : S57Writer();
400 : ~S57Writer();
401 :
402 : void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
403 : bool CreateS57File(const char *pszFilename);
404 : bool Close();
405 :
406 : bool WriteGeometry(DDFRecord *, int, const double *, const double *,
407 : const double *);
408 : bool WriteATTF(DDFRecord *, OGRFeature *);
409 : bool WritePrimitive(OGRFeature *poFeature);
410 : bool WriteCompleteFeature(OGRFeature *poFeature);
411 : bool WriteDSID(int nEXPP = nDEFAULT_EXPP, int nINTU = nDEFAULT_INTU,
412 : const char *pszDSNM = nullptr, const char *pszEDTN = nullptr,
413 : const char *pszUPDN = nullptr, const char *pszUADT = nullptr,
414 : const char *pszISDT = nullptr, const char *pszSTED = nullptr,
415 : int nAGEN = nDEFAULT_AGEN, const char *pszCOMT = nullptr,
416 : int nAALL = 0, int nNALL = 0, int nNOMR = 0, int nNOGR = 0,
417 : int nNOLR = 0, int nNOIN = 0, int nNOCN = 0, int nNOED = 0);
418 : bool WriteDSPM(int nHDAT = nDEFAULT_HDAT, int nVDAT = nDEFAULT_VDAT,
419 : int nSDAT = nDEFAULT_SDAT, int nCSCL = nDEFAULT_CSCL,
420 : int nCOMF = nDEFAULT_COMF, int nSOMF = nDEFAULT_SOMF);
421 :
422 : // semi-private - for sophisticated writers.
423 : DDFRecord *MakeRecord();
424 : DDFModule *poModule;
425 :
426 : private:
427 : int nNext0001Index;
428 : S57ClassRegistrar *poRegistrar;
429 : S57ClassContentExplorer *poClassContentExplorer;
430 :
431 : int m_nCOMF; /* Coordinate multiplier */
432 : int m_nSOMF; /* Vertical (sounding) multiplier */
433 : };
434 :
435 : /* -------------------------------------------------------------------- */
436 : /* Functions to create OGRFeatureDefns. */
437 : /* -------------------------------------------------------------------- */
438 : void CPL_DLL S57GenerateStandardAttributes(OGRFeatureDefn *, int);
439 : OGRFeatureDefn CPL_DLL *S57GenerateGeomFeatureDefn(OGRwkbGeometryType, int);
440 : OGRFeatureDefn CPL_DLL *
441 : S57GenerateObjectClassDefn(S57ClassRegistrar *,
442 : S57ClassContentExplorer *poClassContentExplorer, int,
443 : int);
444 : OGRFeatureDefn CPL_DLL *S57GenerateVectorPrimitiveFeatureDefn(int, int);
445 : OGRFeatureDefn CPL_DLL *S57GenerateDSIDFeatureDefn(void);
446 :
447 : #endif /* ndef S57_H_INCLUDED */
|