/
qgswmsserver.h
289 lines (242 loc) · 14.2 KB
/
qgswmsserver.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
/***************************************************************************
qgswmsserver.h
-------------------
begin : May 14, 2006
copyright : (C) 2006 by Marco Hugentobler
email : marco dot hugentobler at karto dot baug dot ethz dot ch
***************************************************************************/
/***************************************************************************
* *
* 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 QGSWMSSERVER_H
#define QGSWMSSERVER_H
#include "qgsowsserver.h"
#include "qgswmsconfigparser.h"
#include <QDomDocument>
#include <QMap>
#include <QPair>
#include <QString>
#include <map>
class QgsCapabilitiesCache;
class QgsCoordinateReferenceSystem;
class QgsComposerLayerItem;
class QgsComposerLegendItem;
class QgsComposition;
class QgsConfigParser;
class QgsFeature;
class QgsFeatureRenderer;
class QgsMapLayer;
class QgsMapRenderer;
class QgsPoint;
class QgsRasterLayer;
class QgsRasterRenderer;
class QgsRectangle;
class QgsRenderContext;
class QgsVectorLayer;
class QgsSymbol;
class QgsSymbol;
class QgsAccessControl;
class QColor;
class QFile;
class QFont;
class QImage;
class QPaintDevice;
class QPainter;
class QStandardItem;
/** This class handles all the wms server requests. The parameters and values have to be passed in the form of
a map<QString, QString>. This map is usually generated by a subclass of QgsWMSRequestHandler, which makes QgsWMSServer
independent from any server side technology*/
class QgsWmsServer: public QgsOWSServer
{
public:
/** Constructor. Does _NOT_ take ownership of
QgsConfigParser, QgsCapabilitiesCache and QgsMapRenderer*/
QgsWmsServer(
const QString& configFilePath
, QMap<QString, QString> ¶meters
, QgsWmsConfigParser* cp
, QgsRequestHandler* rh
, QgsMapRenderer* renderer
, QgsCapabilitiesCache* capCache
#ifdef HAVE_SERVER_PYTHON_PLUGINS
, const QgsAccessControl* accessControl
#endif
);
~QgsWmsServer();
void executeRequest() override;
/** Returns an XML file with the capabilities description (as described in the WMS specs)
@param version WMS version (1.1.1 or 1.3.0)
@param fullProjectInformation If true: add extended project information (does not validate against WMS schema)*/
QDomDocument getCapabilities( QString version = "1.3.0", bool fullProjectInformation = false );
QDomDocument getContext();
/** Returns the map legend as an image (or a null pointer in case of error). The caller takes ownership
of the image object*/
QImage* getLegendGraphics();
typedef QSet<QgsSymbol*> SymbolSet;
typedef QHash<QgsVectorLayer*, SymbolSet> HitTest;
/** Returns the map as an image (or a null pointer 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 );
/** GetMap request with vector format output. This output is usually symbolized (difference to WFS GetFeature)*/
void getMapAsDxf();
/** Returns an SLD file with the style of the requested layer. Exception is raised in case of troubles :-)*/
QDomDocument getStyle();
/** Returns an SLD file with the styles of the requested layers. Exception is raised in case of troubles :-)*/
QDomDocument getStyles();
/** Returns a describeLayer file with the onlineResource of the requested layers. Exception is raised in case of troubles :-)*/
QDomDocument describeLayer();
/** Returns printed page as binary
@param formatString out: format of the print output (e.g. pdf, svg, png, ...)
@return printed page as binary or 0 in case of error*/
QByteArray* getPrint( const QString& formatString );
/** Creates an xml document that describes the result of the getFeatureInfo request.
@return 0 in case of success*/
int getFeatureInfo( QDomDocument& result, const QString& version = "1.3.0" );
/** Sets configuration parser for administration settings. Does not take ownership*/
void setAdminConfigParser( QgsWmsConfigParser* parser ) { mConfigParser = parser; }
/** Returns the schemaExtension for WMS 1.3.0 capabilities*/
QDomDocument getSchemaExtension();
private:
/** Don't use the default constructor*/
QgsWmsServer();
/** Initializes WMS layers and configures mMapRendering.
@param layersList out: list with WMS layer names
@param stylesList out: list with WMS style names
@param layerIdList out: list with QGIS layer ids
@return image configured together with mMapRenderer (or 0 in case of error). The calling function takes ownership of the image*/
QImage* initializeRendering( QStringList& layersList, QStringList& stylesList, QStringList& layerIdList );
/** 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)
@return 0 in case of error*/
QImage* createImage( int width = -1, int height = -1 ) const;
/** Configures mMapRenderer to the parameters
HEIGHT, WIDTH, BBOX, CRS.
@param paintDevice the device that is used for painting (for dpi)
@return 0 in case of success*/
int configureMapRender( const QPaintDevice* paintDevice ) const;
/** Reads the layers and style lists from the parameters LAYERS and STYLES
@return 0 in case of success*/
int readLayersAndStyles( QStringList& layersList, QStringList& stylesList ) const;
/** If the parameter SLD exists, mSLDParser is configured appropriately. The lists are
set to the layer and style names according to the SLD
@return 0 in case of success*/
int initializeSLDParser( QStringList& layersList, QStringList& stylesList );
static bool infoPointToMapCoordinates( int i, int j, QgsPoint* infoPoint, QgsMapRenderer* mapRenderer );
/** Appends feature info xml for the layer to the layer element of the feature info dom document
@param featureBBox the bounding box of the selected features in output CRS
@return 0 in case of success*/
int featureInfoFromVectorLayer( QgsVectorLayer* layer,
const QgsPoint* infoPoint,
int nFeatures,
QDomDocument& infoDocument,
QDomElement& layerElement,
QgsMapRenderer* mapRender,
QgsRenderContext& renderContext,
const QString& version,
const QString& infoFormat,
QgsRectangle* featureBBox = nullptr ) const;
/** Appends feature info xml for the layer to the layer element of the dom document*/
int featureInfoFromRasterLayer( QgsRasterLayer* layer,
const QgsPoint* infoPoint,
QDomDocument& infoDocument,
QDomElement& layerElement,
const QString& version,
const QString& infoFormat ) const;
/** Creates a layer set and returns a stringlist with layer ids that can be passed to a QgsMapRenderer. Usually used in conjunction with readLayersAndStyles
@param scaleDenominator Filter out layer if scale based visibility does not match (or use -1 if no scale restriction)*/
QStringList layerSet( const QStringList& layersList, const QStringList& stylesList, const QgsCoordinateReferenceSystem& destCRS, double scaleDenominator = -1 ) const;
/** Record which symbols would be used if the map was in the current configuration of mMapRenderer. This is useful for content-based legend*/
void runHitTest( QPainter* painter, HitTest& hitTest );
/** Record which symbols within one layer would be rendered with the given renderer context*/
void runHitTestLayer( QgsVectorLayer* vl, SymbolSet& usedSymbols, QgsRenderContext& context );
/** Read legend parameter from the request or from the first print composer in the project*/
void legendParameters( double& boxSpace, double& layerSpace, double& layerTitleSpace,
double& symbolSpace, double& iconLabelSpace, double& symbolWidth, double& symbolHeight, QFont& layerFont, QFont& itemFont, QColor& layerFontColor, QColor& itemFontColor );
#if 0
QImage* printCompositionToImage( QgsComposition* c ) const;
#endif
/** Apply filter (subset) strings from the request to the layers. Example: '&FILTER=<layer1>:"AND property > 100",<layer2>:"AND bla = 'hallo!'" '
* @param layerList list of layer IDs to filter
* @param originalFilters hash of layer ID to original filter string
* @note It is strongly recommended that this method be called alongside use of QgsOWSServerFilterRestorer
* to ensure that the original filters are always correctly restored, regardless of whether exceptions
* are thrown or functions are terminated early.
*/
void applyRequestedLayerFilters( const QStringList& layerList, QHash<QgsMapLayer*, QString>& originalFilters ) const;
#ifdef HAVE_SERVER_PYTHON_PLUGINS
/** Apply filter strings from the access control to the layers.
* @param layerList layers to filter
* @param originalLayerFilters the original layers filter dictionary
*/
void applyAccessControlLayersFilters( const QStringList& layerList, QHash<QgsMapLayer*, QString>& originalLayerFilters ) const;
#endif
/** Tests if a filter sql string is allowed (safe)
@return 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 );
/** Select vector features with ids specified in parameter SELECTED, e.g. ...&SELECTED=layer1:1,2,9;layer2:3,5,10&...
@return list with layer ids where selections have been created*/
QStringList applyFeatureSelections( const QStringList& layerList ) const;
/** Clear all feature selections in the given layers*/
void clearFeatureSelections( const QStringList& layerIds ) const;
/** Applies opacity on layer/group level*/
void applyOpacities( const QStringList& layerList, QList< QPair< QgsVectorLayer*, QgsFeatureRenderer*> >& vectorRenderers,
QList< QPair< QgsRasterLayer*, QgsRasterRenderer* > >& rasterRenderers,
QList< QPair< QgsVectorLayer*, double > >& labelTransparencies,
QList< QPair< QgsVectorLayer*, double > >& labelBufferTransparencies
);
/** Restore original opacities*/
void restoreOpacities( QList< QPair <QgsVectorLayer*, QgsFeatureRenderer*> >& vectorRenderers,
QList< QPair < QgsRasterLayer*, QgsRasterRenderer* > >& rasterRenderers,
QList< QPair< QgsVectorLayer*, double > >& labelTransparencies,
QList< QPair< QgsVectorLayer*, double > >& labelBufferTransparencies );
void appendFormats( QDomDocument &doc, QDomElement &elem, const QStringList &formats );
/** Checks WIDTH/HEIGHT values agains MaxWidth and MaxHeight
@return true if width/height values are okay*/
bool checkMaximumWidthHeight() const;
/** Get service address from REQUEST_URI if not specified in the configuration*/
QString serviceUrl() const;
/** Add '<?xml version="1.0" ?>'. Some clients need an xml declaration (though it is not strictly required)*/
void addXmlDeclaration( QDomDocument& doc ) const;
/** Converts a feature info xml document to SIA2045 norm*/
void convertFeatureInfoToSIA2045( QDomDocument& doc );
/** Cleanup temporary objects (e.g. SLD parser objects or temporary files) after request*/
void cleanupAfterRequest();
/** Map containing the WMS parameters*/
QgsMapRenderer* mMapRenderer;
QgsCapabilitiesCache* mCapabilitiesCache;
QgsWmsConfigParser* mConfigParser;
bool mOwnsConfigParser; //delete config parser after request (e.g. sent SLD)
// speficy if layer or rule item labels should be drawn in the legend graphic with GetLegendGraphics
bool mDrawLegendLayerLabel;
bool mDrawLegendItemLabel;
QDomElement createFeatureGML(
QgsFeature* feat,
QgsVectorLayer* layer,
QDomDocument& doc,
QgsCoordinateReferenceSystem& crs,
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 QString& attributeVal );
/** Return the image quality to use for getMap request */
int getImageQuality() const;
/** Return precision to use for GetFeatureInfo request */
int getWMSPrecision( int defaultValue ) const;
/** Gets layer search rectangle (depending on request parameter, layer type, map and layer crs)*/
QgsRectangle featureInfoSearchRect( QgsVectorLayer* ml, QgsMapRenderer* mr, const QgsRenderContext& rct, const QgsPoint& infoPoint ) const;
/** Reads and extracts the different options in the FORMAT_OPTIONS parameter*/
void readFormatOptions( QMap<QString, QString>& formatOptions ) const;
void readDxfLayerSettings( QList< QPair<QgsVectorLayer *, int > >& layers, const QMap<QString, QString>& formatOptionsMap ) const;
};
#endif