1 /***************************************************************************
2       qgsgrassrasterprovider.h  -  QGIS Data provider for
3                            GRASS rasters
4                              -------------------
5     begin                : 16 Jan, 2010
6     copyright            : (C) 2010 by Radim Blazek
7     email                : radim dot blazek at gmail dot com
8  ***************************************************************************/
9 
10 /***************************************************************************
11  *                                                                         *
12  *   This program is free software; you can redistribute it and/or modify  *
13  *   it under the terms of the GNU General Public License as published by  *
14  *   the Free Software Foundation; either version 2 of the License, or     *
15  *   (at your option) any later version.                                   *
16  *                                                                         *
17  ***************************************************************************/
18 
19 
20 #ifndef QGSGRASSRASTERPROVIDER_H
21 #define QGSGRASSRASTERPROVIDER_H
22 
23 #include "qgscoordinatereferencesystem.h"
24 #include "qgsrasterdataprovider.h"
25 #include "qgsrectangle.h"
26 #include "qgscolorrampshader.h"
27 #include "qgis_grass_lib.h"
28 
29 extern "C"
30 {
31 #include <grass/version.h>
32 #include <grass/gis.h>
33 #include <grass/raster.h>
34 }
35 
36 #include <QString>
37 #include <QStringList>
38 #include <QDomElement>
39 #include <QMap>
40 #include <QVector>
41 #include <QTemporaryFile>
42 #include <QProcess>
43 #include <QHash>
44 
45 class QgsCoordinateTransform;
46 
47 /**
48  * \brief Read raster value for given coordinates
49  *
50  * Executes qgis.g.info and keeps it open comunicating through pipe. Restarts the command if raster was updated.
51 */
52 
53 class GRASS_LIB_EXPORT QgsGrassRasterValue
54 {
55   public:
56     QgsGrassRasterValue() = default;
57     ~QgsGrassRasterValue();
58 
59     QgsGrassRasterValue( const QgsGrassRasterValue &other ) = delete;
60     QgsGrassRasterValue &operator=( const QgsGrassRasterValue &other ) = delete;
61 
62     void set( const QString &gisdbase, const QString &location, const QString &mapset, const QString &map );
63     void stop();
64     // returns raster value, NaN for no data
65     // OK is set to true if OK or false on error
66     double value( double x, double y, bool *ok );
67   private:
68 
69     void start();
70     QString mGisdbase;      // map gisdabase
71     QString mLocation;      // map location name (not path!)
72     QString mMapset;        // map mapset
73     QString mMapName;       // map name
74     QTemporaryFile mGisrcFile;
75     QProcess *mProcess = nullptr;
76 };
77 
78 /**
79  *
80  * \brief Data provider for GRASS raster layers.
81  *
82  * This provider implements the
83  * interface defined in the QgsDataProvider class to provide access to spatial
84  * data residing in a OGC Web Map Service.
85  *
86 */
87 class GRASS_LIB_EXPORT QgsGrassRasterProvider : public QgsRasterDataProvider
88 {
89     Q_OBJECT
90 
91   public:
92 
93     /**
94      * Constructor for the provider.
95      *
96      * \param   uri   HTTP URL of the Web Server.  If needed a proxy will be used
97      *                otherwise we contact the host directly.
98      *
99      */
100     explicit QgsGrassRasterProvider( QString const &uri = QString() );
101 
102 
103     ~QgsGrassRasterProvider() override;
104 
105     QgsGrassRasterProvider *clone() const override;
106 
107     /**
108      * Returns a provider name
109      *
110      * Essentially just returns the provider key.  Should be used to build file
111      * dialogs so that providers can be shown with their supported types. Thus
112      * if more than one provider supports a given format, the user is able to
113      * select a specific provider to open that file.
114      *
115      * \note
116      *
117      * Instead of being pure virtual, might be better to generalize this
118      * behavior and presume that none of the sub-classes are going to do
119      * anything strange with regards to their name or description?
120      *
121      */
122     QString name() const override;
123 
124 
125     /**
126      * Returns description
127      *
128      * Returns a terse string describing what the provider is.
129      *
130      * \note
131      *
132      * Instead of being pure virtual, might be better to generalize this
133      * behavior and presume that none of the sub-classes are going to do
134      * anything strange with regards to their name or description?
135      *
136      */
137     QString description() const override;
138 
139     QgsCoordinateReferenceSystem crs() const override;
140 
141     /**
142      * Returns the extent for this data layer
143      */
144     QgsRectangle extent() const override;
145 
146     bool isValid() const override;
147 
148     QgsRasterIdentifyResult identify( const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &boundingBox = QgsRectangle(), int width = 0, int height = 0, int dpi = 96 ) override;
149 
150     /**
151      * \brief   Returns the caption error text for the last error in this provider
152      *
153      * If an operation returns 0 (e.g. draw()), this function
154      * returns the text of the error associated with the failure.
155      * Interactive users of this provider can then, for example,
156      * call a QMessageBox to display the contents.
157      */
158     QString lastErrorTitle() override;
159 
160     /**
161      * \brief   Returns the verbose error text for the last error in this provider
162      *
163      * If an operation returns 0 (e.g. draw()), this function
164      * returns the text of the error associated with the failure.
165      * Interactive users of this provider can then, for example,
166      * call a QMessageBox to display the contents.
167      */
168 
169     QString lastError() override;
170 
171     /**
172      * Returns a bitmask containing the supported capabilities
173      * Note, some capabilities may change depending on which
174      * sublayers are visible on this provider, so it may
175      * be prudent to check this value per intended operation.
176     */
177     int capabilities() const override;
178 
179     Qgis::DataType dataType( int bandNo ) const override;
180     Qgis::DataType sourceDataType( int bandNo ) const override;
181 
182     int bandCount() const override;
183 
184     int colorInterpretation( int bandNo ) const override;
185 
186     int xBlockSize() const override;
187     int yBlockSize() const override;
188 
189     int xSize() const override;
190     int ySize() const override;
191 
192     bool readBlock( int bandNo, int xBlock, int yBlock, void *data ) override;
193     bool readBlock( int bandNo, QgsRectangle  const &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) override;
194 
195     QgsRasterBandStats bandStatistics( int bandNo,
196                                        int stats = QgsRasterBandStats::All,
197                                        const QgsRectangle &boundingBox = QgsRectangle(),
198                                        int sampleSize = 0, QgsRasterBlockFeedback *feedback = nullptr ) override;
199 
200     QList<QgsColorRampShader::ColorRampItem> colorTable( int bandNo )const override;
201 
202     // void buildSupportedRasterFileFilter( QString & fileFiltersString );
203 
204     /**
205      * Gets metadata in a format suitable for feeding directly
206      * into a subset of the GUI raster properties "Metadata" tab.
207      */
208     QString htmlMetadata() override;
209 
210     QDateTime dataTimestamp() const override;
211 
212     // used by GRASS tools
213     void freeze();
214     void thaw();
215 
216   private:
217     void setLastError( const QString &error );
218     void clearLastError();
219     // append error if it is not empty
220     void appendIfError( const QString &error );
221 
222     /**
223      * Flag indicating if the layer data source is a valid layer
224      */
225     bool mValid = false;
226 
227     QString mGisdbase;      // map gisdabase
228     QString mLocation;      // map location name (not path!)
229     QString mMapset;        // map mapset
230     QString mMapName;       // map name
231 
232     RASTER_MAP_TYPE mGrassDataType = 0; // CELL_TYPE, DCELL_TYPE, FCELL_TYPE
233 
234     int mCols = 0;
235     int mRows = 0;
236     int mYBlockSize = 0;
237 
238     QHash<QString, QString> mInfo;
239 
240     QgsCoordinateReferenceSystem mCrs;
241 
242     QgsGrassRasterValue mRasterValue;
243 
244     double mNoDataValue;
245 
246     QString mLastErrorTitle;
247     QString mLastError;
248 };
249 
250 #endif
251