Skip to content

Commit

Permalink
Merge branch for sia2045 GetFeatureInfo output
Browse files Browse the repository at this point in the history
  • Loading branch information
mhugent committed Oct 22, 2012
2 parents dbab4a2 + feec5f0 commit 4c161c9
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 3 deletions.
12 changes: 11 additions & 1 deletion src/mapserver/qgis_map_serv.cpp
Expand Up @@ -165,6 +165,8 @@ int main( int argc, char * argv[] )
}
#endif

QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );

// Instantiate the plugin directory so that providers are loaded
QgsProviderRegistry::instance( QgsApplication::pluginPath() );
QgsDebugMsg( "Prefix PATH: " + QgsApplication::prefixPath() );
Expand Down Expand Up @@ -522,7 +524,15 @@ int main( int argc, char * argv[] )
}

//info format for GetFeatureInfo
theRequestHandler->sendGetFeatureInfoResponse( featureInfoDoc, parameterMap.value( "INFO_FORMAT" ) );

//additionally support text/xml; format=sia2045
QString infoFormat = parameterMap.value( "INFO_FORMAT" );
if ( infoFormat.compare( "text/xml", Qt::CaseInsensitive ) == 0 && adminConfigParser->featureInfoFormatSIA2045() )
{
infoFormat = "text/xml; format=sia2045";
}

theRequestHandler->sendGetFeatureInfoResponse( featureInfoDoc, infoFormat );
delete theRequestHandler;
delete theServer;
continue;
Expand Down
11 changes: 11 additions & 0 deletions src/mapserver/qgsconfigparser.h
Expand Up @@ -129,6 +129,17 @@ class QgsConfigParser
int maxWidth() const { return mMaxWidth; }
int maxHeight() const { return mMaxHeight; }

/**Returns map with layer aliases for GetFeatureInfo (or 0 pointer if not supported). Key: layer name, Value: layer alias*/
virtual QHash<QString, QString> featureInfoLayerAliasMap() const { return QHash<QString, QString>(); }

/**Returns name of document element in GetFeatureInfo response*/
virtual QString featureInfoDocumentElement( const QString& defaultValue ) const { return defaultValue; }
/**Returns document element namespace in GetFeatureInfo response or empty string*/
virtual QString featureInfoDocumentElementNS() const { return ""; }

/**Return feature info in format SIA2045?*/
virtual bool featureInfoFormatSIA2045() const { return false; }

protected:
/**Parser to forward not resolved requests (e.g. SLD parser based on user request might have a fallback parser with admin configuration)*/
QgsConfigParser* mFallbackParser;
Expand Down
67 changes: 67 additions & 0 deletions src/mapserver/qgshttprequesthandler.cpp
Expand Up @@ -147,6 +147,73 @@ void QgsHttpRequestHandler::sendGetFeatureInfoResponse( const QDomDocument& info
{
ba = infoDoc.toByteArray();
}
else if ( infoFormat == "text/xml; format=sia2045" )
{
QDomDocument outFeatureInfoDoc;
QDomElement infoDocElement = infoDoc.documentElement();
QDomElement outInfoDocElement = outFeatureInfoDoc.importNode( infoDocElement, false ).toElement();
outFeatureInfoDoc.appendChild( outInfoDocElement );

QString currentAttributeName;
QString currentAttributeValue;
QDomElement currentAttributeElem;
QString currentLayerName;
QDomElement currentLayerElem;
QDomNodeList layerNodeList = infoDocElement.elementsByTagName( "Layer" );
for ( int i = 0; i < layerNodeList.size(); ++i )
{
currentLayerElem = layerNodeList.at( i ).toElement();
currentLayerName = currentLayerElem.attribute( "name" );
QDomElement currentFeatureElem;

QDomNodeList featureList = currentLayerElem.elementsByTagName( "Feature" );
if ( featureList.size() < 1 )
{
//raster?
QDomNodeList attributeList = currentLayerElem.elementsByTagName( "Attribute" );
QDomElement rasterLayerElem;
if ( attributeList.size() > 0 )
{
rasterLayerElem = outFeatureInfoDoc.createElement( currentLayerName );
}
for ( int j = 0; j < attributeList.size(); ++j )
{
currentAttributeElem = attributeList.at( j ).toElement();
currentAttributeName = currentAttributeElem.attribute( "name" );
currentAttributeValue = currentAttributeElem.attribute( "value" );
QDomElement outAttributeElem = outFeatureInfoDoc.createElement( currentAttributeName );
QDomText outAttributeText = outFeatureInfoDoc.createTextNode( currentAttributeValue );
outAttributeElem.appendChild( outAttributeText );
rasterLayerElem.appendChild( outAttributeElem );
}
if ( attributeList.size() > 0 )
{
outInfoDocElement.appendChild( rasterLayerElem );
}
}
else //vector
{
for ( int j = 0; j < featureList.size(); ++j )
{
QDomElement outFeatureElem = outFeatureInfoDoc.createElement( currentLayerName );
currentFeatureElem = featureList.at( j ).toElement();
QDomNodeList attributeList = currentFeatureElem.elementsByTagName( "Attribute" );
for ( int k = 0; k < attributeList.size(); ++k )
{
currentAttributeElem = attributeList.at( k ).toElement();
currentAttributeName = currentAttributeElem.attribute( "name" );
currentAttributeValue = currentAttributeElem.attribute( "value" );
QDomElement outAttributeElem = outFeatureInfoDoc.createElement( currentAttributeName );
QDomText outAttributeText = outFeatureInfoDoc.createTextNode( currentAttributeValue );
outAttributeElem.appendChild( outAttributeText );
outFeatureElem.appendChild( outAttributeElem );
}
outInfoDocElement.appendChild( outFeatureElem );
}
}
}
ba = outFeatureInfoDoc.toByteArray();
}
else if ( infoFormat == "text/plain" || infoFormat == "text/html" )
{
//create string
Expand Down
101 changes: 101 additions & 0 deletions src/mapserver/qgsprojectparser.cpp
Expand Up @@ -1855,6 +1855,107 @@ QStringList QgsProjectParser::wfsLayerNames() const
return layerNameList;
}

QHash<QString, QString> QgsProjectParser::featureInfoLayerAliasMap() const
{
QHash<QString, QString> aliasMap;
QDomElement propertiesElem = mXMLDoc->documentElement().firstChildElement( "properties" );
if ( propertiesElem.isNull() )
{
return aliasMap;
}

//WMSFeatureInfoAliasLayers
QStringList aliasLayerStringList;
QDomElement featureInfoAliasLayersElem = propertiesElem.firstChildElement( "WMSFeatureInfoAliasLayers" );
if ( featureInfoAliasLayersElem.isNull() )
{
return aliasMap;
}
QDomNodeList aliasLayerValueList = featureInfoAliasLayersElem.elementsByTagName( "value" );
for ( int i = 0; i < aliasLayerValueList.size(); ++i )
{
aliasLayerStringList << aliasLayerValueList.at( i ).toElement().text();
}

//WMSFeatureInfoLayerAliases
QStringList layerAliasStringList;
QDomElement featureInfoLayerAliasesElem = propertiesElem.firstChildElement( "WMSFeatureInfoLayerAliases" );
if ( featureInfoLayerAliasesElem.isNull() )
{
return aliasMap;
}
QDomNodeList layerAliasesValueList = featureInfoLayerAliasesElem.elementsByTagName( "value" );
for ( int i = 0; i < layerAliasesValueList.size(); ++i )
{
layerAliasStringList << layerAliasesValueList.at( i ).toElement().text();
}

int nMapEntries = qMin( aliasLayerStringList.size(), layerAliasStringList.size() );
for ( int i = 0; i < nMapEntries; ++i )
{
aliasMap.insert( aliasLayerStringList.at( i ), layerAliasStringList.at( i ) );
}

return aliasMap;
}

QString QgsProjectParser::featureInfoDocumentElement( const QString& defaultValue ) const
{
QDomElement propertiesElem = mXMLDoc->documentElement().firstChildElement( "properties" );
if ( propertiesElem.isNull() )
{
return defaultValue;
}
QDomElement featureInfoDocumentElem = propertiesElem.firstChildElement( "WMSFeatureInfoDocumentElement" );
if ( featureInfoDocumentElem.isNull() )
{
return defaultValue;
}
return featureInfoDocumentElem.text();
}

QString QgsProjectParser::featureInfoDocumentElementNS() const
{
QDomElement propertiesElem = mXMLDoc->documentElement().firstChildElement( "properties" );
if ( propertiesElem.isNull() )
{
return "";
}
QDomElement featureInfoDocumentNSElem = propertiesElem.firstChildElement( "WMSFeatureInfoDocumentElementNS" );
if ( featureInfoDocumentNSElem.isNull() )
{
return "";
}
return featureInfoDocumentNSElem.text();
}

bool QgsProjectParser::featureInfoFormatSIA2045() const
{
if ( !mXMLDoc )
{
return false;
}

QDomElement propertiesElem = mXMLDoc->documentElement().firstChildElement( "properties" );
if ( propertiesElem.isNull() )
{
return false;
}

QDomElement sia2045Elem = propertiesElem.firstChildElement( "WMSInfoFormatSIA2045" );
if ( sia2045Elem.isNull() )
{
return false;
}

if ( sia2045Elem.text().compare( "enabled", Qt::CaseInsensitive ) == 0
|| sia2045Elem.text().compare( "true", Qt::CaseInsensitive ) == 0 )
{
return true;
}
return false;
}

QString QgsProjectParser::convertToAbsolutePath( const QString& file ) const
{
if ( !file.startsWith( "./" ) && !file.startsWith( "../" ) )
Expand Down
10 changes: 10 additions & 0 deletions src/mapserver/qgsprojectparser.h
Expand Up @@ -111,6 +111,16 @@ class QgsProjectParser: public QgsConfigParser
/**Returns the names of the published wfs layers (not the ids as in wfsLayers() )*/
QStringList wfsLayerNames() const;

/**Returns map with layer aliases for GetFeatureInfo (or 0 pointer if not supported). Key: layer name, Value: layer alias*/
virtual QHash<QString, QString> featureInfoLayerAliasMap() const;

virtual QString featureInfoDocumentElement( const QString& defaultValue ) const;

virtual QString featureInfoDocumentElementNS() const;

/**Return feature info in format SIA2045?*/
bool featureInfoFormatSIA2045() const;

private:

//forbidden
Expand Down
18 changes: 18 additions & 0 deletions src/mapserver/qgssldparser.cpp
Expand Up @@ -1546,6 +1546,24 @@ bool QgsSLDParser::featureInfoWithWktGeometry() const
return false;
}

QHash<QString, QString> QgsSLDParser::featureInfoLayerAliasMap() const
{
if ( mFallbackParser )
{
return mFallbackParser->featureInfoLayerAliasMap();
}
return QHash<QString, QString>();
}

bool QgsSLDParser::featureInfoFormatSIA2045() const
{
if ( mFallbackParser )
{
return mFallbackParser->featureInfoFormatSIA2045();
}
return false;
}

#ifdef DIAGRAMSERVER
int QgsSLDParser::overlaysFromUserStyle( const QDomElement& userStyleElement, QgsVectorLayer* vec ) const
{
Expand Down
6 changes: 6 additions & 0 deletions src/mapserver/qgssldparser.h
Expand Up @@ -83,6 +83,12 @@ class QgsSLDParser: public QgsConfigParser
/**True if the feature info response should contain the wkt geometry for vector features*/
virtual bool featureInfoWithWktGeometry() const;

/**Returns map with layer aliases for GetFeatureInfo (or 0 pointer if not supported). Key: layer name, Value: layer alias*/
virtual QHash<QString, QString> featureInfoLayerAliasMap() const;

/**Return feature info in format SIA2045?*/
bool featureInfoFormatSIA2045() const;

private:
/**Don't use the default constructor*/
QgsSLDParser();
Expand Down
25 changes: 23 additions & 2 deletions src/mapserver/qgswmsserver.cpp
Expand Up @@ -729,7 +729,17 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )
QStringList layerIds = layerSet( layersList, stylesList, mMapRenderer->destinationCrs() );
QMap<QString, QString> originalLayerFilters = applyRequestedLayerFilters( layersList );

QDomElement getFeatureInfoElement = result.createElement( "GetFeatureInfoResponse" );
QString featureInfoElemName = mConfigParser->featureInfoDocumentElement( "GetFeatureInfoResponse" );
QString featureInfoElemNS = mConfigParser->featureInfoDocumentElementNS();
QDomElement getFeatureInfoElement;
if ( featureInfoElemNS.isEmpty() )
{
getFeatureInfoElement = result.createElement( featureInfoElemName );
}
else
{
getFeatureInfoElement = result.createElementNS( featureInfoElemNS, featureInfoElemName );
}
result.appendChild( getFeatureInfoElement );

QStringList nonIdentifiableLayers = mConfigParser->identifyDisabledLayers();
Expand All @@ -746,6 +756,9 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )
renderContext.setPainter( 0 );
}

//layers can have assigned a different name for GetCapabilities
QHash<QString, QString> layerAliasMap = mConfigParser->featureInfoLayerAliasMap();

QList<QgsMapLayer*> layerList;
QgsMapLayer* currentLayer = 0;
QStringList::const_iterator layerIt;
Expand Down Expand Up @@ -774,7 +787,15 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )
}

QDomElement layerElement = result.createElement( "Layer" );
layerElement.setAttribute( "name", currentLayer->name() );
QString layerName = currentLayer->name();

//check if the layer is given a different name for GetFeatureInfo output
QHash<QString, QString>::const_iterator layerAliasIt = layerAliasMap.find( layerName );
if ( layerAliasIt != layerAliasMap.constEnd() )
{
layerName = layerAliasIt.value();
}
layerElement.setAttribute( "name", layerName );
getFeatureInfoElement.appendChild( layerElement );

//switch depending on vector or raster
Expand Down

0 comments on commit 4c161c9

Please sign in to comment.