1 /*
2  MDAL - Mesh Data Abstraction Library (MIT License)
3  Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
4 */
5 
6 #ifndef MDAL_DATA_MODEL_HPP
7 #define MDAL_DATA_MODEL_HPP
8 
9 #include <stddef.h>
10 #include <vector>
11 #include <memory>
12 #include <map>
13 #include <string>
14 #include <limits>
15 #include "mdal.h"
16 #include "mdal_datetime.hpp"
17 
18 namespace MDAL
19 {
20   class DatasetGroup;
21   class Mesh;
22 
23   struct BBox
24   {
BBoxMDAL::BBox25     BBox() {}
BBoxMDAL::BBox26     BBox( double lx, double ux, double ly, double uy ): minX( lx ), maxX( ux ), minY( ly ), maxY( uy ) {}
27 
28     double minX = std::numeric_limits<double>::max();
29     double maxX = -std::numeric_limits<double>::max();
30     double minY = std::numeric_limits<double>::max();
31     double maxY = -std::numeric_limits<double>::max();
32   };
33 
34   typedef struct StatisticsType
35   {
36     double minimum = std::numeric_limits<double>::quiet_NaN();
37     double maximum = std::numeric_limits<double>::quiet_NaN();
38   } Statistics;
39 
40   typedef std::vector< std::pair< std::string, std::string > > Metadata;
41   typedef std::vector<std::pair<double, double>> Classification;
42 
43   class Dataset
44   {
45     public:
46       Dataset( DatasetGroup *parent );
47       virtual ~Dataset();
48 
49       size_t valuesCount() const;
50 
51       //! For DataOnVertices or DataOnFaces
52       virtual size_t scalarData( size_t indexStart, size_t count, double *buffer ) = 0;
53       //! For DataOnVertices or DataOnFaces
54       virtual size_t vectorData( size_t indexStart, size_t count, double *buffer ) = 0;
55       //! For drivers that supports it, see supportsActiveFlag()
56       virtual size_t activeData( size_t indexStart, size_t count, int *buffer );
57 
58       //! For DataOnVolumes
59       virtual size_t verticalLevelCountData( size_t indexStart, size_t count, int *buffer ) = 0;
60       //! For DataOnVolumes
61       virtual size_t verticalLevelData( size_t indexStart, size_t count, double *buffer ) = 0;
62       //! For DataOnVolumes
63       virtual size_t faceToVolumeData( size_t indexStart, size_t count, int *buffer ) = 0;
64       //! For DataOnVolumes
65       virtual size_t scalarVolumesData( size_t indexStart, size_t count, double *buffer ) = 0;
66       //! For DataOnVolumes
67       virtual size_t vectorVolumesData( size_t indexStart, size_t count, double *buffer ) = 0;
68 
69       virtual size_t volumesCount() const = 0;
70       virtual size_t maximumVerticalLevelsCount() const = 0;
71 
72       Statistics statistics() const;
73       void setStatistics( const Statistics &statistics );
74 
75       bool isValid() const;
76 
77       DatasetGroup *group() const;
78       Mesh *mesh() const;
79 
80       double time( RelativeTimestamp::Unit unit ) const;
81       RelativeTimestamp timestamp() const;
82       void setTime( double time, RelativeTimestamp::Unit unit = RelativeTimestamp::hours );
83       void setTime( const RelativeTimestamp &time );
84 
85       bool supportsActiveFlag() const;
86       void setSupportsActiveFlag( bool value );
87 
88     private:
89       RelativeTimestamp mTime;
90       bool mIsValid = true;
91       bool mSupportsActiveFlag = false;
92       DatasetGroup *mParent = nullptr;
93       Statistics mStatistics;
94   };
95 
96   class Dataset2D: public Dataset
97   {
98     public:
99       Dataset2D( DatasetGroup *parent );
100       virtual ~Dataset2D() override;
101 
102       size_t verticalLevelCountData( size_t indexStart, size_t count, int *buffer ) override;
103       size_t verticalLevelData( size_t indexStart, size_t count, double *buffer ) override;
104       size_t faceToVolumeData( size_t indexStart, size_t count, int *buffer ) override;
105       size_t scalarVolumesData( size_t indexStart, size_t count, double *buffer ) override;
106       size_t vectorVolumesData( size_t indexStart, size_t count, double *buffer ) override;
107 
108       size_t volumesCount() const override;
109       size_t maximumVerticalLevelsCount() const override;
110   };
111 
112   class Dataset3D: public Dataset
113   {
114     public:
115       Dataset3D(
116         DatasetGroup *parent,
117         size_t volumes,
118         size_t maxVerticalLevelCount
119       );
120       virtual ~Dataset3D() override;
121 
122       virtual size_t scalarData( size_t indexStart, size_t count, double *buffer ) override;
123       virtual size_t vectorData( size_t indexStart, size_t count, double *buffer ) override;
124 
125       size_t volumesCount() const override;
126       size_t maximumVerticalLevelsCount() const override;
127 
128     private:
129       size_t mVolumesCount = 0;
130       size_t mMaximumVerticalLevelsCount = 0;
131   };
132 
133 
134   typedef std::vector<std::shared_ptr<Dataset>> Datasets;
135 
136   class DatasetGroup
137   {
138     public:
139       DatasetGroup( const std::string &driverName,
140                     Mesh *parent,
141                     const std::string &uri
142                   );
143 
144       DatasetGroup( const std::string &driverName,
145                     Mesh *parent,
146                     const std::string &uri,
147                     const std::string &name );
148 
149       ~DatasetGroup();
150 
151       std::string driverName() const;
152 
153       std::string getMetadata( const std::string &key );
154       void setMetadata( const std::string &key, const std::string &val );
155       void setMetadata( const Metadata &new_metadata );
156 
157       std::string name();
158       void setName( const std::string &name );
159 
160       Metadata metadata;
161       Datasets datasets;
162 
163       bool isScalar() const;
164       void setIsScalar( bool isScalar );
165 
166       MDAL_DataLocation dataLocation() const;
167       void setDataLocation( MDAL_DataLocation dataLocation );
168 
169       std::string uri() const;
170       void replaceUri( std::string uri );
171 
172       Statistics statistics() const;
173       void setStatistics( const Statistics &statistics );
174 
175       DateTime referenceTime() const;
176       void setReferenceTime( const DateTime &referenceTime );
177 
178       Mesh *mesh() const;
179 
180       size_t maximumVerticalLevelsCount() const;
181 
182       bool isInEditMode() const;
183       void startEditing();
184       void stopEditing();
185 
186       //! First value is the angle for full rotation and second value is the start angle
187       void setReferenceAngles( const std::pair<double, double> &referenceAngle );
188       std::pair<double, double> referenceAngles() const;
189 
190       bool isPolar() const;
191       void setIsPolar( bool isPolar );
192     private:
193       bool mInEditMode = false;
194 
195       const std::string mDriverName;
196       Mesh *mParent = nullptr;
197       bool mIsScalar = true;
198       bool mIsPolar = false;
199       std::pair<double, double> mReferenceAngles = { -360, 0}; //default full rotation is negative to be consistent with usual geographical clockwise
200       MDAL_DataLocation mDataLocation = MDAL_DataLocation::DataOnVertices;
201       std::string mUri; // file/uri from where it came
202       Statistics mStatistics;
203       DateTime mReferenceTime;
204   };
205 
206   typedef std::vector<std::shared_ptr<DatasetGroup>> DatasetGroups;
207 
208   class MeshVertexIterator
209   {
210     public:
211       virtual ~MeshVertexIterator();
212 
213       virtual size_t next( size_t vertexCount, double *coordinates ) = 0;
214   };
215 
216   class MeshEdgeIterator
217   {
218     public:
219       virtual ~MeshEdgeIterator();
220 
221       virtual size_t next( size_t edgeCount,
222                            int *startVertexIndices,
223                            int *endVertexIndices ) = 0;
224   };
225 
226   class MeshFaceIterator
227   {
228     public:
229       virtual ~MeshFaceIterator();
230 
231       virtual size_t next( size_t faceOffsetsBufferLen,
232                            int *faceOffsetsBuffer,
233                            size_t vertexIndicesBufferLen,
234                            int *vertexIndicesBuffer ) = 0;
235   };
236 
237   class Mesh
238   {
239     public:
240       Mesh( const std::string &driverName,
241             size_t faceVerticesMaximumCount,
242             const std::string &uri );
243 
244       virtual ~Mesh();
245 
246       std::string driverName() const;
247 
248       void setSourceCrs( const std::string &str );
249       void setSourceCrsFromWKT( const std::string &wkt );
250       void setSourceCrsFromEPSG( int code );
251       void setSourceCrsFromPrjFile( const std::string &filename );
252 
253       virtual std::unique_ptr<MDAL::MeshVertexIterator> readVertices() = 0;
254       virtual std::unique_ptr<MDAL::MeshEdgeIterator> readEdges() = 0;
255       virtual std::unique_ptr<MDAL::MeshFaceIterator> readFaces() = 0;
256 
257       DatasetGroups datasetGroups;
258 
259       //! Find a dataset group by name
260       std::shared_ptr<DatasetGroup> group( const std::string &name );
261 
262       virtual size_t verticesCount() const = 0;
263       virtual size_t edgesCount() const = 0;
264       virtual size_t facesCount() const = 0;
265       virtual BBox extent() const = 0;
266       std::string uri() const;
267       std::string crs() const;
268       size_t faceVerticesMaximumCount() const;
269 
270       std::string getMetadata( const std::string &key );
271       void setMetadata( const std::string &key, const std::string &val );
272       void setMetadata( const Metadata &new_metadata );
273 
274       Metadata metadata;
275 
closeSource()276       virtual void closeSource() {};
277 
isEditable() const278       virtual bool isEditable() const {return false;}
279 
280       virtual void addVertices( size_t vertexCount, double *coordinates );
281       virtual void addFaces( size_t faceCount, size_t driverMaxVerticesPerFace, int *faceSizes, int *vertexIndices );
282       virtual void addEdges( size_t edgeCount, int *startVertexIndices, int *endVertexIndices );
283 
284 
285     protected:
286       void setFaceVerticesMaximumCount( const size_t &faceVerticesMaximumCount );
287 
288     private:
289       const std::string mDriverName;
290       size_t mFaceVerticesMaximumCount = 0; //typically 3 or 4, sometimes up to 9
291       const std::string mUri; // file/uri from where it came
292       std::string mCrs;
293   };
294 } // namespace MDAL
295 #endif //MDAL_DATA_MODEL_HPP
296 
297