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