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