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 "chartbase.h" 41 42 #include <string.h> 43 #include <stdint.h> 44 #include <vector> 45 #include <mutex> 46 47 WX_DEFINE_ARRAY_PTR(float *, SENCFloatPtrArray); 48 49 // Various error return enums 50 #define SENC_NO_ERROR 0 51 #define ERROR_SENCFILE_NOT_FOUND 1 52 #define ERROR_SENC_VERSION_MISMATCH 2 53 #define ERROR_CANNOT_CREATE_SENC_DIR 3 54 #define ERROR_CANNOT_CREATE_TEMP_SENC_FILE 4 55 #define ERROR_INGESTING000 5 56 #define ERROR_REGISTRAR_NOT_SET 6 57 #define ERROR_BASEFILE_ATTRIBUTES 7 58 #define ERROR_SENCFILE_ABORT 8 59 60 61 // OSENC V2 record definitions 62 #define HEADER_SENC_VERSION 1 63 #define HEADER_CELL_NAME 2 64 #define HEADER_CELL_PUBLISHDATE 3 65 #define HEADER_CELL_EDITION 4 66 #define HEADER_CELL_UPDATEDATE 5 67 #define HEADER_CELL_UPDATE 6 68 #define HEADER_CELL_NATIVESCALE 7 69 #define HEADER_CELL_SENCCREATEDATE 8 70 71 #define FEATURE_ID_RECORD 64 72 #define FEATURE_ATTRIBUTE_RECORD 65 73 74 #define FEATURE_GEOMETRY_RECORD_POINT 80 75 #define FEATURE_GEOMETRY_RECORD_LINE 81 76 #define FEATURE_GEOMETRY_RECORD_AREA 82 77 #define FEATURE_GEOMETRY_RECORD_MULTIPOINT 83 78 79 #define VECTOR_EDGE_NODE_TABLE_RECORD 96 80 #define VECTOR_CONNECTED_NODE_TABLE_RECORD 97 81 82 #define CELL_COVR_RECORD 98 83 #define CELL_NOCOVR_RECORD 99 84 #define CELL_EXTENT_RECORD 100 85 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; 95 }OSENC_Record_Base; 96 97 typedef struct _OSENC_Record{ 98 uint16_t record_type; 99 uint32_t record_length; 100 unsigned char payload; 101 }OSENC_Record; 102 103 104 typedef struct _OSENC_Feature_Identification_Record_Base{ 105 uint16_t record_type; 106 uint32_t record_length; 107 uint16_t feature_type_code; 108 uint16_t feature_ID; 109 uint8_t feature_primitive; 110 }OSENC_Feature_Identification_Record_Base; 111 112 113 typedef struct _OSENC_Feature_Identification_Record_Payload{ 114 uint16_t feature_type_code; 115 uint16_t feature_ID; 116 uint8_t feature_primitive; 117 }OSENC_Feature_Identification_Record_Payload; 118 119 typedef struct _OSENC_Attribute_Record_Base{ 120 uint16_t record_type; 121 uint32_t record_length; 122 uint16_t attribute_type; 123 unsigned char attribute_value_type; 124 }OSENC_Attribute_Record_Base; 125 126 typedef struct _OSENC_Attribute_Record{ 127 uint16_t record_type; 128 uint32_t record_length; 129 uint16_t attribute_type; 130 unsigned char attribute_value_type; 131 void * payload; 132 }OSENC_Attribute_Record; 133 134 typedef struct _OSENC_Attribute_Record_Payload{ 135 uint16_t attribute_type_code; 136 unsigned char attribute_value_type; 137 138 union{ 139 uint32_t attribute_value_int; 140 double attribute_value_double; 141 char * attribute_value_char_ptr; 142 }; 143 }OSENC_Attribute_Record_Payload; 144 145 146 typedef struct _OSENC_PointGeometry_Record{ 147 uint16_t record_type; 148 uint32_t record_length; 149 double lat; 150 double lon; 151 }OSENC_PointGeometry_Record; 152 153 typedef struct _OSENC_PointGeometry_Record_Payload{ 154 double lat; 155 double lon; 156 }OSENC_PointGeometry_Record_Payload; 157 158 159 typedef struct _OSENC_MultipointGeometry_Record_Base{ 160 uint16_t record_type; 161 uint32_t record_length; 162 double extent_s_lat; 163 double extent_n_lat; 164 double extent_w_lon; 165 double extent_e_lon; 166 uint32_t point_count; 167 }OSENC_MultipointGeometry_Record_Base; 168 169 typedef struct _OSENC_MultipointGeometry_Record_Payload{ 170 double extent_s_lat; 171 double extent_n_lat; 172 double extent_w_lon; 173 double extent_e_lon; 174 uint32_t point_count; 175 void * payLoad; 176 }OSENC_MultipointGeometry_Record_Payload; 177 178 179 typedef struct _OSENC_LineGeometry_Record_Base{ 180 uint16_t record_type; 181 uint32_t record_length; 182 double extent_s_lat; 183 double extent_n_lat; 184 double extent_w_lon; 185 double extent_e_lon; 186 uint32_t edgeVector_count; 187 }OSENC_LineGeometry_Record_Base; 188 189 typedef struct _OSENC_LineGeometry_Record_Payload{ 190 double extent_s_lat; 191 double extent_n_lat; 192 double extent_w_lon; 193 double extent_e_lon; 194 uint32_t edgeVector_count; 195 void * payLoad; 196 }OSENC_LineGeometry_Record_Payload; 197 198 199 typedef struct _OSENC_AreaGeometry_Record_Base{ 200 uint16_t record_type; 201 uint32_t record_length; 202 double extent_s_lat; 203 double extent_n_lat; 204 double extent_w_lon; 205 double extent_e_lon; 206 uint32_t contour_count; 207 uint32_t triprim_count; 208 uint32_t edgeVector_count; 209 }OSENC_AreaGeometry_Record_Base; 210 211 typedef struct _OSENC_AreaGeometry_Record_Payload{ 212 double extent_s_lat; 213 double extent_n_lat; 214 double extent_w_lon; 215 double extent_e_lon; 216 uint32_t contour_count; 217 uint32_t triprim_count; 218 uint32_t edgeVector_count; 219 void * payLoad; 220 }OSENC_AreaGeometry_Record_Payload; 221 222 typedef struct _OSENC_VET_Record{ 223 uint16_t record_type; 224 uint32_t record_length; 225 unsigned char payload; 226 }OSENC_VET_Record; 227 228 typedef struct _OSENC_VET_Record_Base{ 229 uint16_t record_type; 230 uint32_t record_length; 231 }OSENC_VET_Record_Base; 232 233 typedef struct _OSENC_VCT_Record{ 234 uint16_t record_type; 235 uint32_t record_length; 236 unsigned char payload; 237 }OSENC_VCT_Record; 238 239 typedef struct _OSENC_VCT_Record_Base{ 240 uint16_t record_type; 241 uint32_t record_length; 242 }OSENC_VCT_Record_Base; 243 244 typedef struct _OSENC_COVR_Record{ 245 uint16_t record_type; 246 uint32_t record_length; 247 unsigned char payload; 248 }_OSENC_COVR_Record; 249 250 typedef struct _OSENC_COVR_Record_Base{ 251 uint16_t record_type; 252 uint32_t record_length; 253 }_OSENC_COVR_Record_Base; 254 255 typedef struct _OSENC_COVR_Record_Payload{ 256 uint32_t point_count; 257 float point_array; 258 }_OSENC_COVR_Record_Payload; 259 260 typedef struct _OSENC_NOCOVR_Record{ 261 uint16_t record_type; 262 uint32_t record_length; 263 unsigned char payload; 264 }_OSENC_NOCOVR_Record; 265 266 typedef struct _OSENC_NOCOVR_Record_Base{ 267 uint16_t record_type; 268 uint32_t record_length; 269 }_OSENC_NOCOVR_Record_Base; 270 271 typedef struct _OSENC_NOCOVR_Record_Payload{ 272 uint32_t point_count; 273 float point_array; 274 }_OSENC_NOCOVR_Record_Payload; 275 276 277 typedef struct _OSENC_EXTENT_Record{ 278 uint16_t record_type; 279 uint32_t record_length; 280 double extent_sw_lat; 281 double extent_sw_lon; 282 double extent_nw_lat; 283 double extent_nw_lon; 284 double extent_ne_lat; 285 double extent_ne_lon; 286 double extent_se_lat; 287 double extent_se_lon; 288 }_OSENC_EXTENT_Record; 289 290 typedef struct _OSENC_EXTENT_Record_Payload{ 291 double extent_sw_lat; 292 double extent_sw_lon; 293 double extent_nw_lat; 294 double extent_nw_lon; 295 double extent_ne_lat; 296 double extent_ne_lon; 297 double extent_se_lat; 298 double extent_se_lon; 299 }_OSENC_EXTENT_Record_Payload; 300 301 #pragma pack(pop) 302 303 304 305 306 307 308 309 310 311 // Some special defined attribute type codes 312 // Should also be defined in a57attributes.csv 313 314 #define ATTRIBUTE_ID_PRIM 50000 315 316 317 const char *MyCSVGetField( const char * pszFilename, 318 const char * pszKeyFieldName, 319 const char * pszKeyFieldValue, 320 CSVCompareCriteria eCriteria, 321 const char * pszTargetField ) ; 322 323 324 325 326 // Fwd Definitions 327 class wxGenericProgressDialog; 328 class S57Obj; 329 class VE_Element; 330 class VC_Element; 331 class PolyTessGeo; 332 class LineGeometryDescriptor; 333 class wxFFileInputStream; 334 335 typedef std::vector<S57Obj *> S57ObjVector; 336 typedef std::vector<VE_Element *> VE_ElementVector; 337 typedef std::vector<VC_Element *> VC_ElementVector; 338 339 WX_DECLARE_HASH_MAP( int, int, wxIntegerHash, wxIntegerEqual, VectorHelperHash ); 340 341 //-------------------------------------------------------------------------- 342 // Osenc_instream definition 343 //-------------------------------------------------------------------------- 344 class Osenc_instream 345 { 346 public: Osenc_instream()347 Osenc_instream(){}; ~Osenc_instream()348 virtual ~Osenc_instream(){}; 349 350 virtual bool Open( const wxString &senc_file_name ) = 0; 351 virtual void Close() = 0; 352 353 virtual Osenc_instream &Read(void *buffer, size_t size) = 0; 354 virtual bool IsOk() = 0; 355 virtual bool isAvailable() = 0; 356 virtual void Shutdown() = 0; 357 358 }; 359 360 361 //-------------------------------------------------------------------------- 362 // Osenc_instreamFile definition 363 // A simple file stream implementation based on wxFFileInputStream 364 //-------------------------------------------------------------------------- 365 class Osenc_instreamFile : public Osenc_instream 366 { 367 public: 368 Osenc_instreamFile(); 369 ~Osenc_instreamFile(); 370 371 bool Open( const wxString &senc_file_name ); 372 void Close(); 373 374 Osenc_instream &Read(void *buffer, size_t size); 375 bool IsOk(); 376 bool isAvailable(); 377 void Shutdown(); 378 379 380 private: 381 void Init(); 382 383 wxFFileInputStream *m_instream; 384 bool m_ok; 385 386 }; 387 388 389 390 //-------------------------------------------------------------------------- 391 // Osenc_outstream definition 392 //-------------------------------------------------------------------------- 393 class Osenc_outstream 394 { 395 public: Osenc_outstream()396 Osenc_outstream(){}; ~Osenc_outstream()397 virtual ~Osenc_outstream(){}; 398 399 virtual bool Open(const wxString& ofileName) = 0; 400 401 virtual Osenc_outstream& Write(const void* buffer, size_t size) = 0; 402 virtual void Close() = 0; 403 virtual bool IsOk() = 0; 404 405 406 407 }; 408 409 410 //-------------------------------------------------------------------------- 411 // Osenc_outstreamFile definition 412 // A simple file stream implementation based on wxFFileInputStream 413 //-------------------------------------------------------------------------- 414 class Osenc_outstreamFile : public Osenc_outstream 415 { 416 public: 417 Osenc_outstreamFile(); 418 ~Osenc_outstreamFile(); 419 420 bool Open(const wxString& ofileName); 421 422 Osenc_outstream& Write(const void* buffer, size_t size); 423 void Close(); 424 bool IsOk(); 425 426 private: 427 void Init(); 428 429 wxFFileOutputStream *m_outstream; 430 bool m_ok; 431 432 }; 433 434 435 436 437 438 //-------------------------------------------------------------------------- 439 // Osenc definition 440 //-------------------------------------------------------------------------- 441 442 class Osenc 443 { 444 public: 445 Osenc(); 446 ~Osenc(); 447 getLastError()448 wxString getLastError(){ return errorMessage; } 449 void setVerbose(bool verbose ); setNoErrDialog(bool val)450 void setNoErrDialog( bool val ){ m_NoErrDialog = val; } 451 452 int ingestHeader(const wxString &senc_file_name); 453 int ingest(const wxString &senc_file_name, 454 S57ObjVector *pObjectVector, 455 VE_ElementVector *pVEArray, 456 VC_ElementVector *pVCArray); 457 458 int ingest200(const wxString &senc_file_name, 459 S57ObjVector *pObjectVector, 460 VE_ElementVector *pVEArray, 461 VC_ElementVector *pVCArray); 462 463 // SENC creation, by Version desired... SetLODMeters(double meters)464 void SetLODMeters(double meters){ m_LOD_meters = meters;} setRegistrar(S57ClassRegistrar * registrar)465 void setRegistrar( S57ClassRegistrar *registrar ){ m_poRegistrar = registrar; } setRefLocn(double lat,double lon)466 void setRefLocn( double lat, double lon){ m_ref_lat = lat; m_ref_lon = lon; } setOutstream(Osenc_outstream * stream)467 void setOutstream(Osenc_outstream *stream){ m_pauxOutstream = stream; } setInstream(Osenc_instream * stream)468 void setInstream(Osenc_instream *stream){ m_pauxInstream = stream; } 469 getUpdateDate()470 wxString getUpdateDate(){ return m_LastUpdateDate; } getBaseDate()471 wxString getBaseDate(){ return m_sdate000; } 472 getSENCFileCreateDate()473 wxString getSENCFileCreateDate(){ return m_readFileCreateDate; } 474 getSencReadVersion()475 int getSencReadVersion(){ return m_senc_file_read_version; } getSENCReadBaseEdition()476 wxString getSENCReadBaseEdition(){ return m_read_base_edtn; } getSENCReadLastUpdate()477 int getSENCReadLastUpdate(){ return m_read_last_applied_update; } getSENCReadScale()478 int getSENCReadScale(){ return m_Chart_Scale; } getReadName()479 wxString getReadName(){ return m_Name; } getReadID()480 wxString getReadID(){ return m_ID; } getReadExtent()481 Extent &getReadExtent(){ return m_extent; } 482 getSENCReadAuxPointArray()483 SENCFloatPtrArray &getSENCReadAuxPointArray(){ return m_AuxPtrArray;} getSENCReadAuxPointCountArray()484 std::vector<int> &getSENCReadAuxPointCountArray(){ return m_AuxCntArray;} getSENCReadNOCOVRPointArray()485 SENCFloatPtrArray &getSENCReadNOCOVRPointArray(){ return m_NoCovrPtrArray;} getSENCReadNOCOVRPointCountArray()486 std::vector<int> &getSENCReadNOCOVRPointCountArray(){ return m_NoCovrCntArray;} 487 488 int createSenc200(const wxString& FullPath000, const wxString& SENCFileName, bool b_showProg = true); 489 490 void CreateSENCVectorEdgeTableRecord200( Osenc_outstream *stream, S57Reader *poReader ); 491 void CreateSENCVectorConnectedTableRecord200( Osenc_outstream *stream, S57Reader *poReader ); 492 493 void InitializePersistentBuffer( void ); 494 unsigned char *getBuffer( size_t length); 495 getNativeScale()496 int getNativeScale(){ return m_native_scale; } 497 int GetBaseFileInfo(const wxString& FullPath000, const wxString& SENCFileName); 498 499 std::unique_lock<std::mutex> lockCR; 500 501 private: 502 void init(); 503 504 int ingestCell( OGRS57DataSource *poS57DS, const wxString &FullPath000, const wxString &working_dir ); 505 int ValidateAndCountUpdates( const wxFileName file000, const wxString CopyDir, 506 wxString &LastUpdateDate, bool b_copyfiles); 507 int GetUpdateFileArray(const wxFileName file000, wxArrayString *UpFiles); 508 bool GetBaseFileAttr( const wxString &FullPath000 ); 509 unsigned char *getObjectVectorIndexTable( S57Reader *poReader, OGRFeature *poFeature, int &nEntries ); 510 511 OGRFeature *GetChartFirstM_COVR( int &catcov, S57Reader *pENCReader, S57ClassRegistrar *poRegistrar ); 512 OGRFeature *GetChartNextM_COVR( int &catcov, S57Reader *pENCReader ); 513 bool CreateCOVRTables( S57Reader *pENCReader, S57ClassRegistrar *poRegistrar ); 514 bool CreateCovrRecords(Osenc_outstream *stream); 515 516 void CreateSENCRecord124( OGRFeature *pFeature, Osenc_outstream *stream, int mode, S57Reader *poReader ); 517 void CreateSENCVectorEdgeTable(Osenc_outstream *stream, S57Reader *poReader); 518 void CreateSENCConnNodeTable(Osenc_outstream *stream, S57Reader *poReader); 519 520 bool CreateSENCRecord200( OGRFeature *pFeature, Osenc_outstream *stream, int mode, S57Reader *poReader ); 521 bool WriteFIDRecord200( Osenc_outstream *stream, int nOBJL, int featureID, int prim); 522 bool WriteHeaderRecord200( Osenc_outstream *stream, int recordType, std::string payload); 523 bool WriteHeaderRecord200( Osenc_outstream *stream, int recordType, uint16_t value); 524 bool WriteHeaderRecord200( Osenc_outstream *stream, int recordType, uint32_t value); 525 bool CreateAreaFeatureGeometryRecord200( S57Reader *poReader, OGRFeature *pFeature, Osenc_outstream *stream ); 526 bool CreateLineFeatureGeometryRecord200( S57Reader *poReader, OGRFeature *pFeature, Osenc_outstream *stream ); 527 bool CreateMultiPointFeatureGeometryRecord200( OGRFeature *pFeature, Osenc_outstream *stream); 528 529 std::string GetFeatureAcronymFromTypecode( int typeCode ); 530 std::string GetAttributeAcronymFromTypecode( int typeCode ); 531 532 PolyTessGeo *BuildPolyTessGeo(_OSENC_AreaGeometry_Record_Payload *record, unsigned char **bytes_consumed ); 533 bool CalculateExtent( S57Reader *poReader, S57ClassRegistrar *poRegistrar ); 534 535 wxString errorMessage; 536 537 wxString m_Name; 538 wxString m_ID; 539 wxString m_FullPath000; 540 541 int m_Chart_Scale; 542 int m_senc_file_read_version; 543 int m_senc_file_create_version; 544 wxString m_read_base_edtn; 545 int m_read_last_applied_update; 546 547 S57Reader *poReader; 548 549 wxDateTime m_date000; 550 wxString m_sdate000; 551 552 wxString m_edtn000; 553 int m_UPDN; 554 555 int m_nGeoRecords; 556 int m_last_applied_update; 557 wxString m_LastUpdateDate; 558 int m_native_scale; 559 wxString m_readFileCreateDate; 560 561 double m_ref_lat, m_ref_lon; // Common reference point, derived from FullExtent 562 VectorHelperHash m_vector_helper_hash; 563 double m_LOD_meters; 564 S57ClassRegistrar *m_poRegistrar; 565 wxArrayString m_tmpup_array; 566 567 wxGenericProgressDialog *m_ProgDialog; 568 569 570 unsigned char * pBuffer; 571 size_t bufferSize; 572 573 574 Extent m_extent; 575 576 // Clone of Chartbase structures of the same name and purpose 577 // Use mainly for SENC creation for ENC(.000) file 578 int m_nCOVREntries; // number of coverage table entries 579 int *m_pCOVRTablePoints; // int table of number of points in each coverage table entry 580 float **m_pCOVRTable; // table of pointers to list of floats describing valid COVR 581 582 int m_nNoCOVREntries; // number of NoCoverage table entries 583 int *m_pNoCOVRTablePoints; // int table of number of points in each NoCoverage table entry 584 float **m_pNoCOVRTable; // table of pointers to list of floats describing valid NOCOVR 585 586 587 // Arrays used to accumulate coverage regions on oSENC load 588 SENCFloatPtrArray m_AuxPtrArray; 589 std::vector<int> m_AuxCntArray; 590 SENCFloatPtrArray m_NoCovrPtrArray; 591 std::vector<int> m_NoCovrCntArray; 592 593 594 Osenc_outstream *m_pauxOutstream; 595 Osenc_instream *m_pauxInstream; 596 597 Osenc_outstream *m_pOutstream; 598 Osenc_instream *m_pInstream; 599 600 bool m_bVerbose; 601 wxArrayString *m_UpFiles; 602 bool m_bPrivateRegistrar; 603 bool m_NoErrDialog; 604 }; 605 606 607 #endif // Guard 608