OpenCPN Partial API docs
Osenc.h
1 /***************************************************************************
2  *
3  * Project: OpenCPN
4  * Purpose: S57 SENC File Object
5  * Author: David Register
6  *
7  ***************************************************************************
8  * Copyright (C) 2015 by David S. Register *
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  * This program is distributed in the hope that it will be useful, *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18  * GNU General Public License for more details. *
19  * *
20  * You should have received a copy of the GNU General Public License *
21  * along with this program; if not, write to the *
22  * Free Software Foundation, Inc., *
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24  **************************************************************************/
25 
26 #ifndef OSENC_H
27 #define OSENC_H
28 
29 // For compilers that support precompilation, includes "wx.h".
30 #include "wx/wxprec.h"
31 
32 #ifndef WX_PRECOMP
33 #include "wx/wx.h"
34 #endif // precompiled headers
35 
36 #include <wx/filename.h>
37 
38 #include "gdal/cpl_csv.h"
39 #include "ogr_s57.h"
40 #include "s52s57.h"
41 #include "chartbase.h"
42 
43 #include <string.h>
44 #include <stdint.h>
45 #include <vector>
46 #include <mutex>
47 #include <unordered_map>
48 
49 WX_DEFINE_ARRAY_PTR(float *, SENCFloatPtrArray);
50 
51 // Various error return enums
52 #define SENC_NO_ERROR 0
53 #define ERROR_SENCFILE_NOT_FOUND 1
54 #define ERROR_SENC_VERSION_MISMATCH 2
55 #define ERROR_CANNOT_CREATE_SENC_DIR 3
56 #define ERROR_CANNOT_CREATE_TEMP_SENC_FILE 4
57 #define ERROR_INGESTING000 5
58 #define ERROR_REGISTRAR_NOT_SET 6
59 #define ERROR_BASEFILE_ATTRIBUTES 7
60 #define ERROR_SENCFILE_ABORT 8
61 
62 // OSENC V2 record definitions
63 #define HEADER_SENC_VERSION 1
64 #define HEADER_CELL_NAME 2
65 #define HEADER_CELL_PUBLISHDATE 3
66 #define HEADER_CELL_EDITION 4
67 #define HEADER_CELL_UPDATEDATE 5
68 #define HEADER_CELL_UPDATE 6
69 #define HEADER_CELL_NATIVESCALE 7
70 #define HEADER_CELL_SENCCREATEDATE 8
71 
72 #define FEATURE_ID_RECORD 64
73 #define FEATURE_ATTRIBUTE_RECORD 65
74 
75 #define FEATURE_GEOMETRY_RECORD_POINT 80
76 #define FEATURE_GEOMETRY_RECORD_LINE 81
77 #define FEATURE_GEOMETRY_RECORD_AREA 82
78 #define FEATURE_GEOMETRY_RECORD_MULTIPOINT 83
79 
80 #define VECTOR_EDGE_NODE_TABLE_RECORD 96
81 #define VECTOR_CONNECTED_NODE_TABLE_RECORD 97
82 
83 #define CELL_COVR_RECORD 98
84 #define CELL_NOCOVR_RECORD 99
85 #define CELL_EXTENT_RECORD 100
86 
87 //--------------------------------------------------------------------------
88 // Utility Structures
89 //--------------------------------------------------------------------------
90 #pragma pack(push, 1)
91 
92 typedef struct _OSENC_Record_Base {
93  uint16_t record_type;
94  uint32_t record_length;
96 
97 typedef struct _OSENC_Record {
98  uint16_t record_type;
99  uint32_t record_length;
100  unsigned char payload;
101 } OSENC_Record;
102 
104  uint16_t record_type;
105  uint32_t record_length;
106  uint16_t feature_type_code;
107  uint16_t feature_ID;
108  uint8_t feature_primitive;
110 
112  uint16_t feature_type_code;
113  uint16_t feature_ID;
114  uint8_t feature_primitive;
116 
118  uint16_t record_type;
119  uint32_t record_length;
120  uint16_t attribute_type;
121  unsigned char attribute_value_type;
123 
124 typedef struct _OSENC_Attribute_Record {
125  uint16_t record_type;
126  uint32_t record_length;
127  uint16_t attribute_type;
128  unsigned char attribute_value_type;
129  void *payload;
131 
133  uint16_t attribute_type_code;
134  unsigned char attribute_value_type;
135 
136  union {
137  uint32_t attribute_value_int;
138  double attribute_value_double;
139  char *attribute_value_char_ptr;
140  };
142 
144  uint16_t record_type;
145  uint32_t record_length;
146  double lat;
147  double lon;
149 
151  double lat;
152  double lon;
154 
156  uint16_t record_type;
157  uint32_t record_length;
158  double extent_s_lat;
159  double extent_n_lat;
160  double extent_w_lon;
161  double extent_e_lon;
162  uint32_t point_count;
164 
166  double extent_s_lat;
167  double extent_n_lat;
168  double extent_w_lon;
169  double extent_e_lon;
170  uint32_t point_count;
171  void *payLoad;
173 
175  uint16_t record_type;
176  uint32_t record_length;
177  double extent_s_lat;
178  double extent_n_lat;
179  double extent_w_lon;
180  double extent_e_lon;
181  uint32_t edgeVector_count;
183 
185  double extent_s_lat;
186  double extent_n_lat;
187  double extent_w_lon;
188  double extent_e_lon;
189  uint32_t edgeVector_count;
190  void *payLoad;
192 
194  uint16_t record_type;
195  uint32_t record_length;
196  double extent_s_lat;
197  double extent_n_lat;
198  double extent_w_lon;
199  double extent_e_lon;
200  uint32_t contour_count;
201  uint32_t triprim_count;
202  uint32_t edgeVector_count;
204 
206  double extent_s_lat;
207  double extent_n_lat;
208  double extent_w_lon;
209  double extent_e_lon;
210  uint32_t contour_count;
211  uint32_t triprim_count;
212  uint32_t edgeVector_count;
213  void *payLoad;
215 
216 typedef struct _OSENC_VET_Record {
217  uint16_t record_type;
218  uint32_t record_length;
219  unsigned char payload;
221 
222 typedef struct _OSENC_VET_Record_Base {
223  uint16_t record_type;
224  uint32_t record_length;
226 
227 typedef struct _OSENC_VCT_Record {
228  uint16_t record_type;
229  uint32_t record_length;
230  unsigned char payload;
232 
233 typedef struct _OSENC_VCT_Record_Base {
234  uint16_t record_type;
235  uint32_t record_length;
237 
238 typedef struct _OSENC_COVR_Record {
239  uint16_t record_type;
240  uint32_t record_length;
241  unsigned char payload;
243 
244 typedef struct _OSENC_COVR_Record_Base {
245  uint16_t record_type;
246  uint32_t record_length;
248 
250  uint32_t point_count;
251  float point_array;
253 
254 typedef struct _OSENC_NOCOVR_Record {
255  uint16_t record_type;
256  uint32_t record_length;
257  unsigned char payload;
259 
261  uint16_t record_type;
262  uint32_t record_length;
264 
266  uint32_t point_count;
267  float point_array;
269 
270 typedef struct _OSENC_EXTENT_Record {
271  uint16_t record_type;
272  uint32_t record_length;
273  double extent_sw_lat;
274  double extent_sw_lon;
275  double extent_nw_lat;
276  double extent_nw_lon;
277  double extent_ne_lat;
278  double extent_ne_lon;
279  double extent_se_lat;
280  double extent_se_lon;
282 
284  double extent_sw_lat;
285  double extent_sw_lon;
286  double extent_nw_lat;
287  double extent_nw_lon;
288  double extent_ne_lat;
289  double extent_ne_lon;
290  double extent_se_lat;
291  double extent_se_lon;
293 
294 #pragma pack(pop)
295 
296 // Some special defined attribute type codes
297 // Should also be defined in a57attributes.csv
298 
299 #define ATTRIBUTE_ID_PRIM 50000
300 
301 const char *MyCSVGetField(const char *pszFilename, const char *pszKeyFieldName,
302  const char *pszKeyFieldValue,
303  CSVCompareCriteria eCriteria,
304  const char *pszTargetField);
305 
306 // Fwd Definitions
307 class wxGenericProgressDialog;
308 class S57Obj;
309 class VE_Element;
310 class VC_Element;
311 class PolyTessGeo;
312 class LineGeometryDescriptor;
313 class wxFFileInputStream;
314 
315 typedef std::vector<S57Obj *> S57ObjVector;
316 typedef std::vector<VE_Element *> VE_ElementVector;
317 typedef std::vector<VC_Element *> VC_ElementVector;
318 
319 //--------------------------------------------------------------------------
320 // Osenc_instream definition
321 //--------------------------------------------------------------------------
323 public:
324  Osenc_instream(){};
325  virtual ~Osenc_instream(){};
326 
327  virtual bool Open(const wxString &senc_file_name) = 0;
328  virtual void Close() = 0;
329 
330  virtual Osenc_instream &Read(void *buffer, size_t size) = 0;
331  virtual bool IsOk() = 0;
332  virtual bool isAvailable() = 0;
333  virtual void Shutdown() = 0;
334 };
335 
336 //--------------------------------------------------------------------------
337 // Osenc_instreamFile definition
338 // A simple file stream implementation based on wxFFileInputStream
339 //--------------------------------------------------------------------------
341 public:
344 
345  bool Open(const wxString &senc_file_name);
346  void Close();
347 
348  Osenc_instream &Read(void *buffer, size_t size);
349  bool IsOk();
350  bool isAvailable();
351  void Shutdown();
352 
353 private:
354  void Init();
355 
356  wxFFileInputStream *m_instream;
357  bool m_ok;
358 };
359 
360 //--------------------------------------------------------------------------
361 // Osenc_outstream definition
362 //--------------------------------------------------------------------------
364 public:
365  Osenc_outstream(){};
366  virtual ~Osenc_outstream(){};
367 
368  virtual bool Open(const wxString &ofileName) = 0;
369 
370  virtual Osenc_outstream &Write(const void *buffer, size_t size) = 0;
371  virtual void Close() = 0;
372  virtual bool IsOk() = 0;
373 };
374 
375 //--------------------------------------------------------------------------
376 // Osenc_outstreamFile definition
377 // A simple file stream implementation based on wxFFileInputStream
378 //--------------------------------------------------------------------------
380 public:
383 
384  bool Open(const wxString &ofileName);
385 
386  Osenc_outstream &Write(const void *buffer, size_t size);
387  void Close();
388  bool IsOk();
389 
390 private:
391  void Init();
392 
393  wxFFileOutputStream *m_outstream;
394  bool m_ok;
395 };
396 
397 //--------------------------------------------------------------------------
398 // Osenc definition
399 //--------------------------------------------------------------------------
400 
401 class Osenc {
402 public:
403  Osenc();
404  ~Osenc();
405 
406  wxString getLastError() { return errorMessage; }
407  void setVerbose(bool verbose);
408  void setNoErrDialog(bool val) { m_NoErrDialog = val; }
409 
410  int ingestHeader(const wxString &senc_file_name);
411  int ingest(const wxString &senc_file_name, S57ObjVector *pObjectVector,
412  VE_ElementVector *pVEArray, VC_ElementVector *pVCArray);
413 
414  int ingest200(const wxString &senc_file_name, S57ObjVector *pObjectVector,
415  VE_ElementVector *pVEArray, VC_ElementVector *pVCArray);
416 
417  // SENC creation, by Version desired...
418  void SetLODMeters(double meters) { m_LOD_meters = meters; }
419  void setRegistrar(S57ClassRegistrar *registrar) { m_poRegistrar = registrar; }
420  void setRefLocn(double lat, double lon) {
421  m_ref_lat = lat;
422  m_ref_lon = lon;
423  }
424  void setOutstream(Osenc_outstream *stream) { m_pauxOutstream = stream; }
425  void setInstream(Osenc_instream *stream) { m_pauxInstream = stream; }
426 
427  wxString getUpdateDate() { return m_LastUpdateDate; }
428  wxString getBaseDate() { return m_sdate000; }
429 
430  wxString getSENCFileCreateDate() { return m_readFileCreateDate; }
431 
432  int getSencReadVersion() { return m_senc_file_read_version; }
433  wxString getSENCReadBaseEdition() { return m_read_base_edtn; }
434  int getSENCReadLastUpdate() { return m_read_last_applied_update; }
435  int getSENCReadScale() { return m_Chart_Scale; }
436  wxString getReadName() { return m_Name; }
437  wxString getReadID() { return m_ID; }
438  Extent &getReadExtent() { return m_extent; }
439 
440  SENCFloatPtrArray &getSENCReadAuxPointArray() { return m_AuxPtrArray; }
441  std::vector<int> &getSENCReadAuxPointCountArray() { return m_AuxCntArray; }
442  SENCFloatPtrArray &getSENCReadNOCOVRPointArray() { return m_NoCovrPtrArray; }
443  std::vector<int> &getSENCReadNOCOVRPointCountArray() {
444  return m_NoCovrCntArray;
445  }
446 
447  int createSenc200(const wxString &FullPath000, const wxString &SENCFileName,
448  bool b_showProg = true);
449 
450  void CreateSENCVectorEdgeTableRecord200(Osenc_outstream *stream,
451  S57Reader *poReader);
452  void CreateSENCVectorConnectedTableRecord200(Osenc_outstream *stream,
453  S57Reader *poReader);
454 
455  void InitializePersistentBuffer(void);
456  unsigned char *getBuffer(size_t length);
457 
458  int getNativeScale() { return m_native_scale; }
459  int GetBaseFileInfo(const wxString &FullPath000,
460  const wxString &SENCFileName);
461 
462  std::unique_lock<std::mutex> lockCR;
463 
464 private:
465  void init();
466 
467  int ingestCell(OGRS57DataSource *poS57DS, const wxString &FullPath000,
468  const wxString &working_dir);
469  int ValidateAndCountUpdates(const wxFileName file000, const wxString CopyDir,
470  wxString &LastUpdateDate, bool b_copyfiles);
471  int GetUpdateFileArray(const wxFileName file000, wxArrayString *UpFiles);
472  bool GetBaseFileAttr(const wxString &FullPath000);
473  unsigned char *getObjectVectorIndexTable(S57Reader *poReader,
474  OGRFeature *poFeature,
475  int &nEntries);
476 
477  OGRFeature *GetChartFirstM_COVR(int &catcov, S57Reader *pENCReader,
478  S57ClassRegistrar *poRegistrar);
479  OGRFeature *GetChartNextM_COVR(int &catcov, S57Reader *pENCReader);
480  bool CreateCOVRTables(S57Reader *pENCReader, S57ClassRegistrar *poRegistrar);
481  bool CreateCovrRecords(Osenc_outstream *stream);
482 
483  void CreateSENCRecord124(OGRFeature *pFeature, Osenc_outstream *stream,
484  int mode, S57Reader *poReader);
485  void CreateSENCVectorEdgeTable(Osenc_outstream *stream, S57Reader *poReader);
486  void CreateSENCConnNodeTable(Osenc_outstream *stream, S57Reader *poReader);
487 
488  bool CreateSENCRecord200(OGRFeature *pFeature, Osenc_outstream *stream,
489  int mode, S57Reader *poReader);
490  bool WriteFIDRecord200(Osenc_outstream *stream, int nOBJL, int featureID,
491  int prim);
492  bool WriteHeaderRecord200(Osenc_outstream *stream, int recordType,
493  std::string payload);
494  bool WriteHeaderRecord200(Osenc_outstream *stream, int recordType,
495  uint16_t value);
496  bool WriteHeaderRecord200(Osenc_outstream *stream, int recordType,
497  uint32_t value);
498  bool CreateAreaFeatureGeometryRecord200(S57Reader *poReader,
499  OGRFeature *pFeature,
500  Osenc_outstream *stream);
501  bool CreateLineFeatureGeometryRecord200(S57Reader *poReader,
502  OGRFeature *pFeature,
503  Osenc_outstream *stream);
504  bool CreateMultiPointFeatureGeometryRecord200(OGRFeature *pFeature,
505  Osenc_outstream *stream);
506 
507  std::string GetFeatureAcronymFromTypecode(int typeCode);
508  std::string GetAttributeAcronymFromTypecode(int typeCode);
509 
510  PolyTessGeo *BuildPolyTessGeo(_OSENC_AreaGeometry_Record_Payload *record,
511  unsigned char **bytes_consumed);
512  bool CalculateExtent(S57Reader *poReader, S57ClassRegistrar *poRegistrar);
513 
514  wxString errorMessage;
515 
516  wxString m_Name;
517  wxString m_ID;
518  wxString m_FullPath000;
519 
520  int m_Chart_Scale;
521  int m_senc_file_read_version;
522  int m_senc_file_create_version;
523  wxString m_read_base_edtn;
524  int m_read_last_applied_update;
525 
526  S57Reader *poReader;
527 
528  wxDateTime m_date000;
529  wxString m_sdate000;
530 
531  wxString m_edtn000;
532  int m_UPDN;
533 
534  int m_nGeoRecords;
535  int m_last_applied_update;
536  wxString m_LastUpdateDate;
537  int m_native_scale;
538  wxString m_readFileCreateDate;
539 
540  double m_ref_lat,
541  m_ref_lon; // Common reference point, derived from FullExtent
542  std::unordered_map<int, int> m_vector_helper_hash;
543  double m_LOD_meters;
544  S57ClassRegistrar *m_poRegistrar;
545  wxArrayString m_tmpup_array;
546 
547  wxGenericProgressDialog *m_ProgDialog;
548 
549  unsigned char *pBuffer;
550  size_t bufferSize;
551 
552  Extent m_extent;
553 
554  // Clone of Chartbase structures of the same name and purpose
555  // Use mainly for SENC creation for ENC(.000) file
556  int m_nCOVREntries; // number of coverage table entries
557  int *m_pCOVRTablePoints; // int table of number of points in each coverage
558  // table entry
559  float **m_pCOVRTable; // table of pointers to list of floats describing valid
560  // COVR
561 
562  int m_nNoCOVREntries; // number of NoCoverage table entries
563  int *m_pNoCOVRTablePoints; // int table of number of points in each
564  // NoCoverage table entry
565  float **m_pNoCOVRTable; // table of pointers to list of floats describing
566  // valid NOCOVR
567 
568  // Arrays used to accumulate coverage regions on oSENC load
569  SENCFloatPtrArray m_AuxPtrArray;
570  std::vector<int> m_AuxCntArray;
571  SENCFloatPtrArray m_NoCovrPtrArray;
572  std::vector<int> m_NoCovrCntArray;
573 
574  Osenc_outstream *m_pauxOutstream;
575  Osenc_instream *m_pauxInstream;
576 
577  Osenc_outstream *m_pOutstream;
578  Osenc_instream *m_pInstream;
579 
580  bool m_bVerbose;
581  wxArrayString *m_UpFiles;
582  bool m_bPrivateRegistrar;
583  bool m_NoErrDialog;
584 };
585 
586 #endif // Guard
Definition: Osenc.h:401