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 : #include "ddfrecordindex.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 22791 : const char *GetAttrAcronym(int i)
133 : {
134 22791 : return GetAttrInfo(i) == nullptr ? nullptr
135 22791 : : aoAttrInfos[i]->osAcronym.c_str();
136 : }
137 :
138 110047 : char GetAttrType(int i)
139 : {
140 110047 : 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 : /* S57Reader */
204 : /************************************************************************/
205 :
206 : class CPL_DLL S57Reader
207 : {
208 : S57ClassRegistrar *poRegistrar = nullptr;
209 : S57ClassContentExplorer *poClassContentExplorer = nullptr;
210 :
211 : int nFDefnCount = 0;
212 : OGRFeatureDefn **papoFDefnList = nullptr;
213 :
214 : std::vector<OGRFeatureDefn *> apoFDefnByOBJL{};
215 :
216 : char *pszModuleName = nullptr;
217 : char *pszDSNM = nullptr;
218 :
219 : std::unique_ptr<DDFModule> poModule{};
220 :
221 : int nCOMF = 1000000; /* Coordinate multiplier */
222 : int nSOMF = 10; /* Vertical (sounding) multiplier */
223 :
224 : bool bFileIngested = false;
225 : DDFRecordIndex oVI_Index{};
226 : DDFRecordIndex oVC_Index{};
227 : DDFRecordIndex oVE_Index{};
228 : DDFRecordIndex oVF_Index{};
229 :
230 : int nNextVIIndex = 0;
231 : int nNextVCIndex = 0;
232 : int nNextVEIndex = 0;
233 : int nNextVFIndex = 0;
234 :
235 : int nNextFEIndex = 0;
236 : DDFRecordIndex oFE_Index{};
237 :
238 : int nNextDSIDIndex = 0;
239 : std::unique_ptr<DDFRecord> poDSIDRecord{};
240 : std::unique_ptr<DDFRecord> poDSPMRecord{};
241 : std::string m_osEDTNUpdate{};
242 : std::string m_osUPDNUpdate{};
243 : std::string m_osISDTUpdate{};
244 :
245 : char **papszOptions = nullptr;
246 :
247 : int nOptionFlags = S57M_UPDATES;
248 :
249 : int iPointOffset = 0;
250 : std::unique_ptr<OGRFeature> poMultiPoint{};
251 :
252 : int Aall = 0; // see RecodeByDSSI() function
253 : int Nall = 0; // see RecodeByDSSI() function
254 : bool needAallNallSetup = true; // see RecodeByDSSI() function
255 :
256 : void ClearPendingMultiPoint();
257 : OGRFeature *NextPendingMultiPoint();
258 :
259 : OGRFeature *AssembleFeature(const DDFRecord *, OGRFeatureDefn *);
260 :
261 : void ApplyObjectClassAttributes(const DDFRecord *, OGRFeature *);
262 : static void GenerateLNAMAndRefs(const DDFRecord *, OGRFeature *);
263 : void GenerateFSPTAttributes(const DDFRecord *, OGRFeature *);
264 :
265 : void AssembleSoundingGeometry(const DDFRecord *, OGRFeature *);
266 : // cppcheck-suppress functionStatic
267 : void AssemblePointGeometry(const DDFRecord *, OGRFeature *);
268 : bool AssembleLineGeometry(const DDFRecord *, OGRFeature *);
269 : void AssembleAreaGeometry(const DDFRecord *, OGRFeature *);
270 :
271 : bool FetchPoint(int, int, double *, double *, double * = nullptr);
272 : bool FetchLine(const DDFRecord *, int, int, OGRLineString *);
273 :
274 : const OGRFeatureDefn *FindFDefn(const DDFRecord *);
275 : int ParseName(const DDFField *, int = 0, int * = nullptr);
276 :
277 : // cppcheck-suppress functionStatic
278 : bool ApplyRecordUpdate(DDFRecord *, DDFRecord *);
279 :
280 : bool bMissingWarningIssued = false;
281 : bool bAttrWarningIssued = false;
282 :
283 : public:
284 : explicit S57Reader(const char *);
285 : ~S57Reader();
286 :
287 : void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
288 : bool SetOptions(CSLConstList);
289 :
290 474 : int GetOptionFlags()
291 : {
292 474 : return nOptionFlags;
293 : }
294 :
295 : int Open(int bTestOpen);
296 : void Close();
297 :
298 563 : DDFModule *GetModule()
299 : {
300 563 : return poModule.get();
301 : }
302 :
303 : const char *GetDSNM()
304 : {
305 : return pszDSNM;
306 : }
307 :
308 : bool Ingest();
309 : bool ApplyUpdates(DDFModule *);
310 : bool FindAndApplyUpdates(const char *pszPath = nullptr);
311 :
312 : void Rewind();
313 : OGRFeature *ReadNextFeature(OGRFeatureDefn * = nullptr);
314 : OGRFeature *ReadFeature(int nFID, OGRFeatureDefn * = nullptr);
315 : OGRFeature *ReadVector(int nFID, int nRCNM);
316 : OGRFeature *ReadDSID();
317 :
318 : int GetNextFEIndex(int nRCNM = 100);
319 : void SetNextFEIndex(int nNewIndex, int nRCNM = 100);
320 :
321 : void AddFeatureDefn(OGRFeatureDefn *);
322 :
323 : bool CollectClassList(std::vector<int> &anClassCount);
324 :
325 : OGRErr GetExtent(OGREnvelope *psExtent, int bForce);
326 :
327 : char *RecodeByDSSI(const char *SourceString, bool LookAtAALL_NALL);
328 : };
329 :
330 : /************************************************************************/
331 : /* S57Writer */
332 : /************************************************************************/
333 :
334 : class CPL_DLL S57Writer
335 : {
336 : public:
337 : static const int nDEFAULT_EXPP = 1;
338 : static const int nDEFAULT_INTU = 4;
339 : static const int nDEFAULT_AGEN = 540;
340 :
341 : static const int nDEFAULT_HDAT = 2;
342 : static const int nDEFAULT_VDAT = 7;
343 : static const int nDEFAULT_SDAT = 23;
344 : static const int nDEFAULT_CSCL = 52000;
345 : static const int nDEFAULT_COMF = 10000000;
346 : static const int nDEFAULT_SOMF = 10;
347 :
348 : S57Writer();
349 : ~S57Writer();
350 :
351 : void SetClassBased(S57ClassRegistrar *, S57ClassContentExplorer *);
352 : bool CreateS57File(const char *pszFilename);
353 : bool Close();
354 :
355 : bool WriteGeometry(DDFRecord *, int, const double *, const double *,
356 : const double *);
357 : bool WriteATTF(DDFRecord *, OGRFeature *);
358 : bool WritePrimitive(OGRFeature *poFeature);
359 : bool WriteCompleteFeature(OGRFeature *poFeature);
360 : bool WriteDSID(int nEXPP = nDEFAULT_EXPP, int nINTU = nDEFAULT_INTU,
361 : const char *pszDSNM = nullptr, const char *pszEDTN = nullptr,
362 : const char *pszUPDN = nullptr, const char *pszUADT = nullptr,
363 : const char *pszISDT = nullptr, const char *pszSTED = nullptr,
364 : int nAGEN = nDEFAULT_AGEN, const char *pszCOMT = nullptr,
365 : int nAALL = 0, int nNALL = 0, int nNOMR = 0, int nNOGR = 0,
366 : int nNOLR = 0, int nNOIN = 0, int nNOCN = 0, int nNOED = 0);
367 : bool WriteDSPM(int nHDAT = nDEFAULT_HDAT, int nVDAT = nDEFAULT_VDAT,
368 : int nSDAT = nDEFAULT_SDAT, int nCSCL = nDEFAULT_CSCL,
369 : int nCOMF = nDEFAULT_COMF, int nSOMF = nDEFAULT_SOMF);
370 :
371 : // semi-private - for sophisticated writers.
372 : DDFRecord *MakeRecord();
373 : DDFModule *poModule;
374 :
375 : private:
376 : int nNext0001Index;
377 : S57ClassRegistrar *poRegistrar;
378 : S57ClassContentExplorer *poClassContentExplorer;
379 :
380 : int m_nCOMF; /* Coordinate multiplier */
381 : int m_nSOMF; /* Vertical (sounding) multiplier */
382 : };
383 :
384 : /* -------------------------------------------------------------------- */
385 : /* Functions to create OGRFeatureDefns. */
386 : /* -------------------------------------------------------------------- */
387 : void CPL_DLL S57GenerateStandardAttributes(OGRFeatureDefn *, int);
388 : OGRFeatureDefn CPL_DLL *S57GenerateGeomFeatureDefn(OGRwkbGeometryType, int);
389 : OGRFeatureDefn CPL_DLL *
390 : S57GenerateObjectClassDefn(S57ClassRegistrar *,
391 : S57ClassContentExplorer *poClassContentExplorer, int,
392 : int);
393 : OGRFeatureDefn CPL_DLL *S57GenerateVectorPrimitiveFeatureDefn(int, int);
394 : OGRFeatureDefn CPL_DLL *S57GenerateDSIDFeatureDefn(void);
395 :
396 : #endif /* ndef S57_H_INCLUDED */
|