├── .gitignore ├── EncLib.pro ├── EncLib_vc2008 ├── EncLib.sln └── EncLib.vcproj ├── incl ├── GNU_V2.inc ├── boundingbox_degrees.h ├── boundingbox_edit.h ├── catalog031reader.h ├── cell_check_result.h ├── cell_check_s57.h ├── cell_parser_iso8211.h ├── cell_parser_iso8211Gdal.h ├── cell_parser_iso8211dirty.h ├── cell_parser_iso8211dirty4base.h ├── cell_parser_iso8211dirty4header.h ├── cell_parser_iso8211dirty4updt.h ├── cell_record_fields.h ├── cell_records.h ├── cell_s57.h ├── cell_s57_base.h ├── cell_s57_iterators.h ├── cell_s57_update.h ├── cell_writer.h ├── cell_writer_iso8211dirty.h ├── cell_writer_iso8211dirtyDDR.incl ├── cellheader_tabmodel.h ├── cellheader_widget.h ├── checksum.h ├── dictionaryS57.h ├── exSetCheckS57.h ├── exSetFilterWidget.h ├── exsetview.h ├── geo_projections.h ├── geo_spheroids.h ├── helper.h ├── iso8211_simple.h ├── naviNaviWidgets.h ├── naviScene.h ├── naviSceneItems.h ├── naviView.h ├── naviWidget.h ├── presentationS52.h ├── s57updater.h └── version.h ├── parsertest ├── main.cpp └── parsertest.vcproj ├── resources ├── Attributes.S57.txt └── Features.S57.txt └── src ├── boundingbox_degrees.cpp ├── boundingbox_edit.cpp ├── catalog031reader.cpp ├── cell_check_result.cpp ├── cell_check_s57.cpp ├── cell_parser_iso8211.cpp ├── cell_parser_iso8211Gdal.cpp ├── cell_parser_iso8211dirty.cpp ├── cell_parser_iso8211dirty4base.cpp ├── cell_parser_iso8211dirty4header.cpp ├── cell_parser_iso8211dirty4updt.cpp ├── cell_record_fields.cpp ├── cell_records.cpp ├── cell_records_fields_header.cpp ├── cell_s57.cpp ├── cell_s57_base.cpp ├── cell_s57_iterators.cpp ├── cell_s57_update.cpp ├── cell_writer.cpp ├── cell_writer_iso8211dirty.cpp ├── cellheader_tabmodel.cpp ├── cellheader_widget.cpp ├── checksum.cpp ├── dictionaryS57.cpp ├── exSetCheckS57.cpp ├── exSetFilterWidget.cpp ├── exsetview.cpp ├── geo_projections.cpp ├── helper.cpp ├── iso8211_simple.cpp ├── naviNaviWidgets.cpp ├── naviScene.cpp ├── naviSceneItems.cpp ├── naviView.cpp ├── naviWidget.cpp ├── presentationS52.cpp └── s57updater.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | EncLib/Release/ 2 | EncLib/Debug/ 3 | EncLib_vc2008/Debug/ 4 | EncLib_vc2008/Release/ 5 | moc_debug 6 | moc_release/ 7 | -------------------------------------------------------------------------------- /EncLib.pro: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------- 2 | # Project created by QtCreator 2009-12-10T18:19:05 3 | # ------------------------------------------------- 4 | TARGET = EncLib 5 | TEMPLATE = lib 6 | CONFIG += staticlib 7 | CONFIG += debug_and_release 8 | CONFIG += build_all 9 | 10 | INCLUDEPATH += incl 11 | INCLUDEPATH += ../geographiclib-1.1/include 12 | INCLUDEPATH += ../iso8211lib-1_4 13 | 14 | CONFIG(release, debug|release){ 15 | DESTDIR = ../$${TARGET}-build/$${QMAKE_CXX}/release 16 | } 17 | CONFIG(debug, debug|release){ 18 | DESTDIR = ../$${TARGET}-build/$${QMAKE_CXX}/debug 19 | } 20 | 21 | win32 { 22 | DEFINES += _CRT_SECURE_NO_WARNINGS 23 | } 24 | 25 | message("Building with qmake version: " $$QMAKE_QMAKE " - Using compiler: " $$QMAKE_CXX) 26 | 27 | SOURCES += src/exsetview.cpp \ 28 | src/s57updater.cpp \ 29 | src/iso8211_simple.cpp \ 30 | src/helper.cpp \ 31 | src/geo_projections.cpp \ 32 | src/exsetview.cpp \ 33 | src/exSetFilterWidget.cpp \ 34 | src/exSetCheckS57.cpp \ 35 | src/checksum.cpp \ 36 | src/cellheader_widget.cpp \ 37 | src/cellheader_tabmodel.cpp \ 38 | src/cell_writer_iso8211dirty.cpp \ 39 | src/cell_writer.cpp \ 40 | src/cell_s57_update.cpp \ 41 | src/cell_s57_iterators.cpp \ 42 | src/cell_s57_base.cpp \ 43 | src/cell_s57.cpp \ 44 | src/cell_reocord_fields.cpp \ 45 | src/cell_records_fields_header.cpp \ 46 | src/cell_records.cpp \ 47 | src/cell_parser_iso8211Gdal.cpp \ 48 | src/cell_parser_iso8211dirty4updt.cpp \ 49 | src/cell_parser_iso8211dirty4header.cpp \ 50 | src/cell_parser_iso8211dirty4base.cpp \ 51 | src/cell_parser_iso8211dirty.cpp \ 52 | src/cell_parser_iso8211.cpp \ 53 | src/cell_check_s57.cpp \ 54 | src/cell_check_result.cpp \ 55 | src/catalog031reader.cpp \ 56 | src/boundingbox_edit.cpp \ 57 | src/boundingbox_degrees.cpp \ 58 | src/naviView.cpp \ 59 | src/naviScene.cpp \ 60 | src/naviWidget.cpp \ 61 | src/naviSceneItems.cpp \ 62 | src/dictionaryS52.cpp \ 63 | src/naviNaviWidgets.cpp 64 | 65 | HEADERS += incl/exsetview.h \ 66 | incl/boundingbox_degrees.h \ 67 | incl/version.h \ 68 | incl/s57updater.h \ 69 | incl/iso8211_simple.h \ 70 | incl/helper.h \ 71 | incl/geo_spheroids.h \ 72 | incl/geo_projections.h \ 73 | incl/exsetview.h \ 74 | incl/exSetFilterWidget.h \ 75 | incl/exSetCheckS57.h \ 76 | incl/checksum.h \ 77 | incl/cellheader_widget.h \ 78 | incl/cellheader_tabmodel.h \ 79 | incl/cell_writer_iso8211dirty.h \ 80 | incl/cell_writer.h \ 81 | incl/cell_s57_update.h \ 82 | incl/cell_s57_iterators.h \ 83 | incl/cell_s57_base.h \ 84 | incl/cell_s57.h \ 85 | incl/cell_records.h \ 86 | incl/cell_record_fields.h \ 87 | incl/cell_parser_iso8211Gdal.h \ 88 | incl/cell_parser_iso8211dirty4updt.h \ 89 | incl/cell_parser_iso8211dirty4header.h \ 90 | incl/cell_parser_iso8211dirty4base.h \ 91 | incl/cell_parser_iso8211dirty.h \ 92 | incl/cell_parser_iso8211.h \ 93 | incl/cell_check_s57.h \ 94 | incl/cell_check_result.h \ 95 | incl/catalog031reader.h \ 96 | incl/boundingbox_edit.h \ 97 | incl/boundingbox_degrees.h \ 98 | incl/naviView.h \ 99 | incl/naviScene.h \ 100 | incl/naviSceneItems.h \ 101 | incl/dictionaryS52.h \ 102 | incl/naviWidget.h \ 103 | incl/naviNaviWidgets.h 104 | 105 | OTHER_FILES += \ 106 | incl/GNU_V2.inc \ 107 | incl/cell_writer_iso8211dirtyDDR.incl 108 | 109 | RESOURCES += \ 110 | EncLibQt.qrc 111 | -------------------------------------------------------------------------------- /EncLib_vc2008/EncLib.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual C++ Express 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EncLib", "EncLib.vcproj", "{99658DB1-C95D-4555-8C72-C667FCE04AA3}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_iso8211", "..\test_iso8211\test_iso8211.vcproj", "{BD7222DD-5A0C-4E96-979E-5FD373E53056}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minitest", "..\minitest\minitest.vcproj", "{5EF2EBA3-A28F-4404-8099-4117B1A4ED9E}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parsertest", "..\parsertest\parsertest.vcproj", "{EACDCA7A-AE25-4076-94E6-22415ED45425}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Win32 = Debug|Win32 15 | Release|Win32 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {99658DB1-C95D-4555-8C72-C667FCE04AA3}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {99658DB1-C95D-4555-8C72-C667FCE04AA3}.Debug|Win32.Build.0 = Debug|Win32 20 | {99658DB1-C95D-4555-8C72-C667FCE04AA3}.Release|Win32.ActiveCfg = Release|Win32 21 | {99658DB1-C95D-4555-8C72-C667FCE04AA3}.Release|Win32.Build.0 = Release|Win32 22 | {BD7222DD-5A0C-4E96-979E-5FD373E53056}.Debug|Win32.ActiveCfg = Debug|Win32 23 | {BD7222DD-5A0C-4E96-979E-5FD373E53056}.Debug|Win32.Build.0 = Debug|Win32 24 | {BD7222DD-5A0C-4E96-979E-5FD373E53056}.Release|Win32.ActiveCfg = Release|Win32 25 | {BD7222DD-5A0C-4E96-979E-5FD373E53056}.Release|Win32.Build.0 = Release|Win32 26 | {5EF2EBA3-A28F-4404-8099-4117B1A4ED9E}.Debug|Win32.ActiveCfg = Debug|Win32 27 | {5EF2EBA3-A28F-4404-8099-4117B1A4ED9E}.Debug|Win32.Build.0 = Debug|Win32 28 | {5EF2EBA3-A28F-4404-8099-4117B1A4ED9E}.Release|Win32.ActiveCfg = Release|Win32 29 | {5EF2EBA3-A28F-4404-8099-4117B1A4ED9E}.Release|Win32.Build.0 = Release|Win32 30 | {EACDCA7A-AE25-4076-94E6-22415ED45425}.Debug|Win32.ActiveCfg = Debug|Win32 31 | {EACDCA7A-AE25-4076-94E6-22415ED45425}.Debug|Win32.Build.0 = Debug|Win32 32 | {EACDCA7A-AE25-4076-94E6-22415ED45425}.Release|Win32.ActiveCfg = Release|Win32 33 | {EACDCA7A-AE25-4076-94E6-22415ED45425}.Release|Win32.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /EncLib_vc2008/EncLib.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KaiAbuSir/EncLib/ba8547abe7f2fa02132076227fe4b93b37f3de0c/EncLib_vc2008/EncLib.vcproj -------------------------------------------------------------------------------- /incl/boundingbox_degrees.h: -------------------------------------------------------------------------------- 1 | #ifndef BOUNDING_BOX_DEGREES_H 2 | #define BOUNDING_BOX_DEGREES_H 3 | 4 | #include 5 | 6 | namespace Enc 7 | { 8 | 9 | //****************************************************************************** 10 | /// Bounding Box in Decimal Degrees (south-west and north-east corners) 11 | /*! 12 | * BBox works correctly even when bigger than 180 degress, even until 360 degrees, 13 | ***************************************************************************** */ 14 | struct DegBBox 15 | { 16 | DegBBox() : SLAT(0), WLON(0), NLAT(0), ELON(0), stripe(false) 17 | {} 18 | DegBBox(double _SLAT, double _WLON, double _NLAT, double _ELON) : SLAT(_SLAT), WLON(_WLON), NLAT(_NLAT), ELON(_ELON), stripe(false) 19 | {} 20 | DegBBox(const QString & bbString); 21 | void clear() {SLAT = 0; WLON = 0; NLAT = 0; ELON = 0;} 22 | bool isValid() const {return (SLAT != 0 || WLON != 0 || NLAT != 0 || ELON != 0) && (NLAT >= SLAT);} 23 | bool crossesDateLine() const {return WLON > ELON;} 24 | QString toString() const; 25 | void fromString(const QString & bbString); 26 | 27 | void add(double lat, double lon); 28 | void add(const DegBBox & otherBB); 29 | double centerLat() const{ return (NLAT + SLAT)/2.0;} 30 | double centerLon() const; 31 | 32 | double SLAT, WLON; //South-West (LowerLeft) Corner; 33 | double NLAT, ELON; //North-East (UpperRight) Corner; 34 | bool stripe; //if true: W-E-long have no meaning: bbox is a stripe covering whole globe from SLAT to NLAT 35 | 36 | bool operator<(const DegBBox & otherBB) const {return (simpleSize() < otherBB.simpleSize());} /// get the boundingbox with the smaller area 37 | bool operator== (const DegBBox & otherBB) const; 38 | bool operator!= (const DegBBox & otherBB) const {return !(*this == otherBB);} 39 | double simpleSize() const {return (NLAT - SLAT) * deltaLon();} /// Calculate the area without using a projection -> quick 40 | bool overlapp(const DegBBox & otherBBox) const; 41 | 42 | private: 43 | double deltaLon() const {return (crossesDateLine() ? (ELON + 360) - WLON : ELON -WLON);} 44 | }; 45 | 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /incl/boundingbox_edit.h: -------------------------------------------------------------------------------- 1 | #ifndef BOUNDING_BOX_EDITOR_H 2 | #define BOUNDING_BOX_EDITOR_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | #include "boundingbox_degrees.h" 13 | 14 | namespace Enc 15 | { 16 | class BBoxEditDialog; 17 | 18 | //****************************************************************************** 19 | /// Bounding Box Edit Widget 20 | /*! 21 | ***************************************************************************** */ 22 | class BBoxEditor : public QFrame 23 | { 24 | friend class BBoxEditDialog; 25 | public: 26 | BBoxEditor(QWidget * parent =0, const DegBBox & bBox = DegBBox()); 27 | DegBBox getBBox() const; 28 | void setBBox(const DegBBox & newBBox); 29 | void BBoxEditor::clear(); 30 | 31 | protected: 32 | 33 | QLineEdit * northEdt; 34 | QLineEdit * southEdt; 35 | QLineEdit * eastEdt; 36 | QLineEdit * westEdt; 37 | QGridLayout * grdLyt; 38 | }; 39 | 40 | //****************************************************************************** 41 | /// Bounding Box Edit Dialog 42 | /*! 43 | ***************************************************************************** */ 44 | class BBoxEditDialog : public QDialog 45 | { 46 | public: 47 | BBoxEditDialog(QWidget * parent, const DegBBox & bBox); 48 | DegBBox getBBox() const {return bbEdit->getBBox();} 49 | void setBBox(const DegBBox & newBBox) {bbEdit->setBBox(newBBox);} 50 | void clear() {bbEdit->clear();} 51 | 52 | protected: 53 | 54 | BBoxEditor * bbEdit; 55 | QPushButton * okBtn; 56 | }; 57 | 58 | } 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /incl/catalog031reader.h: -------------------------------------------------------------------------------- 1 | #ifndef CATALOG031_READER_H 2 | #define CATALOG031_READER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "boundingbox_degrees.h" 12 | 13 | namespace Enc 14 | { 15 | 16 | //****************************************************************************** 17 | /// Holds all information off a record of a CATALOG.031 File (0001,CATD fields) 18 | /*! 19 | * 20 | ***************************************************************************** */ 21 | struct CatalogEntry 22 | { 23 | const static unsigned int MemberCnt = 10; //number of members in CatalogEntry-struct: 10 24 | enum ColumnNames{COL_RECID8211 = 0, COL_RCNM, COL_RCID, COL_FILE, COL_LFIL, COL_VOLM , COL_IMPL , COL_bBox , COL_CRCS , COL_COMT}; 25 | QVariant operator[](int index)const; 26 | //QString getToolTip(int index)const; 27 | 28 | CatalogEntry(); 29 | //** 0001-field: ISO8211 record id - unimportant, but needed for writing ** 30 | unsigned int recId8211; 31 | 32 | //** catalog record: data of CATD field ** 33 | 34 | char RCNM[4]; //Recored Name always "DS" - unimportant 35 | unsigned int RCID; //Record ID - unimportant 36 | 37 | QString FILE; //Filename 38 | QString LFIL; //Long Filename 39 | QString VOLM; //Volume Name 40 | char IMPL[4]; //Implementation "ASC" or "BIN" (always "BIN" for S-57) 41 | DegBBox bBox; //holds SLAT, WLON, NLAT, ELON 42 | unsigned int CRCS ; //checksum - 0 means: no checksum, althought 0 is a possibble checksum 43 | QString COMT; //comment - Holds S-63 entries !! 44 | 45 | //** methods needed for parsing iso8211 record ** 46 | void parseCatalogRecord(const char * catRecord); 47 | void parseCATD(const char * fieldPtr, unsigned int fieldLen); 48 | 49 | //** methods needed for writing iso8211 record ** 50 | int calcCADTsize(int posPrecision) const; 51 | int getMaxSubFieldSize() const; 52 | void writeCatalogRecord(QTextStream & iso8211strm, unsigned int iso8211rcid, unsigned int field001size = 6, int sizeofFLF =0, int sizeofFPF =0, int posPrecision = 8) const; 53 | void writeCATDfield(QTextStream & iso8211strm, int posPrecision) const; 54 | }; 55 | 56 | //****************************************************************************** 57 | /// Holds information off a record of a CATALOG.031 File, plus check-Result 58 | /*! 59 | * 60 | ***************************************************************************** */ 61 | struct CatalogCheckEntry : public CatalogEntry 62 | { 63 | enum CheckStatus{UnChecked =0, Ok, Warn, Err}; 64 | 65 | CatalogCheckEntry() : CatalogEntry(), chkStat(UnChecked) {} 66 | CheckStatus chkStat; 67 | QStringList messages; 68 | }; 69 | 70 | //****************************************************************************** 71 | /// Reads a S-57 CATALOG.031 File 72 | /*! 73 | ***************************************************************************** */ 74 | class Catalog031reader 75 | { 76 | public: 77 | Catalog031reader(); 78 | ~Catalog031reader(); 79 | void readCatalog031(QString fileName, std::vector & allEntries); 80 | 81 | private: 82 | 83 | }; 84 | 85 | //****************************************************************************** 86 | /// Write a S-57 CATALOG.031 File 87 | /*! 88 | ***************************************************************************** */ 89 | class Catalog031writer 90 | { 91 | public: 92 | Catalog031writer(); 93 | ~Catalog031writer(); 94 | void init(); 95 | void writeCatalog031(QString fileName, std::vector & allEntries); 96 | 97 | private: 98 | 99 | }; 100 | } 101 | 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /incl/cell_check_result.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_CHECK_RESULT_H 2 | #define CELL_CHECK_RESULT_H 3 | 4 | #include 5 | 6 | //#include 7 | #include 8 | 9 | #include "iso8211_simple.h" 10 | 11 | namespace Enc 12 | { 13 | class CellParser8211; 14 | class CellParser8211Dirty; 15 | class CellWriter; 16 | class CellWriter8211Dirty; 17 | class CellParser8211Dirty4Base; 18 | class S57Updater; 19 | 20 | using namespace ISO8211; 21 | 22 | //****************************************************************************** 23 | /// Struct counting errors when checking cells 24 | /*! 25 | * 26 | ***************************************************************************** */ 27 | typedef std::pair RCIDPair; 28 | typedef std::pair FeatSpatPair; 29 | typedef std::pair SpatFeatPair; 30 | typedef std::pairRcidFoidPair; 31 | struct CheckResult 32 | { 33 | std::vector< FeatSpatPair > brokenFeat2Spatial; //features pointing to non existing spatials 34 | std::vector< SpatFeatPair > brokenSpatial2Feat; //spatial pointing to non existing Features (back-pointer error) 35 | std::vector< RCIDPair > brokenFeat2Feat; //feat-feat relation errro (internal calculation error) 36 | std::vector< RCIDPair > brokenFeat2FeatBack; //feat-feat backward rel error (back-pointer error) 37 | std::vector< unsigned long > orphanFeatures; //Features that should have (Point,Line or Area) Geometry, but have not 38 | std::vector< RecNAME > orphanSpatials; //Spatials not used by any feature 39 | std::vector< RCIDPair > brokenEdge2Node; //edges where Bounding node is not found in cell, pair1=edge-rcid, pair2= node-rcid(invalid) 40 | std::vector< unsigned long > edgesMissingBNodes; //edges without bounding nodes at all 41 | std::vector< unsigned long > bNodesMissingEdges; //Bounding nodes without edges 42 | std::vector< RCIDPair > brokenBNodes2Edge; //Node 2 Edge Pointer broken (back-pointer-error) pair1=node-rcid, pair2= edge-rcid(invalid) 43 | std::vector< unsigned long > featMissingFOID; //Features without valid FOID; 44 | //** Not and Error -> Not counted in "errCnt", but suspicious: ** 45 | std::vector< RcidFoidPair > outsidePointer; //Features that contain FOIDs pointing to features in other cells: pair1=Feat that holds the FOISs(=pair2) 46 | 47 | void clear() 48 | { 49 | brokenFeat2Spatial.clear(); brokenSpatial2Feat.clear(); brokenFeat2Feat.clear(); brokenFeat2FeatBack.clear(); orphanFeatures.clear(); orphanSpatials.clear(); 50 | brokenEdge2Node.clear(); edgesMissingBNodes.clear(); bNodesMissingEdges.clear(); brokenBNodes2Edge.clear(); featMissingFOID.clear(); 51 | outsidePointer.clear(); 52 | } 53 | int errCnt() const 54 | { 55 | return brokenFeat2Spatial.size()+ brokenSpatial2Feat.size()+ brokenFeat2Feat.size()+ brokenFeat2FeatBack.size()+ orphanFeatures.size()+ orphanSpatials.size()+ 56 | brokenEdge2Node.size()+ edgesMissingBNodes.size()+ bNodesMissingEdges.size()+ brokenBNodes2Edge.size()+ featMissingFOID.size(); 57 | } 58 | void makeMessage(QStringList & errMsg) const; 59 | }; 60 | } 61 | #endif 62 | -------------------------------------------------------------------------------- /incl/cell_check_s57.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_S57_CHECK_H 2 | #define CELL_S57_CHECK_H 3 | 4 | #include "cell_s57_base.h" 5 | 6 | 7 | namespace Enc 8 | { 9 | 10 | //****************************************************************************** 11 | /// Do basic checks to find out if a ENC is corrupted 12 | /*! 13 | * Check S-57 Base-Cell without considering the Product Type 14 | * - All References and Back-References(Pointer) are checked: 15 | * Feat-Feat, Feat-Spatial, Spatial-Spatial 16 | ***************************************************************************** */ 17 | class CellCheckS57 18 | { 19 | public: 20 | CellCheckS57(const CellS57_Base * cell2check =0) : cell(cell2check) {} 21 | 22 | void setCell(const CellS57_Base * cell2check) {cell = cell2check;} 23 | const CheckResult & check(); 24 | 25 | protected: 26 | 27 | void checkSpatial2FeatureRelation(const SpatialS57 & spat); 28 | 29 | const CellS57_Base * cell; 30 | CheckResult checkRes; 31 | }; 32 | } 33 | #endif -------------------------------------------------------------------------------- /incl/cell_parser_iso8211.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_PARSER_ISO8211 2 | #define CELL_PARSER_ISO8211 3 | 4 | #include "iso8211_simple.h" 5 | 6 | #include 7 | 8 | namespace Enc 9 | { 10 | class CellS57_Header; 11 | 12 | class CellParser8211 13 | { 14 | public: 15 | 16 | enum ParseOptions{StoreDDR = 2, PrsVecRec = 4, PrsFeatRec = 16, FeatTextOnly = 64}; 17 | const static int ParseAll = PrsVecRec | PrsFeatRec; 18 | const static int FullOptions = StoreDDR | ParseAll; 19 | 20 | CellParser8211(unsigned long parseOptions); 21 | virtual ~CellParser8211(); 22 | virtual void setCell(CellS57_Header * cell) =0; 23 | void setOptions(unsigned long parseOptions) {parseOpts = parseOptions;} 24 | virtual void parseS57Cell(QString cellName) =0; 25 | 26 | protected: 27 | 28 | unsigned long parseOpts; 29 | }; 30 | 31 | } 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /incl/cell_parser_iso8211Gdal.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_PARSER_ISO8211_GDAL 2 | #define CELL_PARSER_ISO8211_GDAL 3 | 4 | #include "cell_parser_iso8211.h" 5 | #include "iso8211.h" 6 | #include 7 | 8 | namespace Enc 9 | { 10 | class CellS57_Base; 11 | 12 | //***************************************************************************** 13 | /// Parse a complete ISO-8211 ENC update file, taking care of ALL of the ISO8211 standard 14 | /*! 15 | * NOT YET FINISHED !!! WORK IN PROGRESS 16 | * 17 | ****************************************************************************** */ 18 | class CellParser8211GDAL : public CellParser8211 19 | { 20 | public: 21 | 22 | CellParser8211GDAL(CellS57_Base * cell = 0); 23 | virtual void setCell(CellS57_Base * cell); 24 | 25 | private: 26 | //**** Methods **** 27 | virtual void parseS57CellIntern(QString cellName); 28 | 29 | void ParseHeaderRecord(DDFRecord & rec); 30 | void ParseFeatureRecord(DDFRecord & rec); 31 | 32 | //**** Data **** 33 | CellS57_Base * cellS57; 34 | 35 | DDFModule oModule; //DDR (and rest of file) 36 | 37 | }; 38 | 39 | } 40 | 41 | #endif -------------------------------------------------------------------------------- /incl/cell_parser_iso8211dirty.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_PARSER_ISO8211_DIRTY 2 | #define CELL_PARSER_ISO8211_DIRTY 3 | 4 | #include "cell_s57.h" 5 | #include "iso8211_simple.h" 6 | #include "cell_parser_iso8211.h" 7 | 8 | #include 9 | 10 | namespace Enc 11 | { 12 | 13 | //***************************************************************************** 14 | /// Simplified Class to parse a complete ISO-8211 fiele containing a S-57 ENC 15 | /*! 16 | * Since the S-57 ENCs only use a small subset of ISO8211, this class is simplified, 17 | * but cannot parse other files than S-57 Chart Files 18 | * 19 | * This is a abstract base class: 20 | * It only provides methods to parse Records and Fields, which can be used by 21 | * subclasses to parse different S-57 Cells Types 22 | ****************************************************************************** */ 23 | class CellParser8211Dirty : public CellParser8211 24 | { 25 | public: 26 | 27 | CellParser8211Dirty(unsigned long parseOptions, double factorXY =0, double factorZ =0); 28 | virtual ~CellParser8211Dirty(); 29 | 30 | protected: 31 | 32 | void parseInit(QString cellName, CellS57_Header * cell, uint bytes2read =0); 33 | virtual void parseS57CellIntern(CellS57_Header * cell); 34 | 35 | //**** Methods **** 36 | void readDDR(); 37 | 38 | void parseDSIDField(const char * fieldPtr, int fieldLen, FieldDSID & dsid); 39 | void parseDSSIField(const char * fieldPtr, int fieldLen, FieldDSSI & dssi); 40 | void parseDSPMField(const char * fieldPtr, int fieldLen, FieldDSPM & dspm); 41 | 42 | //** Feature Record Field Parser ** 43 | virtual void parseFeatureRecord(Iso8211fieldIterator & fieldIt) =0; 44 | void parseFeatureRecord(Iso8211fieldIterator & fieldIt, FeatureS57 & feat); 45 | void parseFeatureUpdtRecord(Iso8211fieldIterator & fieldIt, FeatureS57_Updt & feat); 46 | bool parseFeatureField(int &fieldSize, const char * tag, const char * field, FeatureS57 & feat); 47 | void parseFRIDField(const char * fieldPtr, int fieldLen, FieldFRID & frid); 48 | void parseFOIDField(const char * fieldPtr, int fieldLen, FieldFOID & foid); 49 | long parseATTF_NAFTField(const char * fieldPtr, int fieldLen, int lexLevel, bool isNat, FeatureS57 & feat); 50 | void parseFFPCField(const char * fieldPtr, int fieldLen, FieldFFPC & ffpc); //UPDATES only 51 | long parseFFPTField(const char * fieldPtr, int fieldLen, FeatureS57 & feat); 52 | void parseFSPCField(const char * fieldPtr, int fieldLen, FieldFSPC & fspc); //UPDATES only 53 | long parseFSPTField(const char * fieldPtr, int fieldLen, FeatureS57 & feat); 54 | 55 | //** Vector Record Field Parser ** 56 | virtual void parseVectorRecord(Iso8211fieldIterator & fieldIt) =0; 57 | void parseVRIDField(const char * fieldPtr, int fieldLen, FieldVRID & vrid); 58 | void parseEdgeRecord(Iso8211fieldIterator & fieldIt, EdgeS57 & edgeRec); 59 | void parseNodeRecord(Iso8211fieldIterator & fieldIt, NodeS57 & nodeRec); 60 | void parseSndgRecord(Iso8211fieldIterator & fieldIt, SoundgS57 & sndgRec); 61 | void parseATTVFields(const char * fieldPtr, int fieldLen, SpatialS57 & spRec); 62 | void parseVRPCField(const char * fieldPtr, int fieldLen, FieldVRPC & vrpc); //UPDATES only 63 | void parseVRPTField(const char * fieldPtr, int fieldLen, EdgeS57 & edgeRec); 64 | void parseSGCCField(const char * fieldPtr, int fieldLen, FieldSGCC & sgcc); //UPDATES only 65 | long parseSG2DField(const char * fieldPtr, int fieldLen, double &, double &); 66 | void parseSG2DFields(const char * fieldPtr, int fieldLen, std::vector< double > & ); 67 | void parseSG3DFields(const char * fieldPtr, int fieldLen, std::vector< double > &); 68 | 69 | 70 | 71 | //**** Data **** 72 | 73 | char * fileBuffer; //Buffer to store the iso8211-file (or part of it) 74 | uint fileBufSize; //size of fileBuffer 75 | uint fileSize; //size of fileBuffer really used 76 | 77 | double facXY; //COMF from Cellheader, but as double 78 | double facZ; //SOMF from Cellheader, but as double 79 | 80 | unsigned char AALL, NALL; //Lex. Level vor Attributes/Nat.Attributes 81 | 82 | //** just for information: count supicious fields while parsing cell - should be ZERO if cell is ok** 83 | int unusedVRPT; //VRPT not needed for Edge->BouningNode 84 | int unusedSpatTag; //Other unused (non-standard) subfields in Spatials 85 | int unusedFeatTag; //Other unused (non-standard) subfields in Spatials 86 | }; 87 | 88 | 89 | } 90 | 91 | #endif -------------------------------------------------------------------------------- /incl/cell_parser_iso8211dirty4base.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_PARSER_ISO8211_DIRTY4BASE 2 | #define CELL_PARSER_ISO8211_DIRTY4BASE 3 | 4 | 5 | #include "cell_parser_iso8211dirty.h" 6 | 7 | namespace Enc 8 | { 9 | class CellS57_Base; 10 | 11 | //***************************************************************************** 12 | /// Simplified Class to parse a complete ISO-8211 fiele containing a S-57 BASE ENC 13 | /*! 14 | * Since the S-57 BASE ENCs only use a small subset of ISO8211, this class is simplified, 15 | * but cannot parse other files than S-57 BASE Files 16 | ****************************************************************************** */ 17 | class CellParser8211Dirty4Base : public CellParser8211Dirty 18 | { 19 | public: 20 | CellParser8211Dirty4Base(CellS57_Base * cell =0, unsigned long parseOptions = ParseAll); 21 | virtual ~CellParser8211Dirty4Base(); 22 | virtual void setCell(CellS57_Header * cell); 23 | virtual void parseS57Cell(QString cellName); 24 | 25 | protected: 26 | //** Feature Record Field Parser ** 27 | virtual void parseFeatureRecord(Iso8211fieldIterator & fieldIt); 28 | 29 | //** Vector Record Field Parser ** 30 | virtual void parseVectorRecord(Iso8211fieldIterator & fieldIt); 31 | 32 | //**** Data **** 33 | CellS57_Base * cellS57; 34 | }; 35 | 36 | } 37 | 38 | #endif -------------------------------------------------------------------------------- /incl/cell_parser_iso8211dirty4header.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_PARSER_ISO8211_DIRTY4HEADER 2 | #define CELL_PARSER_ISO8211_DIRTY4HEADER 3 | 4 | #include "cell_parser_iso8211dirty.h" 5 | 6 | namespace Enc 7 | { 8 | 9 | //***************************************************************************** 10 | /// Simplified Class to parse the HEADER of a ISO-8211 file containing a S-57 BASE ENC 11 | /*! 12 | * It only parses the 3 Fields contained in the first and second Data-Record, 13 | * but does not parse vector- or feature-records -> fast, when only header-data is needed 14 | ****************************************************************************** */ 15 | class CellParser8211Dirty4Header : public CellParser8211Dirty 16 | { 17 | public: 18 | CellParser8211Dirty4Header(CellS57_Header * cell =0, unsigned long parseOptions =0); 19 | virtual ~CellParser8211Dirty4Header(); 20 | virtual void setCell(CellS57_Header * cell); 21 | virtual void parseS57Cell(QString cellName); 22 | 23 | protected: 24 | 25 | virtual void parseFeatureRecord(Iso8211fieldIterator & fieldIt) {throw QString("Internal Error: Trying to parse Feature in Header of cell: %1!").arg(cellS57 ? cellS57->getDsid().getDSNM():"");} 26 | virtual void parseVectorRecord(Iso8211fieldIterator & fieldIt) {throw QString("Internal Error: Trying to parse Spatial in Header of cell: %1!").arg(cellS57 ? cellS57->getDsid().getDSNM():"");} 27 | 28 | //**** Data **** 29 | CellS57_Header * cellS57; 30 | }; 31 | 32 | } 33 | 34 | #endif -------------------------------------------------------------------------------- /incl/cell_parser_iso8211dirty4updt.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_PARSER_ISO8211_DIRTY4Update 2 | #define CELL_PARSER_ISO8211_DIRTY4Update 3 | 4 | #include "cell_parser_iso8211dirty.h" 5 | #include "cell_s57.h" 6 | 7 | namespace Enc 8 | { 9 | class CellS57_Update; 10 | 11 | //***************************************************************************** 12 | /// Simplified Class to parse a complete ISO-8211 ENC update file 13 | /*! 14 | * It can only parse update files ("ER") 15 | ****************************************************************************** */ 16 | class CellParser8211Dirty4Updt : public CellParser8211Dirty 17 | { 18 | public: 19 | CellParser8211Dirty4Updt(CellS57_Update * cell =0, unsigned long parseOptions =CellParser8211::ParseAll); 20 | CellParser8211Dirty4Updt(double factorXY, double factorZ, unsigned long parseOptions =CellParser8211::ParseAll); 21 | virtual ~CellParser8211Dirty4Updt(); 22 | virtual void setCell(CellS57_Header * cell); 23 | virtual void parseS57Cell(QString cellName); 24 | 25 | protected: 26 | //** Feature Record Field Parser ** 27 | virtual void parseFeatureRecord(Iso8211fieldIterator & fieldIt); 28 | 29 | //** Vector Record Field Parser ** 30 | virtual void parseVectorRecord(Iso8211fieldIterator & fieldIt); 31 | void parseVectorUpdtRecord(Iso8211fieldIterator & fieldIt, SpatialS57 * updtSpatial); 32 | void parseVectorUpdtFields(Iso8211fieldIterator & fieldIt, SpatialS57_Updt &); 33 | 34 | //**** Data **** 35 | CellS57_Update * cellS57; 36 | }; 37 | 38 | } 39 | 40 | #endif -------------------------------------------------------------------------------- /incl/cell_s57.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_S57 2 | #define CELL_S57 3 | 4 | #include "cell_records.h" 5 | 6 | #include 7 | 8 | #include 9 | 10 | namespace Enc 11 | { 12 | class CellParser8211; 13 | class CellParser8211Dirty; 14 | class CellWriter; 15 | class CellWriter8211Dirty; 16 | class CellParser8211Dirty4Base; 17 | class CellParser8211Dirty4Updt; 18 | 19 | //****************************************************************************** 20 | /// Class containig the data (records) common to all S57 Update AND Base Cells 21 | /*! 22 | * Also usefull if only the cellHeader is needed 23 | ***************************************************************************** */ 24 | class CellS57_Header 25 | { 26 | public: 27 | 28 | enum CellS57Class{HeaderOnly = 1, BaseCellClass = 2, UpdtCellClass = 3}; 29 | 30 | CellS57_Header(); 31 | CellS57_Header(const FieldDSPM & baseDSPM); 32 | virtual ~CellS57_Header(); 33 | virtual CellS57Class getClass() const {return HeaderOnly;} //usefull for casting 34 | virtual void clear(); 35 | virtual void clearExceptDSPM(); 36 | 37 | void putDDR(const char * ddrPtr, int len); 38 | 39 | const FieldDSID & getDsid() const {return dsid;} 40 | const FieldDSSI & getDssi() const {return dssi;} 41 | const FieldDSPM & getDspm() const {return dspm;} 42 | 43 | FieldDSID & getDsid() {return dsid;} 44 | FieldDSSI & getDssi() {return dssi;} 45 | FieldDSPM & getDspm() {return dspm;} 46 | 47 | const DegBBox & getBBox() const {return bBox;} 48 | 49 | virtual bool isUpdateCell() const {return dsid.getEXPP() == 2;} 50 | 51 | protected: 52 | 53 | //**** Header Data **** 54 | FieldDSID dsid; 55 | FieldDSSI dssi; 56 | FieldDSPM dspm; //will be empty in case of UpdateCell 57 | 58 | //DDR record (including Leader) - unimportant - only needed if someone wants to read cell and then write original DDR when writing cell 59 | //or if the DDR is non Standard (but that means: not a S-57 cell) 60 | char * DDR; 61 | int DDRlen; //length of DDR 62 | 63 | DegBBox bBox; //Cell Bounding Box, calculated while parsing, only valid vor base-cell, otherwise empty 64 | }; 65 | 66 | } 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /incl/cell_s57_base.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_S57_BASE 2 | #define CELL_S57_BASE 3 | 4 | #include 5 | 6 | #include "cell_check_result.h" 7 | #include "cell_s57.h" 8 | 9 | namespace Enc 10 | { 11 | class CellParser8211; 12 | class CellParser8211Dirty; 13 | class CellWriter; 14 | class CellWriter8211Dirty; 15 | class CellParser8211Dirty4Base; 16 | class S57Updater; 17 | 18 | //****************************************************************************** 19 | /// Class containig the data (records) of a complete S-57 cell 20 | /*! 21 | * Holds ALL information of a base cell, and: 22 | * For every relation(Pointer), the class holds a backward-relation to acellerate access 23 | ***************************************************************************** */ 24 | class CellS57_Base : public CellS57_Header 25 | { 26 | friend class CellParser8211; 27 | friend class CellParser8211Dirty; 28 | friend class CellWriter; 29 | friend class CellWriter8211Dirty; 30 | friend class CellParser8211Dirty4Base; 31 | friend class S57Updater; 32 | 33 | public: 34 | 35 | //**** Methods **** 36 | CellS57_Base(); 37 | virtual ~CellS57_Base(); 38 | virtual CellS57Class getClass() const {return BaseCellClass;} //usefull for casting 39 | virtual void clear(); 40 | 41 | void parseISO8211(QString fileNamePath); 42 | void writeISO8211(QString fileNamePath) const; 43 | void applyUpdates(QStringList updateCells); 44 | 45 | void check() const; 46 | int recordCount() const; 47 | void updateDSSIrecordCounts(); 48 | virtual bool isUpdateCell() const {return false;} 49 | 50 | const std::map< unsigned long, FeatureS57 *> & getFeatures() const {return features;} //Key = RCID (RCNM is 100("FE"), anyway -> ignored) 51 | const std::map< unsigned long, NodeS57 *> & getINodes() const {return iNodes;} //KEY: RecordId of an Isolated Node ("VI") 52 | const std::map< unsigned long, BoundNodeS57 *> &getBNodes() const {return bNodes;} //KEY: RecordId of an Bounding Node ("VC") 53 | const std::map< unsigned long, SoundgS57 *> & getSoundingds()const {return soundings;} //KEY: Rec-id of an Isolanted Node containing 3D-Cluster ("VI") 54 | const std::map< unsigned long, EdgeS57 *> & getEdges() const {return edges;} //KEY: Rec-id of an Edge ("VE") 55 | 56 | bool recordExists(unsigned char RCNM, unsigned long RCID) const; 57 | void deleteRecordStupid(unsigned char RCNM, unsigned long RCID); 58 | void deleteRecordAndBackPointer(unsigned char RCNM, unsigned long RCID); 59 | void deleteFeatureWithOrphans(unsigned long RCID); 60 | void deleteSpatialWithOrphanSpatials(unsigned char RCNM, unsigned long RCID); 61 | 62 | FeatureS57 & getFeature(unsigned long RCID); 63 | SpatialS57 & getSpatial(unsigned int rcnm, unsigned long rcid); 64 | NodeS57 & getINode(unsigned long RCID); 65 | BoundNodeS57 & getBNode(unsigned long RCID); 66 | SoundgS57 & getSounding(unsigned long RCID); 67 | EdgeS57 & getEdge(unsigned long RCID); 68 | 69 | const FeatureS57 & getFeature(unsigned long RCID) const; 70 | const SpatialS57 & getSpatial(unsigned int rcnm, unsigned long rcid) const; 71 | const NodeS57 & getINode(unsigned long RCID) const; 72 | const BoundNodeS57 & getBNode(unsigned long RCID) const; 73 | const SoundgS57 & getSounding(unsigned long RCID) const; 74 | const EdgeS57 & getEdge(unsigned long RCID) const; 75 | 76 | 77 | void addFeature(const FeatureS57 & feat); 78 | void addSpatial(const SpatialS57 & spat); 79 | void addINode(const NodeS57 & feat); 80 | void addBNode(const NodeS57 & bNode); 81 | void addSoundg(const SoundgS57 & sndg); 82 | void addEdge(const EdgeS57 & edge); 83 | 84 | const std::multimap < LongNAMe, unsigned long > & getFOIDs() const {return foid2rcid;} ///Key = FOID, value =Rec-ID of Feature Record("FE") 85 | unsigned long getRcid4Foid(LongNAMe foid) const 86 | { 87 | std::multimap < LongNAMe, unsigned long >::const_iterator it = foid2rcid.find(foid); 88 | if (it == foid2rcid.end()) return 0; 89 | return it->second; 90 | } 91 | 92 | protected: 93 | 94 | //**** methods **** 95 | void processBackwardPointers(); 96 | void processBackwardPointers4newRecords(); 97 | void processBackwardPointer4edge(const EdgeS57 *); 98 | void processBackwardPointer4feature(const FeatureS57 *); 99 | 100 | void calcBoundingBox(); 101 | void calcBoundingBox(EdgeS57 * edge); 102 | 103 | unsigned long getMaxRCID4FE() const; 104 | unsigned long getMaxRCID4VE() const; 105 | unsigned long getMaxRCID4VI() const; 106 | unsigned long getMaxRCID4VC() const; 107 | bool setRCIDifNeeded(SpatialS57 & spatial); 108 | 109 | void getSpatialsForFeature(const FeatureS57 & feat, std::vector & spatials) const; 110 | void getSpatialsForFeature(const FeatureS57 & feat, std::vector & spatials); 111 | 112 | CheckResult checkResult; 113 | 114 | //**** Data (Cell Header is found in base-class) **** 115 | //** Features ** 116 | std::map< unsigned long, FeatureS57 *> features; ///Key = RecordId(RCID) of a Feature(RCNM is 100("FE"), anyway -> ignored) 117 | //** Vector Records are separately stored: Nodes (isolated and connecte), Soundings, and Edges ** 118 | std::map< unsigned long, NodeS57 *> iNodes; ///KEY: RecordId of an Isolated Node ("VI") 119 | std::map< unsigned long, BoundNodeS57 *> bNodes; ///KEY: RecordId of an Bounding Node ("VC") 120 | std::map< unsigned long, SoundgS57 *> soundings; ///KEY: Rec-id of an Isolanted Node containing 3D-Cluster ("VI") 121 | std::map< unsigned long, EdgeS57 *> edges; ///KEY: Rec-id of an Edge ("VE") 122 | 123 | //**** cached Data (needed 4 fast reocrd access) **** 124 | std::multimap < LongNAMe, unsigned long > foid2rcid; ///Key = FOID, value =Rec-ID of Feature Record("FE") - Used to find Feature To Feature Relationships quick 125 | 126 | //**** for updating: remeber new records **** 127 | std::vector newFeatures; //newly added or modifyed Feature-Records 128 | std::vector newEdges; //newly added or modifyed Edge-Records 129 | 130 | }; 131 | } 132 | #endif 133 | 134 | -------------------------------------------------------------------------------- /incl/cell_s57_iterators.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KaiAbuSir/EncLib/ba8547abe7f2fa02132076227fe4b93b37f3de0c/incl/cell_s57_iterators.h -------------------------------------------------------------------------------- /incl/cell_s57_update.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_S57_UPDATE 2 | #define CELL_S57_UPDATE 3 | 4 | #include "cell_s57.h" 5 | 6 | namespace Enc 7 | { 8 | class CellParser8211; 9 | class CellParser8211Dirty; 10 | class CellWriter; 11 | class CellWriter8211Dirty; 12 | class CellParser8211Dirty4Updt; 13 | 14 | //****************************************************************************** 15 | /// Class containig the data (records) of a S-57 UPDATE cell 16 | /*! 17 | * Does not contains maps, "backward"-pointer ... because performance is not that important for updates 18 | ***************************************************************************** */ 19 | class CellS57_Update : public CellS57_Header 20 | { 21 | friend class CellParser8211; 22 | friend class CellParser8211Dirty; 23 | friend class CellParser8211Dirty4Updt; 24 | 25 | public: 26 | CellS57_Update(const FieldDSPM & baseDSPM); 27 | CellS57_Update(); 28 | ~CellS57_Update(); 29 | virtual CellS57Class getClass() const {return UpdtCellClass;} //usefull for casting 30 | 31 | virtual void clear(); 32 | void clearExceptDSPM(); 33 | virtual bool isUpdateCell() const {return true;} 34 | 35 | void parseISO8211(QString fileNamePath); 36 | 37 | const std::vector< FeatureS57_Updt *> & getFeatures() const {return features;} 38 | const std::vector< SpatialS57 *> & getSpatials() const {return spatials;} 39 | 40 | protected: 41 | std::vector features; 42 | std::vector spatials; 43 | }; 44 | } 45 | #endif 46 | -------------------------------------------------------------------------------- /incl/cell_writer.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_WRITER 2 | #define CELL_WRITER 3 | 4 | #include "iso8211_simple.h" 5 | 6 | #include 7 | 8 | namespace Enc 9 | { 10 | class CellS57_Base; 11 | 12 | //****************************************************************************** 13 | /// Interface for Classes writing Base-Cell to ISO8211 Files 14 | /*! 15 | ***************************************************************************** */ 16 | class CellWriter 17 | { 18 | public: 19 | 20 | CellWriter(const CellS57_Base * cell=0) : cellS57(cell) {} 21 | virtual ~CellWriter() {} 22 | void setCell(const CellS57_Base * cell); 23 | void writeS57Cell(QString cellName); 24 | virtual void writeS57Cell(QIODevice * cellDev) = 0; 25 | 26 | protected: 27 | 28 | const CellS57_Base * cellS57; 29 | }; 30 | 31 | } 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /incl/cell_writer_iso8211dirty.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_WRITER_ISO8211_DIRTY 2 | #define CELL_WRITER_ISO8211_DIRTY 3 | 4 | #include 5 | 6 | #include "cell_writer.h" 7 | #include "cell_records.h" 8 | namespace Enc 9 | { 10 | 11 | //***************************************************************************** 12 | /// Write a BaseCell to ISO8211 File 13 | /*! 14 | ****************************************************************************** */ 15 | class CellWriter8211Dirty : public CellWriter 16 | { 17 | public: 18 | 19 | using CellWriter::writeS57Cell; 20 | 21 | CellWriter8211Dirty(const CellS57_Base * cell=0) : CellWriter(cell), cellDev(0), field0001len(0), currentIso8211rcid(0) {} 22 | virtual ~CellWriter8211Dirty(); 23 | virtual void writeS57Cell(QIODevice * device2write); 24 | 25 | protected: 26 | 27 | //**** methods **** 28 | 29 | //** Records ** 30 | unsigned long writeDSGIrecord(); //CellHeader 31 | unsigned long writeDSGRrecord(); //CellHeader 32 | unsigned long writeNode(const NodeS57 & node); 33 | unsigned long writeSounding(const SoundgS57 & sndg); 34 | unsigned long writeEdge(const EdgeS57 & edge); 35 | unsigned long writeFeature(const FeatureS57 & feat); 36 | 37 | unsigned long writeSpatial(const SpatialS57 & spatial, const char * coordTag, unsigned long coordSize, unsigned long vrptSize = 0); 38 | 39 | //** common Fields ** 40 | unsigned long write0001Field(); 41 | //** cellheader Fields ** 42 | unsigned long writeDSIDField(); 43 | unsigned long writeDSSIField(); 44 | unsigned long writeDSPMField(); 45 | //** feature Record Fields ** 46 | unsigned long writeFridField(const FieldFRID &); 47 | unsigned long writeFoidField(const FieldFOID &); 48 | unsigned long writeAttributeField(const FieldAttr &); 49 | unsigned long writeFfpcField(const FieldFFPC &); 50 | unsigned long writeFfptField(const FieldFFPT &); 51 | unsigned long writeFspcField(const FieldFSPC &); 52 | unsigned long writeFsptField(const FieldFSPT &); 53 | 54 | //** Spatial Record Fields ** 55 | unsigned long writeVridField(const FieldVRID &); 56 | unsigned long writeVrpcField(const FieldVRPC &); 57 | unsigned long writeVrptField(const FieldVRPT &); 58 | unsigned long writeSGCCField(const FieldSGCC &); 59 | 60 | void makeVRPT4BoundingNode(FieldVRPT & vrpt, unsigned long recId, bool forward) const; 61 | 62 | //**** data **** 63 | QIODevice * cellDev; 64 | const static char * DefaultDDR; 65 | 66 | int field0001len; //size of 0001 Field EXCLUDING the FT !! (ISO8211 RecId)- must be 2 bytes (DDR) but: depending on Record count, may be 4 bytes! 67 | unsigned long currentIso8211rcid; //to be updated AFTER the 0001 Field is written 68 | }; 69 | 70 | //***************************************************************************** 71 | /// 72 | /*! 73 | ****************************************************************************** */ 74 | class RecordLeaderDirWriter 75 | { 76 | public: 77 | #ifdef _DEBUG 78 | unsigned int recLenWrittn; 79 | #endif 80 | 81 | RecordLeaderDirWriter(int total0001Fieldlength,int sizeofFieldLenField = 0, int sizeofFieldPosField = 0) 82 | : total0001Fieldlen(total0001Fieldlength), sizeFldLenFld(sizeofFieldLenField), sizeFldPosFld(sizeofFieldPosField) {} 83 | unsigned long write(QIODevice *) const; 84 | void addField(const char * tag, int lenght); 85 | 86 | private: 87 | std::vector< ISO8211::DirEntry > dirEntries; 88 | int total0001Fieldlen; 89 | int sizeFldLenFld, sizeFldPosFld; 90 | 91 | }; 92 | 93 | } 94 | 95 | #endif -------------------------------------------------------------------------------- /incl/cell_writer_iso8211dirtyDDR.incl: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | /// Default DDR Record, taken from IHO example Cell 3 | /* 4 | * There are only 2 kinds of non-printable characters in the DDR: the UT and the FT 5 | * rem: \0x1F = UT - Unit Terminator 6 | * rem: \0x1E = FT - Field Terminator 7 | * So, fortunately, there are not NULL chars in DDR, so strlen() works :-) 8 | * string-length is 1969 Bytes, of course. 9 | ***************************************************************************** */ 10 | 11 | const char * CellWriter8211Dirty::DefaultDDR = 12 | 13 | "\x30\x31\x39\x36\x39\x33\x4C\x45\x31\x20\x30\x39\x30\x30\x32\x34\x35\x20\x21\x20\x33\x34\x30\x34\x30\x30\x30\x30\x31\x35\x35\x30" 14 | "\x30\x30\x30\x30\x30\x30\x31\x30\x34\x37\x30\x31\x35\x35\x44\x53\x49\x44\x31\x36\x35\x30\x32\x30\x32\x44\x53\x53\x49\x31\x31\x33" 15 | "\x30\x33\x36\x37\x44\x53\x50\x4D\x31\x33\x30\x30\x34\x38\x30\x56\x52\x49\x44\x30\x37\x38\x30\x36\x31\x30\x41\x54\x54\x56\x30\x35" 16 | "\x38\x30\x36\x38\x38\x56\x52\x50\x43\x30\x37\x31\x30\x37\x34\x36\x56\x52\x50\x54\x30\x37\x36\x30\x38\x31\x37\x53\x47\x43\x43\x30" 17 | "\x36\x30\x30\x38\x39\x33\x53\x47\x32\x44\x30\x34\x38\x30\x39\x35\x33\x53\x47\x33\x44\x30\x37\x30\x31\x30\x30\x31\x46\x52\x49\x44" 18 | "\x31\x30\x30\x31\x30\x37\x31\x46\x4F\x49\x44\x30\x37\x30\x31\x31\x37\x31\x41\x54\x54\x46\x30\x35\x39\x31\x32\x34\x31\x4E\x41\x54" 19 | "\x46\x30\x36\x38\x31\x33\x30\x30\x46\x46\x50\x43\x30\x39\x30\x31\x33\x36\x38\x46\x46\x50\x54\x30\x38\x36\x31\x34\x35\x38\x46\x53" 20 | "\x50\x43\x30\x39\x30\x31\x35\x34\x34\x46\x53\x50\x54\x30\x39\x30\x31\x36\x33\x34\x1E\x30\x30\x30\x30\x3B\x26\x20\x20\x20\x1F\x30" 21 | "\x30\x30\x31\x44\x53\x49\x44\x44\x53\x49\x44\x44\x53\x53\x49\x30\x30\x30\x31\x44\x53\x50\x4D\x30\x30\x30\x31\x56\x52\x49\x44\x56" 22 | "\x52\x49\x44\x41\x54\x54\x56\x56\x52\x49\x44\x56\x52\x50\x43\x56\x52\x49\x44\x56\x52\x50\x54\x56\x52\x49\x44\x53\x47\x43\x43\x56" 23 | "\x52\x49\x44\x53\x47\x32\x44\x56\x52\x49\x44\x53\x47\x33\x44\x30\x30\x30\x31\x46\x52\x49\x44\x46\x52\x49\x44\x46\x4F\x49\x44\x46" 24 | "\x52\x49\x44\x41\x54\x54\x46\x46\x52\x49\x44\x4E\x41\x54\x46\x46\x52\x49\x44\x46\x46\x50\x43\x46\x52\x49\x44\x46\x46\x50\x54\x46" 25 | "\x52\x49\x44\x46\x53\x50\x43\x46\x52\x49\x44\x46\x53\x50\x54\x1E\x30\x35\x30\x30\x3B\x26\x20\x20\x20\x49\x53\x4F\x2F\x49\x45\x43" 26 | "\x20\x38\x32\x31\x31\x20\x52\x65\x63\x6F\x72\x64\x20\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x1F\x1F\x28\x62\x31\x32\x29\x1E\x31" 27 | "\x36\x30\x30\x3B\x26\x20\x20\x20\x44\x61\x74\x61\x20\x73\x65\x74\x20\x69\x64\x65\x6E\x74\x69\x66\x69\x63\x61\x74\x69\x6F\x6E\x20" 28 | "\x66\x69\x65\x6C\x64\x1F\x52\x43\x4E\x4D\x21\x52\x43\x49\x44\x21\x45\x58\x50\x50\x21\x49\x4E\x54\x55\x21\x44\x53\x4E\x4D\x21\x45" 29 | "\x44\x54\x4E\x21\x55\x50\x44\x4E\x21\x55\x41\x44\x54\x21\x49\x53\x44\x54\x21\x53\x54\x45\x44\x21\x50\x52\x53\x50\x21\x50\x53\x44" 30 | "\x4E\x21\x50\x52\x45\x44\x21\x50\x52\x4F\x46\x21\x41\x47\x45\x4E\x21\x43\x4F\x4D\x54\x1F\x28\x62\x31\x31\x2C\x62\x31\x34\x2C\x32" 31 | "\x62\x31\x31\x2C\x33\x41\x2C\x32\x41\x28\x38\x29\x2C\x52\x28\x34\x29\x2C\x62\x31\x31\x2C\x32\x41\x2C\x62\x31\x31\x2C\x62\x31\x32" 32 | "\x2C\x41\x29\x1E\x31\x36\x30\x30\x3B\x26\x20\x20\x20\x44\x61\x74\x61\x20\x73\x65\x74\x20\x73\x74\x72\x75\x63\x74\x75\x72\x65\x20" 33 | "\x69\x6E\x66\x6F\x72\x6D\x61\x74\x69\x6F\x6E\x20\x66\x69\x65\x6C\x64\x1F\x44\x53\x54\x52\x21\x41\x41\x4C\x4C\x21\x4E\x41\x4C\x4C" 34 | "\x21\x4E\x4F\x4D\x52\x21\x4E\x4F\x43\x52\x21\x4E\x4F\x47\x52\x21\x4E\x4F\x4C\x52\x21\x4E\x4F\x49\x4E\x21\x4E\x4F\x43\x4E\x21\x4E" 35 | "\x4F\x45\x44\x21\x4E\x4F\x46\x41\x1F\x28\x33\x62\x31\x31\x2C\x38\x62\x31\x34\x29\x1E\x31\x36\x30\x30\x3B\x26\x20\x20\x20\x44\x61" 36 | "\x74\x61\x20\x73\x65\x74\x20\x70\x61\x72\x61\x6D\x65\x74\x65\x72\x20\x66\x69\x65\x6C\x64\x1F\x52\x43\x4E\x4D\x21\x52\x43\x49\x44" 37 | "\x21\x48\x44\x41\x54\x21\x56\x44\x41\x54\x21\x53\x44\x41\x54\x21\x43\x53\x43\x4C\x21\x44\x55\x4E\x49\x21\x48\x55\x4E\x49\x21\x50" 38 | "\x55\x4E\x49\x21\x43\x4F\x55\x4E\x21\x43\x4F\x4D\x46\x21\x53\x4F\x4D\x46\x21\x43\x4F\x4D\x54\x1F\x28\x62\x31\x31\x2C\x62\x31\x34" 39 | "\x2C\x33\x62\x31\x31\x2C\x62\x31\x34\x2C\x34\x62\x31\x31\x2C\x32\x62\x31\x34\x2C\x41\x29\x1E\x31\x36\x30\x30\x3B\x26\x20\x20\x20" 40 | "\x56\x65\x63\x74\x6F\x72\x20\x72\x65\x63\x6F\x72\x64\x20\x69\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x20\x66\x69\x65\x6C\x64\x1F\x52" 41 | "\x43\x4E\x4D\x21\x52\x43\x49\x44\x21\x52\x56\x45\x52\x21\x52\x55\x49\x4E\x1F\x28\x62\x31\x31\x2C\x62\x31\x34\x2C\x62\x31\x32\x2C" 42 | "\x62\x31\x31\x29\x1E\x32\x36\x30\x30\x3B\x26\x20\x20\x20\x56\x65\x63\x74\x6F\x72\x20\x72\x65\x63\x6F\x72\x64\x20\x61\x74\x74\x72" 43 | "\x69\x62\x75\x74\x65\x20\x66\x69\x65\x6C\x64\x1F\x2A\x41\x54\x54\x4C\x21\x41\x54\x56\x4C\x1F\x28\x62\x31\x32\x2C\x41\x29\x1E\x31" 44 | "\x36\x30\x30\x3B\x26\x20\x20\x20\x56\x65\x63\x74\x6F\x72\x20\x52\x65\x63\x6F\x72\x64\x20\x50\x6F\x69\x6E\x74\x65\x72\x20\x43\x6F" 45 | "\x6E\x74\x72\x6F\x6C\x20\x66\x69\x65\x6C\x64\x1F\x56\x50\x55\x49\x21\x56\x50\x49\x58\x21\x4E\x56\x50\x54\x1F\x28\x62\x31\x31\x2C" 46 | "\x32\x62\x31\x32\x29\x1E\x32\x36\x30\x30\x3B\x26\x20\x20\x20\x56\x65\x63\x74\x6F\x72\x20\x72\x65\x63\x6F\x72\x64\x20\x70\x6F\x69" 47 | "\x6E\x74\x65\x72\x20\x66\x69\x65\x6C\x64\x1F\x2A\x4E\x41\x4D\x45\x21\x4F\x52\x4E\x54\x21\x55\x53\x41\x47\x21\x54\x4F\x50\x49\x21" 48 | "\x4D\x41\x53\x4B\x1F\x28\x42\x28\x34\x30\x29\x2C\x34\x62\x31\x31\x29\x1E\x31\x36\x30\x30\x3B\x26\x20\x20\x20\x43\x6F\x6F\x72\x64" 49 | "\x69\x6E\x61\x74\x65\x20\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x46\x69\x65\x6C\x64\x1F\x43\x43\x55\x49\x21\x43\x43\x49\x58\x21\x43\x43" 50 | "\x4E\x43\x1F\x28\x62\x31\x31\x2C\x32\x62\x31\x32\x29\x1E\x32\x35\x30\x30\x3B\x26\x20\x20\x20\x32\x2D\x44\x20\x63\x6F\x6F\x72\x64" 51 | "\x69\x6E\x61\x74\x65\x20\x66\x69\x65\x6C\x64\x1F\x2A\x59\x43\x4F\x4F\x21\x58\x43\x4F\x4F\x1F\x28\x32\x62\x32\x34\x29\x1E\x32\x35" 52 | "\x30\x30\x3B\x26\x20\x20\x20\x33\x2D\x44\x20\x63\x6F\x6F\x72\x64\x69\x6E\x61\x74\x65\x20\x28\x73\x6F\x75\x6E\x64\x69\x6E\x67\x20" 53 | "\x61\x72\x72\x61\x79\x29\x20\x66\x69\x65\x6C\x64\x1F\x2A\x59\x43\x4F\x4F\x21\x58\x43\x4F\x4F\x21\x56\x45\x33\x44\x1F\x28\x33\x62" 54 | "\x32\x34\x29\x1E\x31\x36\x30\x30\x3B\x26\x20\x20\x20\x46\x65\x61\x74\x75\x72\x65\x20\x72\x65\x63\x6F\x72\x64\x20\x69\x64\x65\x6E" 55 | "\x74\x69\x66\x69\x65\x72\x20\x66\x69\x65\x6C\x64\x1F\x52\x43\x4E\x4D\x21\x52\x43\x49\x44\x21\x50\x52\x49\x4D\x21\x47\x52\x55\x50" 56 | "\x21\x4F\x42\x4A\x4C\x21\x52\x56\x45\x52\x21\x52\x55\x49\x4E\x1F\x28\x62\x31\x31\x2C\x62\x31\x34\x2C\x32\x62\x31\x31\x2C\x32\x62" 57 | "\x31\x32\x2C\x62\x31\x31\x29\x1E\x31\x36\x30\x30\x3B\x26\x20\x20\x20\x46\x65\x61\x74\x75\x72\x65\x20\x6F\x62\x6A\x65\x63\x74\x20" 58 | "\x69\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x20\x66\x69\x65\x6C\x64\x1F\x41\x47\x45\x4E\x21\x46\x49\x44\x4E\x21\x46\x49\x44\x53\x1F" 59 | "\x28\x62\x31\x32\x2C\x62\x31\x34\x2C\x62\x31\x32\x29\x1E\x32\x36\x30\x30\x3B\x26\x2D\x41\x20\x46\x65\x61\x74\x75\x72\x65\x20\x72" 60 | "\x65\x63\x6F\x72\x64\x20\x61\x74\x74\x72\x69\x62\x75\x74\x65\x20\x66\x69\x65\x6C\x64\x1F\x2A\x41\x54\x54\x4C\x21\x41\x54\x56\x4C" 61 | "\x1F\x28\x62\x31\x32\x2C\x41\x29\x1E\x32\x36\x30\x30\x3B\x26\x2D\x41\x20\x46\x65\x61\x74\x75\x72\x65\x20\x72\x65\x63\x6F\x72\x64" 62 | "\x20\x6E\x61\x74\x69\x6F\x6E\x61\x6C\x20\x61\x74\x74\x72\x69\x62\x75\x74\x65\x20\x66\x69\x65\x6C\x64\x1F\x2A\x41\x54\x54\x4C\x21" 63 | "\x41\x54\x56\x4C\x1F\x28\x62\x31\x32\x2C\x41\x29\x1E\x31\x36\x30\x30\x3B\x26\x20\x20\x20\x46\x65\x61\x74\x75\x72\x65\x20\x72\x65" 64 | "\x63\x6F\x72\x64\x20\x74\x6F\x20\x66\x65\x61\x74\x75\x72\x65\x20\x6F\x62\x6A\x65\x63\x74\x20\x70\x6F\x69\x6E\x74\x65\x72\x20\x63" 65 | "\x6F\x6E\x74\x72\x6F\x6C\x20\x66\x69\x65\x6C\x64\x1F\x46\x46\x55\x49\x21\x46\x46\x49\x58\x21\x4E\x46\x50\x54\x1F\x28\x62\x31\x31" 66 | "\x2C\x32\x62\x31\x32\x29\x1E\x32\x36\x30\x30\x3B\x26\x20\x20\x20\x46\x65\x61\x74\x75\x72\x65\x20\x72\x65\x63\x6F\x72\x64\x20\x74" 67 | "\x6F\x20\x66\x65\x61\x74\x75\x72\x65\x20\x6F\x62\x6A\x65\x63\x74\x20\x70\x6F\x69\x6E\x74\x65\x72\x20\x66\x69\x65\x6C\x64\x1F\x2A" 68 | "\x4C\x4E\x41\x4D\x21\x52\x49\x4E\x44\x21\x43\x4F\x4D\x54\x1F\x28\x42\x28\x36\x34\x29\x2C\x62\x31\x31\x2C\x41\x29\x1E\x31\x36\x30" 69 | "\x30\x3B\x26\x20\x20\x20\x46\x65\x61\x74\x75\x72\x65\x20\x72\x65\x63\x6F\x72\x64\x20\x74\x6F\x20\x73\x70\x61\x74\x69\x61\x6C\x20" 70 | "\x72\x65\x63\x6F\x72\x64\x20\x70\x6F\x69\x6E\x74\x65\x72\x20\x63\x6F\x6E\x74\x72\x6F\x6C\x20\x66\x69\x65\x6C\x64\x1F\x46\x53\x55" 71 | "\x49\x21\x46\x53\x49\x58\x21\x4E\x53\x50\x54\x1F\x28\x62\x31\x31\x2C\x32\x62\x31\x32\x29\x1E\x32\x36\x30\x30\x3B\x26\x20\x20\x20" 72 | "\x46\x65\x61\x74\x75\x72\x65\x20\x72\x65\x63\x6F\x72\x64\x20\x74\x6F\x20\x73\x70\x61\x74\x69\x61\x6C\x20\x72\x65\x63\x6F\x72\x64" 73 | "\x20\x70\x6F\x69\x6E\x74\x65\x72\x20\x66\x69\x65\x6C\x64\x1F\x2A\x4E\x41\x4D\x45\x21\x4F\x52\x4E\x54\x21\x55\x53\x41\x47\x21\x4D" 74 | "\x41\x53\x4B\x1F\x28\x42\x28\x34\x30\x29\x2C\x33\x62\x31\x31\x29\x1E"; 75 | 76 | /*** Same, but: Does not work: hex-excape-seqences within text :-( **** 77 | "019693LE1 0900245 ! 34040000155000000010470155DSID1650202DSSI113" 78 | "0367DSPM1300480VRID0780610ATTV0580688VRPC0710746VRPT0760817SGCC0" 79 | "600893SG2D0480953SG3D0701001FRID1001071FOID0701171ATTF0591241NAT" 80 | "F0681300FFPC0901368FFPT0861458FSPC0901544FSPT0901634\x1E0000;& \x1F0" 81 | "001DSIDDSIDDSSI0001DSPM0001VRIDVRIDATTVVRIDVRPCVRIDVRPTVRIDSGCCV" 82 | "RIDSG2DVRIDSG3D0001FRIDFRIDFOIDFRIDATTFFRIDNATFFRIDFFPCFRIDFFPTF" 83 | "RIDFSPCFRIDFSPT\x1E0500;& ISO/IEC 8211 Record Identifier\x1F\x1F(b12)\x1E1" 84 | "600;& Data set identification field\x1FRCNM!RCID!EXPP!INTU!DSNM!E" 85 | "DTN!UPDN!UADT!ISDT!STED!PRSP!PSDN!PRED!PROF!AGEN!COMT\x1F(b11,b14,2" 86 | "b11,3A,2A(8),R(4),b11,2A,b11,b12,A)\x1E1600;& Data set structure " 87 | "information field\x1FDSTR!AALL!NALL!NOMR!NOCR!NOGR!NOLR!NOIN!NOCN!N" 88 | "OED!NOFA\x1F(3b11,8b14)\x1E1600;& Data set parameter field\x1FRCNM!RCID" 89 | "!HDAT!VDAT!SDAT!CSCL!DUNI!HUNI!PUNI!COUN!COMF!SOMF!COMT\x1F(b11,b14" 90 | ",3b11,b14,4b11,2b14,A)\x1E1600;& Vector record identifier field\x1FR" 91 | "CNM!RCID!RVER!RUIN\x1F(b11,b14,b12,b11)\x1E2600;& Vector record attr" 92 | "ibute field\x1F*ATTL!ATVL\x1F(b12,A)\x1E1600;& Vector Record Pointer Co" 93 | "ntrol field\x1FVPUI!VPIX!NVPT\x1F(b11,2b12)\x1E2600;& Vector record poi" 94 | "nter field\x1F*NAME!ORNT!USAG!TOPI!MASK\x1F(B(40),4b11)\x1E1600;& Coord" 95 | "inate Control Field\x1FCCUI!CCIX!CCNC\x1F(b11,2b12)\x1E2500;& 2-D coord" 96 | "inate field\x1F*YCOO!XCOO\x1F(2b24)\x1E2500;& 3-D coordinate (sounding " 97 | "array) field\x1F*YCOO!XCOO!VE3D\x1F(3b24)\x1E1600;& Feature record iden" 98 | "tifier field\x1FRCNM!RCID!PRIM!GRUP!OBJL!RVER!RUIN\x1F(b11,b14,2b11,2b" 99 | "12,b11)\x1E1600;& Feature object identifier field\x1FAGEN!FIDN!FIDS\x1F" 100 | "(b12,b14,b12)\x1E2600;&-A Feature record attribute field\x1F*ATTL!ATVL" 101 | "\x1F(b12,A)\x1E2600;&-A Feature record national attribute field\x1F*ATTL!" 102 | "ATVL\x1F(b12,A)\x1E1600;& Feature record to feature object pointer c" 103 | "ontrol field\x1FFFUI!FFIX!NFPT\x1F(b11,2b12)\x1E2600;& Feature record t" 104 | "o feature object pointer field\x1F*LNAM!RIND!COMT\x1F(B(64),b11,A)\x1E160" 105 | "0;& Feature record to spatial record pointer control field\x1FFSU" 106 | "I!FSIX!NSPT\x1F(b11,2b12)\x1E2600;& Feature record to spatial record" 107 | " pointer field\x1F*NAME!ORNT!USAG!MASK\x1F(B(40),3b11)\x1E"; 108 | */ -------------------------------------------------------------------------------- /incl/cellheader_tabmodel.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_HEADER_TAB_MODEL_H 2 | #define CELL_HEADER_TAB_MODEL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "cell_s57.h" 12 | 13 | namespace Enc 14 | { 15 | class CellHeaderReader; 16 | class HeaderTableView; 17 | class FieldDSID; 18 | 19 | //****************************************************************************** 20 | /// Implementing a Model to view a list of CellHeaderData-records in a Model/TableView widget 21 | /*! 22 | ***************************************************************************** */ 23 | class HeaderTableModel : public QAbstractTableModel 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | HeaderTableModel(QObject * parent = 0); 29 | ~HeaderTableModel(); 30 | 31 | void init(const std::vector & catCnt); 32 | void init(QStringList cellFileList); 33 | 34 | virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; 35 | virtual int columnCount(const QModelIndex & parent = QModelIndex() ) const; 36 | virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole ) const; 37 | 38 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; 39 | 40 | protected: 41 | 42 | std::vector cells; 43 | }; 44 | 45 | 46 | 47 | 48 | } 49 | #endif -------------------------------------------------------------------------------- /incl/cellheader_widget.h: -------------------------------------------------------------------------------- 1 | #ifndef CELL_HEADER_WIDGET_H 2 | #define CELL_HEADER_WIDGET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "cellheader_tabmodel.h" 14 | 15 | namespace Enc 16 | { 17 | class CellHeaderReader; 18 | class HeaderTableView; 19 | struct CellHeaderData; 20 | 21 | //****************************************************************************** 22 | /// Table View, reimplementet to allow hiding of Columns comfortably 23 | /*! 24 | ***************************************************************************** */ 25 | class HeaderTableView : public QTableView 26 | { 27 | Q_OBJECT 28 | public: 29 | 30 | HeaderTableView(QWidget *parent); 31 | virtual ~HeaderTableView(); 32 | 33 | public slots: 34 | 35 | void showAllColumns(bool showAll); 36 | 37 | protected: 38 | 39 | }; 40 | 41 | //****************************************************************************** 42 | /// Simple Widget to display Cell Header Data of several Cells in a Table 43 | /*! 44 | ***************************************************************************** */ 45 | class CellHeaderDialog : public QDialog 46 | { 47 | Q_OBJECT 48 | public: 49 | CellHeaderDialog(QWidget * parent =0); 50 | virtual ~CellHeaderDialog(); 51 | 52 | private slots: 53 | void onOpenFiles(); 54 | void onOpenDir(); 55 | //void onCancel(); 56 | //void onFinished(); 57 | 58 | private: 59 | 60 | void paresCells(QStringList files); 61 | 62 | QLineEdit * fileNameEdt; 63 | HeaderTableView * headerDataTbl; 64 | QProgressBar * progBar; 65 | QPushButton * cancelBtn; 66 | 67 | HeaderTableModel * headerTableModel; 68 | 69 | double progVal, progStep; 70 | }; 71 | 72 | //****************************************************************************** 73 | /// Proxy class to Sort and Filter the HeaderTableModel 74 | /*! 75 | ***************************************************************************** */ 76 | class HeaderTableSortFilterModel : public QSortFilterProxyModel 77 | { 78 | Q_OBJECT 79 | 80 | public: 81 | 82 | HeaderTableSortFilterModel(QObject * parent = 0); 83 | 84 | public slots: 85 | 86 | 87 | protected: 88 | 89 | virtual bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const; 90 | virtual bool lessThan(const QModelIndex & left, const QModelIndex & right)const; 91 | }; 92 | 93 | } 94 | 95 | #endif -------------------------------------------------------------------------------- /incl/checksum.h: -------------------------------------------------------------------------------- 1 | #ifndef CheckSum_H 2 | #define CheckSum_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | namespace Enc 15 | { 16 | 17 | //****************************************************************************** 18 | /// Class calculation a CRC (Checksum) for a file or a byte-field 19 | /*! 20 | * Algorithm is slightly optimized, but not the fastest. 21 | ***************************************************************************** */ 22 | class CheckSum 23 | { 24 | public: 25 | CheckSum(); 26 | ~CheckSum(); 27 | unsigned int calcCRC(QString fileName); 28 | unsigned int calcCRC(const unsigned char *, int len); 29 | 30 | private: 31 | void init(); 32 | unsigned int crctab[256]; 33 | 34 | char * myData; //Used in case memory is allocated by this class 35 | int myDataLen; //size of myData 36 | void reAlloc(int newDataLen); 37 | }; 38 | 39 | //****************************************************************************** 40 | /// Class calculating CRCs (Checksums) for several file in a thread 41 | /*! 42 | * Results are emitted by Signals, only 43 | ***************************************************************************** */ 44 | class CheckSumThread : public QThread 45 | { 46 | Q_OBJECT 47 | signals: 48 | void checksum(int, unsigned int); 49 | void checksumError(int, QString); 50 | 51 | public: 52 | CheckSumThread(); 53 | void calcCRCs(QStringList fNames); 54 | 55 | public slots: 56 | void cancel(); 57 | 58 | protected: 59 | 60 | virtual void run(); 61 | QMutex cancelMtx; 62 | bool cancelSoon; 63 | QStringList fileNames; 64 | }; 65 | 66 | //****************************************************************************** 67 | /// Dialog to select files/directories for CRC calculation 68 | /*! 69 | * Dialog must be called NON-MODAL - Dialog deletes itself on close !!! 70 | ***************************************************************************** */ 71 | class CheckSumDialog : public QDialog 72 | { 73 | Q_OBJECT 74 | public: 75 | CheckSumDialog(QWidget * parent =0); 76 | virtual ~CheckSumDialog(); 77 | 78 | private slots: 79 | void onOpenFiles(); 80 | void onOpenDir(); 81 | void onCancel(); 82 | void onChecksum(int, unsigned int); 83 | void onError(int, QString); 84 | void onCalcFinished(); 85 | 86 | private: 87 | 88 | void setFileNames2Table(QStringList fileNames, int & row); 89 | void getFileNamesFromTable(QStringList & realFiles); 90 | void calcCRCs(QStringList files); 91 | 92 | QLineEdit * fileNameEdt; 93 | QTableWidget * crcTbl; 94 | QProgressBar * progBar; 95 | QPushButton * cancelBtn; 96 | 97 | CheckSumThread crcCalculon; 98 | 99 | double progVal, progStep; 100 | }; 101 | } 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /incl/dictionaryS57.h: -------------------------------------------------------------------------------- 1 | #ifndef DICTIONARY_S57_H 2 | #define DICTIONARY_S57_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace Enc 12 | { 13 | class FeatureS57; 14 | class FieldAttr; 15 | 16 | //***************************************************************************** 17 | /// Dictionary - holds codes, Tokens ... etc of Features and Attributes 18 | /*! 19 | * Just a dummy until now 20 | *************************************************************************** */ 21 | class ObjAttrDictionaryS57 22 | { 23 | public: 24 | ObjAttrDictionaryS57(); 25 | 26 | static bool IsGroup1(unsigned int objCode) ///returns true if objCode is one of the 6 Group1 Objects 27 | { 28 | return (objCode == codeDEPARE || objCode == codeDRGARE || objCode == codeFLODOC || objCode == codeHULKES || 29 | objCode == codeLNDARE || objCode == codePONTON || objCode == codeUNSARE); 30 | } 31 | 32 | QString getFeatToken4Code(unsigned int code) const; 33 | QString getAttrToken4Code(unsigned int code) const; 34 | 35 | static bool getDRVAL12(double & drval1, double & drval2, const std::map & attrMap); 36 | static bool getDoubleVal(double & val, const std::map & attrMap, unsigned short key); 37 | static bool getIntVal(int & val, const std::map & attrMap, unsigned short key); 38 | 39 | private: 40 | void readAttributeCodes(QString fileName); 41 | void readFeatureCodes(QString filename); 42 | 43 | 44 | std::map featureCode2Token; //key = feature code 45 | std::map featureToken2Code; //key = 6char-token 46 | std::map featureCode2Name; //Full Name of Feature 47 | 48 | std::map attributeCode2Token; 49 | std::map attributeToken2Code; 50 | std::map attributeCode2Name; 51 | public: 52 | 53 | //Group1 - most important object codes in s57 54 | static const unsigned short codeDEPARE = 42; //most important number in S57 55 | static const unsigned short codeDRGARE = 46; 56 | static const unsigned short codeFLODOC = 57; 57 | static const unsigned short codeHULKES = 65; 58 | static const unsigned short codeLNDARE = 71; 59 | static const unsigned short codePONTON = 95; 60 | static const unsigned short codeUNSARE = 154; 61 | 62 | //Group2 - Other important object codes is s57 63 | static const unsigned short codeM_COVR = 302; 64 | 65 | //** important Attribute Codes in S57: 66 | static const unsigned short aCodeCATCOV = 18; 67 | static const unsigned short aCodeDRVAL1 = 87; 68 | static const unsigned short aCodeDRVAL2 = 88; 69 | 70 | }; 71 | 72 | } 73 | 74 | #endif // DICTIONARYS52_H 75 | -------------------------------------------------------------------------------- /incl/exSetCheckS57.h: -------------------------------------------------------------------------------- 1 | #ifndef ExSetCheckS57_H 2 | #define ExSetCheckS57_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace Enc 10 | { 11 | struct CatalogCheckEntry; 12 | 13 | struct CheckErrors 14 | { 15 | int missingFilesInDir; 16 | int missingFilesInCat; 17 | int CRCwrong; 18 | int recordErrors; //missing bbox, missing volume ... 19 | 20 | CheckErrors() : missingFilesInDir(0), missingFilesInCat(0), CRCwrong(0), recordErrors(0) 21 | {} 22 | }; 23 | 24 | class ExSetCheckS57 25 | { 26 | public: 27 | 28 | ExSetCheckS57(); 29 | ~ExSetCheckS57(); 30 | void init(QString catFileAndPath, std::vector * catEntries); 31 | void checkAll(); 32 | void checkSome(std::set indices2check); 33 | void checkEntry(CatalogCheckEntry &); 34 | 35 | protected: 36 | 37 | QString catFilePath; 38 | std::vector * checkEntries; 39 | 40 | CheckErrors checkErrors; 41 | }; 42 | 43 | } 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /incl/exSetFilterWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef EXSET_FILTER_WIDGET_H 2 | #define EXSET_FILTER_WIDGET_H 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "boundingbox_degrees.h" 14 | 15 | namespace Enc 16 | { 17 | 18 | 19 | //****************************************************************************** 20 | /// Structur stores all Exchange Set Filter Settings 21 | /*! 22 | ***************************************************************************** */ 23 | struct ExSetFilterSettings 24 | { 25 | enum GeneralAction{DoFilter =1, DoFind =2}; 26 | GeneralAction genAct; 27 | 28 | enum FileNameFilterType{NoFileFilter =0, FixedString=1, WildCard=2, RexExp=3}; 29 | FileNameFilterType fileNameFilter; 30 | QString regExp; 31 | 32 | 33 | bool doFilterBBox; 34 | DegBBox bBox2filter; 35 | bool inside; //all cells inside the filterBox pass the filter 36 | 37 | ExSetFilterSettings() : genAct(DoFilter), fileNameFilter(NoFileFilter), doFilterBBox(false), inside(true) 38 | {} 39 | bool filteringPossible(QString & usgMessage) const; 40 | bool operator==(const ExSetFilterSettings & filter2) const; 41 | bool operator!=(const ExSetFilterSettings & filter2) const {return !(*this == filter2);} 42 | }; 43 | 44 | //****************************************************************************** 45 | /// Widget to display/set ExSetFilterSettings 46 | /*! 47 | ***************************************************************************** */ 48 | class ExSetFilterWidget : public QWidget 49 | { 50 | Q_OBJECT 51 | 52 | signals: 53 | void showAllColumns(bool showAll); 54 | void filter(ExSetFilterSettings); 55 | void unFilter(); //show all rows, again 56 | 57 | public: 58 | ExSetFilterWidget(QWidget * parent); 59 | ~ExSetFilterWidget(); 60 | bool allColumnsOn() const {return showAllBtn->isDown();} 61 | ExSetFilterSettings getFilterSettings() const; 62 | 63 | private slots: 64 | 65 | void onFilterAll(bool); 66 | void onFindNext(); 67 | 68 | void onEnableFileFilter(bool); 69 | void onEnableBBoxFilter(bool); 70 | 71 | void onEditBBox(); 72 | 73 | private: 74 | 75 | QCheckBox * useFNameCBx; 76 | QCheckBox * useBBoxCBx; 77 | QLineEdit * searchNameEdt; 78 | QLineEdit * searchBBoxEdt; 79 | 80 | QPushButton * editBBoxBtn; 81 | 82 | QPushButton * findNextBtn; 83 | QPushButton * filterAllBtn; 84 | QPushButton * showAllBtn; 85 | }; 86 | 87 | } 88 | #endif 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /incl/exsetview.h: -------------------------------------------------------------------------------- 1 | #ifndef EXSETVIEW_H 2 | #define EXSETVIEW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "boundingbox_degrees.h" 14 | #include "exSetFilterWidget.h" //moc wants full type, not forward declaration 15 | 16 | namespace Enc 17 | { 18 | struct CatalogEntry; 19 | 20 | //****************************************************************************** 21 | /// Widget displaying the contents of a CATALOG.031 File 22 | /*! 23 | ***************************************************************************** */ 24 | class ExSetView : public QTableView 25 | { 26 | Q_OBJECT 27 | public: 28 | 29 | ExSetView(QWidget *parent); 30 | virtual ~ExSetView(); 31 | 32 | public slots: 33 | 34 | void showAllColumns(bool showAll); 35 | void doFilter(ExSetFilterSettings); 36 | void unFilter(); 37 | 38 | protected: 39 | 40 | ExSetFilterSettings currentFilterSettings; 41 | 42 | }; 43 | 44 | 45 | //****************************************************************************** 46 | /// 47 | /*! 48 | ***************************************************************************** */ 49 | class ExSetCheckWidget : public QWidget 50 | { 51 | Q_OBJECT 52 | 53 | signals: 54 | void checkAll(); 55 | void checkSelected(); 56 | 57 | public: 58 | 59 | ExSetCheckWidget(QWidget * parent =0); 60 | 61 | protected: 62 | QPushButton * checkAllBtn; 63 | QPushButton * checkSelBtn; 64 | }; 65 | 66 | //****************************************************************************** 67 | /// Implementing a model to used a Catalog.031 in a Model/View widget 68 | /*! 69 | ***************************************************************************** */ 70 | class ExSetModel : public QAbstractTableModel 71 | { 72 | Q_OBJECT 73 | 74 | public: 75 | ExSetModel(QObject * parent = 0); 76 | ~ExSetModel(); 77 | 78 | void init(const std::vector & catCnt); 79 | void init(QString catFileName); 80 | 81 | virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; 82 | virtual int columnCount(const QModelIndex & parent = QModelIndex() ) const; 83 | //virtual QModelIndex parent(const QModelIndex & index) const; 84 | virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole ) const; 85 | 86 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; 87 | 88 | protected: 89 | 90 | std::vector catCont; 91 | }; 92 | 93 | //****************************************************************************** 94 | /// 95 | /*! 96 | ***************************************************************************** */ 97 | 98 | class ExSetSortFilterModel : public QSortFilterProxyModel 99 | { 100 | Q_OBJECT 101 | 102 | public: 103 | 104 | ExSetSortFilterModel(QObject * parent = 0); 105 | 106 | public slots: 107 | 108 | void filterFileName(QString regExp); 109 | 110 | protected: 111 | 112 | virtual bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const; 113 | virtual bool lessThan(const QModelIndex & left, const QModelIndex & right)const; 114 | }; 115 | 116 | } 117 | #endif // EXSETVIEW_H 118 | -------------------------------------------------------------------------------- /incl/geo_projections.h: -------------------------------------------------------------------------------- 1 | #ifndef GEO_PROJECTIONS_H 2 | #define GEO_PROJECTIONS_H 3 | 4 | #include 5 | 6 | namespace GeographicLib 7 | { 8 | class LocalCartesian; 9 | class AzimuthalEquidistant; 10 | class CassiniSoldner; 11 | class LambertConformalConic; 12 | class TransverseMercator; 13 | class TransverseMercatorExact; 14 | class PolarStereographic; 15 | } 16 | 17 | namespace Enc 18 | { 19 | extern char * Projections []; 20 | extern int ProjectionCount; 21 | //extern QStringList projectionList; 22 | 23 | 24 | class Projection 25 | { 26 | public: 27 | enum ProjectionId{NoProjec=0,Platt, AziEquiDist, CassiSold, LambConfCon, PolarStereo, NormalMercator, TMercator, TMercatorExact, UTMercator}; 28 | static Projection * getProjection(int projectionId, double centerLat =0, double centerLon=0); 29 | virtual void latLon2xy(double lat, double lon, double & x, double & y) const = 0; 30 | virtual void xy2LatLon(double x, double y, double & lat, double & lon) const = 0; 31 | 32 | }; 33 | 34 | class Plattkarte : public Projection 35 | { 36 | public: 37 | Plattkarte(double lat0 =0, double lon0 =0); 38 | ~Plattkarte(); 39 | void latLon2xy(double lat, double lon, double & x, double & y) const; 40 | void xy2LatLon(double x, double y, double & lat, double & lon) const; 41 | 42 | protected: 43 | 44 | GeographicLib::LocalCartesian * localCartesian; 45 | }; 46 | 47 | class AzimuthalEquidistant : public Projection 48 | { 49 | public: 50 | AzimuthalEquidistant(double _lat0 =0, double _lon0 =0); 51 | ~AzimuthalEquidistant(); 52 | void latLon2xy(double lat, double lon, double & x, double & y) const; 53 | void xy2LatLon(double x, double y, double & lat, double & lon) const; 54 | 55 | protected: 56 | double lat0, lon0; 57 | GeographicLib::AzimuthalEquidistant * azimuthalEquidistant; 58 | }; 59 | 60 | class CassiniSoldner : public Projection 61 | { 62 | public: 63 | CassiniSoldner(double lat0 =0, double lon0 =0); 64 | ~CassiniSoldner(); 65 | void latLon2xy(double lat, double lon, double & x, double & y) const; 66 | void xy2LatLon(double x, double y, double & lat, double & lon) const; 67 | 68 | protected: 69 | GeographicLib::CassiniSoldner * cassiniSoldner; 70 | }; 71 | 72 | class LambertConformalConic : public Projection 73 | { 74 | public: 75 | LambertConformalConic(double stdlat1 =0, double stdlat2 =0, double _lon0 =0, double k1 =1); 76 | ~LambertConformalConic(); 77 | void latLon2xy(double lat, double lon, double & x, double & y) const; 78 | void xy2LatLon(double x, double y, double & lat, double & lon) const; 79 | 80 | protected: 81 | double lon0; 82 | GeographicLib::LambertConformalConic * lambertConformalConic; 83 | }; 84 | 85 | class PolarStereographic : public Projection 86 | { 87 | public: 88 | PolarStereographic(); 89 | ~PolarStereographic(); 90 | void latLon2xy(double lat, double lon, double & x, double & y) const; 91 | void xy2LatLon(double x, double y, double & lat, double & lon) const; 92 | 93 | protected: 94 | 95 | GeographicLib::PolarStereographic * polarStereo; 96 | }; 97 | 98 | class Mercator : public Projection 99 | { 100 | public: 101 | Mercator(); 102 | ~Mercator(); 103 | void latLon2xy(double lat, double lon, double & x, double & y) const; 104 | void xy2LatLon(double x, double y, double & lat, double & lon) const; 105 | 106 | protected: 107 | 108 | }; 109 | 110 | class TransverseMercator : public Projection 111 | { 112 | public: 113 | TransverseMercator(double _lon0 =0, double k0 =1); 114 | ~TransverseMercator(); 115 | void latLon2xy(double lat, double lon, double & x, double & y) const; 116 | void xy2LatLon(double x, double y, double & lat, double & lon) const; 117 | 118 | protected: 119 | 120 | double lon0; 121 | GeographicLib::TransverseMercator * transversMercator; 122 | }; 123 | 124 | class TransverseMercatorExact : public Projection 125 | { 126 | public: 127 | TransverseMercatorExact(double _lon0 =0, double k0 =1); 128 | ~TransverseMercatorExact(); 129 | void latLon2xy(double lat, double lon, double & x, double & y) const; 130 | void xy2LatLon(double x, double y, double & lat, double & lon) const; 131 | 132 | protected: 133 | double lon0; 134 | GeographicLib::TransverseMercatorExact * transverseMercatorExact; 135 | }; 136 | 137 | class UTM : public Projection 138 | { 139 | public: 140 | UTM(double centerLat =0, double centerLon =0); 141 | ~UTM(); 142 | void latLon2xy(double lat, double lon, double & x, double & y) const; 143 | void xy2LatLon(double x, double y, double & lat, double & lon) const; 144 | 145 | protected: 146 | 147 | int zone; 148 | }; 149 | 150 | } 151 | 152 | 153 | 154 | #endif 155 | 156 | -------------------------------------------------------------------------------- /incl/geo_spheroids.h: -------------------------------------------------------------------------------- 1 | #ifndef GEO_SPHEOROIS_H 2 | #define GEO_SPHEOROIS_H 3 | 4 | namespace Enc 5 | { 6 | 7 | namespace WGS84 8 | { 9 | 10 | const double MajorAxis = 6378137.0; 11 | const double MinorAxis = 6356752.314245; 12 | const double InversFlat = 298.257223563; 13 | } 14 | } 15 | #endif -------------------------------------------------------------------------------- /incl/helper.h: -------------------------------------------------------------------------------- 1 | #ifndef HELPER_H 2 | #define HELPER_H 3 | 4 | #include 5 | #include 6 | #include 7 | namespace Enc 8 | { 9 | namespace Helper 10 | { 11 | 12 | void absFileNames2List(QStringList filesAndDirs, QStringList & nameList); 13 | 14 | 15 | } 16 | } 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /incl/naviNaviWidgets.h: -------------------------------------------------------------------------------- 1 | #ifndef NAVINAVIWIDGETS_H 2 | #define NAVINAVIWIDGETS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Enc 11 | { 12 | 13 | //***************************************************************************** 14 | /// Widget to display and change the Scale 15 | /*! 16 | * 17 | *************************************************************************** */ 18 | class ChartScaleWidget : public QFrame 19 | { 20 | Q_OBJECT 21 | 22 | signals: 23 | void zoomIn(); 24 | void zoomOut(); 25 | 26 | public: 27 | ChartScaleWidget(QWidget * parent =0); 28 | 29 | public slots: 30 | void setScale(int scl); 31 | void setScale(double scl); 32 | 33 | protected: 34 | 35 | QPushButton * zoonInBtn, * zoomOutBtn; 36 | QLineEdit * scaleEdt; 37 | }; 38 | 39 | //***************************************************************************** 40 | /// Simple Widget to display a the current position 41 | /*! 42 | * 43 | *************************************************************************** */ 44 | class ChartPositionWidget : public QFrame 45 | { 46 | Q_OBJECT 47 | 48 | public: 49 | ChartPositionWidget(QWidget * parent =0); 50 | 51 | public slots: 52 | 53 | void setPosition(double lat, double lon); 54 | 55 | protected: 56 | 57 | QLineEdit * latEdt, * lonEdt; 58 | }; 59 | 60 | //***************************************************************************** 61 | /// Simple Widget to display a the current Easting / Northing (X,Y)position 62 | /*! 63 | * 64 | *************************************************************************** */ 65 | class ChartEastNorthWidget : public QFrame 66 | { 67 | Q_OBJECT 68 | 69 | public: 70 | ChartEastNorthWidget(QWidget * parent =0); 71 | 72 | public slots: 73 | 74 | void setEastNorth(double x, double y); 75 | 76 | protected: 77 | 78 | QLineEdit * xEdt, * yEdt; 79 | }; 80 | 81 | //***************************************************************************** 82 | /// Simple Widget to display a the current Easting / Northing (X,Y)position 83 | /*! 84 | * 85 | *************************************************************************** */ 86 | class ChartRotationWidget : public QFrame 87 | { 88 | Q_OBJECT 89 | 90 | signals: 91 | void chartHeading(double); 92 | 93 | public: 94 | ChartRotationWidget(QWidget * parent =0); 95 | 96 | public slots: 97 | 98 | void setHeading(double heading); 99 | 100 | private slots: 101 | void onLeft() ; //const; 102 | void onRight() ; // const; 103 | 104 | protected: 105 | 106 | QPushButton * negBtn, * posBtn; 107 | QLineEdit * rotEdt; 108 | }; 109 | 110 | 111 | //***************************************************************************** 112 | /// Select form a List of Projections 113 | /*! 114 | * 115 | *************************************************************************** */ 116 | class ChartProjectionComboBox : public QComboBox 117 | { 118 | Q_OBJECT 119 | 120 | signals: 121 | 122 | void projectionChanged(int); //user changed projection, see Enc::Projections in geo_projections.h 123 | 124 | public: 125 | ChartProjectionComboBox(QWidget * parent =0); 126 | 127 | int currentProjection() const {return currentIndex();} 128 | }; 129 | 130 | 131 | //***************************************************************************** 132 | /// Struct holding all Navigation-Widgets - just 4 convenience 133 | /*! 134 | * 135 | *************************************************************************** */ 136 | struct AllNaviWidgets 137 | { 138 | public: 139 | AllNaviWidgets(QWidget * parent); 140 | 141 | ChartProjectionComboBox * projectWgt; 142 | ChartScaleWidget * scaleWgt; 143 | ChartRotationWidget * headWgt; 144 | ChartPositionWidget * posWgt; 145 | ChartEastNorthWidget * xyWgt; 146 | ChartRotationWidget * rotWgt; 147 | }; 148 | 149 | } 150 | 151 | #endif // NAVINAVIWIDGETS_H 152 | -------------------------------------------------------------------------------- /incl/naviScene.h: -------------------------------------------------------------------------------- 1 | #ifndef NAVISCENE_H 2 | #define NAVISCENE_H 3 | 4 | #include "dictionaryS57.h" 5 | #include "presentationS52.h" 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace Enc 17 | { 18 | class CellS57_Base; 19 | class Projection; 20 | class FeatureS57; 21 | 22 | class ChartProjectionComboBox; 23 | class ChartScaleWidget; 24 | class ChartPositionWidget; 25 | class ChartEastNorthWidget; 26 | class ChartRotationWidget; 27 | 28 | //***************************************************************************** 29 | /// Scene holding the projected items of a number of ENCs 30 | /*! 31 | * 32 | *************************************************************************** */ 33 | class NaviScene : public QGraphicsScene 34 | { 35 | Q_OBJECT 36 | 37 | signals: 38 | 39 | void progressMessage(const QString &); 40 | void contentChanged(QRectF); 41 | 42 | //** forwarding signals of navi-widgets ** 43 | void zoomIn(); 44 | void zoomOut(); 45 | void chartHeading(double); 46 | void projectionChanged(int); 47 | 48 | public: 49 | NaviScene(QObject * parent = 0 ); 50 | virtual ~NaviScene(); 51 | void addNaviWidgets(); 52 | 53 | public slots: 54 | void loadCharts(QStringList filenames); 55 | void setProjection(int prjctnId); 56 | void onDrawCells(); 57 | void clearAll(); 58 | 59 | protected: 60 | 61 | //**** GUI methods **** 62 | 63 | 64 | //**** Cell-drawing methods **** 65 | const QGraphicsItem * convertFeature(unsigned long, const FeatureS57 * feat, CellS57_Base *); 66 | QGraphicsItem * convertFeaturePoint(unsigned long, const FeatureS57 * feat, CellS57_Base *); 67 | QAbstractGraphicsShapeItem * convertFeatureLine(unsigned long, const FeatureS57 * feat, CellS57_Base *); 68 | QAbstractGraphicsShapeItem * convertFeatureArea(unsigned long, const FeatureS57 * feat, CellS57_Base *); 69 | 70 | 71 | //**** navigation widgets on the scene (added by using proxy-widgets) **** 72 | ChartProjectionComboBox * projectWgt; 73 | ChartScaleWidget * scaleWgt; 74 | ChartPositionWidget * posWgt; 75 | ChartEastNorthWidget * xyWgt; 76 | ChartRotationWidget * rotWgt; 77 | QGraphicsWidget * naviWgt; //holds ALL navi, widgets, but may be NULL 78 | 79 | QMap proxyMap; 80 | 81 | //**** data needed to draw the cell-contents **** 82 | int projectionId; 83 | Projection * projection; 84 | 85 | std::vector cells; 86 | 87 | PresentationS52 * presenterS57; 88 | }; 89 | 90 | 91 | 92 | } 93 | #endif // NAVISCENE_H 94 | -------------------------------------------------------------------------------- /incl/naviSceneItems.h: -------------------------------------------------------------------------------- 1 | #ifndef NAVISCENEITEMS_H 2 | #define NAVISCENEITEMS_H 3 | 4 | #include 5 | 6 | namespace Enc 7 | { 8 | 9 | class GraphicsAreaFeatItem : public QGraphicsPathItem 10 | { 11 | public: 12 | enum {Type = UserType + 1}; 13 | 14 | GraphicsAreaFeatItem(unsigned long rcid, QGraphicsItem * parent = 0); 15 | GraphicsAreaFeatItem(unsigned long rcid, const QPainterPath & path, const QPen & p, const QBrush & b, QGraphicsItem * parent = 0); 16 | unsigned long getRcId() const {return depareRcid;} 17 | virtual int type() const {return Type;} 18 | 19 | private: 20 | unsigned long depareRcid; 21 | 22 | 23 | }; 24 | 25 | class GraphicsDepareItem : public GraphicsAreaFeatItem 26 | { 27 | public: 28 | enum {Type = UserType + 2}; 29 | GraphicsDepareItem(unsigned long rcid, const QPainterPath & path, const QPen & p, const QBrush & b, QGraphicsItem * parent = 0); 30 | virtual int type() const {return Type;} 31 | }; 32 | } 33 | 34 | #endif // NAVISCENEITEMS_H 35 | -------------------------------------------------------------------------------- /incl/naviView.h: -------------------------------------------------------------------------------- 1 | #ifndef NAVIVIEW_H 2 | #define NAVIVIEW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Enc 11 | { 12 | class ChartProjectionComboBox; 13 | class ChartScaleWidget; 14 | class ChartRotationWidget; 15 | class ChartPositionWidget; 16 | class ChartEastNorthWidget; 17 | //***************************************************************************** 18 | /// Widget to display a Chart and appropriate Navi-Buttons 19 | /*! 20 | * Kai : i am trying to put widgets on the view, not on the scene - weiss noch nicht ob und wie das geht 21 | *************************************************************************** */ 22 | class NaviView : public QGraphicsView 23 | { 24 | Q_OBJECT 25 | 26 | signals: 27 | void projectionChanged(int); 28 | void scaleChanged(double); 29 | void headingChanged(double); 30 | 31 | 32 | public: 33 | 34 | NaviView(QWidget * parent = 0); 35 | NaviView(QGraphicsScene * scene, QWidget * parent = 0); 36 | 37 | void initProjections(); 38 | 39 | public slots: 40 | 41 | void zoomIn(); 42 | void zoomOut(); 43 | void setScale(double); 44 | void setChartHeading(double heading); 45 | 46 | void showContent(QRectF); 47 | 48 | protected: 49 | 50 | void updateTransform(); 51 | void addNaviWidgets(); 52 | 53 | ChartProjectionComboBox * projectWgt; 54 | ChartScaleWidget * scaleWgt; 55 | ChartRotationWidget * headWgt; 56 | ChartPositionWidget * posWgt; 57 | ChartEastNorthWidget * xyWgt; 58 | 59 | //** rember current Transformation ** 60 | //kai: rest of tranformation paramters is taken directly from current view-transform 61 | double myAngleZ; //angle (z-dirction) mathematical, not a compass-angle! 62 | double myScale; //scale 63 | }; 64 | 65 | 66 | 67 | 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /incl/naviWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef NAVIWIDGET_H 2 | #define NAVIWIDGET_H 3 | 4 | #include 5 | 6 | #include "naviScene.h" 7 | #include "naviView.h" 8 | 9 | namespace Enc 10 | { 11 | 12 | //***************************************************************************** 13 | /// High Level, Easy2Use Widget to display a Chart and appropriate Navi-Buttons 14 | /*! 15 | * 16 | *************************************************************************** */ 17 | class NaviWidget : public QWidget 18 | { 19 | Q_OBJECT 20 | 21 | signals: 22 | void progressMessage(const QString &); 23 | void projectionChanged(int); 24 | void scaleChanged(double); 25 | void headingChanged(double); 26 | 27 | public: 28 | NaviWidget(QWidget * parent = 0); 29 | 30 | public slots: 31 | 32 | void loadCharts(QStringList filenames); 33 | void onProjectionChanged(int); 34 | void zoomIn() {naviView->zoomIn();} 35 | void zoomOut() {naviView->zoomOut();} 36 | void setScale(double newScale) {naviView->setScale(newScale);} 37 | void setChartHeading(double heading) {naviView->setChartHeading(heading);} 38 | 39 | protected: 40 | 41 | NaviScene * naviScene; 42 | NaviView * naviView; 43 | }; 44 | 45 | 46 | 47 | } 48 | 49 | #endif // NAVIWIDGET_H 50 | -------------------------------------------------------------------------------- /incl/presentationS52.h: -------------------------------------------------------------------------------- 1 | #ifndef PRESENTATION_S52_H 2 | #define PRESENTATION_S52_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace Enc 12 | { 13 | class FeatureS57; 14 | class FieldAttr; 15 | 16 | //***************************************************************************** 17 | /// Presentation Library - Gets the shape,color ... of Features depending on Attributes 18 | /*! 19 | * Far from beeing complete - its ab big job!! 20 | *************************************************************************** */ 21 | class PresentationS52 22 | { 23 | public: 24 | PresentationS52(); 25 | void setDeepShallow(double dp,double shlw, double vShlw); 26 | double getDeep() const {return deep;} 27 | double getShallow() const {return shallow;} 28 | double getVeryShallow() const {return veryShallow;} 29 | QPen getPen(const FeatureS57 * feat) const; 30 | QBrush getBrush(const FeatureS57 * feat) const; 31 | double getPriority(const FeatureS57 * feat) const; 32 | 33 | private: 34 | //** just for colorfull debugging: ** 35 | mutable int cnt; //how often a pen has been requested until now 36 | std::vector colorVecDebug; //just used to make chart colorfull for easier debugging 37 | 38 | //** group 1 Objects have predefined values ** 39 | QBrush interTidalBrush, depareVeryShallowBrush, depareShallowBrush, depareMediumBrush, depareDeepBrush; //also for DRGARE 40 | QBrush LNDAREbrush, FLODOCbrush, HULKESbrush, PONTONbrush, UNSAREbrush; 41 | 42 | double deep, shallow, veryShallow; //deep shallow waters have different colours (in meters) 43 | }; 44 | 45 | } 46 | 47 | #endif -------------------------------------------------------------------------------- /incl/s57updater.h: -------------------------------------------------------------------------------- 1 | #ifndef S57_UPDATER_H 2 | #define S57_UPDATER_H 3 | 4 | #include "cell_s57_base.h" 5 | #include "cell_s57_update.h" 6 | 7 | namespace Enc 8 | { 9 | 10 | //****************************************************************************** 11 | /// Applies S-57 Update Cells to Base Cells to create ReIssue Cells 12 | /*! 13 | ***************************************************************************** */ 14 | class S57Updater 15 | { 16 | public: 17 | S57Updater(); 18 | ~S57Updater(); 19 | void setCell(CellS57_Base * baseCellS57); 20 | void applyUpdate(const CellS57_Update *); 21 | 22 | private: 23 | 24 | void applyUpdtFeature(const FeatureS57_Updt & updtFeat); 25 | void applyUpdtSpatial(const SpatialS57 * spat); 26 | 27 | void modifyFeature(FeatureS57 & oldFeat, const FeatureS57_Updt & updtFeat); 28 | 29 | void modifySpatial(const SpatialS57 * updtSpat); 30 | void modifySpatialCommons(SpatialS57 * oldSpat, const SpatialS57 * updtSpat); 31 | 32 | void applyUpdt2Node(NodeS57 & orgNode, const NodeS57_Updt & updtNode); 33 | void applyUpdt2Soundg(SoundgS57 & orgSndg, const SoundgS57_Updt & updtSndg); 34 | void applyUpdt2Edge(EdgeS57 & orgEdge, const EdgeS57_Updt & updtEdge); 35 | 36 | bool isDeleteAttribute(const FieldAttr & attr); 37 | 38 | CellS57_Base * reIssue; //Cell to which updates will be applied 39 | }; 40 | 41 | inline bool S57Updater::isDeleteAttribute(const FieldAttr & attr) 42 | { 43 | if (!attr.getNat() || reIssue->getDssi().getNALL() == 1) 44 | { 45 | return attr.getValue().at(0) == ISO8211::DelChar; 46 | } 47 | else 48 | { 49 | return attr.getValue().at(0) == ISO8211::DelChar2; 50 | } 51 | } 52 | 53 | } 54 | #endif -------------------------------------------------------------------------------- /incl/version.h: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #ifndef ENC_LIB_VERSION_H 10 | #define ENC_LIB_VERSION_H 11 | 12 | namespace Enc 13 | { 14 | const int MajorVersion = 0; 15 | const int MinorVersion = 2; 16 | const int SubMinorVers = 1; 17 | const char * EncLibName = "ENClib"; 18 | #ifdef _DEBUG 19 | QString VersionString() {return QString("%1.%2.%3 DEBUG").arg(MajorVersion).arg(MinorVersion).arg(SubMinorVers);} 20 | #else 21 | QString VersionString() {return QString("%1.%2.%3").arg(MajorVersion).arg(MinorVersion).arg(SubMinorVers);} 22 | #endif 23 | } 24 | 25 | #endif -------------------------------------------------------------------------------- /parsertest/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "cell_s57.h" 6 | #include "s57updater.h" 7 | #include "cell_check_s57.h" 8 | 9 | using namespace Enc; 10 | 11 | int main( int argc, char ** argv) 12 | { 13 | if (argc <2) 14 | { 15 | printf("\nError: no input dir\n"); 16 | exit(1); 17 | } 18 | //**** parse input dir **** 19 | 20 | QString baseFile; 21 | QStringList updateFiles; 22 | QDir inDir(argv[1]); 23 | QStringList entries = inDir.entryList(QDir::Files); 24 | for (QStringList::iterator dIt = entries.begin(); dIt != entries.end(); ++dIt) 25 | { 26 | if ((*dIt).right(4) == ".000") baseFile = *dIt; 27 | else if ((*dIt).right(3).toUInt() >= 1 && (*dIt).right(3).toUInt() <= 999) 28 | { 29 | updateFiles += inDir.absoluteFilePath(*dIt); 30 | } 31 | } 32 | 33 | //**** read a S-57 cell **** 34 | CellS57_Base s57cell; 35 | try 36 | { 37 | s57cell.parseISO8211(inDir.absoluteFilePath(baseFile).toLatin1()); 38 | } 39 | catch(const QString & msg) 40 | { 41 | qWarning(msg.toLatin1()); 42 | exit(3); 43 | } 44 | catch(...) 45 | { 46 | printf("UNKNOWN ERROR while reading: %s", argv[1]); 47 | exit(3); 48 | } 49 | 50 | //**** check cell after parsing: **** 51 | CellCheckS57 cellChecker(&s57cell); 52 | CheckResult checkResult = cellChecker.check(); 53 | if (checkResult.errCnt() || checkResult.outsidePointer.size() ) 54 | { 55 | if (checkResult.errCnt()) qWarning("ERROR: %d errros after cell parsing:", checkResult.errCnt()); 56 | QStringList errMsg; 57 | checkResult.makeMessage(errMsg); 58 | printf("\n%s", errMsg.join("\n").toLatin1()); 59 | } 60 | 61 | /*const std::multimap < LongNAMe, unsigned long > foids = s57cell.getFoids(); 62 | std::multimap < LongNAMe, unsigned long >::const_iterator fIt; 63 | for (fIt = foids.begin(); fIt != foids.end(); ++fIt) 64 | { 65 | printf("\n%s %s", ISO8211::makeRecNameASCII(RCNM_FE, fIt->second).toLatin1().data(), ISO8211::makeLongNAMeASCII(fIt->first).toLatin1().data()); 66 | } */ 67 | 68 | //**** read and apply update, if available **** 69 | try 70 | { 71 | if (!updateFiles.empty()) 72 | { 73 | s57cell.applyUpdates(updateFiles); 74 | } 75 | } 76 | catch(const QString & msg) 77 | { 78 | qWarning(msg.toLatin1()); 79 | exit(4); 80 | } 81 | 82 | //**** write the cell to file **** 83 | try 84 | { 85 | if (argc >= 1) 86 | { 87 | QDir outDir(argv[2]); 88 | s57cell.writeISO8211(outDir.absoluteFilePath(baseFile).toLatin1()); 89 | } 90 | } 91 | catch(const QString & msg) 92 | { 93 | qWarning(msg.toLatin1()); 94 | exit(3); 95 | } 96 | catch(...) 97 | { 98 | printf("UNKNOWN ERROR while reading: %s", argv[1]); 99 | exit(3); 100 | } 101 | return 0; 102 | } -------------------------------------------------------------------------------- /parsertest/parsertest.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 51 | 54 | 57 | 60 | 67 | 70 | 73 | 76 | 79 | 82 | 85 | 88 | 89 | 97 | 100 | 103 | 106 | 109 | 112 | 123 | 126 | 129 | 132 | 141 | 144 | 147 | 150 | 153 | 156 | 159 | 162 | 163 | 164 | 165 | 166 | 167 | 172 | 175 | 176 | 177 | 182 | 183 | 188 | 189 | 192 | 193 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /resources/Attributes.S57.txt: -------------------------------------------------------------------------------- 1 | #S-57 Attributes, comma separated: Attribute-Id, Token, description 2 | 1, AGENCY, Agency responsible for production 3 | 2, BCNSHP, Beacon shape 4 | 3, BUISHP, Building shape 5 | 4, BOYSHP, Buoy shape 6 | 5, BURDEP, Buried depth 7 | 6, CALSGN, Call sign 8 | 7, CATAIR, Category of airport/airfield 9 | 8, CATACH, Category of anchorage 10 | 9, CATBRG, Category of bridge 11 | 10, CATBUA, Category of built-up area 12 | 13 | 14 | 15 | 87, DRVAL1, Depth range value 1 16 | 88, DRVAL2, Depth range value 2 17 | 18 | 188, CAT_TS, Category of Tidal stream 19 | -------------------------------------------------------------------------------- /resources/Features.S57.txt: -------------------------------------------------------------------------------- 1 | #VERSION 0.1 2 | #S-57 Featurs Classes, comma-seperated: Feature-Id, Token, Explanation 3 | #Not yet ready !!! 4 | 1, ADMARE, Administration Area 5 | 2, AIRARE, Airport/airfield 6 | 3, ACHBRT, Anchor berth 7 | 4, ACHARE, Anchorage area 8 | 5, BCNCAR, Beacon cardinal 9 | 6, BCNISD, Beacon isolated danger 10 | 7, BCNLAT, Beacon lateral 11 | 8, BCNSAW, Beacon safe water 12 | 9, BCNSPP, Beacon special purpose/general 13 | 10, BERTHS, Berth 14 | 11, BRIDGE, Bridge 15 | 12, BUISGL, Building single 16 | 13, BUAARE, Built-up area 17 | 14, BOYCAR, Buoy cardinal 18 | 15, BOYINB, Buoy installation 19 | 16, BOYISD, Buoy isolated danger 20 | 17, BOYLAT, Buoy lateral 21 | 18, BOYSAW, Buoy safe water 22 | 19, BOYSPP, Buoy special purpose/general 23 | 24 | 25 | 161, ARCSLN, Archipelagic Sea Lane 26 | 162, ASLXIS, Archipelagic Sea Lane Axis -------------------------------------------------------------------------------- /src/boundingbox_degrees.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include "boundingbox_degrees.h" 10 | #include 11 | #include 12 | 13 | using namespace Enc; 14 | 15 | #define DegEpsCompare 1E-6 16 | 17 | DegBBox::DegBBox(const QString & bbString) : SLAT(0), WLON(0), NLAT(0), ELON(0) 18 | { 19 | fromString(bbString); 20 | } 21 | 22 | double DegBBox::centerLon() const 23 | { 24 | if (stripe) return 0; 25 | else if (crossesDateLine()) 26 | { 27 | double ret = (WLON + ELON + 360) /2.0; 28 | return (ret > 180 ? ret - 180.0 : ret); 29 | } 30 | return (ELON + WLON) / 2.0; 31 | } 32 | 33 | //****************************************************************************** 34 | /// Enlarge the bounding box by adding a single position 35 | /*! 36 | * This is done in a way that the smaller box will result 37 | ***************************************************************************** */ 38 | void DegBBox::add(double lat, double lon) 39 | { 40 | if (!isValid()) 41 | { 42 | SLAT = NLAT = lat; 43 | WLON = ELON = lon; 44 | assert(SLAT >= -90 && NLAT <= 90 && WLON >= -180 && ELON <= 180 && NLAT >= SLAT); 45 | return; 46 | } 47 | //** Trivial: Latitude ** 48 | if (lat < SLAT) SLAT = lat; 49 | else if (lat > NLAT) NLAT = lat; 50 | 51 | //** Longitude: consider Dateline and minimal size ** 52 | if (stripe) return; 53 | 54 | if (crossesDateLine()) 55 | { 56 | //** take the shorter way (smaller box) ** 57 | if (lon > ELON || lon < WLON) return; 58 | if (WLON - lon > lon - ELON) ELON = lon; 59 | else WLON = lon; 60 | } 61 | else 62 | { 63 | if (lon < ELON && lon > WLON) return; 64 | //** take the shorter way -> maybe rect will cross dateline then ** 65 | if (lon < WLON) 66 | { 67 | if (ELON - lon < 180) WLON = lon; 68 | else ELON = lon; 69 | } 70 | else if (lon > ELON) 71 | { 72 | if (lon - WLON < 180) ELON = lon; 73 | else WLON = lon; 74 | } 75 | } 76 | 77 | assert(SLAT >= -90 && NLAT <= 90 && WLON >= -180 && ELON <= 180 && NLAT >= SLAT); 78 | } 79 | 80 | void DegBBox::add(const DegBBox & otherBB) 81 | { 82 | if (!isValid()) 83 | { 84 | *this = otherBB; 85 | return; 86 | } 87 | //** Trivial: Latitude ** 88 | if (otherBB.SLAT < SLAT) SLAT = otherBB.SLAT; 89 | else if (otherBB.NLAT > NLAT) NLAT = otherBB.NLAT; 90 | 91 | //** Longitude: consider Dateline and minimal size ** 92 | if (stripe) return; 93 | if (otherBB.stripe) 94 | { 95 | stripe = true; 96 | return; 97 | } 98 | 99 | if (crossesDateLine()) 100 | { 101 | //** 1) Trivial, too: both bboxes cross dateline: ** 102 | if (otherBB.crossesDateLine()) 103 | { 104 | if (otherBB.ELON >= WLON || otherBB.WLON >= ELON) stripe = true; 105 | else 106 | { 107 | if (otherBB.ELON > ELON) ELON = otherBB.ELON; 108 | if (otherBB.WLON < WLON) WLON = otherBB.WLON; 109 | } 110 | } 111 | //** 2) special: boxes create stripe: ** 112 | else if (otherBB.WLON < ELON && otherBB.ELON > WLON) 113 | { 114 | stripe = true; 115 | } 116 | //** 3) normal case: take the shorter way (smaller box) ** 117 | else 118 | { 119 | if (otherBB.ELON < ELON || otherBB.WLON < WLON) return; //completly include 120 | else if (otherBB.WLON < ELON) ELON = otherBB.ELON; //overlapp 121 | else if (otherBB.ELON > WLON) WLON = otherBB.WLON; //overlapp 122 | else //no contact 123 | { 124 | if ((otherBB.WLON - ELON) > (WLON - otherBB.ELON)) WLON = otherBB.WLON; 125 | else ELON = otherBB.ELON; 126 | } 127 | } 128 | } 129 | else 130 | { 131 | if (otherBB.crossesDateLine()) 132 | { 133 | if (ELON <= otherBB.ELON || WLON >= otherBB.WLON) 134 | { 135 | ELON = otherBB.ELON; 136 | WLON = otherBB.WLON; 137 | return; 138 | } 139 | else if (ELON >= otherBB.WLON) ELON = otherBB.ELON; 140 | else if (WLON <= otherBB.ELON) WLON = otherBB.WLON; 141 | if ((WLON - otherBB.ELON) > (otherBB.WLON - ELON)) 142 | { 143 | ELON = otherBB.ELON; 144 | } 145 | else 146 | { 147 | WLON = otherBB.WLON; 148 | } 149 | } 150 | //** most likely: no BBox crosses Dateline ** 151 | else 152 | { 153 | //** 1st - simple: if BBoxes overlapp ** 154 | if (otherBB.WLON >= WLON && otherBB.ELON <= ELON) return; //otherBB inside this BB 155 | else if (otherBB.WLON <= WLON && otherBB.ELON >= ELON) //this BB inside otherBB 156 | { 157 | WLON = otherBB.WLON; 158 | ELON = otherBB.ELON; 159 | } 160 | else if (otherBB.WLON < WLON && otherBB.ELON > WLON) WLON = otherBB.WLON; //real overlapp 161 | else if (otherBB.ELON > ELON && otherBB.WLON < ELON) ELON = otherBB.ELON; //real overlapp 162 | //** 2nd: boxes distant: calc smaller BBOX ** 163 | else 164 | { 165 | //**1st: crossing datline makes smaller BBox: ** 166 | if (fabs((ELON + WLON)/2 - (otherBB.ELON + otherBB.WLON)/2) > 180) 167 | { 168 | if (WLON > otherBB.ELON) ELON = otherBB.ELON; 169 | else WLON = otherBB.WLON; 170 | } 171 | //** 2nd: not crossing dateline makes smaller bbox: ** 172 | else 173 | { 174 | if (otherBB.WLON < WLON) WLON = otherBB.WLON; 175 | else ELON = otherBB.ELON; 176 | } 177 | } 178 | } 179 | } 180 | assert(SLAT >= -90 && NLAT <= 90 && WLON >= -180 && ELON <= 180 && NLAT >= SLAT); 181 | } 182 | 183 | 184 | //****************************************************************************** 185 | /// Parse a Bounding box String 186 | /*! 187 | * String must look like "S=1 W=2 N=3 E=4" or contain "STRIPE" instead of E and W 188 | * (the oder of S,N,W,E does not matter) 189 | ***************************************************************************** */ 190 | void DegBBox::fromString(const QString & bbString) 191 | { 192 | //**** convert String like "S=%1 W=%2 N=%3 E=%4" or "STRIPE S=... N=..."**** 193 | int indexS = bbString.indexOf("S="); 194 | int indexW = bbString.indexOf("W="); 195 | int indexN = bbString.indexOf("N="); 196 | int indexE = bbString.indexOf("E="); 197 | int indexStripe = bbString.indexOf("STRIPE"); 198 | if (indexS >= 0 && indexN >= 0 && (indexStripe >= 0 || (indexE >= 0 && indexW >= 0))) 199 | { 200 | indexS += 2; indexW += 2;indexN += 2; indexE += 2; 201 | int endInd = bbString.indexOf(QChar(' '), indexS); 202 | SLAT = bbString.mid(indexS, (endInd>0 ? endInd - indexS: -1)).toDouble(); 203 | endInd = bbString.indexOf(QChar(' '), indexN); 204 | NLAT = bbString.mid(indexN, (endInd>0 ? endInd - indexN : -1)).toDouble(); 205 | if (indexStripe >= 0) stripe = true; 206 | else 207 | { 208 | endInd = bbString.indexOf(QChar(' '), indexW); 209 | WLON = bbString.mid(indexW, (endInd>0 ? endInd - indexW : -1)).toDouble(); 210 | endInd = bbString.indexOf(QChar(' '), indexE); 211 | ELON = bbString.mid(indexE, (endInd>0 ? endInd - indexE : -1)).toDouble(); 212 | } 213 | } 214 | } 215 | 216 | QString DegBBox::toString() const 217 | { 218 | if (isValid()) 219 | { 220 | if (stripe) return QString("STRIPE S=%1 N=%2").arg(SLAT).arg(NLAT); 221 | return QString("S=%1 W=%2 N=%3 E=%4").arg(SLAT).arg(WLON).arg(NLAT).arg(ELON); 222 | } 223 | return QString(); 224 | } 225 | 226 | //****************************************************************************** 227 | /// Compare Bounding boxes, allowing small differences 228 | /*! 229 | * invalid Bounding boxes cannot be equal 230 | ****************************************************************************** */ 231 | bool DegBBox::operator== (const DegBBox & otherBB) const 232 | { 233 | if (isValid() != otherBB.isValid() ) return false; 234 | if (!isValid()) return true; //both invalid -> treat as equal !!?? 235 | if (fabs(SLAT - otherBB.SLAT) > DegEpsCompare || 236 | fabs(NLAT - otherBB.NLAT) > DegEpsCompare || 237 | fabs(WLON - otherBB.WLON) > DegEpsCompare || 238 | fabs(ELON - otherBB.ELON) > DegEpsCompare) return false; 239 | return true; 240 | } 241 | 242 | //****************************************************************************** 243 | /// Check for really overlapping Bounding boxes (touching is not enought) 244 | //****************************************************************************** */ 245 | bool DegBBox::overlapp(const DegBBox & otherBBox) const 246 | { 247 | return !(NLAT < otherBBox.SLAT || 248 | SLAT > otherBBox.NLAT || 249 | ELON < otherBBox.WLON || 250 | WLON > otherBBox.ELON); 251 | } -------------------------------------------------------------------------------- /src/boundingbox_edit.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "boundingbox_edit.h" 14 | 15 | using namespace Enc; 16 | 17 | //****************************************************************************** 18 | /// Bounding Box Edit Widget 19 | /*! 20 | ***************************************************************************** */ 21 | 22 | BBoxEditor::BBoxEditor(QWidget * parent, const DegBBox & bBox) : QFrame(parent) 23 | { 24 | setFrameShape(Box); 25 | grdLyt = new QGridLayout(this); 26 | northEdt = new QLineEdit(this); 27 | southEdt = new QLineEdit(this); 28 | eastEdt = new QLineEdit(this); 29 | westEdt = new QLineEdit(this); 30 | northEdt->setValidator(new QDoubleValidator(-90,90,4,this)); 31 | southEdt->setValidator(new QDoubleValidator(-90,90,4,this)); 32 | eastEdt->setValidator(new QDoubleValidator(-180,180,4,this)); 33 | westEdt->setValidator(new QDoubleValidator(-180,180,4,this)); 34 | 35 | grdLyt->addWidget(new QLabel(tr("North:")), 0, 0, Qt::AlignRight); 36 | grdLyt->addWidget(new QLabel(tr("South:")), 4, 0, Qt::AlignRight); 37 | grdLyt->addWidget(new QLabel(tr("West:")), 1, 0, Qt::AlignLeft); 38 | grdLyt->addWidget(new QLabel(tr("East:")), 1, 2, Qt::AlignRight); 39 | grdLyt->addWidget(new QLabel(" "), 3, 0, Qt::AlignRight); //dummy label to make widget look symmetric 40 | grdLyt->addWidget(northEdt, 0, 1, Qt::AlignJustify); 41 | grdLyt->addWidget(southEdt, 4, 1, Qt::AlignJustify); 42 | grdLyt->addWidget(westEdt, 2, 0, Qt::AlignJustify); 43 | grdLyt->addWidget(eastEdt, 2, 2, Qt::AlignJustify); 44 | } 45 | 46 | //****************************************************************************** 47 | /// Set the values, or clear them if newBBox is not valid 48 | /*! 49 | ***************************************************************************** */ 50 | void BBoxEditor::setBBox(const DegBBox & newBBox) 51 | { 52 | if (newBBox.isValid()) 53 | { 54 | northEdt->setText(QString::number(newBBox.NLAT)); 55 | southEdt->setText(QString::number(newBBox.SLAT)); 56 | eastEdt->setText(QString::number(newBBox.ELON)); 57 | westEdt->setText(QString::number(newBBox.WLON)); 58 | } 59 | else clear(); 60 | } 61 | 62 | //****************************************************************************** 63 | /// clear all edit widgets 64 | /*! 65 | ***************************************************************************** */ 66 | void BBoxEditor::clear() 67 | { 68 | northEdt->clear(); 69 | southEdt->clear(); 70 | eastEdt->clear(); 71 | westEdt->clear(); 72 | } 73 | 74 | //****************************************************************************** 75 | /// Get the Bounding box values 76 | /*! 77 | ***************************************************************************** */ 78 | DegBBox BBoxEditor::getBBox() const 79 | { 80 | DegBBox bbox; 81 | bool nlatOk, slatOk, wlonOk, elonOk; 82 | bbox.NLAT = northEdt->text().toDouble(&nlatOk); 83 | bbox.SLAT = southEdt->text().toDouble(&slatOk); 84 | bbox.ELON = eastEdt->text().toDouble(&elonOk); 85 | bbox.WLON = westEdt->text().toDouble(&wlonOk); 86 | if (!nlatOk || !slatOk || !wlonOk || !elonOk) 87 | { 88 | bbox = DegBBox(); //bbox invalid 89 | } 90 | return bbox; 91 | } 92 | 93 | //****************************************************************************** 94 | //****************************************************************************** 95 | //****************************************************************************** 96 | /// Bounding Box Edit Dialog 97 | /*! 98 | ***************************************************************************** */ 99 | 100 | BBoxEditDialog::BBoxEditDialog(QWidget * parent, const DegBBox & bBox) : QDialog(parent) 101 | { 102 | QVBoxLayout * lyt = new QVBoxLayout(this); 103 | bbEdit = new BBoxEditor(this, bBox); 104 | lyt->addWidget(bbEdit); 105 | 106 | okBtn = new QPushButton("OK", bbEdit); 107 | bbEdit->grdLyt->addWidget(okBtn, 2, 1, Qt::AlignJustify); 108 | connect(okBtn, SIGNAL(clicked()), this, SLOT(accept())); 109 | } 110 | 111 | -------------------------------------------------------------------------------- /src/cell_check_result.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include "cell_check_result.h" 10 | 11 | #include 12 | 13 | using namespace Enc; 14 | using namespace ISO8211; 15 | 16 | 17 | void CheckResult::makeMessage(QStringList & errMsg) const 18 | { 19 | unsigned int i=0; 20 | if (!brokenFeat2Spatial.empty()) 21 | { 22 | errMsg += QString("%1 Features pointing to non existing Spatials:").arg(brokenFeat2Spatial.size()); 23 | for (i=0; i 24 | { 25 | errMsg += QString("Feature %1 Spatial: %2").arg(makeRecNameASCII(RCNM_FE, brokenFeat2Spatial[i].first)).arg(makeRecNameASCII(brokenFeat2Spatial[i].second)); 26 | } 27 | } 28 | if (!brokenSpatial2Feat.empty()) 29 | { 30 | errMsg += QString("%1 Spatials pointing to non existing Features:").arg(brokenSpatial2Feat.size()); 31 | for (i=0; i < brokenSpatial2Feat.size(); ++i) 32 | { 33 | errMsg += QString("Spatial: %1 broken Feature: %2").arg(makeRecNameASCII(brokenSpatial2Feat[i].first)).arg(makeRecNameASCII(RCNM_FE, brokenSpatial2Feat[i].second)); 34 | } 35 | } 36 | if (!brokenFeat2Feat.empty()) 37 | { 38 | errMsg += QString("%1 feature to feature relation errros (internal calculation error)").arg(brokenFeat2Feat.size()); 39 | for (i=0; i < brokenFeat2Feat.size(); ++i) 40 | { 41 | errMsg += QString("Existing Feature: %1 Broken Feature %2").arg(makeRecNameASCII(RCNM_FE, brokenFeat2Feat[i].first)).arg(makeRecNameASCII(RCNM_FE, brokenFeat2Feat[i].second)); 42 | } 43 | } 44 | if (!brokenFeat2FeatBack.empty()) 45 | { 46 | errMsg += QString("%1 feature to feature backward relation errros (internal calculation error)").arg(brokenFeat2FeatBack.size()); 47 | for (i=0; i 48 | { 49 | errMsg += QString("Feature %1 Broken Feature: %2").arg(ISO8211::makeRecNameASCII(RCNM_FE, brokenFeat2FeatBack[i].first)).arg(ISO8211::makeRecNameASCII(RCNM_FE, brokenFeat2FeatBack[i].second)); 50 | } 51 | } 52 | if (!orphanFeatures.empty()) 53 | { 54 | errMsg += QString("%1 Orphaned Geo-Features (Point,Line or Area Geometry): "); 55 | for (i=0; i < orphanFeatures.size(); ++i) 56 | { 57 | errMsg += makeRecNameASCII(RCNM_FE, orphanFeatures[i]); 58 | } 59 | } 60 | if (!orphanSpatials.empty()) 61 | { 62 | errMsg += QString("%1 Orphaned Spatials:").arg(orphanSpatials.size()); 63 | for (i=0; i < orphanSpatials.size(); ++i) 64 | { 65 | errMsg += makeRecNameASCII(orphanSpatials[i]); 66 | } 67 | } 68 | if (!brokenEdge2Node.empty()) 69 | { 70 | errMsg += QString("%1 Broken Edge to Bounding Node Pointer:").arg(brokenEdge2Node.size()); 71 | for (i=0; i < brokenEdge2Node.size(); ++i) 72 | { 73 | errMsg += QString("Edge: %1 Broken Node: %2").arg(makeRecNameASCII(RCNM_VE, brokenEdge2Node[i].first)).arg(makeRecNameASCII(RCNM_VC, brokenEdge2Node[i].second)); 74 | } 75 | } 76 | if (!edgesMissingBNodes.empty()) 77 | { 78 | errMsg += QString("%1 Edges missing Bounding Nodes:").arg(edgesMissingBNodes.size()); 79 | for (i=0; i < edgesMissingBNodes.size(); ++i) 80 | { 81 | errMsg += makeRecNameASCII(RCNM_VE, edgesMissingBNodes[i]); 82 | } 83 | } 84 | if (!bNodesMissingEdges.empty()) 85 | { 86 | errMsg += QString("%1 Bounding Nodes not connected to Edges:").arg(bNodesMissingEdges.size()); 87 | for (i=0; i < bNodesMissingEdges.size(); ++i) 88 | { 89 | errMsg += makeRecNameASCII(RCNM_VC, bNodesMissingEdges[i]); 90 | } 91 | } 92 | if (!brokenBNodes2Edge.empty()) 93 | { 94 | errMsg += QString("%1 Bounding Nodes with broken Edge Pointer (internal error):").arg(brokenBNodes2Edge.size()); 95 | for (i=0; i < brokenBNodes2Edge.size(); ++i) 96 | { 97 | errMsg += QString("Bounding Node: %1 Broken Edge Pointer: %2").arg(makeRecNameASCII(RCNM_VC, brokenBNodes2Edge[i].first)).arg(makeRecNameASCII(RCNM_VE, brokenBNodes2Edge[i].second)); 98 | } 99 | } 100 | if (!featMissingFOID.empty()) 101 | { 102 | errMsg += QString("%1 Features without valid FOID").arg(featMissingFOID.size()); 103 | for (i=0; i < featMissingFOID.size(); ++i) 104 | { 105 | errMsg += makeRecNameASCII(RCNM_FE, featMissingFOID[i]); 106 | } 107 | } 108 | //**** Non-Error messages: **** 109 | if (!outsidePointer.empty()) 110 | { 111 | errMsg += QString("%1 FOIDs pointing to Features in other Cells: ").arg(outsidePointer.size()); 112 | for (i=0; i < outsidePointer.size(); ++i) 113 | { 114 | errMsg += makeRecNameASCII(RCNM_FE, outsidePointer[i].first) +" has OutsideCellPointer: " +ISO8211::makeLongNAMeASCII(outsidePointer[i].second); 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /src/cell_check_s57.cpp: -------------------------------------------------------------------------------- 1 | 2 | //***************************************************************************** 3 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 4 | //** This file is part of the ENClib 5 | //** The ENC lib may be used unter the GPL General Public License Version 2 6 | //** or with a Commercial License granted by Kai R. Neufeldt 7 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 8 | //***************************************************************************** 9 | 10 | #include "cell_check_s57.h" 11 | 12 | using namespace Enc; 13 | 14 | //***************************************************************************** 15 | /// Check the record contents without using the product spec 16 | /*! 17 | * The checks are not ENC specific, only what S-57 specific 18 | ****************************************************************************** */ 19 | const CheckResult & CellCheckS57::check() 20 | { 21 | checkRes.clear(); 22 | 23 | const std::map< unsigned long, FeatureS57 *> & features = cell->getFeatures(); 24 | std::map< unsigned long, FeatureS57 *>::const_iterator feIt = features.begin(); 25 | for(; feIt != features.end(); ++feIt) 26 | { 27 | //**** check feature-feature, if possible **** 28 | const FeatureS57 * feat = feIt->second; 29 | const std::vector < FieldFFPT > & FFPTvec = feat->getFfptVec(); 30 | for (uint ffInd = 0; ffInd < FFPTvec.size(); ++ffInd) 31 | { 32 | unsigned long otherRcid = cell->getRcid4Foid(FFPTvec[ffInd].getLNAM()); //may be 0 if feature is not in same cell 33 | if (otherRcid && !cell->recordExists(ISO8211::RCNM_FE, otherRcid)) 34 | { 35 | checkRes.brokenFeat2Feat.push_back(RCIDPair(feat->getFRID().getRCID(),otherRcid)); 36 | } 37 | if (!otherRcid) 38 | { 39 | checkRes.outsidePointer.push_back(RcidFoidPair(feat->getFRID().getRCID(), FFPTvec[ffInd].getLNAM())); 40 | } 41 | } 42 | //**** check feat-feat-back-pointer **** 43 | const std::vector< unsigned long > & ffptBackVec = feat->getFfptBackVec(); 44 | for (uint bI = 0; bI < ffptBackVec.size(); ++bI) 45 | { 46 | if (!cell->recordExists(ISO8211::RCNM_FE , ffptBackVec[bI])) 47 | { 48 | checkRes.brokenFeat2FeatBack.push_back(RCIDPair(feat->getFRID().getRCID(), ffptBackVec[bI])); 49 | } 50 | } 51 | 52 | //**** check feature->Spatial **** 53 | const std::vector < FieldFSPT > & FSPTvec = feat->getFsptVec(); 54 | for (uint fsInd = 0; fsInd < FSPTvec.size(); ++fsInd) 55 | { 56 | if (!cell->recordExists(FSPTvec[fsInd].getOtherRCNM() ,FSPTvec[fsInd].getOtherRCID())) 57 | { 58 | checkRes.brokenFeat2Spatial.push_back(std::pair(feat->getFRID().getRCID(), FSPTvec[fsInd].getOtherRecName())); 59 | } 60 | } 61 | if (feat->getFRID().getPRIM() != 255 && FSPTvec.empty()) 62 | { 63 | checkRes.orphanFeatures.push_back(feat->getFRID().getRCID()); 64 | } 65 | } 66 | 67 | const std::map< unsigned long, NodeS57 *> & iNodes = cell->getINodes(); 68 | std::map< unsigned long, NodeS57 *>::const_iterator inIt = iNodes.begin(); 69 | for (; inIt != iNodes.end(); ++inIt) 70 | { 71 | checkSpatial2FeatureRelation(*inIt->second); 72 | } 73 | 74 | const std::map< unsigned long, BoundNodeS57 *> & bNodes = cell->getBNodes(); 75 | std::map< unsigned long, BoundNodeS57 *>::const_iterator bnIt = bNodes.begin(); 76 | for (; bnIt != bNodes.end(); ++bnIt) 77 | { 78 | checkSpatial2FeatureRelation(*bnIt->second); 79 | //** check if edge back-pointers are OK ** 80 | const std::vector edges = bnIt->second->getEdges(); 81 | if (edges.empty()) 82 | { 83 | checkRes.bNodesMissingEdges.push_back(bnIt->second->getVRID().getRCID()); 84 | } 85 | for (uint eI = 0; eI < edges.size(); ++ eI) 86 | { 87 | if(!cell->recordExists(ISO8211::RCNM_VE, edges[eI])) 88 | { 89 | checkRes.brokenBNodes2Edge.push_back(RCIDPair(bnIt->second->getVRID().getRCID(), edges[eI])); 90 | } 91 | } 92 | } 93 | 94 | const std::map< unsigned long, SoundgS57 *> & soundings = cell->getSoundingds(); 95 | std::map< unsigned long, SoundgS57 *>::const_iterator sdIt = soundings.begin(); 96 | for (;sdIt != soundings.end(); ++sdIt) 97 | { 98 | checkSpatial2FeatureRelation(*sdIt->second); 99 | } 100 | 101 | const std::map< unsigned long, EdgeS57 *> & edges = cell->getEdges(); 102 | std::map< unsigned long, EdgeS57 *>::const_iterator edIt = edges.begin(); 103 | for (;edIt != edges.end(); ++edIt) 104 | { 105 | const EdgeS57 * edge = edIt->second; 106 | checkSpatial2FeatureRelation(*edge); 107 | //** check if Bounding Nodes are OK ** 108 | if (edge->getStartNodeRecId() == 0 || edge->getEndNodeRecId() == 0) 109 | { 110 | checkRes.edgesMissingBNodes.push_back(edge->getVRID().getRCID()); 111 | } 112 | if (edge->getStartNodeRecId() && !cell->recordExists(ISO8211::RCNM_VC , edge->getStartNodeRecId())) 113 | { 114 | checkRes.brokenEdge2Node.push_back(RCIDPair(edge->getVRID().getRCID(), edge->getStartNodeRecId())); 115 | } 116 | if (edge->getEndNodeRecId() && !cell->recordExists(ISO8211::RCNM_VC , edge->getEndNodeRecId())) 117 | { 118 | checkRes.brokenEdge2Node.push_back(RCIDPair(edge->getVRID().getRCID(), edge->getEndNodeRecId())); 119 | } 120 | } 121 | return checkRes; 122 | } 123 | 124 | //***************************************************************************** 125 | /// Check the Spatial to Feature Pointer 126 | /*! 127 | * 128 | ****************************************************************************** */ 129 | void CellCheckS57::checkSpatial2FeatureRelation(const SpatialS57 & spat) 130 | { 131 | const std::vector & relFeatures = spat.getFeatures(); 132 | for (uint fI = 0; fI < relFeatures.size(); ++fI) 133 | { 134 | if (!cell->recordExists(ISO8211::RCNM_FE , relFeatures[fI])) 135 | { 136 | checkRes.brokenSpatial2Feat.push_back(SpatFeatPair(spat.getNameBIN(), relFeatures[fI])); 137 | } 138 | } 139 | //** Isolated nodes (incl. soundings) and Edges MUST have a relation to a feature ** 140 | if ((spat.getVRID().getRCNM() == ISO8211::RCNM_VI || spat.getVRID().getRCNM() == ISO8211::RCNM_VE) && relFeatures.empty()) 141 | { 142 | checkRes.orphanSpatials.push_back(spat.getNameBIN()); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/cell_parser_iso8211.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include 10 | 11 | #include "cell_parser_iso8211.h" 12 | #include "iso8211_simple.h" 13 | 14 | using namespace Enc; 15 | 16 | CellParser8211::CellParser8211(unsigned long parseOptions) : parseOpts(parseOptions) 17 | {} 18 | 19 | CellParser8211::~CellParser8211() 20 | {} 21 | 22 | -------------------------------------------------------------------------------- /src/cell_parser_iso8211Gdal.cpp: -------------------------------------------------------------------------------- 1 | 2 | //***************************************************************************** 3 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 4 | //** This file is part of the ENClib 5 | //** The ENC lib may be used unter the GPL General Public License Version 2 6 | //** or with a Commercial License granted by Kai R. Neufeldt 7 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 8 | //***************************************************************************** 9 | 10 | #include "cell_parser_iso8211Gdal.h" 11 | #include "cell_records.h" 12 | #include "cell_s57_base.h" 13 | //Gdal includes: 14 | #include "iso8211.h" 15 | #include "cpl_vsi.h" 16 | 17 | 18 | using namespace Enc; 19 | 20 | CellParser8211GDAL::CellParser8211GDAL(CellS57_Base * cell) : CellParser8211(ParseAll) 21 | { 22 | setCell(cell); 23 | } 24 | 25 | void CellParser8211GDAL::parseS57CellIntern(QString cellName) 26 | { 27 | //**** Open ENC, read the DDR **** 28 | if( !oModule.Open(cellName.toLatin1())) 29 | { 30 | throw QString("ERROR: Cannot open S-57 file: %1").arg(cellName); 31 | } 32 | 33 | //**** Read all DataRecords **** 34 | DDFRecord *poRecord; 35 | long nStartLoc; 36 | int recNo = 0; 37 | nStartLoc = VSIFTell( oModule.GetFP() ); 38 | for( poRecord = oModule.ReadRecord(); 39 | poRecord != NULL; poRecord = oModule.ReadRecord(), ++recNo) 40 | { 41 | if (recNo <= 1) ParseHeaderRecord(*poRecord); 42 | else 43 | nStartLoc = VSIFTell(oModule.GetFP() ); 44 | } 45 | oModule.Close(); 46 | 47 | #ifdef DBMALLOC 48 | malloc_dump(1); 49 | #endif 50 | } 51 | 52 | void CellParser8211GDAL::ParseHeaderRecord(DDFRecord & rec) 53 | { 54 | 55 | for (int subI = 0; subI < rec.GetFieldCount(); ++subI) 56 | { 57 | DDFField * recFld = rec.GetField(subI); 58 | const char * tag = recFld->GetFieldDefn()->GetName(); 59 | if (strncmp(tag, "DSID", sizeof(tag)) == 0) 60 | { 61 | 62 | } 63 | else if (strncmp(tag, "DSSI", sizeof(tag)) == 0) 64 | { 65 | 66 | 67 | } 68 | else if (strncmp(tag, "DSPM", sizeof(tag)) == 0) 69 | { 70 | 71 | 72 | } 73 | } 74 | } 75 | 76 | void CellParser8211GDAL::ParseFeatureRecord(DDFRecord & rec) 77 | { 78 | 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/cell_parser_iso8211dirty4base.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include 10 | 11 | #include "cell_parser_iso8211dirty4base.h" 12 | #include "cell_s57_base.h" 13 | #include "cell_records.h" 14 | #include "iso8211_simple.h" 15 | 16 | using namespace Enc; 17 | 18 | //***************************************************************************** 19 | /// 20 | /*! 21 | * 22 | ****************************************************************************** */ 23 | CellParser8211Dirty4Base::CellParser8211Dirty4Base(CellS57_Base * cell, unsigned long parseOptions) : CellParser8211Dirty(parseOptions) 24 | { 25 | setCell(cell); 26 | } 27 | 28 | CellParser8211Dirty4Base::~CellParser8211Dirty4Base() 29 | {} 30 | 31 | //***************************************************************************** 32 | /// 33 | /*! 34 | * 35 | ****************************************************************************** */ 36 | void CellParser8211Dirty4Base::setCell(CellS57_Header * cell) 37 | { 38 | if (!cell) 39 | { 40 | cellS57 = NULL; 41 | return; 42 | } 43 | if (cell->getClass() != CellS57_Header::BaseCellClass) 44 | { 45 | throw QString("ERROR: Cannot set cell pointer: wrong class!"); 46 | } 47 | cellS57 = dynamic_cast(cell); 48 | } 49 | 50 | //***************************************************************************** 51 | /// 52 | /*! 53 | * 54 | ****************************************************************************** */ 55 | void CellParser8211Dirty4Base::parseS57Cell(QString cellName) 56 | { 57 | parseInit(cellName, cellS57); 58 | parseS57CellIntern(cellS57); 59 | #ifdef _DEBUG 60 | printf("DEBUG: parsed: %d Features, %d iNodes, %d bNodes, %d Edges, %d 3Dcluster \n", 61 | cellS57->getFeatures().size(), cellS57->getINodes().size(), cellS57->getBNodes().size(), cellS57->getEdges().size(), cellS57->getSoundingds().size()); 62 | #endif 63 | } 64 | 65 | //***************************************************************************** 66 | /// 67 | /*! 68 | * 69 | ****************************************************************************** */ 70 | void CellParser8211Dirty4Base::parseFeatureRecord(Iso8211fieldIterator & fieldIt) 71 | { 72 | FeatureS57 * feat = new FeatureS57; 73 | CellParser8211Dirty::parseFeatureRecord(fieldIt, *feat); 74 | 75 | //** rember this Feature by Record-id and FeatObjID ** 76 | cellS57->features[feat->getFRID().getRCID()] = feat; 77 | LongNAMe foidHandle = feat->getFOID().getLongNAMe(); 78 | if (foidHandle == 0) 79 | { 80 | cellS57->checkResult.featMissingFOID.push_back(feat->getFRID().getRCID() ); 81 | } 82 | cellS57->foid2rcid.insert(std::pair (foidHandle, feat->getFRID().getRCID())); 83 | } 84 | 85 | //***************************************************************************** 86 | /// 87 | /*! 88 | * 89 | ****************************************************************************** */ 90 | void CellParser8211Dirty4Base::parseVectorRecord(Iso8211fieldIterator & fieldIt) 91 | { 92 | unsigned int fieldInd = 0; 93 | unsigned int iso8211recid = 0; 94 | for (; fieldInd < fieldIt.fieldCount(); ++fieldInd) 95 | { 96 | int fieldSize; 97 | const char * tag = 0; 98 | const char * field = fieldIt.at(fieldInd, &fieldSize, tag); 99 | 100 | FieldVRID vrid; //1st Field after "0001" Field 101 | //ISO8211 Record-id: is not really needed, only for iso8211 internally 102 | if (strncmp(tag, "0001", 4) == 0) 103 | { 104 | if (fieldSize>4) 105 | { 106 | iso8211recid = ISO8211::bytes2ulong(field); //this is against the S-57 Standard!!! 107 | } 108 | else iso8211recid = ISO8211::bytes2ushort(field); //normal case: recid is 2bytes, binary, unsigned 109 | } 110 | else if (strncmp(tag, "VRID", 4) == 0) 111 | { 112 | parseVRIDField(field, fieldSize, vrid); 113 | //** Parse a Node Spatial: might be node (ONE 2D-position) or Sounding (SEVERAL 3D-positions)** 114 | if (vrid.getRCNM() == ISO8211::RCNM_VI) 115 | { 116 | if (fieldIt["SG3D"]) 117 | { 118 | SoundgS57 * sndgRec = new SoundgS57(iso8211recid); 119 | sndgRec->setVRID(vrid); 120 | parseSndgRecord(fieldIt, *sndgRec); 121 | cellS57->soundings[sndgRec->getVRID().getRCID()] = sndgRec; 122 | } 123 | else 124 | { 125 | NodeS57 * nodeRec = new NodeS57(iso8211recid); 126 | nodeRec->setVRID(vrid); 127 | parseNodeRecord(fieldIt, *nodeRec); 128 | cellS57->iNodes[nodeRec->getVRID().getRCID()] = nodeRec; 129 | } 130 | } 131 | //** Parse a Bounding Node Spatial (parsing is same as or isoNodes, but has pointers to Edges) ** 132 | else if (vrid.getRCNM() == ISO8211::RCNM_VC) 133 | { 134 | BoundNodeS57 * nodeRec = new BoundNodeS57(iso8211recid); 135 | nodeRec->setVRID(vrid); 136 | parseNodeRecord(fieldIt, *nodeRec); 137 | cellS57->bNodes[nodeRec->getVRID().getRCID()] = nodeRec; 138 | } 139 | //** Parse a Edge Spatial ** 140 | else if (vrid.getRCNM() == ISO8211::RCNM_VE) 141 | { 142 | EdgeS57 * edgeRec = new EdgeS57(iso8211recid); 143 | edgeRec->setVRID(vrid); 144 | parseEdgeRecord(fieldIt, *edgeRec); 145 | cellS57->edges[edgeRec->getVRID().getRCID()] = edgeRec; 146 | } 147 | else 148 | { 149 | throw QString("ERROR: Cannot Parse Spatial Record: Neither Node nor Edge!"); 150 | } 151 | 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/cell_parser_iso8211dirty4header.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include 10 | 11 | #include "cell_parser_iso8211dirty4header.h" 12 | #include "cell_records.h" 13 | #include "iso8211_simple.h" 14 | 15 | using namespace Enc; 16 | 17 | CellParser8211Dirty4Header::CellParser8211Dirty4Header(CellS57_Header * cell, unsigned long parseOptions) : CellParser8211Dirty(parseOptions), cellS57(cell) 18 | {} 19 | 20 | CellParser8211Dirty4Header::~CellParser8211Dirty4Header() 21 | {} 22 | 23 | 24 | void CellParser8211Dirty4Header::setCell(CellS57_Header * cell) 25 | { 26 | if (!cell) 27 | { 28 | cellS57 = NULL; 29 | return; 30 | } 31 | cellS57 = cell; 32 | } 33 | 34 | //***************************************************************************** 35 | /// Parse the Header of an S-57 ISO8211 Base or Update Cell 36 | /*! 37 | * Only the first 4096 Bytes are Read to make parsing faster! 38 | ****************************************************************************** */ 39 | void CellParser8211Dirty4Header::parseS57Cell(QString cellName) 40 | { 41 | parseInit(cellName, cellS57, 4096); 42 | parseS57CellIntern(cellS57); 43 | } 44 | -------------------------------------------------------------------------------- /src/cell_parser_iso8211dirty4updt.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include 10 | 11 | #include "cell_parser_iso8211dirty4updt.h" 12 | #include "cell_s57_update.h" 13 | #include "cell_records.h" 14 | #include "iso8211_simple.h" 15 | 16 | using namespace Enc; 17 | 18 | CellParser8211Dirty4Updt::CellParser8211Dirty4Updt(CellS57_Update * cell, unsigned long parseOptions) : CellParser8211Dirty(parseOptions) 19 | { 20 | setCell(cell); 21 | } 22 | CellParser8211Dirty4Updt::CellParser8211Dirty4Updt(double factorXY, double factorZ, unsigned long parseOptions) : CellParser8211Dirty(parseOptions, factorXY, factorZ) 23 | {} 24 | 25 | CellParser8211Dirty4Updt::~CellParser8211Dirty4Updt() 26 | {} 27 | 28 | 29 | void CellParser8211Dirty4Updt::setCell(CellS57_Header * cell) 30 | { 31 | if (!cell) 32 | { 33 | cellS57 = NULL; 34 | return; 35 | } 36 | if (cell->getClass() != CellS57_Header::UpdtCellClass) 37 | { 38 | throw QString("ERROR: Cannot set cell pointer: wrong class!"); 39 | } 40 | cellS57 = dynamic_cast(cell); 41 | 42 | //** rem: update cell has no DSPM record, but maybe it already got the DSPM from its base-cell ** 43 | if (cellS57->getDspm().getCOMF()) facXY = cellS57->getDspm().getCOMF(); 44 | if (cellS57->getDspm().getSOMF()) facZ = cellS57->getDspm().getSOMF(); 45 | } 46 | 47 | //***************************************************************************** 48 | /// 49 | /*! 50 | * 51 | ****************************************************************************** */ 52 | void CellParser8211Dirty4Updt::parseS57Cell(QString cellName) 53 | { 54 | if (facXY == 0) throw QString("ERROR: Cannot parse %1, coordinate multiplication factor not set!").arg(cellName); 55 | if (facZ == 0) throw QString("ERROR: Cannot parse %1, sounding multiplication factor not set!").arg(cellName); 56 | 57 | parseInit(cellName, cellS57); 58 | parseS57CellIntern(cellS57); 59 | } 60 | 61 | //***************************************************************************** 62 | /// 63 | /*! 64 | * 65 | ****************************************************************************** */ 66 | void CellParser8211Dirty4Updt::parseFeatureRecord(Iso8211fieldIterator & fieldIt) 67 | { 68 | FeatureS57_Updt * feat = new FeatureS57_Updt; 69 | parseFeatureUpdtRecord(fieldIt, *feat); 70 | 71 | //** rember this Feature by Record-id and FeatObjID ** 72 | cellS57->features.push_back(feat); 73 | } 74 | 75 | //***************************************************************************** 76 | /// 77 | /*! 78 | * 79 | ****************************************************************************** */ 80 | void CellParser8211Dirty4Updt:: parseVectorRecord(Iso8211fieldIterator & fieldIt) 81 | { 82 | unsigned int fieldInd = 0; 83 | unsigned int iso8211recid = 0; 84 | for (; fieldInd < fieldIt.fieldCount(); ++fieldInd) 85 | { 86 | int fieldSize; 87 | const char * tag = 0; 88 | const char * field = fieldIt.at(fieldInd, &fieldSize, tag); 89 | 90 | FieldVRID vrid; //1st Field after "0001" Field 91 | SpatialS57 * updtSpatial = 0; 92 | //ISO8211 Record-id: is not really needed, only for iso8211 internally 93 | if (strncmp(tag, "0001", 4) == 0) 94 | { 95 | if (fieldSize>4) 96 | { 97 | iso8211recid = ISO8211::bytes2ulong(field); //this is against the S-57 Standard!!! 98 | } 99 | else iso8211recid = ISO8211::bytes2ushort(field); //normal case: recid is 2bytes, binary, unsigned 100 | } 101 | else if (strncmp(tag, "VRID", 4) == 0) 102 | { 103 | parseVRIDField(field, fieldSize, vrid); 104 | //** Parse a Sounding (SEVERAL 3D-positions)** 105 | if (vrid.getRCNM() == RCNM_VI && fieldIt["SG3D"]) 106 | { 107 | updtSpatial = new SoundgS57_Updt(vrid, iso8211recid); 108 | } 109 | //** Parse a normal Node Spatial (bounding node or isolated node)** 110 | else if (vrid.getRCNM() == ISO8211::RCNM_VI || vrid.getRCNM() == ISO8211::RCNM_VC) 111 | { 112 | updtSpatial = new NodeS57_Updt(vrid, iso8211recid); 113 | } 114 | //** Parse a Edge Spatial ** 115 | else if (vrid.getRCNM() == RCNM_VE) 116 | { 117 | updtSpatial = new EdgeS57_Updt(vrid, iso8211recid); 118 | } 119 | else 120 | { 121 | throw QString("ERROR: Cannot Parse Spatial Record: Neither Node nor Edge!").arg(ISO8211::makeRecNameASCII(vrid.getRCNM(), vrid.getRCID())); 122 | } 123 | parseVectorUpdtRecord(fieldIt, updtSpatial); 124 | cellS57->spatials.push_back(updtSpatial); 125 | } 126 | } 127 | } 128 | 129 | void CellParser8211Dirty4Updt::parseVectorUpdtRecord(Iso8211fieldIterator & fieldIt, SpatialS57 * updtSpatial) 130 | { 131 | parseVectorUpdtFields(fieldIt, *reinterpret_cast(updtSpatial)); //somehow bold :) 132 | 133 | if (updtSpatial->getType() == Record8211::SoundingUPDT) 134 | { 135 | parseSndgRecord(fieldIt, *static_cast(updtSpatial)); 136 | } 137 | else if (updtSpatial->getType() == Record8211::NodeUPDT) 138 | { 139 | parseNodeRecord(fieldIt, *static_cast(updtSpatial)); 140 | } 141 | else if (updtSpatial->getType() == Record8211::EdgeUPDT) 142 | { 143 | parseEdgeRecord(fieldIt, *static_cast(updtSpatial)); 144 | } 145 | } 146 | 147 | //***************************************************************************** 148 | /// Parse Fields needed for Updating a Vector record ("ER" file) 149 | /*! 150 | * VRPC or SGCC may not be present, Update Records might have missing fields 151 | ****************************************************************************** */ 152 | void CellParser8211Dirty4Updt::parseVectorUpdtFields(Iso8211fieldIterator & fieldIt, SpatialS57_Updt & spatial_updat) 153 | { 154 | const char * fieldPtr = fieldIt["VRPC"]; 155 | if (fieldPtr) parseVRPCField(fieldPtr, 0, spatial_updat.getVrpc()); 156 | fieldPtr = fieldIt["SGCC"]; 157 | if (fieldPtr) parseSGCCField(fieldPtr, 0, spatial_updat.getSgcc()); 158 | } 159 | -------------------------------------------------------------------------------- /src/cell_record_fields.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include "cell_record_fields.h" 10 | #include "cell_parser_iso8211dirty.h" 11 | 12 | #include 13 | 14 | #include "iso8211.h" 15 | #include "cpl_vsi.h" 16 | using namespace Enc; 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/cell_records.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include "cell_records.h" 10 | 11 | 12 | using namespace Enc; 13 | 14 | //const int FieldFRID::MemberCnt; 15 | 16 | const DegBBox & SoundgS57::getBoundingBox() 17 | { 18 | if (!bBox.isValid()) 19 | { 20 | for (int i =0; i < SG3Dvec.size(); i += 3) 21 | { 22 | bBox.add(SG3Dvec[i], SG3Dvec[i+1]); 23 | } 24 | } 25 | return bBox; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/cell_records_fields_header.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include "cell_record_fields.h" 10 | #include "cell_parser_iso8211dirty.h" 11 | 12 | #include 13 | 14 | #include "iso8211.h" 15 | #include "cpl_vsi.h" 16 | using namespace Enc; 17 | 18 | //const int FieldDSID::MemberCnt; 19 | //const int FieldDSSI::MemberCnt; 20 | //const int FieldDSPM::MemberCnt; 21 | 22 | FieldDSID::FieldDSID() : RCNM(0), RCID(0), EXPP(0), INTU(0), EDTN(-1), UPDN(-1), PRSP(0), PROF(0), AGEN(0) 23 | { 24 | //** init Update/Issue date with 8 valid chars - They Must always be 8 Chars long! ** 25 | memset(UADT,' ',8); 26 | UADT[8]=0; 27 | memset(ISDT,' ',8); 28 | ISDT[8]=0; 29 | //** init STED with 4 valid chars - STED must always be 4 Chars long! ** 30 | memset(STED ,' ',4); 31 | STED[4]=0; 32 | } 33 | FieldDSID::FieldDSID(const FieldDSID & cpDSID) 34 | { 35 | *this = cpDSID; 36 | } 37 | 38 | //****************************************************************************** 39 | /// index-operator: use this Struct like a vector :-) 40 | /*! 41 | ***************************************************************************** */ 42 | QVariant FieldDSID::operator[](int index)const 43 | { 44 | if (index == COL_RCNM) return RCNM; 45 | else if (index == COL_RCID) return (uint)RCID; //QVariant has problems with unsigned long 46 | else if (index == COL_EXPP) return EXPP; 47 | else if (index == COL_INTU) return INTU; 48 | else if (index == COL_DSNM) return DSNM; 49 | else if (index == COL_EDTN) return EDTN; 50 | else if (index == COL_UPDN) return UPDN; 51 | else if (index == COL_UADT) return UADT; 52 | else if (index == COL_ISDT) return ISDT; 53 | else if (index == COL_STED) return STED; 54 | else if (index == COL_PRSP) return PRSP; 55 | else if (index == COL_PSDN) return PSDN; 56 | else if (index == COL_PRED) return PRED; 57 | else if (index == COL_PROF) return PROF; 58 | else if (index == COL_AGEN) return AGEN; 59 | else if (index == COL_COMT) return COMT; 60 | return QVariant(); 61 | } 62 | FieldDSID & FieldDSID::operator=(const FieldDSID & otherDSID) 63 | { 64 | if (this == &otherDSID) *this; 65 | 66 | RCNM = otherDSID.RCNM; 67 | RCID = otherDSID.RCID; //Record ID - unimportant 68 | EXPP = otherDSID.EXPP; //Exchange purpose - 'N' (new) or 'R' (revision) 69 | INTU = otherDSID.INTU; //usage 70 | EDTN = otherDSID.EDTN; //Edition Number 71 | UPDN = otherDSID.UPDN; //Update Number 72 | 73 | DSNM = otherDSID.DSNM; //Data Set Name 74 | PSDN = otherDSID.PSDN; //Product Specification description - unimportant 75 | PRED = otherDSID.PRED; //Product Specification edition number - unimportant 76 | COMT = otherDSID.COMT; //Comment 77 | 78 | PRSP = otherDSID.PRSP; //Product Specification - normally "ENC" 79 | PROF = otherDSID.PROF; //Application profile identification - "EN" "ER" or "DD" 80 | AGEN = otherDSID.AGEN; //Producing agency 81 | 82 | strncpy(UADT, otherDSID.UADT, sizeof(UADT)); //Update application Date 83 | strncpy(ISDT, otherDSID.ISDT, sizeof(ISDT)); //Issue Date 84 | strncpy(STED, otherDSID.STED, sizeof(STED)); //Edition Number S-57 always "03.1" - unimportant 85 | 86 | return *this; 87 | } 88 | 89 | bool FieldDSID::operator==(const FieldDSID & otherDSID) const 90 | { 91 | //**** at first: simple type compares (fast) 92 | if (RCNM != otherDSID.RCNM || 93 | RCID != otherDSID.RCID || //Record ID - unimportant 94 | EXPP != otherDSID.EXPP || //Exchange purpose - 'N' (new) or 'R' (revision) 95 | INTU != otherDSID.INTU || //Usage 96 | EDTN != otherDSID.EDTN || //Edition Number 97 | UPDN != otherDSID.UPDN || //Update Number 98 | PRSP != otherDSID.PRSP || //Product Specification - normally "ENC" 99 | PROF != otherDSID.PROF || //Application profile identification - "EN" "ER" or "DD" 100 | AGEN != otherDSID.AGEN) //Producing agency 101 | return false; 102 | 103 | //**** then char compares, slower **** 104 | if (strncmp(UADT, otherDSID.UADT, sizeof(UADT))!= 0 || //Update application Date 105 | strncmp(ISDT, otherDSID.ISDT, sizeof(ISDT))!= 0 || //Issue Date 106 | strncmp(STED, otherDSID.STED, sizeof(STED))!= 0) //Edition Number S-57 always "03.1" - unimportant 107 | return false; 108 | 109 | //**** even slower: QString compares **** 110 | if(DSNM != otherDSID.DSNM || //Data Set Name 111 | PSDN != otherDSID.PSDN || //Product Specification description - unimportant 112 | PRED != otherDSID.PRED || //Product Specification edition number - unimportant 113 | COMT != otherDSID.COMT) //Comment 114 | return false; 115 | 116 | return true; 117 | } 118 | 119 | unsigned long FieldDSID::getIso8211Length() const 120 | { 121 | return 31 //all fixed length values 122 | +DSNM.length() +1 //dsnm + UT 123 | +Digits4EditionNo +1 //EDTN: Assuming: 4 digits + UT 124 | +Digits4UpdateNo +1 //UPDT: Assuming: 3 digits + UT 125 | +PSDN.length() +1 //PSDN +UT 126 | +PRED.length() +1 //PRED +UT 127 | +COMT.length() +1 //Comment + UT 128 | +1; //Final FT 129 | } 130 | 131 | //****************************************************************************** 132 | //****************************************************************************** 133 | /// Struct containig the data (subfields) of the DSSI Field 134 | /*! 135 | * found in S-57 cell header record: first record, second field 136 | ***************************************************************************** */ 137 | //****************************************************************************** 138 | FieldDSSI::FieldDSSI() : DSTR(0), AALL(0), NALL(0), NOMR(0), NOCR(0), NOGR(0), NOLR(0), NOIN(0), NOCN(0), NOED(0), NOFA(0) 139 | {} 140 | 141 | QVariant FieldDSSI::operator[](int index)const 142 | { 143 | if (index == COL_DSTR) return DSTR; 144 | else if (index == COL_AALL) return AALL; 145 | else if (index == COL_NALL) return NALL; 146 | else if (index == COL_NOMR) return NOMR; 147 | else if (index == COL_NOCR) return NOCR; 148 | else if (index == COL_NOGR) return NOGR; 149 | else if (index == COL_NOLR) return NOLR; 150 | else if (index == COL_NOIN) return NOIN; 151 | else if (index == COL_NOCN) return NOCN; 152 | else if (index == COL_NOED) return NOED; 153 | else if (index == COL_NOFA) return NOFA; 154 | return QVariant(); 155 | } 156 | 157 | 158 | unsigned long FieldDSSI::getIso8211Length() const 159 | { 160 | return 36; 161 | } 162 | //****************************************************************************** 163 | //****************************************************************************** 164 | /// Struct containig the data (subfields) of the DSPM Field 165 | /*! 166 | * found in S-57 cell header record: second record, first field 167 | ***************************************************************************** */ 168 | //****************************************************************************** 169 | FieldDSPM::FieldDSPM() : RCNM(0), RCID(0), HDAT(0), VDAT(0), SDAT(0), CSCL(0), DUNI(0), HUNI(0), PUNI(0), COMF(0), SOMF(0) 170 | {} 171 | 172 | QVariant FieldDSPM::operator[](int index)const 173 | { 174 | if (index == COL_RCNM) return COL_RCNM; 175 | else if (index == COL_RCID) return (uint)RCID; 176 | else if (index == COL_HDAT) return HDAT; 177 | else if (index == COL_VDAT) return VDAT; 178 | else if (index == COL_SDAT) return SDAT; 179 | else if (index == COL_CSCL) return (uint)CSCL; 180 | else if (index == COL_DUNI) return DUNI; 181 | else if (index == COL_HUNI) return HUNI; 182 | else if (index == COL_PUNI) return PUNI; 183 | else if (index == COL_COUN) return COUN; 184 | else if (index == COL_COMF) return (uint)COMF; 185 | else if (index == COL_SOMF) return (uint)SOMF; 186 | else if (index == COL_COMT) return COMT; 187 | return QVariant(); 188 | } 189 | 190 | unsigned long FieldDSPM::getIso8211Length() const 191 | { 192 | return 24 + COMT.length() +1 +1 ; 193 | } 194 | -------------------------------------------------------------------------------- /src/cell_s57.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include "cell_s57.h" 10 | 11 | #include 12 | 13 | #include "cell_parser_iso8211dirty4base.h" 14 | #include "cell_parser_iso8211dirty4updt.h" 15 | #include "cell_writer_iso8211dirty.h" 16 | 17 | using namespace Enc; 18 | 19 | CellS57_Header::CellS57_Header() : DDR(0), DDRlen(0) 20 | {} 21 | 22 | CellS57_Header::CellS57_Header(const FieldDSPM & baseDSPM) : dspm(baseDSPM), DDR(0), DDRlen(0) 23 | {} 24 | 25 | 26 | CellS57_Header::~CellS57_Header() 27 | { 28 | delete [] DDR; 29 | } 30 | 31 | void CellS57_Header::clear() 32 | { 33 | dsid.clear(); 34 | dssi.clear(); 35 | dspm.clear(); 36 | delete [] DDR; 37 | DDRlen = 0; 38 | } 39 | 40 | void CellS57_Header::clearExceptDSPM() 41 | { 42 | dsid.clear(); 43 | dssi.clear(); 44 | delete [] DDR; 45 | DDRlen = 0; 46 | } 47 | 48 | void CellS57_Header::putDDR(const char * ddrPtr, int len) 49 | { 50 | if (DDR && DDRlen != len) 51 | { 52 | delete [] DDR; 53 | DDR = new char[len]; 54 | } 55 | DDRlen = len; 56 | memcpy(DDR, ddrPtr, DDRlen); 57 | } 58 | -------------------------------------------------------------------------------- /src/cell_s57_update.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include "cell_s57_update.h" 10 | 11 | #include 12 | 13 | #include "cell_parser_iso8211dirty4updt.h" 14 | #include "cell_writer_iso8211dirty.h" 15 | 16 | using namespace Enc; 17 | 18 | CellS57_Update::CellS57_Update() : CellS57_Header() 19 | { 20 | } 21 | CellS57_Update::CellS57_Update(const FieldDSPM & baseDSPM) : CellS57_Header(baseDSPM) 22 | { 23 | } 24 | 25 | CellS57_Update::~CellS57_Update() 26 | { 27 | clear(); 28 | } 29 | 30 | //****************************************************************************** 31 | /// Clear All Container, free all Memory - Cell becomes an empty cell again 32 | //**************************************************************************** */ 33 | void CellS57_Update::clear() 34 | { 35 | CellS57_Header::clear(); 36 | 37 | for (std::vector ::iterator it = features.begin(); it != features.end(); ++it) delete *it; 38 | features.clear(); 39 | for (std::vector ::iterator sIt = spatials.begin(); sIt != spatials.end(); ++sIt) delete *sIt; 40 | spatials.clear(); 41 | } 42 | 43 | void CellS57_Update::clearExceptDSPM() 44 | { 45 | CellS57_Header::clearExceptDSPM(); 46 | 47 | for (std::vector ::iterator it = features.begin(); it != features.end(); ++it) delete *it; 48 | features.clear(); 49 | for (std::vector ::iterator sIt = spatials.begin(); sIt != spatials.end(); ++sIt) delete *sIt; 50 | spatials.clear(); 51 | } 52 | 53 | //****************************************************************************** 54 | /// Conveniance Method: Fill update cell by parsing a update-File 55 | /*! File is paresed completely, except the DDR 56 | **************************************************************************** */ 57 | void CellS57_Update::parseISO8211(QString fileNamePath) 58 | { 59 | CellParser8211Dirty4Updt s57parser(this, CellParser8211::ParseAll); 60 | s57parser.parseS57Cell(fileNamePath); 61 | } 62 | -------------------------------------------------------------------------------- /src/cell_writer.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include "cell_writer.h" 10 | 11 | #include 12 | 13 | using namespace Enc; 14 | 15 | void CellWriter::setCell(const CellS57_Base * cell) 16 | { 17 | cellS57 = cell; 18 | } 19 | 20 | void CellWriter::writeS57Cell(QString cellName) 21 | { 22 | if (!cellS57) throw QString("ERROR: Cannot write S-57 Cell %1 No Cell Pointer!").arg(cellName); 23 | QFile iso8211file(cellName); 24 | if (!iso8211file.open(QIODevice::WriteOnly)) throw QString("ERROR: cannot open S-57 File %1 for writing").arg(cellName); 25 | writeS57Cell(&iso8211file); 26 | iso8211file.close(); 27 | } 28 | -------------------------------------------------------------------------------- /src/cellheader_tabmodel.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include "cellheader_tabmodel.h" 10 | #include "cell_records.h" 11 | #include "cell_parser_iso8211dirty4header.h" 12 | 13 | //#include 14 | #include 15 | 16 | using namespace Enc; 17 | 18 | HeaderTableModel::HeaderTableModel(QObject * parent) : QAbstractTableModel(parent) 19 | {} 20 | HeaderTableModel::~HeaderTableModel() 21 | {} 22 | 23 | void HeaderTableModel::init(const std::vector & cellsContent) 24 | { 25 | cells = cellsContent; 26 | reset(); 27 | } 28 | 29 | void HeaderTableModel::init(QStringList cellFileList) 30 | { 31 | CellParser8211Dirty4Header clHdrRdr; 32 | QStringList::const_iterator cit = cellFileList.begin(); 33 | for(; cit != cellFileList.end(); ++cit) 34 | { 35 | try 36 | { 37 | CellS57_Header cell; 38 | clHdrRdr.setCell(&cell); 39 | clHdrRdr.parseS57Cell(*cit); 40 | cells.push_back(cell); 41 | } 42 | catch (const char * errMsg) 43 | { 44 | printf("DEBUG: Error parsing cell: %s - %s",(*cit).toLatin1(), errMsg); 45 | } 46 | } 47 | reset(); 48 | } 49 | 50 | int HeaderTableModel::rowCount(const QModelIndex & parent) const 51 | { 52 | return cells.size(); 53 | } 54 | int HeaderTableModel::columnCount(const QModelIndex & parent ) const 55 | { 56 | return FieldDSID::MemberCnt; 57 | } 58 | QVariant HeaderTableModel::data(const QModelIndex & index, int role) const 59 | { 60 | //**** check if index is valid ***** 61 | if (index.row() >= cells.size() || index.column() >= FieldDSID::MemberCnt) 62 | { 63 | return QVariant(); 64 | } 65 | //**** rem: Data-Role is handled by CatalogEntry-struct itself **** 66 | if (role == Qt::DisplayRole) 67 | { 68 | const FieldDSID & headerData = cells[index.row()].getDsid(); 69 | if (index.column() == FieldDSID::COL_EXPP) 70 | { 71 | return S57::EXPP2string(headerData.getEXPP()); 72 | } 73 | else if (index.column() == FieldDSID::COL_INTU) 74 | { 75 | return S57::INTU2string(headerData.getINTU()); 76 | } 77 | else if (index.column() == FieldDSID::COL_PROF) 78 | { 79 | return S57::PROF2string(headerData.getPROF()); 80 | } 81 | return headerData[index.column()]; 82 | } 83 | //**** ToolTips: display column contents for columns which are typically long **** 84 | else if (role == Qt::ToolTipRole) 85 | { 86 | const FieldDSID & dsid = cells[index.row()].getDsid(); 87 | if (index.column() == FieldDSID::COL_DSNM) 88 | { 89 | if (!dsid.getDSNM().isEmpty()) return dsid.getDSNM(); 90 | } 91 | else if (index.column() == FieldDSID::COL_COMT) 92 | { 93 | if (!dsid.getCOMT().isEmpty()) return dsid.getCOMT(); 94 | } 95 | } 96 | return QVariant(); 97 | } 98 | QVariant HeaderTableModel::headerData(int section, Qt::Orientation orientation, int role) const 99 | { 100 | if (orientation == Qt::Horizontal) 101 | { 102 | if (role == Qt::DisplayRole) 103 | { 104 | if (section == FieldDSID::COL_RCNM) return tr("Token"); 105 | else if (section == FieldDSID::COL_RCID) return tr("Record Id"); 106 | else if (section == FieldDSID::COL_EXPP) return tr("Exchange purpose"); 107 | else if (section == FieldDSID::COL_INTU) return tr("Usage"); 108 | else if (section == FieldDSID::COL_DSNM) return tr("Dataset name"); 109 | else if (section == FieldDSID::COL_EDTN) return tr("Edition"); 110 | else if (section == FieldDSID::COL_UPDN) return tr("Update Number"); 111 | else if (section == FieldDSID::COL_UADT) return tr("Update Date"); 112 | else if (section == FieldDSID::COL_ISDT) return tr("Issue Date"); 113 | else if (section == FieldDSID::COL_STED) return tr("S-57 Ed. Num."); 114 | else if (section == FieldDSID::COL_PRSP) return tr("Prod. Spec."); 115 | else if (section == FieldDSID::COL_PSDN) return tr("Prod. descr."); 116 | else if (section == FieldDSID::COL_PRED) return tr("Prod. Spec. ed."); 117 | else if (section == FieldDSID::COL_PROF) return tr("App. profile"); 118 | else if (section == FieldDSID::COL_AGEN) return tr("Ag Code"); 119 | else if (section == FieldDSID::COL_COMT) return tr("Comment"); 120 | return QVariant(); 121 | } 122 | else if (role == Qt::ToolTipRole) 123 | { 124 | if (section == FieldDSID::COL_RCNM) 125 | { 126 | return tr("S-57 Record Name Token, always \"CD\""); 127 | } 128 | else if (section == FieldDSID::COL_RCID) 129 | { 130 | return tr("S-57 Record ID"); 131 | } 132 | else if (section == FieldDSID::COL_EXPP) 133 | { 134 | return tr("Exchange purpose, normally: \n- 'N' (new) or \n'R' (revision)"); 135 | } 136 | else if (section == FieldDSID::COL_DSNM) 137 | { 138 | return tr("Dataset name"); 139 | 140 | } 141 | else if (section == FieldDSID::COL_UPDN) 142 | { 143 | return tr("Update Number"); 144 | } 145 | else if (section == FieldDSID::COL_UADT) 146 | { 147 | return tr("Update Application Date \nOnly for Reissues"); 148 | } 149 | else if (section == FieldDSID::COL_ISDT) 150 | { 151 | return tr("Issue Date"); 152 | } 153 | else if (section == FieldDSID::COL_STED) 154 | { 155 | return tr("S-57 Edition Number \nAlways \"03.1\" for S-57 ENCs"); 156 | } 157 | else if (section == FieldDSID::COL_PRSP) 158 | { 159 | return tr("Product Specification \nnormally \"ENC\" for S-57 Naviagtion Charts"); 160 | } 161 | else if (section == FieldDSID::COL_PSDN) 162 | { 163 | return tr("Product Specification description"); 164 | } 165 | else if (section == FieldDSID::COL_PRED) 166 | { 167 | return tr("Product Specification edition number"); 168 | } 169 | else if (section == FieldDSID::COL_PROF) 170 | { 171 | return tr("Application profile identification - \"EN\" \"ER\" or \"DD\""); 172 | } 173 | else if (section == FieldDSID::COL_AGEN) 174 | { 175 | return tr("Agency Code of Producing Agency"); 176 | } 177 | else if (section == FieldDSID::COL_COMT) 178 | { 179 | return tr("Comment: "); 180 | } 181 | } 182 | } 183 | //**** rem: No need for (orientation == Qt::Horizontal) header, because row-numbers are provided by QAbstractTableModel 184 | return QAbstractTableModel::headerData(section, orientation,role); 185 | 186 | } 187 | 188 | -------------------------------------------------------------------------------- /src/cellheader_widget.cpp: -------------------------------------------------------------------------------- 1 | 2 | //***************************************************************************** 3 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 4 | //** This file is part of the ENClib 5 | //** The ENC lib may be used unter the GPL General Public License Version 2 6 | //** or with a Commercial License granted by Kai R. Neufeldt 7 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 8 | //***************************************************************************** 9 | 10 | #include "cellheader_widget.h" 11 | #include "cell_records.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | //#include 18 | #include 19 | 20 | using namespace Enc; 21 | 22 | //****************************************************************************** 23 | /// 24 | /*! 25 | ***************************************************************************** */ 26 | HeaderTableView::HeaderTableView(QWidget *parent) : QTableView(parent) 27 | { 28 | } 29 | HeaderTableView::~HeaderTableView() 30 | { 31 | } 32 | void HeaderTableView::showAllColumns(bool showAll) 33 | { 34 | if (showAll) 35 | { 36 | showColumn(FieldDSID::COL_RCNM); 37 | showColumn(FieldDSID::COL_RCID); 38 | showColumn(FieldDSID::COL_STED); 39 | showColumn(FieldDSID::COL_PRSP); 40 | showColumn(FieldDSID::COL_PSDN); 41 | showColumn(FieldDSID::COL_PRED); 42 | } 43 | else 44 | { 45 | hideColumn(FieldDSID::COL_RCNM); 46 | hideColumn(FieldDSID::COL_RCID); 47 | hideColumn(FieldDSID::COL_STED); 48 | hideColumn(FieldDSID::COL_PRSP); 49 | hideColumn(FieldDSID::COL_PSDN); 50 | hideColumn(FieldDSID::COL_PRED); 51 | } 52 | } 53 | 54 | //****************************************************************************** 55 | /// Constructor: Create widgets and make connection to headerReader-thread 56 | /*! 57 | ***************************************************************************** */ 58 | CellHeaderDialog::CellHeaderDialog(QWidget * parent) : QDialog(parent), headerTableModel(0) 59 | { 60 | QVBoxLayout * mainLyt = new QVBoxLayout(this); 61 | QHBoxLayout * openLyt = new QHBoxLayout(this); 62 | mainLyt->addLayout(openLyt); 63 | 64 | fileNameEdt = new QLineEdit(this); 65 | QPushButton * openFileBtn = new QPushButton(tr("Open File"), this); 66 | QPushButton * openDirBtn = new QPushButton(tr("Open Dir"), this); 67 | openLyt->addWidget(new QLabel(tr("File Name"), this), 0); 68 | openLyt->addWidget(fileNameEdt, 1); 69 | openLyt->addWidget(openFileBtn, 0); 70 | openLyt->addWidget(openDirBtn, 0); 71 | 72 | headerDataTbl = new HeaderTableView(this); 73 | mainLyt->addWidget(headerDataTbl, 1000); 74 | 75 | QPushButton * allBtn = new QPushButton("Show All", this); 76 | allBtn->setCheckable(true); 77 | mainLyt->addWidget(allBtn, 0); 78 | 79 | headerTableModel = new HeaderTableModel(this); 80 | headerDataTbl->setModel(headerTableModel); 81 | 82 | QHBoxLayout * progLyt = new QHBoxLayout(this); 83 | mainLyt->addLayout(progLyt, 0); 84 | progBar = new QProgressBar(this); 85 | cancelBtn = new QPushButton(tr("Cancel"), this); 86 | progLyt->addWidget(progBar, 1); 87 | progLyt->addWidget(cancelBtn, 0); 88 | 89 | //**** inits **** 90 | headerDataTbl->showAllColumns(allBtn->isDown()); 91 | 92 | //**** connections **** 93 | connect(openFileBtn, SIGNAL(clicked()), this, SLOT(onOpenFiles())); 94 | connect(openDirBtn, SIGNAL(clicked()), this, SLOT(onOpenDir())); 95 | connect(cancelBtn, SIGNAL(clicked()), this, SLOT(onCancel())); 96 | 97 | connect(allBtn, SIGNAL(toggled(bool)), headerDataTbl, SLOT(showAllColumns(bool))); 98 | //** rem: the following connections carry data between different threads ** 99 | //connect(&crcCalculon, SIGNAL(checksum(int, unsigned int)), this, SLOT(onChecksum(int, unsigned int)), Qt::QueuedConnection); 100 | //connect(&crcCalculon, SIGNAL(checksumError(int, QString)), this, SLOT(onError(int, QString)), Qt::QueuedConnection); 101 | //connect(&crcCalculon, SIGNAL(finished()), this, SLOT(onCalcFinished())); 102 | } 103 | 104 | 105 | //****************************************************************************** 106 | /// Destructor - deletes the Dialog itself -> dont delete Dialog manually!! 107 | //***************************************************************************** */ 108 | CellHeaderDialog::~CellHeaderDialog() 109 | { 110 | delete headerTableModel; 111 | headerTableModel = NULL; 112 | if (!isModal()) this->deleteLater(); 113 | } 114 | 115 | //****************************************************************************** 116 | /// Get a directory to pares all included cells, including subdirs 117 | /*! 118 | * all Subdirs of "dir" are evaluated recursively ! 119 | ***************************************************************************** */ 120 | void CellHeaderDialog::onOpenDir() 121 | { 122 | QDir recentDir(fileNameEdt->text()); 123 | if (!recentDir.exists()) recentDir = QDir::home(); 124 | 125 | QString dir = QFileDialog::getExistingDirectory(this, tr("Select directory to parse all included cells"), recentDir.absolutePath(), QFileDialog::DontResolveSymlinks); 126 | if (dir.isEmpty()) return; 127 | 128 | fileNameEdt->setText(dir); 129 | 130 | //fehlt: cell-parsen 131 | } 132 | 133 | //****************************************************************************** 134 | /// Get filenames of cells to parse 135 | /*! 136 | ***************************************************************************** */ 137 | void CellHeaderDialog::onOpenFiles() 138 | { 139 | QDir recentDir(fileNameEdt->text()); 140 | if (!recentDir.exists()) recentDir = QDir::home(); 141 | QStringList files = QFileDialog::getOpenFileNames(this, tr("Select one or more cells to read"), recentDir.currentPath(), tr("All files (*);;S-57 Chart (*.000)")); 142 | if (files.isEmpty()) return; 143 | 144 | paresCells(files); 145 | } 146 | 147 | //****************************************************************************** 148 | /// Init the calculation of all CRCs in "files" 149 | /*! 150 | * before calculating, all Filenames are set to table - that can take much time :-( 151 | * The actual calculation is done by crcCalculon in a separate Thread 152 | ***************************************************************************** */ 153 | void CellHeaderDialog::paresCells(QStringList files) 154 | { 155 | if (files.count() == 0) return; 156 | else if (files.count() == 1) fileNameEdt->setText(files.first()); 157 | else 158 | { 159 | fileNameEdt->setText(QFileInfo(files.first()).absoluteDir().absolutePath()); 160 | } 161 | headerTableModel->init(files); 162 | } 163 | -------------------------------------------------------------------------------- /src/dictionaryS57.cpp: -------------------------------------------------------------------------------- 1 | #include "dictionaryS57.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | 8 | #include "cell_records.h" 9 | 10 | using namespace Enc; 11 | 12 | 13 | //***************************************************************************** 14 | /// Constructor initializes Attribute/Feature code/token values 15 | /*! 16 | * Default values are inside app 17 | *************************************************************************** */ 18 | ObjAttrDictionaryS57::ObjAttrDictionaryS57() 19 | { 20 | readAttributeCodes(":/resources/Attributes.S57.txt"); 21 | readFeatureCodes(":/resources/Features.S57.txt"); 22 | } 23 | 24 | //***************************************************************************** 25 | /// 26 | /*! 27 | * 28 | *************************************************************************** */ 29 | QString ObjAttrDictionaryS57::getFeatToken4Code(unsigned int code) const 30 | { 31 | std::map::const_iterator it = featureCode2Token.find(code); 32 | if (it != featureCode2Token.end()) return it->second; 33 | return QString::null; 34 | } 35 | 36 | QString ObjAttrDictionaryS57::getAttrToken4Code(unsigned int code) const 37 | { 38 | std::map::const_iterator it = attributeCode2Token.find(code); 39 | if (it != attributeCode2Token.end()) return it->second; 40 | return QString::null; 41 | } 42 | 43 | //***************************************************************************** 44 | /// Convenience Method to get DRVAL1 and DRVAL2 45 | /*! 46 | * returns true only if both values are correct 47 | *************************************************************************** */ 48 | bool ObjAttrDictionaryS57::getDRVAL12(double & drval1, double & drval2, const std::map & attrMap) 49 | { 50 | if (!getDoubleVal(drval1, attrMap, aCodeDRVAL1)) return false; 51 | if (!getDoubleVal(drval2, attrMap, aCodeDRVAL2)) return false; 52 | return true; 53 | } 54 | 55 | //***************************************************************************** 56 | /// Returns the value of a double-attribute 57 | /*! 58 | * returns false if attribute not found or conversion fails 59 | *************************************************************************** */ 60 | bool ObjAttrDictionaryS57::getDoubleVal(double & val, const std::map & attrMap, unsigned short key) 61 | { 62 | std::map::const_iterator vIt = attrMap.find(key); 63 | if (vIt == attrMap.end()) return false; 64 | bool valOk; 65 | val = vIt->second.getValue().toDouble(&valOk); 66 | return valOk; 67 | } 68 | 69 | bool ObjAttrDictionaryS57::getIntVal(int & val, const std::map & attrMap, unsigned short key) 70 | { 71 | std::map::const_iterator vIt = attrMap.find(key); 72 | if (vIt == attrMap.end()) return false; 73 | bool valOk; 74 | val = vIt->second.getValue().toInt(&valOk); 75 | return valOk; 76 | } 77 | 78 | //***************************************************************************** 79 | /// 80 | /*! 81 | * 82 | *************************************************************************** */ 83 | void ObjAttrDictionaryS57::readAttributeCodes(QString fileName) 84 | { 85 | QFile attrFile(fileName); 86 | if (!attrFile.open(QIODevice::ReadOnly | QIODevice::Text)) 87 | { 88 | throw "Cannot open Attribute Codes File: " +fileName; 89 | } 90 | QTextStream stream(&fileName); 91 | int missCnt =0; 92 | for (int lineNum =0;!stream.atEnd(); ++lineNum) 93 | { 94 | QString line = stream.readLine(32000).trimmed(); 95 | if (line.isEmpty() || line.at(0) == '#') continue; 96 | QStringList lineLst = line.split(','); 97 | if (lineLst.size() < 2) 98 | { 99 | ++missCnt; 100 | continue; //harmless Error: Token missing 101 | } 102 | bool intOk; 103 | unsigned int code = lineLst[0].toInt(&intOk); 104 | if (!intOk) 105 | { 106 | continue; 107 | } 108 | featureCode2Token[code] = lineLst[1].trimmed(); 109 | featureToken2Code[lineLst[1].trimmed()] = code; 110 | if (lineLst.size() >= 3) featureCode2Name[code] = lineLst[2].trimmed(); 111 | } 112 | attrFile.close(); 113 | } 114 | 115 | //***************************************************************************** 116 | /// 117 | /*! 118 | * 119 | *************************************************************************** */ 120 | void ObjAttrDictionaryS57::readFeatureCodes(QString fileName) 121 | { 122 | QFile featFile(fileName); 123 | if (!featFile.open(QIODevice::ReadOnly | QIODevice::Text)) 124 | { 125 | throw "Cannot open Attribute Codes File: " +fileName; 126 | } 127 | QTextStream stream(&fileName); 128 | int missCnt =0; 129 | for (int lineNum =0;!stream.atEnd(); ++lineNum) 130 | { 131 | QString line = stream.readLine(32000).trimmed(); 132 | if (line.isEmpty() || line.at(0) == '#') continue; 133 | QStringList lineLst = line.split(','); 134 | if (lineLst.size() < 2) 135 | { 136 | ++missCnt; 137 | continue; //harmless Error: Token missing 138 | } 139 | bool intOk; 140 | unsigned int code = lineLst[0].toInt(&intOk); 141 | if (!intOk) 142 | { 143 | continue; 144 | } 145 | attributeCode2Token[code] = lineLst[1].trimmed(); 146 | attributeToken2Code[lineLst[1].trimmed()] = code; 147 | if (lineLst.size() >= 3) attributeCode2Name[code] = lineLst[2].trimmed(); 148 | } 149 | featFile.close(); 150 | } 151 | -------------------------------------------------------------------------------- /src/exSetCheckS57.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include "exSetCheckS57.h" 10 | 11 | #include "catalog031reader.h" 12 | 13 | using namespace Enc; 14 | 15 | ExSetCheckS57::ExSetCheckS57() : checkEntries(NULL) 16 | { 17 | 18 | } 19 | 20 | ExSetCheckS57::~ExSetCheckS57() 21 | {} 22 | 23 | void ExSetCheckS57::init(QString catFileAndPath, std::vector * catEntries) 24 | { 25 | catFilePath = catFileAndPath; 26 | checkEntries = catEntries; 27 | checkErrors = CheckErrors(); 28 | } 29 | 30 | void ExSetCheckS57::checkAll() 31 | { 32 | //**** check parent-dir **** 33 | 34 | //**** check all entries **** 35 | std::vector::iterator entryIt; 36 | for (entryIt = checkEntries->begin(); entryIt != checkEntries->end(); ++entryIt) 37 | { 38 | checkEntry(*entryIt); 39 | 40 | } 41 | } 42 | 43 | void ExSetCheckS57::checkSome(std::set indices2check) 44 | { 45 | if (checkEntries== NULL || *indices2check.begin() < 0 || *indices2check.end() >= checkEntries->size()) 46 | { 47 | throw QString("INTERNAL ERROR: invalid indices while checking catalog records"); 48 | } 49 | //**################################################################################################################################# 50 | } 51 | 52 | void ExSetCheckS57::checkEntry(CatalogCheckEntry & entry2check) 53 | { 54 | //**** check if entry exists ***** 55 | //**################################################################################################################################# 56 | 57 | //**** check CRC **** 58 | //**################################################################################################################################# 59 | 60 | //**** check FileType **** 61 | //**################################################################################################################################# 62 | 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/exSetFilterWidget.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "catalog031reader.h" 15 | #include "exSetFilterWidget.h" 16 | #include "boundingbox_edit.h" 17 | 18 | using namespace Enc; 19 | 20 | //****************************************************************************** 21 | /// Check if filter Settings are logical equal 22 | /*! 23 | * if only the not-enabled settings are different, Settings are still treated as equal! 24 | ***************************************************************************** */ 25 | bool ExSetFilterSettings::operator==(const ExSetFilterSettings & filter2) const 26 | { 27 | const ExSetFilterSettings & filter1 = *this; 28 | if (filter1.genAct != filter2.genAct) return false; 29 | 30 | enum FileNameFilterType{NoFileFilter =0, FixedString=1, WildCard=2, RexExp=3}; 31 | if (filter1.fileNameFilter != filter2.fileNameFilter) return false; 32 | else if (filter1.fileNameFilter != NoFileFilter) 33 | { 34 | if (filter1.regExp != filter2.regExp) return false; 35 | } 36 | 37 | if (filter1.doFilterBBox != filter2.doFilterBBox) return false; 38 | else if (filter1.doFilterBBox) 39 | { 40 | if (filter1.bBox2filter != filter2.bBox2filter) return false; 41 | } 42 | if (filter1.inside != filter2.inside) return false; 43 | 44 | return true; 45 | } 46 | 47 | //****************************************************************************** 48 | /// Check if filter settings are usable for filtering 49 | //**************************************************************************** */ 50 | bool ExSetFilterSettings::filteringPossible(QString & usrMsg) const 51 | { 52 | if (fileNameFilter == NoFileFilter && !doFilterBBox) 53 | { 54 | usrMsg += QObject::tr("ERROR: Neither Filename Filter nor Bounding Box Filter enabled!"); 55 | return false; 56 | } 57 | if (fileNameFilter != NoFileFilter) 58 | { 59 | if (regExp.isEmpty()) 60 | { 61 | usrMsg += QObject::tr("ERROR: Empty Filter Expression for Filename!"); 62 | return false; 63 | } 64 | //check regExp syntay ????? 65 | } 66 | if (doFilterBBox && !bBox2filter.isValid()) 67 | { 68 | usrMsg += QObject::tr("ERROR: Bounding Box Filter enabled, but Bounding Box not valiD!"); 69 | return false; 70 | } 71 | return true; 72 | } 73 | 74 | //****************************************************************************** 75 | /// Construct a Widget where the user can select Filter Settings 76 | //****************************************************************************** 77 | ExSetFilterWidget::ExSetFilterWidget(QWidget * parent) : QWidget(parent) 78 | { 79 | QHBoxLayout * mainLyt = new QHBoxLayout(this); 80 | 81 | QFrame * settingsFrm = new QFrame(this); 82 | settingsFrm->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); 83 | mainLyt->addWidget(settingsFrm, 1); 84 | QVBoxLayout * filterItemsLyt = new QVBoxLayout(settingsFrm); 85 | QHBoxLayout * nameFilterLyt = new QHBoxLayout(); 86 | QHBoxLayout * bboxFilterLyt = new QHBoxLayout(); 87 | filterItemsLyt->addLayout(nameFilterLyt, 0); 88 | filterItemsLyt->addLayout(bboxFilterLyt, 0); 89 | 90 | //**** Checkboxes to enable items **** 91 | useFNameCBx = new QCheckBox(settingsFrm); 92 | useBBoxCBx = new QCheckBox(settingsFrm); 93 | 94 | //**** name Filter widgets **** 95 | QLabel * searchNameLbl = new QLabel(tr("Filename: "), settingsFrm); 96 | searchNameEdt = new QLineEdit(settingsFrm); 97 | nameFilterLyt->addWidget(useFNameCBx, 0); 98 | nameFilterLyt->addWidget(searchNameLbl, 0); 99 | nameFilterLyt->addWidget(searchNameEdt, 1); 100 | 101 | //**** bounding Box widgets **** 102 | QLabel * bBoxLbl = new QLabel(tr("Bounding Box: "), settingsFrm); 103 | searchBBoxEdt = new QLineEdit(settingsFrm); 104 | editBBoxBtn = new QPushButton("Edit", settingsFrm); 105 | editBBoxBtn->setFixedSize(editBBoxBtn->sizeHint()); 106 | bboxFilterLyt->addWidget(useBBoxCBx, 0); 107 | bboxFilterLyt->addWidget(bBoxLbl, 0); 108 | bboxFilterLyt->addWidget(searchBBoxEdt, 1); 109 | bboxFilterLyt->addWidget(editBBoxBtn, 0); 110 | 111 | //**** the "Start Filter" buttons **** 112 | QFrame * buttonsFrm = new QFrame(this); 113 | buttonsFrm->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); 114 | mainLyt->addWidget(buttonsFrm, 0); 115 | QVBoxLayout * btnLyt = new QVBoxLayout(buttonsFrm); 116 | findNextBtn = new QPushButton(tr("Find next"), buttonsFrm); 117 | filterAllBtn = new QPushButton(tr("Filter"), buttonsFrm); 118 | filterAllBtn->setCheckable(true); 119 | filterAllBtn->setChecked(false); 120 | 121 | btnLyt->addWidget(findNextBtn, 0); 122 | btnLyt->addWidget(filterAllBtn, 0); 123 | 124 | showAllBtn = new QPushButton(tr("Show\nAll"), this); 125 | showAllBtn->setCheckable(true); 126 | showAllBtn->setChecked(false); 127 | mainLyt->addWidget(showAllBtn, 0); 128 | 129 | connect(showAllBtn, SIGNAL(toggled(bool)), this, SIGNAL(showAllColumns(bool))); 130 | connect(filterAllBtn, SIGNAL(toggled(bool)), this, SLOT(onFilterAll(bool))); 131 | connect(findNextBtn, SIGNAL(clicked()), this, SLOT(onFindNext())); 132 | 133 | connect(useFNameCBx, SIGNAL(toggled(bool)), this, SLOT(onEnableFileFilter(bool))); 134 | connect(useBBoxCBx, SIGNAL(toggled(bool)), this, SLOT(onEnableBBoxFilter(bool))); 135 | 136 | connect(editBBoxBtn, SIGNAL(clicked()), this, SLOT(onEditBBox())); 137 | 138 | //** inits ** 139 | onEnableFileFilter(useFNameCBx->isDown()); 140 | onEnableBBoxFilter(useBBoxCBx->isDown()); 141 | 142 | //**** tooltips **** 143 | useFNameCBx->setToolTip(tr("Enable the File Name Filter")); 144 | useBBoxCBx->setToolTip(tr("Enable the Bounding Box Filter")); 145 | 146 | findNextBtn->setToolTip(tr("Find and Select next matching Record")); 147 | filterAllBtn->setToolTip(tr("Show only those Records that pass the Filter")); 148 | showAllBtn->setToolTip(tr("Show even unimportant Columns, which have no menaning for the Exchange Set")); 149 | } 150 | 151 | ExSetFilterWidget::~ExSetFilterWidget() 152 | {} 153 | 154 | //****************************************************************************** 155 | /// Slot Called if user wants to find next matching item 156 | /*! 157 | ***************************************************************************** */ 158 | void ExSetFilterWidget::onFindNext() 159 | { 160 | //**** Filtering AND finding makes no sense! **** 161 | if (filterAllBtn->isDown()) 162 | { 163 | filterAllBtn->setDown(false); 164 | emit unFilter(); 165 | } 166 | 167 | //**** get the Filter Settings, check them, and send filter-signal **** 168 | ExSetFilterSettings filterSettings = getFilterSettings(); 169 | filterSettings.genAct = ExSetFilterSettings::DoFind; 170 | 171 | QString usrMsg; 172 | bool filterOk = filterSettings.filteringPossible(usrMsg); 173 | if (!filterOk) 174 | { 175 | QMessageBox::warning(this, "ExSetCheck", usrMsg); 176 | return; 177 | } 178 | emit filter(filterSettings); 179 | } 180 | 181 | //****************************************************************************** 182 | /// Slot called if user wants to filter whole Exchange Set at once (or stop Filtering) 183 | /*! 184 | ***************************************************************************** */ 185 | void ExSetFilterWidget::onFilterAll(bool filterOn) 186 | { 187 | if (filterOn) 188 | { 189 | ExSetFilterSettings filterSettings = getFilterSettings(); 190 | filterSettings.genAct = ExSetFilterSettings::DoFilter; 191 | QString usrMsg; 192 | bool filterOk = filterSettings.filteringPossible(usrMsg); 193 | if (!filterOk) 194 | { 195 | QMessageBox::warning(this, "ExSetCheck", usrMsg); 196 | return; 197 | } 198 | 199 | emit filter(filterSettings); 200 | } 201 | else emit unFilter(); 202 | } 203 | 204 | //****************************************************************************** 205 | /// Parse all Widgets to get the selected Filter Settings 206 | //****************************************************************************** 207 | ExSetFilterSettings ExSetFilterWidget:: getFilterSettings() const 208 | { 209 | ExSetFilterSettings filterSettings; 210 | 211 | if (useFNameCBx->isDown()) filterSettings.fileNameFilter = ExSetFilterSettings::WildCard; 212 | filterSettings.regExp = searchNameEdt->text().simplified(); 213 | 214 | filterSettings.doFilterBBox = useBBoxCBx->isDown(); 215 | filterSettings.bBox2filter.fromString(searchBBoxEdt->text().simplified()); 216 | 217 | return filterSettings; 218 | } 219 | 220 | //****************************************************************************** 221 | /// Enable FileName Widgets only if Filename-Filtering is enabled 222 | //****************************************************************************** 223 | void ExSetFilterWidget::onEnableFileFilter(bool on) 224 | { 225 | searchNameEdt->setEnabled(on); 226 | } 227 | 228 | //****************************************************************************** 229 | /// Enable BoundingBox Widgets only if BoundingBox is enabled 230 | //****************************************************************************** 231 | void ExSetFilterWidget::onEnableBBoxFilter(bool on) 232 | { 233 | editBBoxBtn->setEnabled(on); 234 | searchBBoxEdt->setEnabled(on); 235 | } 236 | 237 | //****************************************************************************** 238 | /// Enable BoundingBox Widgets only if BoundingBox is enabled 239 | //****************************************************************************** 240 | void ExSetFilterWidget::onEditBBox() 241 | { 242 | DegBBox bBox(searchBBoxEdt->text()); 243 | BBoxEditDialog * bbDlg = new BBoxEditDialog(this, bBox); 244 | if (bbDlg->exec() == QDialog::Accepted) 245 | { 246 | searchBBoxEdt->setText(bbDlg->getBBox().toString()); 247 | } 248 | } -------------------------------------------------------------------------------- /src/geo_projections.cpp: -------------------------------------------------------------------------------- 1 | #include "geo_projections.h" 2 | #include "geo_spheroids.h" 3 | 4 | #include "GeographicLib/LocalCartesian.hpp" 5 | #include "GeographicLib/AzimuthalEquidistant.hpp" 6 | #include "GeographicLib/CassiniSoldner.hpp" 7 | #include "GeographicLib/Geocentric.hpp" 8 | #include "GeographicLib/LambertConformalConic.hpp" 9 | #include "GeographicLib/PolarStereographic.hpp" 10 | #include "GeographicLib/TransverseMercator.hpp" 11 | #include "GeographicLib/TransverseMercatorExact.hpp" 12 | #include "GeographicLib/UTMUPS.hpp" 13 | 14 | 15 | 16 | char * Enc::Projections [] ={ "No Projection", 17 | "Plattkarte", 18 | "Azimuthal Equidistant", 19 | "Cassini Soldner", 20 | "Lambert Conformal Conic", 21 | "Polar Stereographic", 22 | "Mercator", 23 | "Transverse Mercator", 24 | "Transverse Mercator Exact", 25 | "UTM"}; 26 | int Enc::ProjectionCount = 10; 27 | 28 | //Enc::projectionList << "No Projection" << "Plattkarte"; 29 | using namespace Enc; 30 | 31 | Projection * Projection::getProjection(int projectionId, double centerLat, double centerLon) 32 | { 33 | Projection * prjctn = 0; 34 | if (projectionId == Platt) prjctn = new Plattkarte(); 35 | else if (projectionId == AziEquiDist) prjctn = new AzimuthalEquidistant(centerLat, centerLon); 36 | else if (projectionId == CassiSold) prjctn = new CassiniSoldner(centerLat, centerLon); 37 | else if (projectionId == LambConfCon) prjctn = new LambertConformalConic(centerLat, centerLat, centerLon); 38 | else if (projectionId == PolarStereo) prjctn = new PolarStereographic(); 39 | else if (projectionId == NormalMercator)prjctn = new Mercator(); 40 | else if (projectionId == TMercator) prjctn = new TransverseMercator(centerLon); 41 | else if (projectionId == TMercatorExact)prjctn = new TransverseMercatorExact(centerLon); 42 | else if (projectionId == UTMercator) prjctn = new UTM(centerLat, centerLon); 43 | return prjctn; 44 | } 45 | 46 | //***************************************************************************** 47 | /// 48 | /*! 49 | ****************************************************************************** */ 50 | Plattkarte::Plattkarte(double lat0, double lon0) 51 | { 52 | localCartesian = new GeographicLib::LocalCartesian(lat0, lon0); 53 | } 54 | Plattkarte::~Plattkarte() 55 | { 56 | delete localCartesian; 57 | } 58 | void Plattkarte::latLon2xy(double lat, double lon, double & x, double & y) const 59 | { 60 | double dummyH =0, dummyZ =0; 61 | localCartesian->Forward(lat, lon, dummyH,x, y, dummyZ); 62 | } 63 | 64 | void Plattkarte::xy2LatLon(double x, double y, double & lat, double & lon) const 65 | { 66 | double dummyH =0, dummyZ =0; 67 | localCartesian->Reverse(x, y, dummyZ, lat, lon, dummyH); 68 | } 69 | 70 | //***************************************************************************** 71 | /// 72 | /*! 73 | ****************************************************************************** */ 74 | Mercator::Mercator() 75 | { 76 | 77 | } 78 | 79 | void Mercator::latLon2xy(double lat, double lon, double & x, double & y) const 80 | { 81 | 82 | } 83 | void Mercator::xy2LatLon(double x, double y, double & lat, double & lon) const 84 | { 85 | 86 | } 87 | 88 | //***************************************************************************** 89 | /// 90 | /*! 91 | ****************************************************************************** */ 92 | AzimuthalEquidistant::AzimuthalEquidistant(double _lat0, double _lon0) : lat0(_lat0), lon0(_lon0) 93 | { 94 | azimuthalEquidistant = new GeographicLib::AzimuthalEquidistant; 95 | } 96 | AzimuthalEquidistant::~AzimuthalEquidistant() 97 | { 98 | delete azimuthalEquidistant; 99 | } 100 | void AzimuthalEquidistant::latLon2xy(double lat, double lon, double & x, double & y) const 101 | { 102 | double azi, rk; 103 | azimuthalEquidistant->Forward(lat0, lon0, lat, lon, x, y, azi, rk); 104 | } 105 | void AzimuthalEquidistant::xy2LatLon(double x, double y, double & lat, double & lon) const 106 | { 107 | double azi, rk; 108 | azimuthalEquidistant->Reverse(lat0, lon0, x, y, lat, lon, azi, rk); 109 | } 110 | 111 | //***************************************************************************** 112 | /// 113 | /*! 114 | ****************************************************************************** */ 115 | CassiniSoldner::CassiniSoldner(double lat0, double lon0) 116 | { 117 | cassiniSoldner = new GeographicLib::CassiniSoldner(lat0, lon0); 118 | } 119 | 120 | CassiniSoldner::~CassiniSoldner() 121 | { 122 | delete cassiniSoldner; 123 | } 124 | void CassiniSoldner::latLon2xy(double lat, double lon, double & x, double & y) const 125 | { 126 | double azi, rk; 127 | cassiniSoldner->Forward(lat, lon, x, y, azi, rk); 128 | } 129 | void CassiniSoldner::xy2LatLon(double x, double y, double & lat, double & lon) const 130 | { 131 | double azi, rk; 132 | cassiniSoldner->Reverse(x, y, lat, lon, azi, rk); 133 | } 134 | 135 | //***************************************************************************** 136 | /// 137 | /*! 138 | ****************************************************************************** */ 139 | LambertConformalConic::LambertConformalConic(double stdlat1, double stdlat2, double _lon0, double k1) : lon0(_lon0) 140 | { 141 | lambertConformalConic = new GeographicLib::LambertConformalConic(WGS84::MajorAxis, WGS84::InversFlat, stdlat1, stdlat2, k1); 142 | } 143 | 144 | LambertConformalConic::~LambertConformalConic() 145 | { 146 | delete lambertConformalConic; 147 | } 148 | 149 | void LambertConformalConic::latLon2xy(double lat, double lon, double & x, double & y) const 150 | { 151 | double gamma =0, k =0; 152 | lambertConformalConic->Forward(lon0, lat, lon, x, y, gamma, k); 153 | } 154 | 155 | void LambertConformalConic::xy2LatLon(double x, double y, double & lat, double & lon) const 156 | { 157 | double gamma =0, k =0; 158 | lambertConformalConic->Reverse(lon0, x, y, lat, lon, gamma, k); 159 | } 160 | 161 | //***************************************************************************** 162 | /// 163 | /*! 164 | ****************************************************************************** */ 165 | PolarStereographic::PolarStereographic() 166 | { 167 | polarStereo = new GeographicLib::PolarStereographic(WGS84::MajorAxis, WGS84::InversFlat, 1); 168 | 169 | } 170 | 171 | PolarStereographic::~PolarStereographic() 172 | { 173 | delete polarStereo; 174 | } 175 | 176 | void PolarStereographic::latLon2xy(double lat, double lon, double & x, double & y) const 177 | { 178 | double gamma, k; 179 | polarStereo->Forward(true, lat, lon, x, y, gamma, k); 180 | } 181 | 182 | void PolarStereographic::xy2LatLon(double x, double y, double & lat, double & lon) const 183 | { 184 | double gamma, k; 185 | polarStereo->Reverse(true, x, y, lat, lon, gamma, k); 186 | } 187 | 188 | //***************************************************************************** 189 | /// 190 | /*! 191 | ****************************************************************************** */ 192 | TransverseMercator::TransverseMercator(double _lon0, double k0) : lon0(_lon0) 193 | { 194 | transversMercator = new GeographicLib::TransverseMercator(WGS84::MajorAxis, WGS84::InversFlat, k0); 195 | } 196 | TransverseMercator::~TransverseMercator() 197 | { 198 | delete transversMercator; 199 | } 200 | 201 | void TransverseMercator::latLon2xy(double lat, double lon, double & x, double & y) const 202 | { 203 | double gamma=0, k=0; 204 | transversMercator->Forward(lon0, lat, lon, x, y, gamma, k); 205 | } 206 | 207 | void TransverseMercator::xy2LatLon(double x, double y, double & lat, double & lon) const 208 | { 209 | double gamma=0, k=0; 210 | transversMercator->Reverse(lon0, x, y, lat, lon, gamma, k); 211 | } 212 | //***************************************************************************** 213 | /// 214 | /*! 215 | ****************************************************************************** */ 216 | TransverseMercatorExact::TransverseMercatorExact(double _lon0, double k0) : lon0(_lon0) 217 | { 218 | transverseMercatorExact = new GeographicLib::TransverseMercatorExact(WGS84::MajorAxis, WGS84::InversFlat, k0); 219 | } 220 | 221 | TransverseMercatorExact::~TransverseMercatorExact() 222 | { 223 | delete transverseMercatorExact; 224 | } 225 | 226 | void TransverseMercatorExact::latLon2xy(double lat, double lon, double & x, double & y) const 227 | { 228 | double gamma=0, k=0; 229 | transverseMercatorExact->Forward(lon0, lat, lon, x, y, gamma, k); 230 | } 231 | 232 | void TransverseMercatorExact::xy2LatLon(double x, double y, double & lat, double & lon) const 233 | { 234 | double gamma=0, k=0; 235 | transverseMercatorExact->Reverse(lon0, x, y, lat, lon, gamma, k); 236 | } 237 | 238 | //***************************************************************************** 239 | /// 240 | /*! 241 | ****************************************************************************** */ 242 | UTM::UTM(double centerLat, double centerLon) 243 | { 244 | zone = GeographicLib::UTMUPS::StandardZone(centerLat,centerLon); 245 | } 246 | 247 | UTM::~UTM() 248 | {} 249 | 250 | void UTM::latLon2xy(double lat, double lon, double & x, double & y) const 251 | { 252 | double gamma, k; 253 | bool northp; 254 | int currentZone; 255 | GeographicLib::UTMUPS::Forward(lat, lon, currentZone, northp, x, y, gamma, k); 256 | if (currentZone != zone) 257 | { 258 | //correct x (easting) 259 | } 260 | } 261 | 262 | void UTM::xy2LatLon(double x, double y, double & lat, double & lon) const 263 | { 264 | //** check if x > zone limits ** 265 | int currentZone = zone; 266 | if (fabs(x) > 180000) 267 | { 268 | //correct zone ?? 269 | } 270 | 271 | double gamma, k; 272 | GeographicLib::UTMUPS::Reverse(currentZone, true, x, y, lat, lon, gamma, k); 273 | } 274 | 275 | -------------------------------------------------------------------------------- /src/helper.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | //** Copyright (C) 2010 Kai R. Neufeldt, Ahrensburg, Germany 3 | //** This file is part of the ENClib 4 | //** The ENC lib may be used unter the GPL General Public License Version 2 5 | //** or with a Commercial License granted by Kai R. Neufeldt 6 | //** contact Kai R. Neufeldt, Manhagener Allee 65, 22926 Ahrensburg, Germany 7 | //***************************************************************************** 8 | 9 | #include "helper.h" 10 | 11 | using namespace Enc; 12 | 13 | //****************************************************************************** 14 | /// Write absolute filenames into a StringList, and go recursive into subdirectories, too 15 | /*! 16 | ***************************************************************************** */ 17 | void Helper::absFileNames2List(QStringList filesAndDirs, QStringList & nameList) 18 | { 19 | QStringList::iterator fit = filesAndDirs.begin(); 20 | for (; fit != filesAndDirs.end(); ++fit) 21 | { 22 | if (QFileInfo(*fit).isDir()) 23 | { 24 | if ((*fit).isEmpty() || *fit == "." || *fit == "..") continue; 25 | QDir subDir(*fit); 26 | QStringList entryList = subDir.entryList(); 27 | for (QStringList::iterator eit = entryList.begin(); eit != entryList.end(); ++eit) 28 | { 29 | if ((*eit).isEmpty() || *eit == "." || *eit == "..") continue; 30 | 31 | *eit = subDir.absoluteFilePath(*eit); //turn every entry into an absolut path 32 | QString c2 = (*eit); 33 | } 34 | absFileNames2List(entryList, nameList); 35 | } 36 | else 37 | { 38 | nameList.append(*fit); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/naviNaviWidgets.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KaiAbuSir/EncLib/ba8547abe7f2fa02132076227fe4b93b37f3de0c/src/naviNaviWidgets.cpp -------------------------------------------------------------------------------- /src/naviScene.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KaiAbuSir/EncLib/ba8547abe7f2fa02132076227fe4b93b37f3de0c/src/naviScene.cpp -------------------------------------------------------------------------------- /src/naviSceneItems.cpp: -------------------------------------------------------------------------------- 1 | #include "naviSceneItems.h" 2 | 3 | using namespace Enc; 4 | 5 | GraphicsAreaFeatItem::GraphicsAreaFeatItem(unsigned long rcid, QGraphicsItem * parent) : QGraphicsPathItem(parent), depareRcid(rcid) 6 | {} 7 | 8 | GraphicsAreaFeatItem::GraphicsAreaFeatItem(unsigned long rcid, const QPainterPath & path, const QPen & p, const QBrush & b, QGraphicsItem * parent) 9 | : QGraphicsPathItem(path, parent), depareRcid(rcid) 10 | { 11 | setPen(p); 12 | setBrush(b); 13 | } 14 | 15 | GraphicsDepareItem::GraphicsDepareItem(unsigned long rcid, const QPainterPath & path, const QPen & p, const QBrush & b, QGraphicsItem * parent) 16 | : GraphicsAreaFeatItem(rcid, path, p, b, parent) 17 | {} -------------------------------------------------------------------------------- /src/naviView.cpp: -------------------------------------------------------------------------------- 1 | #include "naviView.h" 2 | #include "naviNaviWidgets.h" 3 | 4 | #include 5 | 6 | #include "geo_projections.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace Enc; 14 | 15 | NaviView::NaviView(QWidget * parent) : QGraphicsView(parent), myAngleZ(0), myScale(1) 16 | { 17 | //addNaviWidgets(); 18 | } 19 | 20 | NaviView::NaviView(QGraphicsScene * scene, QWidget * parent): QGraphicsView(scene, parent), myAngleZ(0), myScale(1) 21 | { 22 | 23 | } 24 | 25 | void NaviView::showContent(QRectF contentRect) 26 | { 27 | setSceneRect(contentRect); 28 | update(); 29 | } 30 | 31 | //***************************************************************************** 32 | /// Draw Navigation Widgets onto the chart - optional 33 | /*! 34 | * Signals are connected, too 35 | ****************************************************************************** */ 36 | void NaviView::addNaviWidgets() 37 | { 38 | QHBoxLayout * mainLyt = new QHBoxLayout(viewport()); 39 | QVBoxLayout * leftLyt = new QVBoxLayout(); 40 | QVBoxLayout * rigthLyt = new QVBoxLayout(); 41 | 42 | mainLyt->addLayout(leftLyt); 43 | mainLyt->addStretch(); 44 | mainLyt->addLayout(rigthLyt); 45 | 46 | projectWgt = new ChartProjectionComboBox(this); 47 | scaleWgt = new ChartScaleWidget(this); 48 | headWgt = new ChartRotationWidget(this); 49 | posWgt = new ChartPositionWidget(this); 50 | xyWgt = new ChartEastNorthWidget(this); 51 | 52 | rigthLyt->addWidget(projectWgt); 53 | rigthLyt->addWidget(scaleWgt); 54 | rigthLyt->addWidget(headWgt); 55 | rigthLyt->addWidget(posWgt); 56 | rigthLyt->addWidget(xyWgt); 57 | 58 | rigthLyt->addStretch(1000); 59 | 60 | //**** inits **** 61 | initProjections(); 62 | 63 | connect(projectWgt, SIGNAL(currentIndexChanged(int)), this, SIGNAL(projectionChanged(int))); 64 | connect(scaleWgt, SIGNAL(zoonIn()), this, SLOT(zoomIn())); 65 | connect(scaleWgt, SIGNAL(zoomOut()), this, SLOT(zoomOut())); 66 | 67 | 68 | connect(this, SIGNAL(scaleChanged(double)), scaleWgt, SLOT(setScale(double))); 69 | connect(this, SIGNAL(headingChanged(double)), headWgt, SLOT(setHeading(double))); 70 | } 71 | 72 | void NaviView::initProjections() 73 | { 74 | for (int prI=0; prI < ProjectionCount; ++prI) projectWgt->addItem(Projections[prI]); 75 | } 76 | 77 | /// Zoom in by 2.0 78 | void NaviView::zoomIn() 79 | { 80 | myScale = myScale *2.0; 81 | updateTransform(); 82 | emit scaleChanged(myScale); 83 | } 84 | 85 | /// Zoom Out by 0.5 86 | void NaviView::zoomOut() 87 | { 88 | myScale = myScale *0.5; 89 | updateTransform(); 90 | emit scaleChanged(myScale); 91 | } 92 | 93 | /// Set Scale if scale is really different 94 | void NaviView::setScale(double newScale) 95 | { 96 | if (fabs(myScale - newScale) < 0.5) return; 97 | myScale = newScale; 98 | updateTransform(); 99 | emit scaleChanged(myScale); 100 | } 101 | 102 | //***************************************************************************** 103 | /// Appy new chart heading to the view 104 | /*! 105 | * Rem: compass heading has to be transformed into mathematical rotation 106 | ****************************************************************************** */ 107 | void NaviView::setChartHeading(double newHeading) 108 | { 109 | double newAngleZ = 90.0 - newHeading; //mathematical angle 110 | if (fabs(newAngleZ - myAngleZ) < 0.1) return; 111 | 112 | myAngleZ = newAngleZ; 113 | updateTransform(); 114 | emit headingChanged(90.0 - myAngleZ); 115 | } 116 | 117 | //***************************************************************************** 118 | /// Appy the current transformation to the view 119 | /*! 120 | * Signals about scale/rotation/translation are NOT emitted - caller must do that! 121 | ****************************************************************************** */ 122 | void NaviView::updateTransform() 123 | { 124 | QTransform trans; 125 | trans.rotate(myAngleZ ,Qt::ZAxis); 126 | trans.scale(myScale, myScale); 127 | trans.translate(transform().dx(), transform().dy()); 128 | setTransform(trans); 129 | } 130 | -------------------------------------------------------------------------------- /src/naviWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "naviWidget.h" 2 | 3 | #include "naviScene.h" 4 | #include "naviView.h" 5 | 6 | #include 7 | 8 | using namespace Enc; 9 | 10 | NaviWidget::NaviWidget(QWidget * parent) : QWidget(parent) 11 | { 12 | naviScene = new NaviScene(this); 13 | naviView = new NaviView(naviScene); 14 | 15 | QHBoxLayout * lyt = new QHBoxLayout(this); 16 | lyt->addWidget(naviView); 17 | 18 | connect(naviView, SIGNAL(projectionChanged(int)), this, SLOT(onProjectionChanged(int))); 19 | 20 | connect(naviView, SIGNAL(scaleChanged(double)), this, SIGNAL(scaleChanged(double))); 21 | connect(naviView, SIGNAL(headingChanged(double)), this, SIGNAL(headingChanged(double))); 22 | 23 | connect(naviScene, SIGNAL(contentChanged(QRectF)), naviView, SLOT(showContent(QRectF))); 24 | connect(naviScene, SIGNAL(progressMessage(const QString &)), this, SIGNAL(progressMessage(const QString &))); 25 | } 26 | 27 | void NaviWidget::loadCharts(QStringList filenames) 28 | { 29 | naviScene->loadCharts(filenames); //will redraw cells, too 30 | } 31 | 32 | void NaviWidget::onProjectionChanged(int prjktIt) 33 | { 34 | naviScene->setProjection(prjktIt); 35 | naviScene->onDrawCells(); //kai - mal gucken , ob man view noch benachrichtigen muss 36 | } 37 | -------------------------------------------------------------------------------- /src/presentationS52.cpp: -------------------------------------------------------------------------------- 1 | #include "presentationS52.h" 2 | #include "dictionaryS57.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | 9 | #include "cell_records.h" 10 | 11 | using namespace Enc; 12 | 13 | //***************************************************************************** 14 | /// Dictionary - just a dummy, will become a real dict later 15 | /*! 16 | * 17 | *************************************************************************** */ 18 | PresentationS52::PresentationS52() : cnt(0), deep(20), shallow(3), veryShallow(1) 19 | { 20 | //** Default Brushes for Group1 Objects ** 21 | interTidalBrush = QBrush(QColor(139,226,179, 200)); //kais hellgruen, nur zum testen 22 | depareVeryShallowBrush = QBrush(QColor(196,247,236, 200));//kais ganz hell blau, nur zum testen 23 | depareShallowBrush = QBrush(QColor(187,241,251, 200)); //kais hell blau, nur zum testen 24 | depareMediumBrush = QBrush(QColor(27,137,217, 200)); //kais mittelblau, nur zum testen 25 | depareDeepBrush = QBrush(QColor(18,47,146, 200)); //kais dunkelblau, nur zum testen 26 | 27 | LNDAREbrush = QBrush(QColor(231,164,24, 200)); //kais braun, nur zum testen 28 | FLODOCbrush = QBrush(QColor(231,164,24, 200)); //kais braun, nur zum testen 29 | HULKESbrush = QBrush(QColor(231,164,24, 200)); //kais braun, nur zum testen 30 | PONTONbrush = QBrush(QColor(231,164,24, 200)); //kais braun, nur zum testen 31 | UNSAREbrush = QBrush(QColor(205,254,254, 200)); //kais hellblau, nur zum testen 32 | 33 | 34 | 35 | //**** just used 4 debug **** 36 | colorVecDebug.push_back((QColor(0,0,0))); 37 | colorVecDebug.push_back((QColor(125,0,0))); 38 | colorVecDebug.push_back((QColor(250,0,0))); 39 | colorVecDebug.push_back((QColor(0,125,0))); 40 | colorVecDebug.push_back((QColor(0,250,0))); 41 | colorVecDebug.push_back((QColor(0,0,125))); 42 | colorVecDebug.push_back((QColor(0,0,250))); 43 | colorVecDebug.push_back((QColor(20,50,100))); 44 | colorVecDebug.push_back((QColor(100,50,20))); 45 | colorVecDebug.push_back((QColor(50,100,20))); 46 | colorVecDebug.push_back((QColor(20,100,50))); 47 | colorVecDebug.push_back((QColor(50,20,100))); 48 | colorVecDebug.push_back((QColor(100,20,50))); 49 | } 50 | 51 | void PresentationS52::setDeepShallow(double dp, double shlw, double vShlw) 52 | { 53 | deep = dp; shallow = shlw; veryShallow = vShlw; 54 | 55 | if (veryShallow > shallow) veryShallow = shallow; 56 | if (deep < shallow) deep = shallow; 57 | } 58 | 59 | //***************************************************************************** 60 | /// Return the pen to draw a line-geometry item 61 | /*! 62 | * 63 | *************************************************************************** */ 64 | QPen PresentationS52::getPen(const FeatureS57 * feat) const 65 | { 66 | if (!feat) throw "Internal Error: No Feature Pointer"; 67 | QPen myPen; 68 | myPen.setCosmetic(true); 69 | 70 | //kai: just for debug, code not yet ready 71 | ++cnt; //++ *(const_cast(&cnt)); //rem: we are const 72 | myPen.setColor(colorVecDebug[cnt % 13]); //kai: just for debug 73 | 74 | 75 | return myPen; 76 | } 77 | 78 | //***************************************************************************** 79 | /// Return the Brush to fill the shape of a area-geometry item 80 | /*! 81 | * 82 | *************************************************************************** */ 83 | QBrush PresentationS52::getBrush(const FeatureS57 * feat) const 84 | { 85 | //**** if no area-feat -> no brush needed **** 86 | if (feat->getFRID().getPRIM() != 3) return QBrush(); 87 | 88 | const unsigned short objCode = feat->getFRID().getOBJL(); 89 | 90 | //**** Group 1 feature **** 91 | if ( ObjAttrDictionaryS57::IsGroup1(objCode)) 92 | { 93 | 94 | if (objCode == ObjAttrDictionaryS57::codeDEPARE || objCode == ObjAttrDictionaryS57::codeDRGARE) 95 | { 96 | QBrush depareBrush; 97 | const std::map & featAttribs = feat->getAttribs(); 98 | double drval1, drval2; 99 | if(ObjAttrDictionaryS57::getDRVAL12(drval1, drval2, featAttribs)) 100 | { 101 | if (drval1 < 0 || drval2 < 0) depareBrush = interTidalBrush; 102 | if (drval1 > deep) depareBrush = depareDeepBrush; 103 | if (drval2 < veryShallow) depareBrush = depareVeryShallowBrush; 104 | if (drval2 < shallow) depareBrush = depareShallowBrush; 105 | depareBrush = depareMediumBrush; 106 | } 107 | if (objCode == ObjAttrDictionaryS57::codeDRGARE) 108 | { 109 | depareBrush.setStyle(Qt::Dense1Pattern); 110 | } 111 | return depareBrush; 112 | } 113 | else if (objCode == ObjAttrDictionaryS57::codeUNSARE) 114 | { 115 | return UNSAREbrush; 116 | } 117 | else if (objCode == ObjAttrDictionaryS57::codeFLODOC) 118 | { 119 | return FLODOCbrush; 120 | } 121 | else if (objCode == ObjAttrDictionaryS57::codeHULKES) 122 | { 123 | return HULKESbrush; 124 | } 125 | else if (objCode == ObjAttrDictionaryS57::codeLNDARE) 126 | { 127 | return LNDAREbrush; 128 | } 129 | else if (objCode == ObjAttrDictionaryS57::codePONTON) 130 | { 131 | return PONTONbrush; 132 | } 133 | } 134 | 135 | //**** Group 2 feature **** 136 | else 137 | { 138 | QBrush featBrush(Qt::SolidPattern); //rem: default brush is NO-Brush! 139 | QColor featColor; 140 | //** Coverage object: no brush if there is coverage ** 141 | if (objCode == ObjAttrDictionaryS57::codeM_COVR) 142 | { 143 | int catCov; 144 | if (ObjAttrDictionaryS57::getIntVal(catCov, feat->getAttribs(), ObjAttrDictionaryS57::aCodeCATCOV) && catCov == 2) //no coverage 145 | { 146 | featColor = QColor(244,244,244); 147 | } 148 | else //coverage 149 | { 150 | return QBrush(); 151 | } 152 | } 153 | //** Feature Objects not yet handled -> use fantasy color ** 154 | else 155 | { 156 | featColor = colorVecDebug[cnt % 13]; // for debug only: default fantasy color for Objects not yet in pres-lib: ** 157 | } 158 | featColor.setAlpha(70); //kai: test: Group2 tranparent ?? 159 | featBrush.setColor(featColor); 160 | return featBrush; 161 | } 162 | return QBrush(); 163 | } 164 | 165 | //***************************************************************************** 166 | /// Get the Drawing Priority of a feature 167 | /*! 168 | * Objects with higher values will be drawn onto objects with lower value 169 | *************************************************************************** */ 170 | double PresentationS52::getPriority(const FeatureS57 * feat) const 171 | { 172 | if (feat->getFRID().getPRIM() == 1) //Point 173 | { 174 | return 250; //Kai: here we should distinct between more and less important objects 175 | } 176 | else if (feat->getFRID().getPRIM() == 2) return 200; //Line 177 | else if (feat->getFRID().getPRIM() == 3) //area 178 | { 179 | if (ObjAttrDictionaryS57::IsGroup1(feat->getFRID().getOBJL())) return 0; 180 | else 181 | { 182 | return 100; 183 | } 184 | } 185 | 186 | return 0; //or should we throw someting?? 187 | } 188 | --------------------------------------------------------------------------------