-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
qgswmsrenderer.h
295 lines (240 loc) · 11.7 KB
/
qgswmsrenderer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/***************************************************************************
qgswmsrendrer.h
-------------------
begin : May 14, 2006
copyright : (C) 2006 by Marco Hugentobler
(C) 2017 by David Marteau
email : marco dot hugentobler at karto dot baug dot ethz dot ch
david dot marteau at 3liz dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSWMSRENDERER_H
#define QGSWMSRENDERER_H
#include "qgsserversettings.h"
#include "qgswmsparameters.h"
#include "qgswmsrendercontext.h"
#include "qgsfeaturefilter.h"
#include <QDomDocument>
#include <QMap>
#include <QString>
class QgsCoordinateReferenceSystem;
class QgsPrintLayout;
class QgsFeature;
class QgsLayout;
class QgsMapLayer;
class QgsMapSettings;
class QgsPointXY;
class QgsRasterLayer;
class QgsRectangle;
class QgsRenderContext;
class QgsVectorLayer;
class QgsAccessControl;
class QgsDxfExport;
class QgsLayerTreeModel;
class QgsLayerTree;
class QgsServerInterface;
class QImage;
class QPaintDevice;
class QPainter;
class QgsLayerTreeGroup;
namespace QgsWms
{
/**
* \ingroup server
* \class QgsWms::QgsRenderer
* \brief Map renderer for WMS requests
* \since QGIS 3.0
*/
class QgsRenderer
{
public:
/**
* Constructor for QgsRenderer.
* \param context The rendering context.
* \since QGIS 3.8
*/
QgsRenderer( const QgsWmsRenderContext &context );
/**
* Destructor for QgsRenderer.
*/
~QgsRenderer();
/**
* Returns the map legend as an image (or NULLPTR in case of error). The caller takes ownership
of the image object*/
QImage *getLegendGraphics();
typedef QSet<QString> SymbolSet;
typedef QHash<QgsVectorLayer *, SymbolSet> HitTest;
/**
* Returns the map as an image (or NULLPTR in case of error). The caller takes ownership
of the image object). If an instance to existing hit test structure is passed, instead of rendering
it will fill the structure with symbols that would be used for rendering */
QImage *getMap( HitTest *hitTest = nullptr );
/**
* Identical to getMap( HitTest* hitTest ) and updates the map settings actually used.
\since QGIS 3.0 */
QImage *getMap( QgsMapSettings &mapSettings, HitTest *hitTest = nullptr );
/**
* Returns the map as DXF data
* \returns the map as DXF data
* \since QGIS 3.0
*/
QgsDxfExport getDxf();
/**
* Returns printed page as binary
\returns printed page as binary or 0 in case of error*/
QByteArray getPrint();
/**
* Creates an xml document that describes the result of the getFeatureInfo request.
* May throw an exception
*/
QByteArray getFeatureInfo( const QString &version = "1.3.0" );
private:
// Build and returns highlight layers
QList<QgsMapLayer *> highlightLayers( QList<QgsWmsParametersHighlightLayer> params );
// Build and returns external layers
QList<QgsMapLayer *> externalLayers( const QList<QgsWmsParametersExternalLayer> ¶ms );
// Rendering step for layers
QPainter *layersRendering( const QgsMapSettings &mapSettings, QImage &image, HitTest *hitTest = nullptr ) const;
// Rendering step for annotations
void annotationsRendering( QPainter *painter ) const;
// Set layer opacity
void setLayerOpacity( QgsMapLayer *layer, int opacity ) const;
// Set layer filter
void setLayerFilter( QgsMapLayer *layer, const QList<QgsWmsParametersFilter> &filters );
// Set layer python filter
void setLayerAccessControlFilter( QgsMapLayer *layer ) const;
// Set layer selection
void setLayerSelection( QgsMapLayer *layer, const QStringList &fids ) const;
// Combine map extent with layer extent
void updateExtent( const QgsMapLayer *layer, QgsMapSettings &mapSettings ) const;
// Scale image with WIDTH/HEIGHT if necessary
QImage *scaleImage( const QImage *image ) const;
// Build a layer tree model for legend
QgsLayerTreeModel *buildLegendTreeModel( const QList<QgsMapLayer *> &layers, double scaleDenominator, QgsLayerTree &rootGroup );
/**
* Creates a QImage from the HEIGHT and WIDTH parameters
* \param width image width (or -1 if width should be taken from WIDTH wms parameter)
* \param height image height (or -1 if height should be taken from HEIGHT wms parameter)
* \param useBbox flag to indicate if the BBOX has to be used to adapt aspect ratio
* \returns a non null pointer
* may throw an exception
*/
QImage *createImage( int width = -1, int height = -1, bool useBbox = true ) const;
/**
* Configures map settings according to WMS parameters.
* \param paintDevice The device that is used for painting (for dpi)
* \param mapSettings Map settings to use for rendering
* \param mandatoryCrsParam does the CRS parameter has to be considered mandatory
* may throw an exception
*/
void configureMapSettings( const QPaintDevice *paintDevice, QgsMapSettings &mapSettings, bool mandatoryCrsParam = true ) const;
QDomDocument featureInfoDocument( QList<QgsMapLayer *> &layers, const QgsMapSettings &mapSettings,
const QImage *outputImage, const QString &version ) const;
/**
* Appends feature info xml for the layer to the layer element of the
* feature info dom document.
* \param layer The vector layer
* \param infoPoint The point coordinates
* \param nFeatures The number of features
* \param infoDocument Feature info document
* \param layerElement Layer XML element
* \param mapSettings Map settings with extent, CRS, ...
* \param renderContext Context to use for feature rendering
* \param version WMS version
* \param featureBBox The bounding box of the selected features in output CRS
* \param filterGeom Geometry for filtering selected features
* \returns TRUE in case of success
*/
bool featureInfoFromVectorLayer( QgsVectorLayer *layer,
const QgsPointXY *infoPoint,
int nFeatures,
QDomDocument &infoDocument,
QDomElement &layerElement,
const QgsMapSettings &mapSettings,
QgsRenderContext &renderContext,
const QString &version,
QgsRectangle *featureBBox = nullptr,
QgsGeometry *filterGeom = nullptr ) const;
//! Appends feature info xml for the layer to the layer element of the dom document
bool featureInfoFromRasterLayer( QgsRasterLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
QDomDocument &infoDocument,
QDomElement &layerElement,
const QString &version ) const;
//! Record which symbols would be used if the map was in the current configuration of renderer. This is useful for content-based legend
void runHitTest( const QgsMapSettings &mapSettings, HitTest &hitTest ) const;
//! Record which symbols within one layer would be rendered with the given renderer context
void runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols, QgsRenderContext &context ) const;
/**
* Tests if a filter sql string is allowed (safe)
\returns true in case of success, false if string seems unsafe*/
bool testFilterStringSafety( const QString &filter ) const;
//! Helper function for filter safety test. Groups stringlist to merge entries starting/ending with quotes
static void groupStringList( QStringList &list, const QString &groupString );
/**
* Checks WIDTH/HEIGHT values against MaxWidth and MaxHeight
\returns true if width/height values are okay*/
bool checkMaximumWidthHeight() const;
//! Converts a feature info xml document to SIA2045 norm
void convertFeatureInfoToSia2045( QDomDocument &doc ) const;
//! Converts a feature info xml document to HTML
QByteArray convertFeatureInfoToHtml( const QDomDocument &doc ) const;
//! Converts a feature info xml document to Text
QByteArray convertFeatureInfoToText( const QDomDocument &doc ) const;
//! Converts a feature info xml document to json
QByteArray convertFeatureInfoToJson( const QList<QgsMapLayer *> &layers, const QDomDocument &doc ) const;
QDomElement createFeatureGML(
QgsFeature *feat,
QgsVectorLayer *layer,
QDomDocument &doc,
QgsCoordinateReferenceSystem &crs,
const QgsMapSettings &mapSettings,
const QString &typeName,
bool withGeom,
int version,
QStringList *attributes = nullptr ) const;
//! Replaces attribute value with ValueRelation or ValueRelation if defined. Otherwise returns the original value
static QString replaceValueMapAndRelation( QgsVectorLayer *vl, int idx, const QVariant &attributeVal );
//! Gets layer search rectangle (depending on request parameter, layer type, map and layer crs)
QgsRectangle featureInfoSearchRect( QgsVectorLayer *ml, const QgsMapSettings &ms, const QgsRenderContext &rct, const QgsPointXY &infoPoint ) const;
/*
* Configures the print layout for the GetPrint request
*\param c the print layout
*\param mapSettings the map settings
*\param atlasPrint true if atlas is used for printing
*\returns true in case of success
* */
bool configurePrintLayout( QgsPrintLayout *c, const QgsMapSettings &mapSettings, bool atlasPrint = false );
void removeTemporaryLayers();
void handlePrintErrors( const QgsLayout *layout ) const;
/**
* Returns QgsWmsParameter SRCWIDTH if it's a GetLegendGraphics request and otherwise HEIGHT parameter
* \returns height parameter
* \since QGIS 3.4.7
*/
int height() const;
/**
* Returns QgsWmsParameter SRCWIDTH parameter if it's a GetLegendGraphics request and otherwise WIDTH parameter
* \returns width parameter
* \since QGIS 3.4.7
*/
int width() const;
void configureLayers( QList<QgsMapLayer *> &layers, QgsMapSettings *settings = nullptr );
void setLayerStyle( QgsMapLayer *layer, const QString &style ) const;
void setLayerSld( QgsMapLayer *layer, const QDomElement &sld ) const;
QgsWmsParameters mWmsParameters;
QgsFeatureFilter mFeatureFilter;
const QgsProject *mProject = nullptr;
QList<QgsMapLayer *> mTemporaryLayers;
QgsWmsRenderContext mContext;
};
} // namespace QgsWms
#endif