20
20
***************************************************************************/
21
21
#include " qgswmsutils.h"
22
22
#include " qgswmsgetcontext.h"
23
+ #include " qgsserverprojectutils.h"
24
+
25
+ #include " qgslayertreenode.h"
26
+ #include " qgslayertreegroup.h"
27
+ #include " qgslayertreelayer.h"
28
+ #include " qgslayertreemodel.h"
29
+ #include " qgslayertree.h"
30
+ #include " qgsmaplayerstylemanager.h"
31
+
32
+ #include " qgscsexception.h"
23
33
24
34
namespace QgsWms
25
35
{
36
+ namespace
37
+ {
38
+ void appendOwsLayerStyles ( QDomDocument &doc, QDomElement &layerElem, QgsMapLayer *currentLayer );
39
+
40
+ void appendOwsLayersFromTreeGroup ( QDomDocument &doc,
41
+ QDomElement &parentLayer,
42
+ QgsServerInterface *serverIface,
43
+ const QgsProject *project,
44
+ const QgsServerRequest &request,
45
+ const QgsLayerTreeGroup *layerTreeGroup,
46
+ QgsRectangle &combinedBBox,
47
+ const QString &strGroup );
48
+
49
+ void appendOwsGeneralAndResourceList ( QDomDocument &doc, QDomElement &parentElement,
50
+ QgsServerInterface *serverIface, const QgsProject *project,
51
+ const QgsServerRequest &request );
52
+ }
26
53
27
54
void writeGetContext ( QgsServerInterface *serverIface, const QgsProject *project,
28
55
const QString &version, const QgsServerRequest &request,
@@ -40,7 +67,7 @@ namespace QgsWms
40
67
{
41
68
Q_UNUSED ( version );
42
69
43
- QgsWmsConfigParser *configParser = getConfigParser ( serverIface );
70
+ // QgsWmsConfigParser *configParser = getConfigParser( serverIface );
44
71
45
72
QDomDocument doc;
46
73
QDomProcessingInstruction xmlDeclaration = doc.createProcessingInstruction ( QStringLiteral ( " xml" ),
@@ -64,11 +91,374 @@ namespace QgsWms
64
91
owsContextElem.setAttribute ( QStringLiteral ( " version" ), QStringLiteral ( " 0.3.1" ) );
65
92
doc.appendChild ( owsContextElem );
66
93
67
- QString hrefString = serviceUrl ( request, project ).toString ( QUrl::FullyDecoded );
68
- configParser->owsGeneralAndResourceList ( owsContextElem, doc, hrefString );
94
+ appendOwsGeneralAndResourceList ( doc, owsContextElem, serverIface, project, request );
69
95
70
96
return doc;
71
97
}
98
+ namespace
99
+ {
100
+ void appendOwsGeneralAndResourceList ( QDomDocument &doc, QDomElement &parentElement,
101
+ QgsServerInterface *serverIface, const QgsProject *project,
102
+ const QgsServerRequest &request )
103
+ {
104
+ parentElement.setAttribute ( QStringLiteral ( " id" ), " ows-context-" + project->fileInfo ().baseName () );
105
+
106
+ // OWSContext General element
107
+ QDomElement generalElem = doc.createElement ( QStringLiteral ( " General" ) );
108
+
109
+ // OWSContext Window element
110
+ QDomElement windowElem = doc.createElement ( QStringLiteral ( " Window" ) );
111
+ windowElem.setAttribute ( QStringLiteral ( " height" ), QStringLiteral ( " 600" ) );
112
+ windowElem.setAttribute ( QStringLiteral ( " width" ), QStringLiteral ( " 800" ) );
113
+ generalElem.appendChild ( windowElem );
114
+
115
+ // OWS title
116
+ // why not use project title ?
117
+ QString title = QgsServerProjectUtils::owsServiceTitle ( *project );
118
+ if ( !title.isEmpty () )
119
+ {
120
+ QDomElement titleElem = doc.createElement ( QStringLiteral ( " ows:Title" ) );
121
+ QDomText titleText = doc.createTextNode ( title );
122
+ titleElem.appendChild ( titleText );
123
+ generalElem.appendChild ( titleElem );
124
+ }
125
+
126
+ // OWS abstract
127
+ QString abstract = QgsServerProjectUtils::owsServiceAbstract ( *project );
128
+ if ( !abstract.isEmpty () )
129
+ {
130
+ QDomElement abstractElem = doc.createElement ( QStringLiteral ( " ows:Abstract" ) );
131
+ QDomText abstractText = doc.createCDATASection ( abstract );
132
+ abstractElem.appendChild ( abstractText );
133
+ generalElem.appendChild ( abstractElem );
134
+ }
135
+
136
+ // OWS Keywords
137
+ QStringList keywords = QgsServerProjectUtils::owsServiceKeywords ( *project );
138
+ if ( !keywords.isEmpty () )
139
+ {
140
+ bool sia2045 = QgsServerProjectUtils::wmsInfoFormatSia2045 ( *project );
141
+
142
+ QDomElement keywordsElem = doc.createElement ( QStringLiteral ( " ows:Keywords" ) );
143
+
144
+ for ( int i = 0 ; i < keywords.size (); ++i )
145
+ {
146
+ QString keyword = keywords.at ( i );
147
+ if ( !keyword.isEmpty () )
148
+ {
149
+ QDomElement keywordElem = doc.createElement ( QStringLiteral ( " ows:Keyword" ) );
150
+ QDomText keywordText = doc.createTextNode ( keyword );
151
+ keywordElem.appendChild ( keywordText );
152
+ if ( sia2045 )
153
+ {
154
+ keywordElem.setAttribute ( QStringLiteral ( " vocabulary" ), QStringLiteral ( " SIA_Geo405" ) );
155
+ }
156
+ keywordsElem.appendChild ( keywordElem );
157
+ }
158
+ }
159
+ generalElem.appendChild ( keywordsElem );
160
+ }
161
+
162
+ // OWSContext General element is complete
163
+ parentElement.appendChild ( generalElem );
164
+
165
+ // OWSContext ResourceList element
166
+ QDomElement resourceListElem = doc.createElement ( QStringLiteral ( " ResourceList" ) );
167
+ const QgsLayerTree *projectLayerTreeRoot = project->layerTreeRoot ();
168
+ QgsRectangle combinedBBox;
169
+ appendOwsLayersFromTreeGroup ( doc, resourceListElem, serverIface, project, request, projectLayerTreeRoot, combinedBBox, QString () );
170
+ parentElement.appendChild ( resourceListElem );
171
+
172
+ // OWSContext BoundingBox
173
+ QgsCoordinateReferenceSystem projectCrs = project->crs ();
174
+ QgsRectangle mapRect = QgsServerProjectUtils::wmsExtent ( *project );
175
+ if ( mapRect.isEmpty () )
176
+ {
177
+ mapRect = combinedBBox;
178
+ }
179
+ QDomElement bboxElem = doc.createElement ( QStringLiteral ( " ows:BoundingBox" ) );
180
+ bboxElem.setAttribute ( QStringLiteral ( " crs" ), projectCrs.authid () );
181
+ if ( projectCrs.hasAxisInverted () )
182
+ {
183
+ mapRect.invert ();
184
+ }
185
+ QDomElement lowerCornerElem = doc.createElement ( QStringLiteral ( " ows:LowerCorner" ) );
186
+ QDomText lowerCornerText = doc.createTextNode ( QString::number ( mapRect.xMinimum () ) + " " + QString::number ( mapRect.yMinimum () ) );
187
+ lowerCornerElem.appendChild ( lowerCornerText );
188
+ bboxElem.appendChild ( lowerCornerElem );
189
+ QDomElement upperCornerElem = doc.createElement ( QStringLiteral ( " ows:UpperCorner" ) );
190
+ QDomText upperCornerText = doc.createTextNode ( QString::number ( mapRect.xMaximum () ) + " " + QString::number ( mapRect.yMaximum () ) );
191
+ upperCornerElem.appendChild ( upperCornerText );
192
+ bboxElem.appendChild ( upperCornerElem );
193
+ generalElem.appendChild ( bboxElem );
194
+ }
195
+
196
+ void appendOwsLayersFromTreeGroup ( QDomDocument &doc,
197
+ QDomElement &parentLayer,
198
+ QgsServerInterface *serverIface,
199
+ const QgsProject *project,
200
+ const QgsServerRequest &request,
201
+ const QgsLayerTreeGroup *layerTreeGroup,
202
+ QgsRectangle &combinedBBox,
203
+ const QString &strGroup )
204
+ {
205
+ QStringList restrictedLayers = QgsServerProjectUtils::wmsRestrictedLayers ( *project );
206
+
207
+ QList< QgsLayerTreeNode * > layerTreeGroupChildren = layerTreeGroup->children ();
208
+ for ( int i = 0 ; i < layerTreeGroupChildren.size (); ++i )
209
+ {
210
+ QgsLayerTreeNode *treeNode = layerTreeGroupChildren.at ( i );
211
+
212
+ if ( treeNode->nodeType () == QgsLayerTreeNode::NodeGroup )
213
+ {
214
+ QgsLayerTreeGroup *treeGroupChild = static_cast <QgsLayerTreeGroup *>( treeNode );
215
+
216
+ QString name = treeGroupChild->name ();
217
+ if ( restrictedLayers.contains ( name ) ) // unpublished group
218
+ {
219
+ continue ;
220
+ }
221
+
222
+ QString group;
223
+ if ( strGroup.isEmpty () )
224
+ {
225
+ group = name;
226
+ }
227
+ else
228
+ {
229
+ group = strGroup + " /" + name;
230
+ }
231
+
232
+ appendOwsLayersFromTreeGroup ( doc, parentLayer, serverIface, project, request, treeGroupChild, combinedBBox, group );
233
+ }
234
+ else
235
+ {
236
+ QgsLayerTreeLayer *treeLayer = static_cast <QgsLayerTreeLayer *>( treeNode );
237
+ QgsMapLayer *l = treeLayer->layer ();
238
+ if ( restrictedLayers.contains ( l->name () ) ) // unpublished layer
239
+ {
240
+ continue ;
241
+ }
242
+
243
+ QgsAccessControl *accessControl = serverIface->accessControls ();
244
+ if ( accessControl && !accessControl->layerReadPermission ( l ) )
245
+ {
246
+ continue ;
247
+ }
248
+
249
+ QDomElement layerElem = doc.createElement ( QStringLiteral ( " Layer" ) );
250
+
251
+ // queryable layer
252
+ if ( project->nonIdentifiableLayers ().contains ( l->id () ) )
253
+ {
254
+ layerElem.setAttribute ( QStringLiteral ( " queryable" ), QStringLiteral ( " false" ) );
255
+ }
256
+ else
257
+ {
258
+ layerElem.setAttribute ( QStringLiteral ( " queryable" ), QStringLiteral ( " true" ) );
259
+ }
260
+
261
+ // visibility
262
+ if ( treeLayer->itemVisibilityChecked () )
263
+ {
264
+ layerElem.setAttribute ( QStringLiteral ( " hidden" ), QStringLiteral ( " true" ) );
265
+ }
266
+ else
267
+ {
268
+ layerElem.setAttribute ( QStringLiteral ( " hidden" ), QStringLiteral ( " false" ) );
269
+ }
270
+
271
+ // layer group
272
+ if ( !strGroup.isEmpty () )
273
+ {
274
+ layerElem.setAttribute ( QStringLiteral ( " group" ), strGroup );
275
+ }
276
+
277
+ // Because Layer transparency is used for the rendering
278
+ // OWSContext Layer opacity is set to 1
279
+ layerElem.setAttribute ( QStringLiteral ( " opacity" ), 1 );
280
+
281
+ QString wmsName = l->name ();
282
+ if ( QgsServerProjectUtils::wmsUseLayerIds ( *project ) )
283
+ {
284
+ wmsName = l->id ();
285
+ }
286
+ else if ( !l->shortName ().isEmpty () )
287
+ {
288
+ wmsName = l->shortName ();
289
+ }
290
+ // layer wms name
291
+ layerElem.setAttribute ( QStringLiteral ( " name" ), wmsName );
292
+ // define an id based on layer wms name
293
+ layerElem.setAttribute ( QStringLiteral ( " id" ), wmsName.replace ( QRegExp ( " [\\ W]" ), QStringLiteral ( " _" ) ) );
294
+
295
+ // layer title
296
+ QDomElement titleElem = doc.createElement ( QStringLiteral ( " ows:Title" ) );
297
+ QString title = l->title ();
298
+ if ( title.isEmpty () )
299
+ {
300
+ title = l->name ();
301
+ }
302
+ QDomText titleText = doc.createTextNode ( title );
303
+ titleElem.appendChild ( titleText );
304
+ layerElem.appendChild ( titleElem );
305
+
306
+ // WMS GetMap output format
307
+ QDomElement formatElem = doc.createElement ( QStringLiteral ( " ows:OutputFormat" ) );
308
+ QDomText formatText = doc.createTextNode ( QStringLiteral ( " image/png" ) );
309
+ formatElem.appendChild ( formatText );
310
+ layerElem.appendChild ( formatElem );
311
+
312
+ // Get WMS service URL for Server Element
313
+ QUrl href = serviceUrl ( request, project );
314
+
315
+ // href needs to be a prefix
316
+ QString hrefString = href.toString ( QUrl::FullyDecoded );
317
+ hrefString.append ( href.hasQuery () ? " &" : " ?" );
318
+
319
+ // COntext Server Element with WMS service URL
320
+ QDomElement serverElem = doc.createElement ( QStringLiteral ( " Server" ) );
321
+ serverElem.setAttribute ( QStringLiteral ( " service" ), QStringLiteral ( " urn:ogc:serviceType:WMS" ) );
322
+ serverElem.setAttribute ( QStringLiteral ( " version" ), QStringLiteral ( " 1.3.0" ) );
323
+ serverElem.setAttribute ( QStringLiteral ( " default" ), QStringLiteral ( " true" ) );
324
+ QDomElement orServerElem = doc.createElement ( QStringLiteral ( " OnlineResource" ) );
325
+ orServerElem.setAttribute ( QStringLiteral ( " xlink:href" ), hrefString );
326
+ serverElem.appendChild ( orServerElem );
327
+ layerElem.appendChild ( serverElem );
328
+
329
+ QString abstract = l->abstract ();
330
+ if ( !abstract.isEmpty () )
331
+ {
332
+ QDomElement abstractElem = doc.createElement ( QStringLiteral ( " ows:Abstract" ) );
333
+ QDomText abstractText = doc.createTextNode ( abstract );
334
+ abstractElem.appendChild ( abstractText );
335
+ layerElem.appendChild ( abstractElem );
336
+ }
337
+
338
+ // min/max scale denominatorScaleBasedVisibility
339
+ if ( l->hasScaleBasedVisibility () )
340
+ {
341
+ QString minScaleString = QString::number ( l->minimumScale () );
342
+ QString maxScaleString = QString::number ( l->maximumScale () );
343
+ QDomElement minScaleElem = doc.createElement ( QStringLiteral ( " sld:MinScaleDenominator" ) );
344
+ QDomText minScaleText = doc.createTextNode ( minScaleString );
345
+ minScaleElem.appendChild ( minScaleText );
346
+ layerElem.appendChild ( minScaleElem );
347
+ QDomElement maxScaleElem = doc.createElement ( QStringLiteral ( " sld:MaxScaleDenominator" ) );
348
+ QDomText maxScaleText = doc.createTextNode ( maxScaleString );
349
+ maxScaleElem.appendChild ( maxScaleText );
350
+ layerElem.appendChild ( maxScaleElem );
351
+ }
352
+
353
+ // Style list
354
+ appendOwsLayerStyles ( doc, layerElem, l );
355
+
356
+ // keyword list
357
+ if ( !l->keywordList ().isEmpty () )
358
+ {
359
+ QStringList keywordStringList = l->keywordList ().split ( QStringLiteral ( " ," ) );
360
+ bool sia2045 = QgsServerProjectUtils::wmsInfoFormatSia2045 ( *project );
361
+
362
+ QDomElement keywordsElem = doc.createElement ( QStringLiteral ( " ows:Keywords" ) );
363
+ for ( int i = 0 ; i < keywordStringList.size (); ++i )
364
+ {
365
+ QDomElement keywordElem = doc.createElement ( QStringLiteral ( " ows:Keyword" ) );
366
+ QDomText keywordText = doc.createTextNode ( keywordStringList.at ( i ).trimmed () );
367
+ keywordElem.appendChild ( keywordText );
368
+ if ( sia2045 )
369
+ {
370
+ keywordElem.setAttribute ( QStringLiteral ( " vocabulary" ), QStringLiteral ( " SIA_Geo405" ) );
371
+ }
372
+ keywordsElem.appendChild ( keywordElem );
373
+ }
374
+ layerElem.appendChild ( keywordsElem );
375
+ }
376
+
377
+ // layer data URL
378
+ QString dataUrl = l->dataUrl ();
379
+ if ( !dataUrl.isEmpty () )
380
+ {
381
+ QDomElement dataUrlElem = doc.createElement ( QStringLiteral ( " DataURL" ) );
382
+ QString dataUrlFormat = l->dataUrlFormat ();
383
+ dataUrlElem.setAttribute ( QStringLiteral ( " format" ), dataUrlFormat );
384
+ QDomElement dataORElem = doc.createElement ( QStringLiteral ( " OnlineResource" ) );
385
+ dataORElem.setAttribute ( QStringLiteral ( " xmlns:xlink" ), QStringLiteral ( " http://www.w3.org/1999/xlink" ) );
386
+ dataORElem.setAttribute ( QStringLiteral ( " xlink:type" ), QStringLiteral ( " simple" ) );
387
+ dataORElem.setAttribute ( QStringLiteral ( " xlink:href" ), dataUrl );
388
+ dataUrlElem.appendChild ( dataORElem );
389
+ layerElem.appendChild ( dataUrlElem );
390
+ }
391
+
392
+ // layer metadata URL
393
+ QString metadataUrl = l->metadataUrl ();
394
+ if ( !metadataUrl.isEmpty () )
395
+ {
396
+ QDomElement metaUrlElem = doc.createElement ( QStringLiteral ( " MetadataURL" ) );
397
+ QString metadataUrlFormat = l->metadataUrlFormat ();
398
+ metaUrlElem.setAttribute ( QStringLiteral ( " format" ), metadataUrlFormat );
399
+ QDomElement metaUrlORElem = doc.createElement ( QStringLiteral ( " OnlineResource" ) );
400
+ metaUrlORElem.setAttribute ( QStringLiteral ( " xmlns:xlink" ), QStringLiteral ( " http://www.w3.org/1999/xlink" ) );
401
+ metaUrlORElem.setAttribute ( QStringLiteral ( " xlink:type" ), QStringLiteral ( " simple" ) );
402
+ metaUrlORElem.setAttribute ( QStringLiteral ( " xlink:href" ), metadataUrl );
403
+ metaUrlElem.appendChild ( metaUrlORElem );
404
+ layerElem.appendChild ( metaUrlElem );
405
+ }
406
+
407
+ // update combineBBox
408
+ try
409
+ {
410
+ QgsCoordinateTransform t ( l->crs (), project->crs () );
411
+ QgsRectangle BBox = t.transformBoundingBox ( l->extent () );
412
+ if ( combinedBBox.isEmpty () )
413
+ {
414
+ combinedBBox = BBox;
415
+ }
416
+ else
417
+ {
418
+ combinedBBox.combineExtentWith ( BBox );
419
+ }
420
+ }
421
+ catch ( const QgsCsException &cse )
422
+ {
423
+ Q_UNUSED ( cse );
424
+ }
425
+
426
+ if ( parentLayer.hasChildNodes () )
427
+ {
428
+ parentLayer.insertBefore ( layerElem, parentLayer.firstChild () );
429
+ }
430
+ else
431
+ {
432
+ parentLayer.appendChild ( layerElem );
433
+ }
434
+ }// end of treeNode type
435
+ }// end of for
436
+ }
437
+
438
+ void appendOwsLayerStyles ( QDomDocument &doc, QDomElement &layerElem, QgsMapLayer *currentLayer )
439
+ {
440
+ Q_FOREACH ( QString styleName, currentLayer->styleManager ()->styles () )
441
+ {
442
+ if ( styleName.isEmpty () )
443
+ styleName = EMPTY_STYLE_NAME;
444
+
445
+ QDomElement styleListElem = doc.createElement ( QStringLiteral ( " StyleList" ) );
446
+ // only one default style in project file mode
447
+ QDomElement styleElem = doc.createElement ( QStringLiteral ( " Style" ) );
448
+ styleElem.setAttribute ( QStringLiteral ( " current" ), QStringLiteral ( " true" ) );
449
+ QDomElement styleNameElem = doc.createElement ( QStringLiteral ( " Name" ) );
450
+ QDomText styleNameText = doc.createTextNode ( styleName );
451
+ styleNameElem.appendChild ( styleNameText );
452
+ QDomElement styleTitleElem = doc.createElement ( QStringLiteral ( " Title" ) );
453
+ QDomText styleTitleText = doc.createTextNode ( styleName );
454
+ styleTitleElem.appendChild ( styleTitleText );
455
+ styleElem.appendChild ( styleNameElem );
456
+ styleElem.appendChild ( styleTitleElem );
457
+ styleListElem.appendChild ( styleElem );
458
+ layerElem.appendChild ( styleListElem );
459
+ }
460
+ }
461
+ }
72
462
73
463
} // samespace QgsWms
74
464
0 commit comments