1 /**************************************************************************
2 *
3 * Project:  ChartManager
4 * Purpose:  Basic Chart Info Storage
5 * Author:   David S Register, Mark A Sikes
6 *
7 ***************************************************************************
8 *   Copyright (C) 2010 by David S. Register *
9 *                                                                         *
10 *   This program is free software; you can redistribute it and/or modify  *
11 *   it under the terms of the GNU General Public License as published by  *
12 *   the Free Software Foundation; either version 2 of the License, or     *
13 *   (at your option) any later version.                                   *
14 *                                                                         *
15 *   This program is distributed in the hope that it will be useful,       *
16 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18 *   GNU General Public License for more details.                          *
19 *                                                                         *
20 *   You should have received a copy of the GNU General Public License     *
21 *   along with this program; if not, write to the                         *
22 *   Free Software Foundation, Inc.,                                       *
23 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA.         *
24 **************************************************************************/
25 
26 #ifndef __CHARTDBS_H__
27 #define __CHARTDBS_H__
28 
29 #include <map>
30 #include <memory>
31 #include <vector>
32 
33 #include "ocpn_types.h"
34 #include "bbox.h"
35 #include "LLRegion.h"
36 
37 class wxGenericProgressDialog;
38 class ChartBase;
39 
40 //    A small class used in an array to describe chart directories
41 class ChartDirInfo
42 {
43 public:
44     wxString    fullpath;
45     wxString    magic_number;
46 };
47 
48 WX_DECLARE_OBJARRAY(ChartDirInfo, ArrayOfCDI);
49 
50 ///////////////////////////////////////////////////////////////////////
51 
52 static const int DB_VERSION_PREVIOUS = 17;
53 static const int DB_VERSION_CURRENT = 18;
54 
55 class ChartDatabase;
56 class ChartGroupArray;
57 
58 struct ChartTableEntry_onDisk_18
59 {
60     int         EntryOffset;
61     int         ChartType;
62     int         ChartFamily;
63     float       LatMax;
64     float       LatMin;
65     float       LonMax;
66     float       LonMin;
67 
68     int         Scale;
69     int         edition_date;
70     int         file_date;
71 
72     int         nPlyEntries;
73     int         nAuxPlyEntries;
74 
75     float       skew;
76     int         ProjectionType;
77     bool        bValid;
78 
79     int         nNoCovrPlyEntries;
80 };
81 
82 
83 struct ChartTableEntry_onDisk_17
84 {
85     int         EntryOffset;
86     int         ChartType;
87     float       LatMax;
88     float       LatMin;
89     float       LonMax;
90     float       LonMin;
91 
92     int         Scale;
93     int         edition_date;
94     int         file_date;
95 
96     int         nPlyEntries;
97     int         nAuxPlyEntries;
98 
99     float       skew;
100     int         ProjectionType;
101     bool        bValid;
102 
103     int         nNoCovrPlyEntries;
104 };
105 
106 
107 struct ChartTableEntry_onDisk_16
108 {
109       int         EntryOffset;
110       int         ChartType;
111       float       LatMax;
112       float       LatMin;
113       float       LonMax;
114       float       LonMin;
115 
116       int         Scale;
117       int         edition_date;
118       int         file_date;
119 
120       int         nPlyEntries;
121       int         nAuxPlyEntries;
122 
123       float       skew;
124       int         ProjectionType;
125       bool        bValid;
126 };
127 
128 
129 struct ChartTableEntry_onDisk_15
130 {
131     int         EntryOffset;
132     int         ChartType;
133     float       LatMax;
134     float       LatMin;
135     float       LonMax;
136     float       LonMin;
137 
138     int         Scale;
139     time_t      edition_date;
140     time_t      file_date;
141 
142     int         nPlyEntries;
143     int         nAuxPlyEntries;
144 
145     bool        bValid;
146 };
147 
148 struct ChartTableEntry_onDisk_14
149 {
150     int         EntryOffset;
151     int         ChartType;
152     char        ChartID[16];
153     float       LatMax;
154     float       LatMin;
155     float       LonMax;
156     float       LonMin;
157     char        *pFullPath;
158     int         Scale;
159     time_t      edition_date;
160     float       *pPlyTable;
161     int         nPlyEntries;
162     int         nAuxPlyEntries;
163     float       **pAuxPlyTable;
164     int         *pAuxCntTable;
165     bool        bValid;
166 };
167 
168 struct ChartTableHeader
169 {
ChartTableHeaderChartTableHeader170     ChartTableHeader() {}
ChartTableHeaderChartTableHeader171     ChartTableHeader(int dirEntries, int tableEntries) :
172                 nTableEntries(tableEntries), nDirEntries(dirEntries) {}
173 
174     void Read(wxInputStream &is);
175     void Write(wxOutputStream &os);
176     bool CheckValid();
GetDirEntriesChartTableHeader177     int GetDirEntries() const { return nDirEntries; }
GetTableEntriesChartTableHeader178     int GetTableEntries() const { return nTableEntries; }
GetDBVersionStringChartTableHeader179     char *GetDBVersionString(){ return dbVersion; }
180 
181 private:
182     // NOTE: on-disk structure - cannot add, remove, or reorder!
183     char dbVersion[4];
184     int nTableEntries;
185     int nDirEntries;
186 };
187 
188 struct ChartTableEntry
189 {
ChartTableEntryChartTableEntry190     ChartTableEntry() { Clear(); }
191     ChartTableEntry(ChartBase &theChart, wxString& utf8Path);
192     ~ChartTableEntry();
193 
194     bool IsEqualTo(const ChartTableEntry &cte) const;
195     bool IsEarlierThan(const ChartTableEntry &cte) const;
196     bool Read(const ChartDatabase *pDb, wxInputStream &is);
197     bool Write(const ChartDatabase *pDb, wxOutputStream &os);
198     void Clear();
199     void Disable();
200     void ReEnable();
201 
SetValidChartTableEntry202     void SetValid(bool valid) { bValid = valid; }
GetFileTimeChartTableEntry203     time_t GetFileTime() const { return file_date; }
204 
GetnPlyEntriesChartTableEntry205     int GetnPlyEntries() const { return nPlyEntries; }
GetpPlyTableChartTableEntry206     float *GetpPlyTable() const { return pPlyTable; }
207 
GetnAuxPlyEntriesChartTableEntry208     int GetnAuxPlyEntries() const { return nAuxPlyEntries; }
GetpAuxPlyTableEntryChartTableEntry209     float *GetpAuxPlyTableEntry(int index) const { return pAuxPlyTable[index];}
GetAuxCntTableEntryChartTableEntry210     int GetAuxCntTableEntry(int index) const { return pAuxCntTable[index];}
211 
GetnNoCovrPlyEntriesChartTableEntry212     int GetnNoCovrPlyEntries() const { return nNoCovrPlyEntries; }
GetpNoCovrPlyTableEntryChartTableEntry213     float *GetpNoCovrPlyTableEntry(int index) const { return pNoCovrPlyTable[index];}
GetNoCovrCntTableEntryChartTableEntry214     int GetNoCovrCntTableEntry(int index) const { return pNoCovrCntTable[index];}
215 
GetBBoxChartTableEntry216     const LLBBox &GetBBox() const { return m_bbox; }
217 
GetpFullPathChartTableEntry218     char *GetpFullPath() const { return pFullPath; }
GetLonMaxChartTableEntry219     float GetLonMax() const { return LonMax; }
GetLonMinChartTableEntry220     float GetLonMin() const { return LonMin; }
GetLatMaxChartTableEntry221     float GetLatMax() const { return LatMax; }
GetLatMinChartTableEntry222     float GetLatMin() const { return LatMin; }
GetScaleChartTableEntry223     int GetScale() const { return Scale; }
GetChartTypeChartTableEntry224     int GetChartType() const  { return ChartType; }
GetChartFamilyChartTableEntry225     int GetChartFamily() const  { return ChartFamily; }
GetChartProjectionTypeChartTableEntry226     int GetChartProjectionType() const { return ProjectionType; }
GetChartSkewChartTableEntry227     float GetChartSkew() const { return Skew; }
228 
GetbValidChartTableEntry229     bool GetbValid(){ return bValid;}
SetEntryOffsetChartTableEntry230     void SetEntryOffset(int n) { EntryOffset = n;}
GetpFileNameChartTableEntry231     const wxString *GetpFileName(void) const { return m_pfilename; }
GetpsFullPathChartTableEntry232     wxString *GetpsFullPath(void) const { return m_psFullPath; }
GetFullSystemPathChartTableEntry233     wxString GetFullSystemPath() const { return m_fullSystemPath; }
234 
GetGroupArrayChartTableEntry235     const std::vector<int> &GetGroupArray(void) const { return m_GroupArray; }
ClearGroupArrayChartTableEntry236     void ClearGroupArray(void) { m_GroupArray.clear(); }
AddIntToGroupArrayChartTableEntry237     void AddIntToGroupArray( int val ) { m_GroupArray.push_back( val ); }
SetAvailableChartTableEntry238     void SetAvailable(bool avail ){ m_bavail = avail;}
239 
240     std::vector<float> GetReducedPlyPoints();
241     std::vector<float> GetReducedAuxPlyPoints( int iTable);
242 
243     LLRegion quilt_candidate_region;
244 
245     void        SetScale(int scale);
Scale_eqChartTableEntry246     bool	Scale_eq( int b ) const { return abs ( Scale - b) <= rounding; }
Scale_geChartTableEntry247     bool        Scale_ge( int b ) const { return  Scale_eq( b ) || Scale > b; }
Scale_gtChartTableEntry248     bool        Scale_gt( int b ) const { return  Scale > b && !Scale_eq( b ); }
249 
250   private:
251     int         EntryOffset;
252     int         ChartType;
253     int         ChartFamily;
254     float       LatMax;
255     float       LatMin;
256     float       LonMax;
257     float       LonMin;
258     char        *pFullPath;
259     int		rounding;
260     int         Scale;
261     time_t      edition_date;
262     time_t      file_date;
263     float       *pPlyTable;
264     int         nPlyEntries;
265     int         nAuxPlyEntries;
266     float       **pAuxPlyTable;
267     int         *pAuxCntTable;
268     float       Skew;
269     int         ProjectionType;
270     bool        bValid;
271     int         nNoCovrPlyEntries;
272     int         *pNoCovrCntTable;
273     float       **pNoCovrPlyTable;
274 
275     std::vector<int> m_GroupArray;
276     wxString    *m_pfilename;             // a helper member, not on disk
277     wxString    *m_psFullPath;
278     wxString    m_fullSystemPath;
279 
280     LLBBox m_bbox;
281     bool        m_bavail;
282 
283     std::vector<float> m_reducedPlyPoints;
284 
285     std::vector<std::vector<float> > m_reducedAuxPlyPointsVector;
286 };
287 
288 enum
289 {
290       BUILTIN_DESCRIPTOR       = 0,
291       PLUGIN_DESCRIPTOR
292 };
293 
294 class ChartClassDescriptor
295 {
296 public:
ChartClassDescriptor()297       ChartClassDescriptor(){};
~ChartClassDescriptor()298       virtual ~ChartClassDescriptor(){}
299 
ChartClassDescriptor(wxString classn,wxString mask,int type)300       ChartClassDescriptor(wxString classn, wxString mask, int type)
301       : m_class_name(classn), m_search_mask(mask), m_descriptor_type(type) {};
302 
303       wxString    m_class_name;
304       wxString    m_search_mask;
305       int         m_descriptor_type;
306 };
307 
308 
309 ///////////////////////////////////////////////////////////////////////
310 // Chart Database
311 ///////////////////////////////////////////////////////////////////////
312 
313 WX_DECLARE_OBJARRAY(ChartTableEntry, ChartTable);
314 WX_DECLARE_OBJARRAY(ChartClassDescriptor, ArrayOfChartClassDescriptor);
315 
316 class ChartDatabase
317 {
318 public:
319     ChartDatabase();
~ChartDatabase()320     virtual ~ChartDatabase(){};
321 
322     bool Create(ArrayOfCDI& dir_array, wxGenericProgressDialog *pprog);
323     bool Update(ArrayOfCDI& dir_array, bool bForce, wxGenericProgressDialog *pprog);
324 
325     bool Read(const wxString &filePath);
326     bool Write(const wxString &filePath);
327 
328     bool AddSingleChart( wxString &fullpath, bool b_force_full_search = true );
329     bool RemoveSingleChart( wxString &ChartFullPath );
330 
GetDBFileName()331     const wxString & GetDBFileName() const { return m_DBFileName; }
GetChartDirArray()332     ArrayOfCDI& GetChartDirArray(){ return m_dir_array; }
GetChartDirArrayString()333     wxArrayString &GetChartDirArrayString(){ return m_chartDirs; }
SetChartDirArray(ArrayOfCDI array)334     void SetChartDirArray( ArrayOfCDI array ){ m_dir_array = array; }
335     bool CompareChartDirArray( ArrayOfCDI& test_array );
336     wxString GetMagicNumberCached(wxString dir);
337 
338     void UpdateChartClassDescriptorArray(void);
339 
GetChartTableEntries()340     int GetChartTableEntries() const { return active_chartTable.size(); }
341     const ChartTableEntry &GetChartTableEntry(int index) const;
342     ChartTableEntry *GetpChartTableEntry(int index) const;
GetChartTable()343     inline ChartTable &GetChartTable(){ return active_chartTable; }
344 
IsValid()345     bool IsValid() const { return bValid; }
346     int DisableChart(wxString& PathToDisable);
347     bool GetCentroidOfLargestScaleChart(double *clat, double *clon, ChartFamilyEnum family);
348     int GetDBChartType(int dbIndex);
349     int GetDBChartFamily(int dbIndex);
350     float GetDBChartSkew(int dbIndex);
351     int GetDBChartProj(int dbIndex);
352     int GetDBChartScale(int dbIndex);
353 
354     bool GetDBBoundingBox(int dbindex, LLBBox &box);
355     const LLBBox &GetDBBoundingBox(int dbIndex);
356 
357     int  GetnAuxPlyEntries(int dbIndex);
358     int  GetDBPlyPoint(int dbIndex, int plyindex, float *lat, float *lon);
359     int  GetDBAuxPlyPoint(int dbIndex, int plyindex, int iAuxPly, float *lat, float *lon);
GetVersion()360     int  GetVersion(){ return m_dbversion; }
361     wxString GetFullChartInfo(ChartBase *pc, int dbIndex, int *char_width, int *line_count);
362     int FinddbIndex(wxString PathToFind);
363     wxString GetDBChartFileName(int dbIndex);
364     void ApplyGroupArray(ChartGroupArray *pGroupArray);
365     bool IsChartAvailable( int dbIndex );
366     ChartTable    active_chartTable;
367     std::map <wxString, int> active_chartTable_pathindex;
368 
369     std::vector<float> GetReducedPlyPoints(int dbIndex);
370     std::vector<float> GetReducedAuxPlyPoints(int dbIndex, int iTable);
371 
IsBusy()372     bool IsBusy(){ return m_b_busy; }
373 
374 protected:
375     virtual ChartBase *GetChart(const wxChar *theFilePath, ChartClassDescriptor &chart_desc) const;
376     int AddChartDirectory(const wxString &theDir, bool bshow_prog);
SetValid(bool valid)377     void SetValid(bool valid) { bValid = valid; }
378     ChartTableEntry *CreateChartTableEntry(const wxString &filePath, wxString &utf8Path, ChartClassDescriptor &chart_desc);
379 
380     ArrayOfChartClassDescriptor    m_ChartClassDescriptorArray;
381     ArrayOfCDI    m_dir_array;
382     bool              m_b_busy;
383 
384 private:
385     bool IsChartDirUsed(const wxString &theDir);
386 
387     int SearchDirAndAddCharts(wxString& dir_name_base, ChartClassDescriptor &chart_desc, wxGenericProgressDialog *pprog);
388 
389     int TraverseDirAndAddCharts(ChartDirInfo& dir_info, wxGenericProgressDialog *pprog, wxString& dir_magic, bool bForce);
390     bool DetectDirChange(const wxString & dir_path, const wxString & prog_label, const wxString & magic, wxString &new_magic, wxGenericProgressDialog *pprog);
391 
392     bool AddChart( wxString &chartfilename, ChartClassDescriptor &chart_desc, wxGenericProgressDialog *pprog,
393                    int isearch, bool bthis_dir_in_dB );
394 
395     bool Check_CM93_Structure(wxString dir_name);
396 
397     bool          bValid;
398     wxArrayString m_chartDirs;
399     int           m_dbversion;
400 
401     ChartTableEntry           m_ChartTableEntryDummy;   // used for return value if database is not valid
402     wxString      m_DBFileName;
403 
404     int           m_pdifile;
405     int           m_pdnFile;
406 
407     int         m_nentries;
408 
409     LLBBox m_dummy_bbox;
410 };
411 
412 
413 //-------------------------------------------------------------------------------------------
414 //    Chart Group Structure Definitions
415 //-------------------------------------------------------------------------------------------
416 class ChartGroupElement;
417 class ChartGroup;
418 
419 WX_DEFINE_ARRAY_PTR(ChartGroup*, ChartGroupArray);
420 
421 class ChartGroupElement
422 {
423   // ChartGroupElements need nothing special to delete since
424   // m_missing_name_array is a wxArrayString which manages
425   // memory for the strings cleanly without need for a .Clear.
426 public:
427       wxString      m_element_name;
428       wxArrayString m_missing_name_array;
429 };
430 
431 class ChartGroup
432 {
433 public:
434       wxString                                         m_group_name;
435       std::vector<std::unique_ptr<ChartGroupElement>>  m_element_array;
436 };
437 
438 
439 #endif
440 
441