/*************************************************************************** * * Project: OpenCPN * Purpose: S57 SENC File Object * Author: David Register * *************************************************************************** * Copyright (C) 2015 by David S. Register * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * **************************************************************************/ #ifndef OSENC_H #define OSENC_H // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif //precompiled headers #include #include "gdal/cpl_csv.h" #include "ogr_s57.h" #include "chartbase.h" #include #include #include #include WX_DEFINE_ARRAY_PTR(float *, SENCFloatPtrArray); // Various error return enums #define SENC_NO_ERROR 0 #define ERROR_SENCFILE_NOT_FOUND 1 #define ERROR_SENC_VERSION_MISMATCH 2 #define ERROR_CANNOT_CREATE_SENC_DIR 3 #define ERROR_CANNOT_CREATE_TEMP_SENC_FILE 4 #define ERROR_INGESTING000 5 #define ERROR_REGISTRAR_NOT_SET 6 #define ERROR_BASEFILE_ATTRIBUTES 7 #define ERROR_SENCFILE_ABORT 8 // OSENC V2 record definitions #define HEADER_SENC_VERSION 1 #define HEADER_CELL_NAME 2 #define HEADER_CELL_PUBLISHDATE 3 #define HEADER_CELL_EDITION 4 #define HEADER_CELL_UPDATEDATE 5 #define HEADER_CELL_UPDATE 6 #define HEADER_CELL_NATIVESCALE 7 #define HEADER_CELL_SENCCREATEDATE 8 #define FEATURE_ID_RECORD 64 #define FEATURE_ATTRIBUTE_RECORD 65 #define FEATURE_GEOMETRY_RECORD_POINT 80 #define FEATURE_GEOMETRY_RECORD_LINE 81 #define FEATURE_GEOMETRY_RECORD_AREA 82 #define FEATURE_GEOMETRY_RECORD_MULTIPOINT 83 #define VECTOR_EDGE_NODE_TABLE_RECORD 96 #define VECTOR_CONNECTED_NODE_TABLE_RECORD 97 #define CELL_COVR_RECORD 98 #define CELL_NOCOVR_RECORD 99 #define CELL_EXTENT_RECORD 100 //-------------------------------------------------------------------------- // Utility Structures //-------------------------------------------------------------------------- #pragma pack(push,1) typedef struct _OSENC_Record_Base{ uint16_t record_type; uint32_t record_length; }OSENC_Record_Base; typedef struct _OSENC_Record{ uint16_t record_type; uint32_t record_length; unsigned char payload; }OSENC_Record; typedef struct _OSENC_Feature_Identification_Record_Base{ uint16_t record_type; uint32_t record_length; uint16_t feature_type_code; uint16_t feature_ID; uint8_t feature_primitive; }OSENC_Feature_Identification_Record_Base; typedef struct _OSENC_Feature_Identification_Record_Payload{ uint16_t feature_type_code; uint16_t feature_ID; uint8_t feature_primitive; }OSENC_Feature_Identification_Record_Payload; typedef struct _OSENC_Attribute_Record_Base{ uint16_t record_type; uint32_t record_length; uint16_t attribute_type; unsigned char attribute_value_type; }OSENC_Attribute_Record_Base; typedef struct _OSENC_Attribute_Record{ uint16_t record_type; uint32_t record_length; uint16_t attribute_type; unsigned char attribute_value_type; void * payload; }OSENC_Attribute_Record; typedef struct _OSENC_Attribute_Record_Payload{ uint16_t attribute_type_code; unsigned char attribute_value_type; union{ uint32_t attribute_value_int; double attribute_value_double; char * attribute_value_char_ptr; }; }OSENC_Attribute_Record_Payload; typedef struct _OSENC_PointGeometry_Record{ uint16_t record_type; uint32_t record_length; double lat; double lon; }OSENC_PointGeometry_Record; typedef struct _OSENC_PointGeometry_Record_Payload{ double lat; double lon; }OSENC_PointGeometry_Record_Payload; typedef struct _OSENC_MultipointGeometry_Record_Base{ uint16_t record_type; uint32_t record_length; double extent_s_lat; double extent_n_lat; double extent_w_lon; double extent_e_lon; uint32_t point_count; }OSENC_MultipointGeometry_Record_Base; typedef struct _OSENC_MultipointGeometry_Record_Payload{ double extent_s_lat; double extent_n_lat; double extent_w_lon; double extent_e_lon; uint32_t point_count; void * payLoad; }OSENC_MultipointGeometry_Record_Payload; typedef struct _OSENC_LineGeometry_Record_Base{ uint16_t record_type; uint32_t record_length; double extent_s_lat; double extent_n_lat; double extent_w_lon; double extent_e_lon; uint32_t edgeVector_count; }OSENC_LineGeometry_Record_Base; typedef struct _OSENC_LineGeometry_Record_Payload{ double extent_s_lat; double extent_n_lat; double extent_w_lon; double extent_e_lon; uint32_t edgeVector_count; void * payLoad; }OSENC_LineGeometry_Record_Payload; typedef struct _OSENC_AreaGeometry_Record_Base{ uint16_t record_type; uint32_t record_length; double extent_s_lat; double extent_n_lat; double extent_w_lon; double extent_e_lon; uint32_t contour_count; uint32_t triprim_count; uint32_t edgeVector_count; }OSENC_AreaGeometry_Record_Base; typedef struct _OSENC_AreaGeometry_Record_Payload{ double extent_s_lat; double extent_n_lat; double extent_w_lon; double extent_e_lon; uint32_t contour_count; uint32_t triprim_count; uint32_t edgeVector_count; void * payLoad; }OSENC_AreaGeometry_Record_Payload; typedef struct _OSENC_VET_Record{ uint16_t record_type; uint32_t record_length; unsigned char payload; }OSENC_VET_Record; typedef struct _OSENC_VET_Record_Base{ uint16_t record_type; uint32_t record_length; }OSENC_VET_Record_Base; typedef struct _OSENC_VCT_Record{ uint16_t record_type; uint32_t record_length; unsigned char payload; }OSENC_VCT_Record; typedef struct _OSENC_VCT_Record_Base{ uint16_t record_type; uint32_t record_length; }OSENC_VCT_Record_Base; typedef struct _OSENC_COVR_Record{ uint16_t record_type; uint32_t record_length; unsigned char payload; }_OSENC_COVR_Record; typedef struct _OSENC_COVR_Record_Base{ uint16_t record_type; uint32_t record_length; }_OSENC_COVR_Record_Base; typedef struct _OSENC_COVR_Record_Payload{ uint32_t point_count; float point_array; }_OSENC_COVR_Record_Payload; typedef struct _OSENC_NOCOVR_Record{ uint16_t record_type; uint32_t record_length; unsigned char payload; }_OSENC_NOCOVR_Record; typedef struct _OSENC_NOCOVR_Record_Base{ uint16_t record_type; uint32_t record_length; }_OSENC_NOCOVR_Record_Base; typedef struct _OSENC_NOCOVR_Record_Payload{ uint32_t point_count; float point_array; }_OSENC_NOCOVR_Record_Payload; typedef struct _OSENC_EXTENT_Record{ uint16_t record_type; uint32_t record_length; double extent_sw_lat; double extent_sw_lon; double extent_nw_lat; double extent_nw_lon; double extent_ne_lat; double extent_ne_lon; double extent_se_lat; double extent_se_lon; }_OSENC_EXTENT_Record; typedef struct _OSENC_EXTENT_Record_Payload{ double extent_sw_lat; double extent_sw_lon; double extent_nw_lat; double extent_nw_lon; double extent_ne_lat; double extent_ne_lon; double extent_se_lat; double extent_se_lon; }_OSENC_EXTENT_Record_Payload; #pragma pack(pop) // Some special defined attribute type codes // Should also be defined in a57attributes.csv #define ATTRIBUTE_ID_PRIM 50000 const char *MyCSVGetField( const char * pszFilename, const char * pszKeyFieldName, const char * pszKeyFieldValue, CSVCompareCriteria eCriteria, const char * pszTargetField ) ; // Fwd Definitions class wxGenericProgressDialog; class S57Obj; class VE_Element; class VC_Element; class PolyTessGeo; class LineGeometryDescriptor; class wxFFileInputStream; typedef std::vector S57ObjVector; typedef std::vector VE_ElementVector; typedef std::vector VC_ElementVector; WX_DECLARE_HASH_MAP( int, int, wxIntegerHash, wxIntegerEqual, VectorHelperHash ); //-------------------------------------------------------------------------- // Osenc_instream definition //-------------------------------------------------------------------------- class Osenc_instream { public: Osenc_instream(){}; virtual ~Osenc_instream(){}; virtual bool Open( const wxString &senc_file_name ) = 0; virtual void Close() = 0; virtual Osenc_instream &Read(void *buffer, size_t size) = 0; virtual bool IsOk() = 0; virtual bool isAvailable() = 0; virtual void Shutdown() = 0; }; //-------------------------------------------------------------------------- // Osenc_instreamFile definition // A simple file stream implementation based on wxFFileInputStream //-------------------------------------------------------------------------- class Osenc_instreamFile : public Osenc_instream { public: Osenc_instreamFile(); ~Osenc_instreamFile(); bool Open( const wxString &senc_file_name ); void Close(); Osenc_instream &Read(void *buffer, size_t size); bool IsOk(); bool isAvailable(); void Shutdown(); private: void Init(); wxFFileInputStream *m_instream; bool m_ok; }; //-------------------------------------------------------------------------- // Osenc_outstream definition //-------------------------------------------------------------------------- class Osenc_outstream { public: Osenc_outstream(){}; virtual ~Osenc_outstream(){}; virtual bool Open(const wxString& ofileName) = 0; virtual Osenc_outstream& Write(const void* buffer, size_t size) = 0; virtual void Close() = 0; virtual bool IsOk() = 0; }; //-------------------------------------------------------------------------- // Osenc_outstreamFile definition // A simple file stream implementation based on wxFFileInputStream //-------------------------------------------------------------------------- class Osenc_outstreamFile : public Osenc_outstream { public: Osenc_outstreamFile(); ~Osenc_outstreamFile(); bool Open(const wxString& ofileName); Osenc_outstream& Write(const void* buffer, size_t size); void Close(); bool IsOk(); private: void Init(); wxFFileOutputStream *m_outstream; bool m_ok; }; //-------------------------------------------------------------------------- // Osenc definition //-------------------------------------------------------------------------- class Osenc { public: Osenc(); ~Osenc(); wxString getLastError(){ return errorMessage; } void setVerbose(bool verbose ); void setNoErrDialog( bool val ){ m_NoErrDialog = val; } int ingestHeader(const wxString &senc_file_name); int ingest(const wxString &senc_file_name, S57ObjVector *pObjectVector, VE_ElementVector *pVEArray, VC_ElementVector *pVCArray); int ingest200(const wxString &senc_file_name, S57ObjVector *pObjectVector, VE_ElementVector *pVEArray, VC_ElementVector *pVCArray); // SENC creation, by Version desired... void SetLODMeters(double meters){ m_LOD_meters = meters;} void setRegistrar( S57ClassRegistrar *registrar ){ m_poRegistrar = registrar; } void setRefLocn( double lat, double lon){ m_ref_lat = lat; m_ref_lon = lon; } void setOutstream(Osenc_outstream *stream){ m_pauxOutstream = stream; } void setInstream(Osenc_instream *stream){ m_pauxInstream = stream; } wxString getUpdateDate(){ return m_LastUpdateDate; } wxString getBaseDate(){ return m_sdate000; } wxString getSENCFileCreateDate(){ return m_readFileCreateDate; } int getSencReadVersion(){ return m_senc_file_read_version; } wxString getSENCReadBaseEdition(){ return m_read_base_edtn; } int getSENCReadLastUpdate(){ return m_read_last_applied_update; } int getSENCReadScale(){ return m_Chart_Scale; } wxString getReadName(){ return m_Name; } wxString getReadID(){ return m_ID; } Extent &getReadExtent(){ return m_extent; } SENCFloatPtrArray &getSENCReadAuxPointArray(){ return m_AuxPtrArray;} std::vector &getSENCReadAuxPointCountArray(){ return m_AuxCntArray;} SENCFloatPtrArray &getSENCReadNOCOVRPointArray(){ return m_NoCovrPtrArray;} std::vector &getSENCReadNOCOVRPointCountArray(){ return m_NoCovrCntArray;} int createSenc200(const wxString& FullPath000, const wxString& SENCFileName, bool b_showProg = true); void CreateSENCVectorEdgeTableRecord200( Osenc_outstream *stream, S57Reader *poReader ); void CreateSENCVectorConnectedTableRecord200( Osenc_outstream *stream, S57Reader *poReader ); void InitializePersistentBuffer( void ); unsigned char *getBuffer( size_t length); int getNativeScale(){ return m_native_scale; } int GetBaseFileInfo(const wxString& FullPath000, const wxString& SENCFileName); std::unique_lock lockCR; private: void init(); int ingestCell( OGRS57DataSource *poS57DS, const wxString &FullPath000, const wxString &working_dir ); int ValidateAndCountUpdates( const wxFileName file000, const wxString CopyDir, wxString &LastUpdateDate, bool b_copyfiles); int GetUpdateFileArray(const wxFileName file000, wxArrayString *UpFiles); bool GetBaseFileAttr( const wxString &FullPath000 ); unsigned char *getObjectVectorIndexTable( S57Reader *poReader, OGRFeature *poFeature, int &nEntries ); OGRFeature *GetChartFirstM_COVR( int &catcov, S57Reader *pENCReader, S57ClassRegistrar *poRegistrar ); OGRFeature *GetChartNextM_COVR( int &catcov, S57Reader *pENCReader ); bool CreateCOVRTables( S57Reader *pENCReader, S57ClassRegistrar *poRegistrar ); bool CreateCovrRecords(Osenc_outstream *stream); void CreateSENCRecord124( OGRFeature *pFeature, Osenc_outstream *stream, int mode, S57Reader *poReader ); void CreateSENCVectorEdgeTable(Osenc_outstream *stream, S57Reader *poReader); void CreateSENCConnNodeTable(Osenc_outstream *stream, S57Reader *poReader); bool CreateSENCRecord200( OGRFeature *pFeature, Osenc_outstream *stream, int mode, S57Reader *poReader ); bool WriteFIDRecord200( Osenc_outstream *stream, int nOBJL, int featureID, int prim); bool WriteHeaderRecord200( Osenc_outstream *stream, int recordType, std::string payload); bool WriteHeaderRecord200( Osenc_outstream *stream, int recordType, uint16_t value); bool WriteHeaderRecord200( Osenc_outstream *stream, int recordType, uint32_t value); bool CreateAreaFeatureGeometryRecord200( S57Reader *poReader, OGRFeature *pFeature, Osenc_outstream *stream ); bool CreateLineFeatureGeometryRecord200( S57Reader *poReader, OGRFeature *pFeature, Osenc_outstream *stream ); bool CreateMultiPointFeatureGeometryRecord200( OGRFeature *pFeature, Osenc_outstream *stream); std::string GetFeatureAcronymFromTypecode( int typeCode ); std::string GetAttributeAcronymFromTypecode( int typeCode ); PolyTessGeo *BuildPolyTessGeo(_OSENC_AreaGeometry_Record_Payload *record, unsigned char **bytes_consumed ); bool CalculateExtent( S57Reader *poReader, S57ClassRegistrar *poRegistrar ); wxString errorMessage; wxString m_Name; wxString m_ID; wxString m_FullPath000; int m_Chart_Scale; int m_senc_file_read_version; int m_senc_file_create_version; wxString m_read_base_edtn; int m_read_last_applied_update; S57Reader *poReader; wxDateTime m_date000; wxString m_sdate000; wxString m_edtn000; int m_UPDN; int m_nGeoRecords; int m_last_applied_update; wxString m_LastUpdateDate; int m_native_scale; wxString m_readFileCreateDate; double m_ref_lat, m_ref_lon; // Common reference point, derived from FullExtent VectorHelperHash m_vector_helper_hash; double m_LOD_meters; S57ClassRegistrar *m_poRegistrar; wxArrayString m_tmpup_array; wxGenericProgressDialog *m_ProgDialog; unsigned char * pBuffer; size_t bufferSize; Extent m_extent; // Clone of Chartbase structures of the same name and purpose // Use mainly for SENC creation for ENC(.000) file int m_nCOVREntries; // number of coverage table entries int *m_pCOVRTablePoints; // int table of number of points in each coverage table entry float **m_pCOVRTable; // table of pointers to list of floats describing valid COVR int m_nNoCOVREntries; // number of NoCoverage table entries int *m_pNoCOVRTablePoints; // int table of number of points in each NoCoverage table entry float **m_pNoCOVRTable; // table of pointers to list of floats describing valid NOCOVR // Arrays used to accumulate coverage regions on oSENC load SENCFloatPtrArray m_AuxPtrArray; std::vector m_AuxCntArray; SENCFloatPtrArray m_NoCovrPtrArray; std::vector m_NoCovrCntArray; Osenc_outstream *m_pauxOutstream; Osenc_instream *m_pauxInstream; Osenc_outstream *m_pOutstream; Osenc_instream *m_pInstream; bool m_bVerbose; wxArrayString *m_UpFiles; bool m_bPrivateRegistrar; bool m_NoErrDialog; }; #endif // Guard