Skip to content

Commit

Permalink
[FEATURE]: possibility to select features in QGIS server by layername…
Browse files Browse the repository at this point in the history
… / id in GetMap and GetPrint
  • Loading branch information
mhugent committed Aug 18, 2011
1 parent f32cd21 commit a7a85aa
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/mapserver/qgsprojectparser.cpp
Expand Up @@ -22,6 +22,7 @@
#include "qgslogger.h"
#include "qgsmapserviceexception.h"
#include "qgsrasterlayer.h"
#include "qgsrenderer.h"
#include "qgsvectorlayer.h"

#include "qgscomposition.h"
Expand All @@ -42,6 +43,7 @@ QgsProjectParser::QgsProjectParser( QDomDocument* xmlDoc, const QString& filePat
{
mOutputUnits = QgsMapRenderer::Millimeters;
setLegendParametersFromProject();
QgsRenderer::setSelectionColor( QColor( 255, 255, 0 ) );
}

QgsProjectParser::~QgsProjectParser()
Expand Down
101 changes: 96 additions & 5 deletions src/mapserver/qgswmsserver.cpp
Expand Up @@ -410,7 +410,8 @@ QByteArray* QgsWMSServer::getPrint( const QString& formatString )
}
delete theImage;

QMap<QString, QString> originalLayerFilters = applyRequestedLayerFilters( layersList, layerIdList );
QMap<QString, QString> originalLayerFilters = applyRequestedLayerFilters( layersList );
QStringList selectedLayerIdList = applyFeatureSelections( layersList );

//GetPrint request needs a template parameter
std::map<QString, QString>::const_iterator templateIt = mParameterMap.find( "TEMPLATE" );
Expand All @@ -423,6 +424,7 @@ QByteArray* QgsWMSServer::getPrint( const QString& formatString )
if ( !c )
{
restoreLayerFilters( originalLayerFilters );
clearFeatureSelections( selectedLayerIdList );
return 0;
}

Expand Down Expand Up @@ -480,6 +482,7 @@ QByteArray* QgsWMSServer::getPrint( const QString& formatString )
{
delete c;
restoreLayerFilters( originalLayerFilters );
clearFeatureSelections( selectedLayerIdList );
return 0;
}

Expand Down Expand Up @@ -523,6 +526,7 @@ QByteArray* QgsWMSServer::getPrint( const QString& formatString )
throw QgsMapServiceException( "InvalidFormat", "Output format '" + formatString + "' is not supported in the GetPrint request" );
}
restoreLayerFilters( originalLayerFilters );
clearFeatureSelections( selectedLayerIdList );

delete c;
return ba;
Expand Down Expand Up @@ -552,9 +556,13 @@ QImage* QgsWMSServer::getMap()
QPainter thePainter( theImage );
thePainter.setRenderHint( QPainter::Antialiasing ); //make it look nicer

QMap<QString, QString> originalLayerFilters = applyRequestedLayerFilters( layersList, layerIdList );
QMap<QString, QString> originalLayerFilters = applyRequestedLayerFilters( layersList );
QStringList selectedLayerIdList = applyFeatureSelections( layersList );

mMapRenderer->render( &thePainter );

restoreLayerFilters( originalLayerFilters );
clearFeatureSelections( selectedLayerIdList );

QgsMapLayerRegistry::instance()->mapLayers().clear();
return theImage;
Expand Down Expand Up @@ -693,7 +701,7 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result )

//get the layer registered in QgsMapLayerRegistry and apply possible filters
QStringList layerIds = layerSet( layersList, stylesList, mMapRenderer->destinationCrs() );
QMap<QString, QString> originalLayerFilters = applyRequestedLayerFilters( layersList, layerIds );
QMap<QString, QString> originalLayerFilters = applyRequestedLayerFilters( layersList );

QDomElement getFeatureInfoElement = result.createElement( "GetFeatureInfoResponse" );
result.appendChild( getFeatureInfoElement );
Expand Down Expand Up @@ -1617,11 +1625,11 @@ void QgsWMSServer::drawRasterSymbol( QgsComposerLegendItem* item, QPainter* p, d
p->drawRect( QRectF( boxSpace, currentY + yDownShift, symbolWidth, symbolHeight ) );
}

QMap<QString, QString> QgsWMSServer::applyRequestedLayerFilters( const QStringList& layerList, const QStringList& layerIds ) const
QMap<QString, QString> QgsWMSServer::applyRequestedLayerFilters( const QStringList& layerList ) const
{
QMap<QString, QString> filterMap;

if ( layerList.isEmpty() || layerIds.isEmpty() )
if ( layerList.isEmpty() )
{
return filterMap;
}
Expand Down Expand Up @@ -1818,3 +1826,86 @@ bool QgsWMSServer::testFilterStringSafety( const QString& filter ) const

return true;
}

QStringList QgsWMSServer::applyFeatureSelections( const QStringList& layerList ) const
{
QStringList layersWithSelections;
if ( layerList.isEmpty() )
{
return layersWithSelections;
}

std::map<QString, QString>::const_iterator selectionIt = mParameterMap.find( "SELECTION" );
if ( selectionIt == mParameterMap.end() )
{
return layersWithSelections;
}

QString selectionString = selectionIt->second;
QStringList selectionLayerList = selectionString.split( ";" );
QStringList::const_iterator selectionLayerIt = selectionLayerList.constBegin();
for ( ; selectionLayerIt != selectionLayerList.constEnd(); ++selectionLayerIt )
{
//separate layer name from id list
QStringList layerIdSplit = selectionLayerIt->split( ":" );
if ( layerIdSplit.size() < 2 )
{
continue;
}

//find layerId for layer name
QString layerName = layerIdSplit.at( 0 );
QgsVectorLayer* vLayer = 0;

QMap<QString, QgsMapLayer*>& layerMap = QgsMapLayerRegistry::instance()->mapLayers();
QMap<QString, QgsMapLayer*>::iterator layerIt = layerMap.begin();
for ( ; layerIt != layerMap.end(); ++layerIt )
{
if ( layerIt.value() && layerIt.value()->name() == layerName )
{
vLayer = qobject_cast<QgsVectorLayer*>( layerIt.value() );
layersWithSelections.push_back( vLayer->id() );
break;
}
}

if ( !vLayer )
{
continue;
}

QStringList idList = layerIdSplit.at( 1 ).split( "," );
QgsFeatureIds selectedIds;

QStringList::const_iterator idIt = idList.constBegin();
for ( ; idIt != idList.constEnd(); ++idIt )
{
selectedIds.insert( STRING_TO_FID( *idIt ) );
}

vLayer->setSelectedFeatures( selectedIds );
}


return layersWithSelections;
}

void QgsWMSServer::clearFeatureSelections( const QStringList& layerIds ) const
{
QMap<QString, QgsMapLayer*>& layerMap = QgsMapLayerRegistry::instance()->mapLayers();

QStringList::const_iterator layerIdIt = layerIds.constBegin();
for ( ; layerIdIt != layerIds.constEnd(); ++layerIdIt )
{
QMap<QString, QgsMapLayer*>::iterator layerIt = layerMap.find( *layerIdIt );
if ( layerIt != layerMap.end() )
{
QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer*>( layerIt.value() );
if ( vlayer )
{
vlayer->setSelectedFeatures( QgsFeatureIds() );
}
}
}
return;
}
8 changes: 7 additions & 1 deletion src/mapserver/qgswmsserver.h
Expand Up @@ -142,13 +142,19 @@ class QgsWMSServer

/**Apply filter (subset) strings from the request to the layers. Example: '&FILTER=<layer1>:"AND property > 100",<layer2>:"AND bla = 'hallo!'" '
@return a map with the original filters ( layer id / filter string )*/
QMap<QString, QString> applyRequestedLayerFilters( const QStringList& layerList, const QStringList& layerIds ) const;
QMap<QString, QString> applyRequestedLayerFilters( const QStringList& layerList ) const;
/**Restores the original layer filters*/
void restoreLayerFilters( const QMap < QString, QString >& filterMap ) const;
/**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;

/**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;

/**Map containing the WMS parameters*/
std::map<QString, QString> mParameterMap;
QgsConfigParser* mConfigParser;
Expand Down

0 comments on commit a7a85aa

Please sign in to comment.