Rev 1221 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
671 | werner | 1 | /******************************************************************************************** |
2 | ** iLand - an individual based forest landscape and disturbance model |
||
3 | ** http://iland.boku.ac.at |
||
4 | ** Copyright (C) 2009- Werner Rammer, Rupert Seidl |
||
5 | ** |
||
6 | ** This program is free software: you can redistribute it and/or modify |
||
7 | ** it under the terms of the GNU General Public License as published by |
||
8 | ** the Free Software Foundation, either version 3 of the License, or |
||
9 | ** (at your option) any later version. |
||
10 | ** |
||
11 | ** This program is distributed in the hope that it will be useful, |
||
12 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
14 | ** GNU General Public License for more details. |
||
15 | ** |
||
16 | ** You should have received a copy of the GNU General Public License |
||
17 | ** along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
18 | ********************************************************************************************/ |
||
538 | werner | 19 | |
671 | werner | 20 | |
538 | werner | 21 | #ifndef GISGRID_H |
22 | #define GISGRID_H |
||
23 | |||
24 | #include <QString> |
||
25 | #include <QPointF> |
||
26 | #include <QRectF> |
||
27 | |||
28 | #include "grid.h" |
||
29 | |||
30 | struct SCoordTrans { |
||
539 | werner | 31 | SCoordTrans() { setupTransformation(0.,0.,0.,0.); } |
538 | werner | 32 | double RotationAngle; |
33 | double sinRotate, cosRotate; |
||
34 | double sinRotateReverse, cosRotateReverse; |
||
35 | double offsetX, offsetY, offsetZ; |
||
539 | werner | 36 | void setupTransformation(double new_offsetx, double new_offsety, double new_offsetz, double angle_degree) |
37 | { |
||
38 | offsetX = new_offsetx; |
||
39 | offsetY = new_offsety; |
||
40 | offsetZ = new_offsetz; |
||
41 | RotationAngle=angle_degree * M_PI / 180.; |
||
42 | sinRotate=sin(RotationAngle); |
||
43 | cosRotate=cos(RotationAngle); |
||
44 | sinRotateReverse=sin(-RotationAngle); |
||
45 | cosRotateReverse=cos(-RotationAngle); |
||
46 | } |
||
538 | werner | 47 | }; |
48 | |||
539 | werner | 49 | /** GIS Transformation |
50 | The transformation is defined by three offsets (x,y,z) and a rotation information. |
||
51 | the (x/y) denotes the real-world coordinates of the left lower edge of the grid (at least for the northern hemisphere), i.e. the (0/0). |
||
52 | The z-offset is currently not used. |
||
53 | |||
54 | */ |
||
538 | werner | 55 | // setup routine -- give a vector with offsets [m] and rotation angle. |
56 | void setupGISTransformation(const double offsetx, |
||
57 | const double offsety, |
||
58 | const double offsetz, |
||
59 | const double angle_degree); |
||
60 | // transformation routines. |
||
646 | werner | 61 | void worldToModel(const Vector3D &From, Vector3D &To); |
62 | void modelToWorld(const Vector3D &From, Vector3D &To); |
||
1157 | werner | 63 | QPointF modelToWorld(QPointF model_coordinates); |
64 | QPointF worldToModel(QPointF world_coordinates); |
||
538 | werner | 65 | |
66 | |||
539 | werner | 67 | class GisGrid |
538 | werner | 68 | { |
69 | public: |
||
539 | werner | 70 | GisGrid(); |
71 | ~GisGrid(); |
||
538 | werner | 72 | // maintenance |
73 | bool loadFromFile(const QString &fileName); ///< load ESRI style text file |
||
74 | // access |
||
75 | int dataSize() const { return mDataSize; } ///< number of data items (rows*cols) |
||
76 | int rows() const { return mNRows; } ///< number of rows |
||
77 | int cols() const { return mNCols; } ///< number of columns |
||
1157 | werner | 78 | QPointF origin() const { return mOrigin; } ///< coordinates of the lower left corner of the grid |
538 | werner | 79 | double cellSize() const { return mCellSize; } ///< size of a cell (meters) |
80 | double minValue() const { return min_value; } ///< minimum data value |
||
81 | double maxValue() const { return max_value; } ///< maximum data value |
||
550 | werner | 82 | int noDataValue() const { return mNODATAValue; } ///< no data value of the grid |
567 | werner | 83 | /// get grid value at local coordinates (X/Y); returs NODATAValue if out of range |
84 | /// @p X and @p Y are local coordinates. |
||
538 | werner | 85 | double value(const QPointF &p) const {return value(p.x(), p.y());} |
86 | double value(const double X, const double Y) const; |
||
87 | double value(const int indexx, const int indexy) const; ///< get value of grid at index positions |
||
881 | werner | 88 | double value(const int Index) const; ///< get value of grid at index positions |
538 | werner | 89 | /// get coordinates of the center of the cell with 'Index' |
646 | werner | 90 | Vector3D coord(const int Index) const; |
91 | Vector3D coord(const int indexx, const int indexy) const; |
||
538 | werner | 92 | QRectF rectangle(const int indexx, const int indexy) const; |
93 | void clip(const QRectF & box); ///< clip the grid to 'Box' (set values outside to -1) |
||
94 | |||
95 | // special operations |
||
96 | //QRectF GetBoundingBox(int LookFor, SBoundingBox &Result, double x_m, double y_m); |
||
97 | QList<double> distinctValues(); ///< returns a list of distinct values |
||
98 | //void GetDistinctValues(TStringList *ResultList, double x_m, double y_m); |
||
99 | //void CountOccurence(int intID, int & Count, int & left, int &upper, int &right, int &lower, SBoundingBox *OuterBox); |
||
100 | //S3dVector GetNthOccurence(int ID, int N, int left, int upper, int right, int lower); |
||
101 | //void ExportToTable(AnsiString OutFileName); |
||
102 | |||
1157 | werner | 103 | // global conversion functions between local and world coordinates |
104 | // the world-context is created by calling setupGISTransformation() (once). |
||
105 | /// convert model to world coordinates (metric) |
||
106 | static QPointF modelToWorld(QPointF model_coordinates); |
||
107 | /// convert world (i.e. GIS) to model coordinates (metric) (with 0/0 at lower left edge of project area) |
||
108 | static QPointF worldToModel(QPointF world_coordinates); |
||
109 | |||
110 | |||
538 | werner | 111 | private: |
112 | |||
113 | int mDataSize; ///< number of data items (rows*cols) |
||
114 | double mCellSize; // size of cells [m] |
||
115 | double max_value; |
||
116 | double min_value; |
||
117 | QPointF mOrigin; // lowerleftcorner |
||
118 | QPointF xAxis; // transformed axis (moved, rotated) |
||
119 | QPointF yAxis; |
||
120 | int mNRows; |
||
121 | int mNCols; // count of rows and cols |
||
122 | double *mData; |
||
123 | int mNODATAValue; |
||
124 | }; |
||
125 | |||
126 | |||
127 | // Cached GIS - Dataset |
||
128 | // template class. |
||
129 | /* |
||
130 | template <class T> class TGISData |
||
131 | { |
||
132 | public: |
||
133 | TTypedList<T> *Items; |
||
134 | |||
135 | TGISGrid *Grid; |
||
136 | TGISData() { |
||
137 | Items = new TTypedList<T>(true); |
||
138 | Grid=0; |
||
139 | } |
||
140 | ~TGISData() { |
||
141 | delete Items; |
||
142 | //if (Grid) |
||
143 | // delete Grid; |
||
144 | } |
||
145 | int Add(T* Item) { |
||
146 | return Items->Add(Item); |
||
147 | } |
||
148 | void Clear() { Items->Clear(); } |
||
149 | // template <class T> * Select(int ID); |
||
150 | T* Select(int ID) { |
||
151 | for (int i=0;i<Items->Count;i++) |
||
152 | if (Items->Items[i]->ID == ID) |
||
153 | return Items->Items[i]; |
||
154 | return 0; |
||
155 | } |
||
156 | T* SelectAt(double X, double Y) { |
||
157 | if (!Grid) |
||
158 | return 0; |
||
159 | int CellValue = Grid->value(X,Y); |
||
160 | return Select(CellValue); |
||
161 | } |
||
162 | //bool Select(int ID); |
||
163 | }; |
||
164 | |||
165 | */ |
||
166 | //--------------------------------------------------------------------------- |
||
167 | #endif |