QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgswcsgetcoverage.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgswcsgetcoverage.cpp
3 -------------------------
4 begin : January 16 , 2017
5 copyright : (C) 2013 by René-Luc D'Hont ( parts from qgswcsserver )
6 (C) 2017 by David Marteau
7 email : rldhont at 3liz dot com
8 david dot marteau at 3liz dot com
9 ***************************************************************************/
10
11/***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19
20#include "qgswcsgetcoverage.h"
21
22#include "qgsproject.h"
24#include "qgsrasterfilewriter.h"
25#include "qgsrasterlayer.h"
26#include "qgsrasterpipe.h"
27#include "qgsrasterprojector.h"
29#include "qgswcsutils.h"
30
31#include <QString>
32#include <QTemporaryFile>
33
34using namespace Qt::StringLiterals;
35
36namespace QgsWcs
37{
38
42 void writeGetCoverage( QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response )
43 {
44 Q_UNUSED( version )
45
46 response.write( getCoverageData( serverIface, project, request ) );
47 response.setHeader( "Content-Type", "image/tiff" );
48 }
49
50 QByteArray getCoverageData( QgsServerInterface *serverIface, const QgsProject *project, const QgsServerRequest &request )
51 {
52 const QgsServerRequest::Parameters parameters = request.parameters();
53
54#ifdef HAVE_SERVER_PYTHON_PLUGINS
55 QgsAccessControl *accessControl = serverIface->accessControls();
56#else
57 ( void ) serverIface;
58#endif
59 //defining coverage name
60 QString coveName;
61 //read COVERAGE
62 const QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( u"COVERAGE"_s );
63 if ( cove_name_it != parameters.constEnd() )
64 {
65 coveName = cove_name_it.value();
66 }
67 if ( coveName.isEmpty() )
68 {
69 const QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( u"IDENTIFIER"_s );
70 if ( cove_name_it != parameters.constEnd() )
71 {
72 coveName = cove_name_it.value();
73 }
74 }
75
76 if ( coveName.isEmpty() )
77 {
78 throw QgsRequestNotWellFormedException( u"COVERAGE is mandatory"_s );
79 }
80
81 //get the raster layer
82 const QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project );
83
84 QgsRasterLayer *rLayer = nullptr;
85 for ( int i = 0; i < wcsLayersId.size(); ++i )
86 {
87 QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) );
88 if ( !layer )
89 {
90 continue;
91 }
92 if ( layer->type() != Qgis::LayerType::Raster )
93 {
94 continue;
95 }
96#ifdef HAVE_SERVER_PYTHON_PLUGINS
97 if ( !accessControl->layerReadPermission( layer ) )
98 {
99 continue;
100 }
101#endif
102 QString name = layer->name();
103 if ( !layer->serverProperties()->shortName().isEmpty() )
104 name = layer->serverProperties()->shortName();
105 name = name.replace( " "_L1, "_"_L1 );
106
107 if ( name == coveName )
108 {
109 rLayer = qobject_cast<QgsRasterLayer *>( layer );
110 break;
111 }
112 }
113 if ( !rLayer )
114 {
115 throw QgsRequestNotWellFormedException( u"The layer for the COVERAGE '%1' is not found"_s.arg( coveName ) );
116 }
117
118 double minx = 0.0, miny = 0.0, maxx = 0.0, maxy = 0.0;
119 // WIDTh and HEIGHT
120 int width = 0, height = 0;
121 // CRS
122 QString crs;
123
124 // read BBOX
125 const QgsRectangle bbox = parseBbox( parameters.value( u"BBOX"_s ) );
126 if ( !bbox.isEmpty() )
127 {
128 minx = bbox.xMinimum();
129 miny = bbox.yMinimum();
130 maxx = bbox.xMaximum();
131 maxy = bbox.yMaximum();
132 }
133 else
134 {
135 throw QgsRequestNotWellFormedException( u"The BBOX is mandatory and has to be xx.xxx,yy.yyy,xx.xxx,yy.yyy"_s );
136 }
137
138 // read WIDTH
139 bool conversionSuccess = false;
140 width = parameters.value( u"WIDTH"_s, u"0"_s ).toInt( &conversionSuccess );
141 if ( !conversionSuccess )
142 {
143 width = 0;
144 }
145 // read HEIGHT
146 height = parameters.value( u"HEIGHT"_s, u"0"_s ).toInt( &conversionSuccess );
147 if ( !conversionSuccess )
148 {
149 height = 0;
150 }
151
152 if ( width < 0 || height < 0 )
153 {
154 throw QgsRequestNotWellFormedException( u"The WIDTH and HEIGHT are mandatory and have to be integer"_s );
155 }
156
157 crs = parameters.value( u"CRS"_s );
158 if ( crs.isEmpty() )
159 {
160 throw QgsRequestNotWellFormedException( u"The CRS is mandatory"_s );
161 }
162
164 if ( !requestCRS.isValid() )
165 {
166 throw QgsRequestNotWellFormedException( u"Invalid CRS"_s );
167 }
168
169 QgsRectangle rect( minx, miny, maxx, maxy );
170
171 // transform rect
172 if ( requestCRS != rLayer->crs() )
173 {
174 const QgsCoordinateTransform t( requestCRS, rLayer->crs(), project );
175 rect = t.transformBoundingBox( rect );
176 }
177
178 // RESPONSE_CRS
179 QgsCoordinateReferenceSystem responseCRS = rLayer->crs();
180 crs = parameters.value( u"RESPONSE_CRS"_s );
181 if ( !crs.isEmpty() )
182 {
184 if ( !responseCRS.isValid() )
185 {
186 responseCRS = rLayer->crs();
187 }
188 }
189
190 QTemporaryFile tempFile;
191 if ( !tempFile.open() )
192 {
193 throw QgsRequestNotWellFormedException( u"Cannot open temporary file"_s );
194 }
195 QgsRasterFileWriter fileWriter( tempFile.fileName() );
196
197 // clone pipe/provider
198 QgsRasterPipe pipe;
199 if ( !pipe.set( rLayer->dataProvider()->clone() ) )
200 {
201 throw QgsRequestNotWellFormedException( u"Cannot set pipe provider"_s );
202 }
203
204 // add projector if necessary
205 if ( responseCRS != rLayer->crs() )
206 {
207 QgsRasterProjector *projector = new QgsRasterProjector;
208 projector->setCrs( rLayer->crs(), responseCRS, rLayer->transformContext() );
209 if ( !pipe.insert( 2, projector ) )
210 {
211 throw QgsRequestNotWellFormedException( u"Cannot set pipe projector"_s );
212 }
213 }
214
215 const Qgis::RasterFileWriterResult err = fileWriter.writeRaster( &pipe, width, height, rect, responseCRS, rLayer->transformContext() );
217 {
218 throw QgsRequestNotWellFormedException( u"Cannot write raster error code: %1"_s.arg( qgsEnumValueToKey( err ) ) );
219 }
220 return tempFile.readAll();
221 }
222
223} // namespace QgsWcs
RasterFileWriterResult
Raster file export results.
Definition qgis.h:1700
@ Success
Successful export.
Definition qgis.h:1701
@ Raster
Raster layer.
Definition qgis.h:195
A helper class that centralizes restrictions given by all the access control filter plugins.
bool layerReadPermission(const QgsMapLayer *layer) const
Returns the layer read right.
Represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Handles coordinate transforms between two coordinate systems.
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const
Transforms a rectangle from the source CRS to the destination CRS.
QString shortName() const
Returns the short name of the layer used by QGIS Server to identify the layer.
Base class for all map layer types.
Definition qgsmaplayer.h:83
QString name
Definition qgsmaplayer.h:87
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:90
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
Qgis::LayerType type
Definition qgsmaplayer.h:93
QgsCoordinateTransformContext transformContext() const
Returns the layer data provider coordinate transform context or a default transform context if the la...
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:112
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QgsRasterDataProvider * clone() const override=0
Clone itself, create deep copy.
The raster file writer which allows you to save a raster to a new file.
Q_DECL_DEPRECATED Qgis::RasterFileWriterResult writeRaster(const QgsRasterPipe *pipe, int nCols, int nRows, const QgsRectangle &outputExtent, const QgsCoordinateReferenceSystem &crs, QgsRasterBlockFeedback *feedback=nullptr) SIP_DEPRECATED
Write raster file.
Represents a raster layer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
Contains a pipeline of raster interfaces for sequential raster processing.
bool set(QgsRasterInterface *interface)
Inserts a new known interface in default place or replace interface of the same role if it already ex...
bool insert(int idx, QgsRasterInterface *interface)
Attempts to insert interface at specified index and connect if connection would fail,...
Implements approximate projection support for optimised raster transformation.
Q_DECL_DEPRECATED void setCrs(const QgsCoordinateReferenceSystem &srcCRS, const QgsCoordinateReferenceSystem &destCRS, int srcDatumTransform=-1, int destDatumTransform=-1)
Sets the source and destination CRS.
A rectangle specified with double values.
double xMinimum
double yMinimum
double xMaximum
double yMaximum
Defines interfaces exposed by QGIS Server and made available to plugins.
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
static QStringList wcsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WCS.
Defines requests passed to QgsService classes.
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
QMap< QString, QString > Parameters
Defines the response interface passed to QgsService.
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device.
virtual void setHeader(const QString &key, const QString &value)=0
Set Header entry Add Header entry to the response Note that it is usually an error to set Header afte...
Exception thrown in case of malformed request.
WCS implementation.
Definition qgswcs.cpp:34
QgsRectangle parseBbox(const QString &bboxStr)
Parse bounding box.
void writeGetCoverage(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output WCS DescribeCoverage response.
QByteArray getCoverageData(QgsServerInterface *serverIface, const QgsProject *project, const QgsServerRequest &request)
Compute coverage data.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:7091