QGIS API Documentation 3.41.0-Master (af5edcb665c)
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 <QTemporaryFile>
21
22#include "qgswcsutils.h"
24#include "qgswcsgetcoverage.h"
25
26#include "qgsproject.h"
27#include "qgsrasterlayer.h"
29#include "qgsrasterpipe.h"
30#include "qgsrasterprojector.h"
31#include "qgsrasterfilewriter.h"
32
33
34namespace QgsWcs
35{
36
40 void writeGetCoverage( QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response )
41 {
42 Q_UNUSED( version )
43
44 response.write( getCoverageData( serverIface, project, request ) );
45 response.setHeader( "Content-Type", "image/tiff" );
46 }
47
48 QByteArray getCoverageData( QgsServerInterface *serverIface, const QgsProject *project, const QgsServerRequest &request )
49 {
50 const QgsServerRequest::Parameters parameters = request.parameters();
51
52#ifdef HAVE_SERVER_PYTHON_PLUGINS
53 QgsAccessControl *accessControl = serverIface->accessControls();
54#else
55 ( void ) serverIface;
56#endif
57 //defining coverage name
58 QString coveName;
59 //read COVERAGE
60 const QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "COVERAGE" ) );
61 if ( cove_name_it != parameters.constEnd() )
62 {
63 coveName = cove_name_it.value();
64 }
65 if ( coveName.isEmpty() )
66 {
67 const QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "IDENTIFIER" ) );
68 if ( cove_name_it != parameters.constEnd() )
69 {
70 coveName = cove_name_it.value();
71 }
72 }
73
74 if ( coveName.isEmpty() )
75 {
76 throw QgsRequestNotWellFormedException( QStringLiteral( "COVERAGE is mandatory" ) );
77 }
78
79 //get the raster layer
80 const QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project );
81
82 QgsRasterLayer *rLayer = nullptr;
83 for ( int i = 0; i < wcsLayersId.size(); ++i )
84 {
85 QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) );
86 if ( !layer )
87 {
88 continue;
89 }
90 if ( layer->type() != Qgis::LayerType::Raster )
91 {
92 continue;
93 }
94#ifdef HAVE_SERVER_PYTHON_PLUGINS
95 if ( !accessControl->layerReadPermission( layer ) )
96 {
97 continue;
98 }
99#endif
100 QString name = layer->name();
101 if ( !layer->serverProperties()->shortName().isEmpty() )
102 name = layer->serverProperties()->shortName();
103 name = name.replace( QLatin1String( " " ), QLatin1String( "_" ) );
104
105 if ( name == coveName )
106 {
107 rLayer = qobject_cast<QgsRasterLayer *>( layer );
108 break;
109 }
110 }
111 if ( !rLayer )
112 {
113 throw QgsRequestNotWellFormedException( QStringLiteral( "The layer for the COVERAGE '%1' is not found" ).arg( coveName ) );
114 }
115
116 double minx = 0.0, miny = 0.0, maxx = 0.0, maxy = 0.0;
117 // WIDTh and HEIGHT
118 int width = 0, height = 0;
119 // CRS
120 QString crs;
121
122 // read BBOX
123 const QgsRectangle bbox = parseBbox( parameters.value( QStringLiteral( "BBOX" ) ) );
124 if ( !bbox.isEmpty() )
125 {
126 minx = bbox.xMinimum();
127 miny = bbox.yMinimum();
128 maxx = bbox.xMaximum();
129 maxy = bbox.yMaximum();
130 }
131 else
132 {
133 throw QgsRequestNotWellFormedException( QStringLiteral( "The BBOX is mandatory and has to be xx.xxx,yy.yyy,xx.xxx,yy.yyy" ) );
134 }
135
136 // read WIDTH
137 bool conversionSuccess = false;
138 width = parameters.value( QStringLiteral( "WIDTH" ), QStringLiteral( "0" ) ).toInt( &conversionSuccess );
139 if ( !conversionSuccess )
140 {
141 width = 0;
142 }
143 // read HEIGHT
144 height = parameters.value( QStringLiteral( "HEIGHT" ), QStringLiteral( "0" ) ).toInt( &conversionSuccess );
145 if ( !conversionSuccess )
146 {
147 height = 0;
148 }
149
150 if ( width < 0 || height < 0 )
151 {
152 throw QgsRequestNotWellFormedException( QStringLiteral( "The WIDTH and HEIGHT are mandatory and have to be integer" ) );
153 }
154
155 crs = parameters.value( QStringLiteral( "CRS" ) );
156 if ( crs.isEmpty() )
157 {
158 throw QgsRequestNotWellFormedException( QStringLiteral( "The CRS is mandatory" ) );
159 }
160
162 if ( !requestCRS.isValid() )
163 {
164 throw QgsRequestNotWellFormedException( QStringLiteral( "Invalid CRS" ) );
165 }
166
167 QgsRectangle rect( minx, miny, maxx, maxy );
168
169 // transform rect
170 if ( requestCRS != rLayer->crs() )
171 {
172 const QgsCoordinateTransform t( requestCRS, rLayer->crs(), project );
173 rect = t.transformBoundingBox( rect );
174 }
175
176 // RESPONSE_CRS
177 QgsCoordinateReferenceSystem responseCRS = rLayer->crs();
178 crs = parameters.value( QStringLiteral( "RESPONSE_CRS" ) );
179 if ( !crs.isEmpty() )
180 {
182 if ( !responseCRS.isValid() )
183 {
184 responseCRS = rLayer->crs();
185 }
186 }
187
188 QTemporaryFile tempFile;
189 tempFile.open();
190 QgsRasterFileWriter fileWriter( tempFile.fileName() );
191
192 // clone pipe/provider
193 QgsRasterPipe pipe;
194 if ( !pipe.set( rLayer->dataProvider()->clone() ) )
195 {
196 throw QgsRequestNotWellFormedException( QStringLiteral( "Cannot set pipe provider" ) );
197 }
198
199 // add projector if necessary
200 if ( responseCRS != rLayer->crs() )
201 {
202 QgsRasterProjector *projector = new QgsRasterProjector;
203 projector->setCrs( rLayer->crs(), responseCRS, rLayer->transformContext() );
204 if ( !pipe.insert( 2, projector ) )
205 {
206 throw QgsRequestNotWellFormedException( QStringLiteral( "Cannot set pipe projector" ) );
207 }
208 }
209
210 const Qgis::RasterFileWriterResult err = fileWriter.writeRaster( &pipe, width, height, rect, responseCRS, rLayer->transformContext() );
212 {
213 throw QgsRequestNotWellFormedException( QStringLiteral( "Cannot write raster error code: %1" ).arg( qgsEnumValueToKey( err ) ) );
214 }
215 return tempFile.readAll();
216 }
217
218} // namespace QgsWcs
RasterFileWriterResult
Raster file export results.
Definition qgis.h:1552
@ Success
Successful export.
@ Raster
Raster layer.
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.
This class 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.
Class for doing transforms between two map 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:76
QString name
Definition qgsmaplayer.h:80
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:83
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
Qgis::LayerType type
Definition qgsmaplayer.h:86
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:107
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
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins.
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
QMap< QString, QString > Parameters
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
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.
SERVER_EXPORT QStringList wcsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WCS.
WCS implementation.
Definition qgswcs.cpp:30
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:6257
const QgsCoordinateReferenceSystem & crs