Skip to content

Commit

Permalink
Implement attribute restrictions in wms/wfs servers
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Hugentobler committed Oct 17, 2012
1 parent a02225c commit 19b0dbc
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 59 deletions.
7 changes: 5 additions & 2 deletions src/mapserver/qgsconfigparser.h
Expand Up @@ -109,8 +109,11 @@ class QgsConfigParser
Default implementation returns an empty map*/
virtual QMap< QString, QMap< int, QString > > layerAliasInfo() const { return QMap< QString, QMap<int, QString> > (); }

/**Returns information about vector attributes with hidden edit type. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > hiddenAttributes() const { return QMap< QString, QSet<QString> >(); }
/**Returns attributes excluded from WMS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wmsExcludedAttributes() const { return QMap< QString, QSet<QString> >(); }

/**Returns attributes excluded from WFS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wfsExcludedAttributes() const { return QMap< QString, QSet<QString> >(); }

/**Creates a print composition, usually for a GetPrint request. Replaces map and label parameters*/
QgsComposition* createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const;
Expand Down
54 changes: 33 additions & 21 deletions src/mapserver/qgsprojectparser.cpp
Expand Up @@ -210,7 +210,7 @@ void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElemen

QStringList wfsLayersId = wfsLayers();
QMap< QString, QMap< int, QString > > aliasInfo = layerAliasInfo();
QMap< QString, QSet<QString> > hiddenAttrs = hiddenAttributes();
QMap< QString, QSet<QString> > excludedAttrs = wfsExcludedAttributes();

foreach ( const QDomElement &elem, mProjectLayerElements )
{
Expand All @@ -237,11 +237,11 @@ void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElemen
}

//hidden attributes for this layer
QSet<QString> layerHiddenAttributes;
QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttrs.find( mLayer->id() );
if ( hiddenIt != hiddenAttrs.constEnd() )
QSet<QString> layerExcludedAttributes;
QMap< QString, QSet<QString> >::const_iterator exclIt = excludedAttrs.find( mLayer->id() );
if ( exclIt != excludedAttrs.constEnd() )
{
layerHiddenAttributes = hiddenIt.value();
layerExcludedAttributes = exclIt.value();
}

QString typeName = layer->name();
Expand Down Expand Up @@ -316,7 +316,7 @@ void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElemen

QString attributeName = it.value().name();
//skip attribute if it has edit type 'hidden'
if ( layerHiddenAttributes.contains( attributeName ) )
if ( layerExcludedAttributes.contains( attributeName ) )
{
continue;
}
Expand Down Expand Up @@ -1053,34 +1053,46 @@ QMap< QString, QMap< int, QString > > QgsProjectParser::layerAliasInfo() const
return resultMap;
}

QMap< QString, QSet<QString> > QgsProjectParser::hiddenAttributes() const
QMap< QString, QSet<QString> > QgsProjectParser::wmsExcludedAttributes() const
{
QMap< QString, QSet<QString> > resultMap;
QList<QDomElement>::const_iterator layerIt = mProjectLayerElements.constBegin();
for ( ; layerIt != mProjectLayerElements.constEnd(); ++layerIt )
{
QDomNodeList editTypesList = layerIt->elementsByTagName( "edittypes" );
if ( editTypesList.size() > 0 )
QDomElement excludeWMSElem = layerIt->firstChildElement( "excludeAttributesWMS" );
QDomNodeList attributeNodeList = excludeWMSElem.elementsByTagName( "attribute" );
if ( attributeNodeList.size() > 0 )
{
QSet< QString > hiddenAttributes;
QDomElement editTypesElem = editTypesList.at( 0 ).toElement();
QDomNodeList editTypeList = editTypesElem.elementsByTagName( "edittype" );
for ( int i = 0; i < editTypeList.size(); ++i )
QSet<QString> layerExcludedAttributes;
for ( int i = 0; i < attributeNodeList.size(); ++i )
{
QDomElement editTypeElem = editTypeList.at( i ).toElement();
if ( editTypeElem.attribute( "type" ).toInt() == QgsVectorLayer::Hidden )
{
hiddenAttributes.insert( editTypeElem.attribute( "name" ) );
}
layerExcludedAttributes.insert( attributeNodeList.at( i ).toElement().text() );
}
resultMap.insert( layerId( *layerIt ), layerExcludedAttributes );
}
}
return resultMap;
}

if ( hiddenAttributes.size() > 0 )
/**Returns attributes excluded from WFS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
QMap< QString, QSet<QString> > QgsProjectParser::wfsExcludedAttributes() const
{
QMap< QString, QSet<QString> > resultMap;
QList<QDomElement>::const_iterator layerIt = mProjectLayerElements.constBegin();
for ( ; layerIt != mProjectLayerElements.constEnd(); ++layerIt )
{
QDomElement excludeWMSElem = layerIt->firstChildElement( "excludeAttributesWFS" );
QDomNodeList attributeNodeList = excludeWMSElem.elementsByTagName( "attribute" );
if ( attributeNodeList.size() > 0 )
{
QSet<QString> layerExcludedAttributes;
for ( int i = 0; i < attributeNodeList.size(); ++i )
{
resultMap.insert( layerId( *layerIt ), hiddenAttributes );
layerExcludedAttributes.insert( attributeNodeList.at( i ).toElement().text() );
}
resultMap.insert( layerId( *layerIt ), layerExcludedAttributes );
}
}

return resultMap;
}

Expand Down
7 changes: 5 additions & 2 deletions src/mapserver/qgsprojectparser.h
Expand Up @@ -87,8 +87,11 @@ class QgsProjectParser: public QgsConfigParser
Default implementation returns an empty map*/
virtual QMap< QString, QMap< int, QString > > layerAliasInfo() const;

/**Returns a stringlist containing the names of the attributes with hidden edit types*/
virtual QMap< QString, QSet<QString> > hiddenAttributes() const;
/**Returns attributes excluded from WMS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wmsExcludedAttributes() const;

/**Returns attributes excluded from WFS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wfsExcludedAttributes() const;

/**Returns map rectangle for the project file*/
QgsRectangle mapRectangle() const;
Expand Down
40 changes: 20 additions & 20 deletions src/mapserver/qgswfsserver.cpp
Expand Up @@ -287,7 +287,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format

QStringList wfsLayersId = mConfigParser->wfsLayers();
QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo();
QMap< QString, QSet<QString> > hiddenAttributes = mConfigParser->hiddenAttributes();
QMap< QString, QSet<QString> > excludedAttributes = mConfigParser->wfsExcludedAttributes();

QList<QgsMapLayer*> layerList;
QgsMapLayer* currentLayer = 0;
Expand All @@ -306,12 +306,12 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
layerAliasInfo = aliasIt.value();
}

//hidden attributes for this layer
QSet<QString> layerHiddenAttributes;
QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttributes.find( currentLayer->id() );
if ( hiddenIt != hiddenAttributes.constEnd() )
//excluded attributes for this layer
QSet<QString> layerExcludedAttributes;
QMap< QString, QSet<QString> >::const_iterator exclIt = excludedAttributes.find( currentLayer->id() );
if ( exclIt != excludedAttributes.constEnd() )
{
layerHiddenAttributes = hiddenIt.value();
layerExcludedAttributes = exclIt.value();
}

//do a select with searchRect and go through all the features
Expand Down Expand Up @@ -455,7 +455,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
if ( fidOk )
{
provider->featureAtId( fid.toInt(), feature, mWithGeom, attrIndexes );
sendGetFeature( request, format, &feature, 0, layerCrs, fields, layerHiddenAttributes );
sendGetFeature( request, format, &feature, 0, layerCrs, fields, layerExcludedAttributes );
}
else if ( filterOk )
{
Expand All @@ -469,13 +469,13 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
{
if ( mFilter->evaluate( feature ) )
{
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes );
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerExcludedAttributes );
++featureCounter;
}
}
else
{
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes );
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerExcludedAttributes );
++featureCounter;
}
}
Expand All @@ -487,7 +487,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format

while ( provider->nextFeature( feature ) && featureCounter < maxFeat )
{
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes );
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerExcludedAttributes );
++featureCounter;
}
}
Expand All @@ -497,7 +497,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
provider->select( attrIndexes, searchRect, mWithGeom, true );
while ( provider->nextFeature( feature ) && featureCounter < maxFeat )
{
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes );
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerExcludedAttributes );
++featureCounter;
}
}
Expand Down Expand Up @@ -633,7 +633,7 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
fcString = "";
}

void QgsWFSServer::sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/
void QgsWFSServer::sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/
{
QByteArray result;
if ( format == "GeoJSON" )
Expand All @@ -643,7 +643,7 @@ void QgsWFSServer::sendGetFeature( QgsRequestHandler& request, const QString& fo
fcString += " ";
else
fcString += " ,";
fcString += createFeatureGeoJSON( feat, crs, fields, hiddenAttributes );
fcString += createFeatureGeoJSON( feat, crs, fields, excludedAttributes );
fcString += "\n";

result = fcString.toUtf8();
Expand All @@ -653,7 +653,7 @@ void QgsWFSServer::sendGetFeature( QgsRequestHandler& request, const QString& fo
else
{
QDomDocument gmlDoc;
QDomElement featureElement = createFeatureElem( feat, gmlDoc, crs, fields, hiddenAttributes );
QDomElement featureElement = createFeatureElem( feat, gmlDoc, crs, fields, excludedAttributes );
gmlDoc.appendChild( featureElement );

result = gmlDoc.toByteArray();
Expand Down Expand Up @@ -684,7 +684,7 @@ void QgsWFSServer::endGetFeature( QgsRequestHandler& request, const QString& for
}
}

QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateReferenceSystem &, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/
QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateReferenceSystem &, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/
{
QString fStr = "{\"type\": \"Feature\",\n";

Expand All @@ -711,8 +711,8 @@ QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateRefer
for ( QgsAttributeMap::const_iterator it = featureAttributes.begin(); it != featureAttributes.end(); ++it )
{
QString attributeName = fields[it.key()].name();
//skip attribute if it has edit type 'hidden'
if ( hiddenAttributes.contains( attributeName ) )
//skip attribute if it is excluded from WFS publication
if ( excludedAttributes.contains( attributeName ) )
{
continue;
}
Expand Down Expand Up @@ -744,7 +744,7 @@ QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateRefer
return fStr;
}

QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/
QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/
{
//gml:FeatureMember
QDomElement featureElement = doc.createElement( "gml:featureMember"/*wfs:FeatureMember*/ );
Expand Down Expand Up @@ -787,8 +787,8 @@ QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc
{

QString attributeName = fields[it.key()].name();
//skip attribute if it has edit type 'hidden'
if ( hiddenAttributes.contains( attributeName ) )
//skip attribute if is explicitely excluded from WFS publication
if ( excludedAttributes.contains( attributeName ) )
{
continue;
}
Expand Down
6 changes: 3 additions & 3 deletions src/mapserver/qgswfsserver.h
Expand Up @@ -82,14 +82,14 @@ class QgsWFSServer
protected:

void startGetFeature( QgsRequestHandler& request, const QString& format, QgsCoordinateReferenceSystem& crs, QgsRectangle* rect );
void sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes );
void sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes );
void endGetFeature( QgsRequestHandler& request, const QString& format );

//methods to write GeoJSON
QString createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/;
QString createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/;

//methods to write GML2
QDomElement createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/;
QDomElement createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/;

QDomElement createBoxElem( QgsRectangle* box, QDomDocument& doc ) /* const */;
QDomElement createGeometryElem( QgsGeometry* g, QDomDocument& doc ) /*const*/;
Expand Down
20 changes: 10 additions & 10 deletions src/mapserver/qgswmsserver.cpp
Expand Up @@ -727,7 +727,7 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )

QStringList nonIdentifiableLayers = mConfigParser->identifyDisabledLayers();
QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo();
QMap< QString, QSet<QString> > hiddenAttributes = mConfigParser->hiddenAttributes();
QMap< QString, QSet<QString> > excludedAttributes = mConfigParser->wmsExcludedAttributes();

//Render context is needed to determine feature visibility for vector layers
QgsRenderContext renderContext;
Expand Down Expand Up @@ -784,16 +784,16 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )
layerAliasInfo = aliasIt.value();
}

//hidden attributes for this layer
QSet<QString> layerHiddenAttributes;
QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttributes.find( currentLayer->id() );
if ( hiddenIt != hiddenAttributes.constEnd() )
//excluded attributes for this layer
QSet<QString> layerExcludedAttributes;
QMap< QString, QSet<QString> >::const_iterator excludedIt = excludedAttributes.find( currentLayer->id() );
if ( excludedIt != excludedAttributes.constEnd() )
{
layerHiddenAttributes = hiddenIt.value();
layerExcludedAttributes = excludedIt.value();
}

if ( featureInfoFromVectorLayer( vectorLayer, infoPoint, featureCount, result, layerElement, mMapRenderer, renderContext,
layerAliasInfo, layerHiddenAttributes, version, featuresRect ) != 0 )
layerAliasInfo, layerExcludedAttributes, version, featuresRect ) != 0 )
{
continue;
}
Expand Down Expand Up @@ -1141,7 +1141,7 @@ int QgsWMSServer::featureInfoFromVectorLayer( QgsVectorLayer* layer,
QgsMapRenderer* mapRender,
QgsRenderContext& renderContext,
QMap<int, QString>& aliasMap,
QSet<QString>& hiddenAttributes,
QSet<QString>& excludedAttributes,
QString version,
QgsRectangle* featureBBox ) const
{
Expand Down Expand Up @@ -1231,8 +1231,8 @@ int QgsWMSServer::featureInfoFromVectorLayer( QgsVectorLayer* layer,
{

QString attributeName = fields[it.key()].name();
//skip attribute if it has edit type 'hidden'
if ( hiddenAttributes.contains( attributeName ) )
//skip attribute if it is explicitely excluded from WMS publication
if ( excludedAttributes.contains( attributeName ) )
{
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/mapserver/qgswmsserver.h
Expand Up @@ -117,7 +117,7 @@ class QgsWMSServer
@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, QMap<int, QString>& aliasMap, QSet<QString>& hiddenAttributes, QString version, QgsRectangle* featureBBox = 0 ) const;
QgsRenderContext& renderContext, QMap<int, QString>& aliasMap, QSet<QString>& excludedAttributes, QString version, QgsRectangle* featureBBox = 0 ) 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, QString version ) const;

Expand Down

0 comments on commit 19b0dbc

Please sign in to comment.