Skip to content

Commit

Permalink
Add dimenstion support for GetPrint
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Sep 28, 2021
1 parent b3e6200 commit e2dd38e
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/server/CMakeLists.txt
Expand Up @@ -47,6 +47,7 @@ set(QGIS_SERVER_SRCS
qgsservicenativeloader.cpp
qgsserviceregistry.cpp
qgsfeaturefilterprovidergroup.cpp
qgsdimensionfilter.cpp
qgsfeaturefilter.cpp
qgsstorebadlayerinfo.cpp
qgsserverquerystringparameter.cpp
Expand Down
43 changes: 43 additions & 0 deletions src/server/qgsdimensionfilter.cpp
@@ -0,0 +1,43 @@
/***************************************************************************
qgsdimensionfilter.cpp
-------------------
begin : September 2021
copyright : (C) 2021 Matthias Kuhn
email : matthias@opengis.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. *
* *
***************************************************************************/

#include "qgsdimensionfilter.h"

QgsDimensionFilter::QgsDimensionFilter( const QMap<const QgsVectorLayer *, QStringList> dimensionFilter )
: mDimensionFilter( dimensionFilter )
{

}

void QgsDimensionFilter::filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &featureRequest ) const
{
const QStringList dimFilters = mDimensionFilter.value( layer );

for ( const QString &flt : dimFilters )
featureRequest.combineFilterExpression( flt );
}

QStringList QgsDimensionFilter::layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const
{
Q_UNUSED( layer )
return attributes;
}

QgsDimensionFilter *QgsDimensionFilter::clone() const
{
return new QgsDimensionFilter( mDimensionFilter );
}
49 changes: 49 additions & 0 deletions src/server/qgsdimensionfilter.h
@@ -0,0 +1,49 @@
/***************************************************************************
qgsdimensionfilter.h
-------------------
begin : September 2021
copyright : (C) 2021 Matthias Kuhn
email : matthias@opengis.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 QGSDIMENSIONFILTER_H
#define QGSDIMENSIONFILTER_H

#define SIP_NO_FILE

#include "qgsfeaturefilterprovider.h"
#include "qgis_server.h"

/**
* \ingroup server
* \class QgsDimensionFilter
* \brief A server filter to apply a dimension filter to a request
* \since QGIS 3.22
*/
class SERVER_EXPORT QgsDimensionFilter : public QgsFeatureFilterProvider
{
public:

/**
* Creates a new dimension filter object with a list of filters to be applied to
* vector layers.
*/
QgsDimensionFilter( const QMap<const QgsVectorLayer *, QStringList> dimensionFilter );

void filterFeatures( const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures ) const override;
QStringList layerAttributes( const QgsVectorLayer *layer, const QStringList &attributes ) const override;
QgsDimensionFilter *clone() const override;
private:
QMap<const QgsVectorLayer *, QStringList> mDimensionFilter;
};

#endif // QGSDIMENSIONFILTER_H
29 changes: 22 additions & 7 deletions src/server/services/wms/qgswmsrenderer.cpp
Expand Up @@ -68,6 +68,7 @@
#include "qgsattributeeditorcontainer.h"
#include "qgsattributeeditorelement.h"
#include "qgsattributeeditorfield.h"
#include "qgsdimensionfilter.h"

#include <QImage>
#include <QPainter>
Expand Down Expand Up @@ -360,15 +361,15 @@ namespace QgsWms
}
else
{
QgsAttributeList pkIndexes = cLayer->primaryKeyAttributes();
const QgsAttributeList pkIndexes = cLayer->primaryKeyAttributes();
if ( pkIndexes.size() < 1 )
{
throw QgsException( QStringLiteral( "An error occurred during the Atlas print" ) );
}
QStringList pkAttributeNames;
for ( int i = 0; i < pkIndexes.size(); ++i )
for ( int pkIndex : pkIndexes )
{
pkAttributeNames.append( cLayer->fields()[pkIndexes.at( i )].name() );
pkAttributeNames.append( cLayer->fields().at( pkIndex ).name() );
}

int nAtlasFeatures = atlasPk.size() / pkIndexes.size();
Expand Down Expand Up @@ -437,14 +438,28 @@ namespace QgsWms
// configure layout
configurePrintLayout( layout.get(), mapSettings, atlas );

#ifdef HAVE_SERVER_PYTHON_PLUGINS
QgsLayoutRenderContext &layoutRendererContext = layout->renderContext();
QgsFeatureFilterProviderGroup filters;
mContext.accessControl()->resolveFilterFeatures( mapSettings.layers() );
const QList<QgsMapLayer *> lyrs = mapSettings.layers();

#ifdef HAVE_SERVER_PYTHON_PLUGINS
mContext.accessControl()->resolveFilterFeatures( lyrs );
filters.addProvider( mContext.accessControl() );
QgsLayoutRenderContext &layoutRendererContext = layout->renderContext();
layoutRendererContext.setFeatureFilterProvider( &filters );
#endif

QMap<const QgsVectorLayer *, QStringList> fltrs;
for ( QgsMapLayer *l : lyrs )
{
if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( l ) )
{
fltrs.insert( vl, dimensionFilter( vl ) );
}
}

QgsDimensionFilter dimFilter( fltrs );
filters.addProvider( &dimFilter );
layoutRendererContext.setFeatureFilterProvider( &filters );

// Get the temporary output file
const QgsWmsParameters::Format format = mWmsParameters.format();
const QString extension = QgsWmsParameters::formatAsString( format ).toLower();
Expand Down
19 changes: 19 additions & 0 deletions tests/src/python/test_qgsserver_wms_dimension.py
Expand Up @@ -385,6 +385,25 @@ def test_wms_getmap_with_filter(self):
# same as ELEVATION=1000
self._img_diff_error(r, h, "WMS_GetMap_Dimension_Elevation_Value")

def test_wms_getprint_dimension(self):
qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.3.0",
"REQUEST": "GetPrint",
"TEMPLATE": "layoutA4",
"FORMAT": "png",
"map0:EXTENT": "-1219081,4281848,172260,5673189",
"map0:LAYERS": "dem,Datetime_dim",
"map0:SCALE": "10013037",
"CRS": "EPSG:3857",
"HEIGHT": "500",
"DIM_DATE": "2021-05-31,2021-06-30"
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetPrint_Dimension", max_size_diff=QSize(1, 1))


if __name__ == "__main__":
unittest.main()
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e2dd38e

Please sign in to comment.