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