mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[Server] WMS GetFeatureInfo refactoring
This commit is contained in:
parent
e61daed979
commit
f926033699
@ -145,6 +145,62 @@ namespace QgsServerProjectUtils
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool wmsFeatureInfoAddWktGeometry( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns if the geometry is displayed as Well Known Text in GetFeatureInfo request.
|
||||
\param project the QGIS project
|
||||
:return: if the geometry is displayed as Well Known Text in GetFeatureInfo request.
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool wmsFeatureInfoSegmentizeWktGeometry( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns if the geometry has to be segmentize in GetFeatureInfo request.
|
||||
\param project the QGIS project
|
||||
:return: if the geometry has to be segmentize in GetFeatureInfo request.
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
int wmsFeatureInfoPrecision( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns the geometry precision for GetFeatureInfo request.
|
||||
\param project the QGIS project
|
||||
:return: the geometry precision for GetFeatureInfo request.
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
QString wmsFeatureInfoDocumentElement( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns the document element name for XML GetFeatureInfo request.
|
||||
\param project the QGIS project
|
||||
:return: the document element name for XML GetFeatureInfo request.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QString wmsFeatureInfoDocumentElementNs( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns the document element namespace for XML GetFeatureInfo request.
|
||||
\param project the QGIS project
|
||||
:return: the document element namespace for XML GetFeatureInfo request.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QString wmsFeatureInfoSchema( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns the schema URL for XML GetFeatureInfo request.
|
||||
\param project the QGIS project
|
||||
:return: the schema URL for XML GetFeatureInfo request.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QHash<QString, QString> wmsFeatureInfoLayerAliasMap( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns the mapping between layer name and wms layer name for GetFeatureInfo request.
|
||||
\param project the QGIS project
|
||||
:return: the mapping between layer name and wms layer name for GetFeatureInfo request.
|
||||
:rtype: QHash<str, QString>
|
||||
%End
|
||||
|
||||
bool wmsInspireActivate( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns if Inspire is activated.
|
||||
|
@ -117,6 +117,77 @@ bool QgsServerProjectUtils::wmsInfoFormatSia2045( const QgsProject &project )
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QgsServerProjectUtils::wmsFeatureInfoAddWktGeometry( const QgsProject &project )
|
||||
{
|
||||
QString wktGeom = project.readEntry( QStringLiteral( "WMSAddWktGeometry" ), QStringLiteral( "/" ), "" );
|
||||
|
||||
if ( wktGeom.compare( QLatin1String( "enabled" ), Qt::CaseInsensitive ) == 0
|
||||
|| wktGeom.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QgsServerProjectUtils::wmsFeatureInfoSegmentizeWktGeometry( const QgsProject &project )
|
||||
{
|
||||
QString segmGeom = project.readEntry( QStringLiteral( "WMSSegmentizeFeatureInfoGeometry" ), QStringLiteral( "/" ), "" );
|
||||
|
||||
if ( segmGeom.compare( QLatin1String( "enabled" ), Qt::CaseInsensitive ) == 0
|
||||
|| segmGeom.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int QgsServerProjectUtils::wmsFeatureInfoPrecision( const QgsProject &project )
|
||||
{
|
||||
return project.readNumEntry( QStringLiteral( "WMSPrecision" ), QStringLiteral( "/" ), 6 );
|
||||
}
|
||||
|
||||
QString QgsServerProjectUtils::wmsFeatureInfoDocumentElement( const QgsProject &project )
|
||||
{
|
||||
return project.readEntry( QStringLiteral( "WMSFeatureInfoDocumentElement" ), QStringLiteral( "/" ), "" );
|
||||
}
|
||||
|
||||
QString QgsServerProjectUtils::wmsFeatureInfoDocumentElementNs( const QgsProject &project )
|
||||
{
|
||||
return project.readEntry( QStringLiteral( "WMSFeatureInfoDocumentElementNS" ), QStringLiteral( "/" ), "" );
|
||||
}
|
||||
|
||||
QString QgsServerProjectUtils::wmsFeatureInfoSchema( const QgsProject &project )
|
||||
{
|
||||
return project.readEntry( QStringLiteral( "WMSFeatureInfoSchema" ), QStringLiteral( "/" ), "" );
|
||||
}
|
||||
|
||||
QHash<QString, QString> QgsServerProjectUtils::wmsFeatureInfoLayerAliasMap( const QgsProject &project )
|
||||
{
|
||||
QHash<QString, QString> aliasMap;
|
||||
|
||||
//WMSFeatureInfoAliasLayers
|
||||
QStringList aliasLayerStringList = project.readListEntry( QStringLiteral( "WMSFeatureInfoAliasLayers" ), QStringLiteral( "/value" ), QStringList() );
|
||||
if ( aliasLayerStringList.isEmpty() )
|
||||
{
|
||||
return aliasMap;
|
||||
}
|
||||
|
||||
//WMSFeatureInfoLayerAliases
|
||||
QStringList layerAliasStringList = project.readListEntry( QStringLiteral( "WMSFeatureInfoLayerAliases" ), QStringLiteral( "/value" ), QStringList() );
|
||||
if ( layerAliasStringList.isEmpty() )
|
||||
{
|
||||
return aliasMap;
|
||||
}
|
||||
|
||||
int nMapEntries = qMin( aliasLayerStringList.size(), layerAliasStringList.size() );
|
||||
for ( int i = 0; i < nMapEntries; ++i )
|
||||
{
|
||||
aliasMap.insert( aliasLayerStringList.at( i ), layerAliasStringList.at( i ) );
|
||||
}
|
||||
|
||||
return aliasMap;
|
||||
}
|
||||
|
||||
bool QgsServerProjectUtils::wmsInspireActivate( const QgsProject &project )
|
||||
{
|
||||
return project.readBoolEntry( QStringLiteral( "WMSInspire" ), QStringLiteral( "/activated" ) );
|
||||
|
@ -132,6 +132,48 @@ namespace QgsServerProjectUtils
|
||||
*/
|
||||
SERVER_EXPORT bool wmsInfoFormatSia2045( const QgsProject &project );
|
||||
|
||||
/** Returns if the geometry is displayed as Well Known Text in GetFeatureInfo request.
|
||||
* \param project the QGIS project
|
||||
* \returns if the geometry is displayed as Well Known Text in GetFeatureInfo request.
|
||||
*/
|
||||
SERVER_EXPORT bool wmsFeatureInfoAddWktGeometry( const QgsProject &project );
|
||||
|
||||
/** Returns if the geometry has to be segmentize in GetFeatureInfo request.
|
||||
* \param project the QGIS project
|
||||
* \returns if the geometry has to be segmentize in GetFeatureInfo request.
|
||||
*/
|
||||
SERVER_EXPORT bool wmsFeatureInfoSegmentizeWktGeometry( const QgsProject &project );
|
||||
|
||||
/** Returns the geometry precision for GetFeatureInfo request.
|
||||
* \param project the QGIS project
|
||||
* \returns the geometry precision for GetFeatureInfo request.
|
||||
*/
|
||||
SERVER_EXPORT int wmsFeatureInfoPrecision( const QgsProject &project );
|
||||
|
||||
/** Returns the document element name for XML GetFeatureInfo request.
|
||||
* \param project the QGIS project
|
||||
* \returns the document element name for XML GetFeatureInfo request.
|
||||
*/
|
||||
SERVER_EXPORT QString wmsFeatureInfoDocumentElement( const QgsProject &project );
|
||||
|
||||
/** Returns the document element namespace for XML GetFeatureInfo request.
|
||||
* \param project the QGIS project
|
||||
* \returns the document element namespace for XML GetFeatureInfo request.
|
||||
*/
|
||||
SERVER_EXPORT QString wmsFeatureInfoDocumentElementNs( const QgsProject &project );
|
||||
|
||||
/** Returns the schema URL for XML GetFeatureInfo request.
|
||||
* \param project the QGIS project
|
||||
* \returns the schema URL for XML GetFeatureInfo request.
|
||||
*/
|
||||
SERVER_EXPORT QString wmsFeatureInfoSchema( const QgsProject &project );
|
||||
|
||||
/** Returns the mapping between layer name and wms layer name for GetFeatureInfo request.
|
||||
* \param project the QGIS project
|
||||
* \returns the mapping between layer name and wms layer name for GetFeatureInfo request.
|
||||
*/
|
||||
SERVER_EXPORT QHash<QString, QString> wmsFeatureInfoLayerAliasMap( const QgsProject &project );
|
||||
|
||||
/** Returns if Inspire is activated.
|
||||
* \param project the QGIS project
|
||||
* \returns if Inspire is activated.
|
||||
|
@ -191,6 +191,41 @@ namespace QgsWms
|
||||
};
|
||||
save( pFormat );
|
||||
|
||||
const Parameter pInfoFormat = { ParameterName::INFO_FORMAT,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pInfoFormat );
|
||||
|
||||
const Parameter pI = { ParameterName::I,
|
||||
QVariant::Int,
|
||||
QVariant( -1 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pI );
|
||||
|
||||
const Parameter pJ = { ParameterName::J,
|
||||
QVariant::Int,
|
||||
QVariant( -1 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pJ );
|
||||
|
||||
const Parameter pX = { ParameterName::X,
|
||||
QVariant::Int,
|
||||
QVariant( -1 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pX );
|
||||
|
||||
const Parameter pY = { ParameterName::Y,
|
||||
QVariant::Int,
|
||||
QVariant( -1 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pY );
|
||||
|
||||
const Parameter pRule = { ParameterName::RULE,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
@ -254,6 +289,20 @@ namespace QgsWms
|
||||
};
|
||||
save( pLayers );
|
||||
|
||||
const Parameter pQueryLayers = { ParameterName::QUERY_LAYERS,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pQueryLayers );
|
||||
|
||||
const Parameter pFeatureCount = { ParameterName::FEATURE_COUNT,
|
||||
QVariant::Int,
|
||||
QVariant( 1 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pFeatureCount );
|
||||
|
||||
const Parameter pLayerTitle = { ParameterName::LAYERTITLE,
|
||||
QVariant::Bool,
|
||||
QVariant( true ),
|
||||
@ -324,12 +373,26 @@ namespace QgsWms
|
||||
};
|
||||
save( pFilter );
|
||||
|
||||
const Parameter pFilterGeom = { ParameterName::FILTER_GEOM,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pFilterGeom );
|
||||
|
||||
const Parameter pSelection = { ParameterName::SELECTION,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pSelection );
|
||||
|
||||
const Parameter pWmsPrecision = { ParameterName::WMS_PRECISION,
|
||||
QVariant::Int,
|
||||
QVariant( -1 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pWmsPrecision );
|
||||
}
|
||||
|
||||
QgsWmsParameters::QgsWmsParameters( const QgsServerRequest::Parameters ¶meters )
|
||||
@ -341,6 +404,7 @@ namespace QgsWms
|
||||
{
|
||||
mRequestParameters = parameters;
|
||||
|
||||
log( "load WMS Request parameters:" );
|
||||
const QMetaEnum metaEnum( QMetaEnum::fromType<ParameterName>() );
|
||||
foreach ( QString key, parameters.keys() )
|
||||
{
|
||||
@ -351,6 +415,7 @@ namespace QgsWms
|
||||
if ( value.canConvert( mParameters[name].mType ) )
|
||||
{
|
||||
mParameters[name].mValue = value;
|
||||
log( " - " + key + " : " + parameters[key] );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -628,9 +693,12 @@ namespace QgsWms
|
||||
|
||||
QgsWmsParameters::Format QgsWmsParameters::format() const
|
||||
{
|
||||
Format f = Format::PNG;
|
||||
QString fStr = formatAsString();
|
||||
|
||||
if ( fStr.isEmpty() )
|
||||
return Format::NONE;
|
||||
|
||||
Format f = Format::PNG;
|
||||
if ( fStr.compare( QLatin1String( "jpg" ), Qt::CaseInsensitive ) == 0
|
||||
|| fStr.compare( QLatin1String( "jpeg" ), Qt::CaseInsensitive ) == 0
|
||||
|| fStr.compare( QLatin1String( "image/jpeg" ), Qt::CaseInsensitive ) == 0 )
|
||||
@ -639,6 +707,69 @@ namespace QgsWms
|
||||
return f;
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::infoFormatAsString() const
|
||||
{
|
||||
return value( ParameterName::INFO_FORMAT ).toString();
|
||||
}
|
||||
|
||||
QgsWmsParameters::Format QgsWmsParameters::infoFormat() const
|
||||
{
|
||||
QString fStr = infoFormatAsString();
|
||||
|
||||
if ( fStr.isEmpty() )
|
||||
return Format::NONE;
|
||||
|
||||
Format f = Format::TEXT;
|
||||
if ( fStr.startsWith( QLatin1String( "text/xml" ), Qt::CaseInsensitive ) )
|
||||
f = Format::XML;
|
||||
else if ( fStr.startsWith( QLatin1String( "text/html" ), Qt::CaseInsensitive ) )
|
||||
f = Format::HTML;
|
||||
else if ( fStr.startsWith( QLatin1String( "application/vnd.ogc.gml" ), Qt::CaseInsensitive ) )
|
||||
f = Format::GML;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::i() const
|
||||
{
|
||||
return value( ParameterName::I ).toString();
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::j() const
|
||||
{
|
||||
return value( ParameterName::J ).toString();
|
||||
}
|
||||
|
||||
int QgsWmsParameters::iAsInt() const
|
||||
{
|
||||
return toInt( ParameterName::I );
|
||||
}
|
||||
|
||||
int QgsWmsParameters::jAsInt() const
|
||||
{
|
||||
return toInt( ParameterName::J );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::x() const
|
||||
{
|
||||
return value( ParameterName::X ).toString();
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::y() const
|
||||
{
|
||||
return value( ParameterName::Y ).toString();
|
||||
}
|
||||
|
||||
int QgsWmsParameters::xAsInt() const
|
||||
{
|
||||
return toInt( ParameterName::X );
|
||||
}
|
||||
|
||||
int QgsWmsParameters::yAsInt() const
|
||||
{
|
||||
return toInt( ParameterName::Y );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::rule() const
|
||||
{
|
||||
return value( ParameterName::RULE ).toString();
|
||||
@ -674,6 +805,16 @@ namespace QgsWms
|
||||
return toBool( ParameterName::SHOWFEATURECOUNT );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::featureCount() const
|
||||
{
|
||||
return value( ParameterName::FEATURE_COUNT ).toString();
|
||||
}
|
||||
|
||||
int QgsWmsParameters::featureCountAsInt() const
|
||||
{
|
||||
return toInt( ParameterName::FEATURE_COUNT );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::boxSpace() const
|
||||
{
|
||||
return value( ParameterName::BOXSPACE ).toString();
|
||||
@ -960,6 +1101,16 @@ namespace QgsWms
|
||||
return toFloatList( highlightLabelBufferSize(), ParameterName::HIGHLIGHT_LABELBUFFERSIZE );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::wmsPrecision() const
|
||||
{
|
||||
return value( ParameterName::WMS_PRECISION ).toString();
|
||||
}
|
||||
|
||||
int QgsWmsParameters::wmsPrecisionAsInt() const
|
||||
{
|
||||
return toInt( ParameterName::WMS_PRECISION );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::sld() const
|
||||
{
|
||||
return value( ParameterName::SLD ).toString();
|
||||
@ -970,6 +1121,11 @@ namespace QgsWms
|
||||
return toStringList( ParameterName::FILTER, ';' );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::filterGeom() const
|
||||
{
|
||||
return value( ParameterName::FILTER_GEOM ).toString();
|
||||
}
|
||||
|
||||
QStringList QgsWmsParameters::selections() const
|
||||
{
|
||||
return toStringList( ParameterName::SELECTION );
|
||||
@ -992,6 +1148,11 @@ namespace QgsWms
|
||||
return layer << layers;
|
||||
}
|
||||
|
||||
QStringList QgsWmsParameters::queryLayersNickname() const
|
||||
{
|
||||
return toStringList( ParameterName::QUERY_LAYERS );
|
||||
}
|
||||
|
||||
QStringList QgsWmsParameters::allStyles() const
|
||||
{
|
||||
QStringList style = value( ParameterName::STYLE ).toString().split( ",", QString::SkipEmptyParts );
|
||||
|
@ -86,6 +86,8 @@ namespace QgsWms
|
||||
LAYERS,
|
||||
LAYERSPACE,
|
||||
LAYERTITLESPACE,
|
||||
QUERY_LAYERS,
|
||||
FEATURE_COUNT,
|
||||
SHOWFEATURECOUNT,
|
||||
STYLE,
|
||||
STYLES,
|
||||
@ -95,7 +97,13 @@ namespace QgsWms
|
||||
OPACITIES,
|
||||
SLD,
|
||||
FILTER,
|
||||
FILTER_GEOM,
|
||||
FORMAT,
|
||||
INFO_FORMAT,
|
||||
I,
|
||||
J,
|
||||
X,
|
||||
Y,
|
||||
RULE,
|
||||
RULELABEL,
|
||||
SCALE,
|
||||
@ -108,7 +116,8 @@ namespace QgsWms
|
||||
HIGHLIGHT_LABELWEIGHT,
|
||||
HIGHLIGHT_LABELCOLOR,
|
||||
HIGHLIGHT_LABELBUFFERCOLOR,
|
||||
HIGHLIGHT_LABELBUFFERSIZE
|
||||
HIGHLIGHT_LABELBUFFERSIZE,
|
||||
WMS_PRECISION
|
||||
};
|
||||
Q_ENUM( ParameterName )
|
||||
|
||||
@ -116,7 +125,11 @@ namespace QgsWms
|
||||
{
|
||||
NONE,
|
||||
JPG,
|
||||
PNG
|
||||
PNG,
|
||||
TEXT,
|
||||
XML,
|
||||
HTML,
|
||||
GML
|
||||
};
|
||||
|
||||
struct Parameter
|
||||
@ -203,6 +216,11 @@ namespace QgsWms
|
||||
*/
|
||||
QStringList filters() const;
|
||||
|
||||
/** Returns the filter geometry found in FILTER_GEOM parameter.
|
||||
* \returns the filter geometry as Well Known Text.
|
||||
*/
|
||||
QString filterGeom() const;
|
||||
|
||||
/** Returns the list of opacities found in OPACITIES parameter.
|
||||
* \returns the list of opacities in string
|
||||
*/
|
||||
@ -221,6 +239,11 @@ namespace QgsWms
|
||||
*/
|
||||
QStringList allLayersNickname() const;
|
||||
|
||||
/** Returns nickname of layers found in QUERY_LAYERS parameter.
|
||||
* \returns nickname of layers
|
||||
*/
|
||||
QStringList queryLayersNickname() const;
|
||||
|
||||
/** Returns styles found in STYLE and STYLES parameters.
|
||||
* \returns name of styles
|
||||
*/
|
||||
@ -242,6 +265,69 @@ namespace QgsWms
|
||||
*/
|
||||
Format format() const;
|
||||
|
||||
/** Returns INFO_FORMAT parameter as a string.
|
||||
* \returns INFO_FORMAT parameter as string
|
||||
*/
|
||||
QString infoFormatAsString() const;
|
||||
|
||||
/** Returns infoFormat. If the INFO_FORMAT parameter is not used, then the
|
||||
* default value is text/plain.
|
||||
* \returns infoFormat
|
||||
*/
|
||||
Format infoFormat() const;
|
||||
|
||||
/** Returns I parameter or an empty string if not defined.
|
||||
* \returns i parameter
|
||||
*/
|
||||
QString i() const;
|
||||
|
||||
/** Returns I parameter as an int or its default value if not
|
||||
* defined. An exception is raised if I is defined and cannot be
|
||||
* converted.
|
||||
* \returns i parameter
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
int iAsInt() const;
|
||||
|
||||
/** Returns J parameter or an empty string if not defined.
|
||||
* \returns j parameter
|
||||
*/
|
||||
QString j() const;
|
||||
|
||||
/** Returns J parameter as an int or its default value if not
|
||||
* defined. An exception is raised if J is defined and cannot be
|
||||
* converted.
|
||||
* \returns j parameter
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
int jAsInt() const;
|
||||
|
||||
/** Returns X parameter or an empty string if not defined.
|
||||
* \returns x parameter
|
||||
*/
|
||||
QString x() const;
|
||||
|
||||
/** Returns X parameter as an int or its default value if not
|
||||
* defined. An exception is raised if X is defined and cannot be
|
||||
* converted.
|
||||
* \returns x parameter
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
int xAsInt() const;
|
||||
|
||||
/** Returns Y parameter or an empty string if not defined.
|
||||
* \returns y parameter
|
||||
*/
|
||||
QString y() const;
|
||||
|
||||
/** Returns Y parameter as an int or its default value if not
|
||||
* defined. An exception is raised if Y is defined and cannot be
|
||||
* converted.
|
||||
* \returns j parameter
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
int yAsInt() const;
|
||||
|
||||
/** Returns RULE parameter or an empty string if none is defined
|
||||
* \returns RULE parameter or an empty string if none is defined
|
||||
*/
|
||||
@ -271,6 +357,18 @@ namespace QgsWms
|
||||
*/
|
||||
bool showFeatureCountAsBool() const;
|
||||
|
||||
/** Returns FEATURE_COUNT parameter or an empty string if none is defined
|
||||
* \returns FEATURE_COUNT parameter or an empty string if none is defined
|
||||
*/
|
||||
QString featureCount() const;
|
||||
|
||||
/** Returns FEATURE_COUNT as an integer. An exception is raised if an invalid
|
||||
* parameter is found.
|
||||
* \returns FeatureCount
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
int featureCountAsInt() const;
|
||||
|
||||
/** Returns SCALE parameter or an empty string if none is defined
|
||||
* \returns SCALE parameter or an empty string if none is defined
|
||||
*/
|
||||
@ -595,6 +693,19 @@ namespace QgsWms
|
||||
*/
|
||||
QList<QColor> highlightLabelBufferColorAsColor() const;
|
||||
|
||||
/** Returns WMS_PRECISION parameter or an empty string if not defined.
|
||||
* \returns wms precision parameter
|
||||
*/
|
||||
QString wmsPrecision() const;
|
||||
|
||||
/** Returns WMS_PRECISION parameter as an int or its default value if not
|
||||
* defined. An exception is raised if WMS_PRECISION is defined and cannot be
|
||||
* converted.
|
||||
* \returns wms precision parameter
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
int wmsPrecisionAsInt() const;
|
||||
|
||||
private:
|
||||
QString name( ParameterName name ) const;
|
||||
void raiseError( ParameterName name ) const;
|
||||
|
@ -644,131 +644,161 @@ namespace QgsWms
|
||||
|
||||
QDomDocument QgsRenderer::getFeatureInfo( const QString &version )
|
||||
{
|
||||
if ( !mConfigParser )
|
||||
// Verifying Mandatory parameters
|
||||
// The INFO_FORMAT parameter is Mandatory
|
||||
if ( mWmsParameters.infoFormat() == QgsWmsParameters::Format::NONE )
|
||||
{
|
||||
throw QgsException( QStringLiteral( "No config parser" ) );
|
||||
throw QgsBadRequestException( QStringLiteral( "ParameterMissing" ),
|
||||
QStringLiteral( "INFO_FORMAT parameter is required for GetFeatureInfo" ) );
|
||||
}
|
||||
|
||||
QDomDocument result;
|
||||
QStringList layersList, stylesList;
|
||||
bool conversionSuccess;
|
||||
|
||||
for ( auto it = mParameters.constBegin(); it != mParameters.constEnd(); ++it )
|
||||
// The QUERY_LAYERS parameter is Mandatory
|
||||
QStringList queryLayers = mWmsParameters.queryLayersNickname();
|
||||
if ( queryLayers.isEmpty() )
|
||||
{
|
||||
QgsMessageLog::logMessage( QStringLiteral( "%1 // %2" ).arg( it.key(), it.value() ) );
|
||||
throw QgsBadRequestException( QStringLiteral( "ParameterMissing" ),
|
||||
QStringLiteral( "QUERY_LAYERS parameter is required for GetFeatureInfo" ) );
|
||||
}
|
||||
|
||||
readLayersAndStyles( mParameters, layersList, stylesList );
|
||||
initializeSLDParser( layersList, stylesList );
|
||||
// The I/J parameters are Mandatory if they are not replaced by X/Y or FILTER or FILTER_GEOM
|
||||
bool ijDefined = false;
|
||||
if ( !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty() )
|
||||
ijDefined = true;
|
||||
|
||||
bool xyDefined = false;
|
||||
if ( !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty() )
|
||||
xyDefined = true;
|
||||
|
||||
bool filtersDefined = false;
|
||||
if ( !mWmsParameters.filters().isEmpty() )
|
||||
filtersDefined = true;
|
||||
|
||||
bool filterGeomDefined = false;
|
||||
if ( !mWmsParameters.filterGeom().isEmpty() )
|
||||
filterGeomDefined = true;
|
||||
|
||||
if ( !ijDefined && !xyDefined && !filtersDefined && !filterGeomDefined )
|
||||
{
|
||||
throw QgsBadRequestException( QStringLiteral( "ParameterMissing" ),
|
||||
QStringLiteral( "I/J parameters are required for GetFeatureInfo" ) );
|
||||
}
|
||||
|
||||
// get layers parameters
|
||||
QList<QgsMapLayer *> layers;
|
||||
QList<QgsWmsParametersLayer> params = mWmsParameters.layersParameters();
|
||||
|
||||
// init layer restorer before doing anything
|
||||
std::unique_ptr<QgsLayerRestorer> restorer;
|
||||
restorer.reset( new QgsLayerRestorer( mNicknameLayers.values() ) );
|
||||
|
||||
// init stylized layers according to LAYERS/STYLES or SLD
|
||||
QString sld = mWmsParameters.sld();
|
||||
if ( !sld.isEmpty() )
|
||||
layers = sldStylizedLayers( sld );
|
||||
else
|
||||
layers = stylizedLayers( params );
|
||||
|
||||
// create the mapSettings and the output image
|
||||
QgsMapSettings mapSettings;
|
||||
std::unique_ptr<QImage> outputImage( createImage() );
|
||||
|
||||
// configure map settings (background, DPI, ...)
|
||||
configureMapSettings( outputImage.get(), mapSettings );
|
||||
|
||||
QgsMessageLog::logMessage( "mapSettings.destinationCrs(): " + mapSettings.destinationCrs().authid() );
|
||||
QgsMessageLog::logMessage( "mapSettings.extent(): " + mapSettings.extent().toString() );
|
||||
QgsMessageLog::logMessage( QStringLiteral( "mapSettings width = %1 height = %2" ).arg( mapSettings.outputSize().width() ).arg( mapSettings.outputSize().height() ) );
|
||||
QgsMessageLog::logMessage( QStringLiteral( "mapSettings.mapUnitsPerPixel() = %1" ).arg( mapSettings.mapUnitsPerPixel() ) );
|
||||
|
||||
//find out the current scale denominator and set it to the SLD parser
|
||||
QgsScaleCalculator scaleCalc( ( outputImage->logicalDpiX() + outputImage->logicalDpiY() ) / 2, mapSettings.destinationCrs().mapUnits() );
|
||||
QgsRectangle mapExtent = mapSettings.extent();
|
||||
double scaleDenominator = scaleCalc.calculate( mapExtent, outputImage->width() );
|
||||
mConfigParser->setScaleDenominator( scaleDenominator );
|
||||
|
||||
//read FEATURE_COUNT
|
||||
int featureCount = 1;
|
||||
if ( mParameters.contains( QStringLiteral( "FEATURE_COUNT" ) ) )
|
||||
// remove unwanted layers (restricted layers, ...)
|
||||
removeUnwantedLayers( layers, scaleDenominator );
|
||||
// remove non identifiable layers
|
||||
QStringList nonIdentifiableLayers = mProject->nonIdentifiableLayers();
|
||||
if ( !nonIdentifiableLayers.isEmpty() )
|
||||
{
|
||||
featureCount = mParameters[ QStringLiteral( "FEATURE_COUNT" )].toInt( &conversionSuccess );
|
||||
if ( !conversionSuccess )
|
||||
QList<QgsMapLayer *> wantedLayers;
|
||||
|
||||
Q_FOREACH ( QgsMapLayer *layer, layers )
|
||||
{
|
||||
featureCount = 1;
|
||||
if ( nonIdentifiableLayers.contains( layer->id() ) )
|
||||
continue;
|
||||
|
||||
wantedLayers.append( layer );
|
||||
}
|
||||
|
||||
layers = wantedLayers;
|
||||
}
|
||||
|
||||
Q_FOREACH ( QgsMapLayer *layer, layers )
|
||||
{
|
||||
Q_FOREACH ( QgsWmsParametersLayer param, params )
|
||||
{
|
||||
if ( param.mNickname == layerNickname( *layer ) )
|
||||
{
|
||||
checkLayerReadPermissions( layer );
|
||||
|
||||
setLayerFilter( layer, param.mFilter );
|
||||
|
||||
setLayerAccessControlFilter( layer );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//read QUERY_LAYERS
|
||||
if ( !mParameters.contains( QStringLiteral( "QUERY_LAYERS" ) ) )
|
||||
// add layers to map settings (revert order for the rendering)
|
||||
std::reverse( layers.begin(), layers.end() );
|
||||
mapSettings.setLayers( layers );
|
||||
|
||||
int featureCount = mWmsParameters.featureCountAsInt();
|
||||
if ( featureCount < 1 )
|
||||
{
|
||||
throw QgsBadRequestException( QStringLiteral( "ParameterMissing" ), QStringLiteral( "No QUERY_LAYERS" ) );
|
||||
featureCount = 1;
|
||||
}
|
||||
|
||||
QStringList queryLayerList = mParameters[ QStringLiteral( "QUERY_LAYERS" )].split( ',', QString::SkipEmptyParts );
|
||||
if ( queryLayerList.isEmpty() )
|
||||
int i = mWmsParameters.iAsInt();
|
||||
int j = mWmsParameters.jAsInt();
|
||||
if ( xyDefined && !ijDefined )
|
||||
{
|
||||
throw QgsBadRequestException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Malformed QUERY_LAYERS" ) );
|
||||
i = mWmsParameters.xAsInt();
|
||||
j = mWmsParameters.yAsInt();
|
||||
}
|
||||
int width = mWmsParameters.widthAsInt();
|
||||
int height = mWmsParameters.heightAsInt();
|
||||
if ( ( i != -1 && j != -1 && width != 0 && height != 0 ) && ( width != outputImage->width() || height != outputImage->height() ) )
|
||||
{
|
||||
i *= ( outputImage->width() / ( double )width );
|
||||
j *= ( outputImage->height() / ( double )height );
|
||||
}
|
||||
|
||||
//read I,J resp. X,Y
|
||||
QString iString = mParameters.value( QStringLiteral( "I" ), mParameters.value( QStringLiteral( "X" ) ) );
|
||||
int i = iString.toInt( &conversionSuccess );
|
||||
if ( !conversionSuccess )
|
||||
{
|
||||
i = -1;
|
||||
}
|
||||
|
||||
QString jString = mParameters.value( QStringLiteral( "J" ), mParameters.value( QStringLiteral( "Y" ) ) );
|
||||
int j = jString.toInt( &conversionSuccess );
|
||||
if ( !conversionSuccess )
|
||||
{
|
||||
j = -1;
|
||||
}
|
||||
|
||||
//read FILTER_GEOM
|
||||
std::unique_ptr<QgsGeometry> filterGeom;
|
||||
if ( mParameters.contains( QStringLiteral( "FILTER_GEOM" ) ) )
|
||||
{
|
||||
filterGeom.reset( new QgsGeometry( QgsGeometry::fromWkt( mParameters.value( QStringLiteral( "FILTER_GEOM" ) ) ) ) );
|
||||
}
|
||||
|
||||
//In case the output image is distorted (WIDTH/HEIGHT ratio not equal to BBOX width/height), I and J need to be adapted as well
|
||||
int widthParam = mParameters.value( "WIDTH", "-1" ).toInt();
|
||||
int heightParam = mParameters.value( "HEIGHT", "-1" ).toInt();
|
||||
if ( ( i != -1 && j != -1 && widthParam != -1 && heightParam != -1 ) && ( widthParam != outputImage->width() || heightParam != outputImage->height() ) )
|
||||
{
|
||||
i *= ( outputImage->width() / ( double )widthParam );
|
||||
j *= ( outputImage->height() / ( double )heightParam );
|
||||
}
|
||||
|
||||
//Normally, I/J or X/Y are mandatory parameters.
|
||||
//However, in order to make attribute only queries via the FILTER parameter, it is allowed to skip them if the FILTER parameter is there
|
||||
|
||||
// init search variables
|
||||
std::unique_ptr<QgsRectangle> featuresRect;
|
||||
std::unique_ptr<QgsGeometry> filterGeom;
|
||||
std::unique_ptr<QgsPointXY> infoPoint;
|
||||
|
||||
if ( i == -1 || j == -1 )
|
||||
{
|
||||
if ( mParameters.contains( QStringLiteral( "FILTER" ) ) )
|
||||
{
|
||||
featuresRect.reset( new QgsRectangle() );
|
||||
}
|
||||
else if ( !filterGeom.get() )
|
||||
{
|
||||
throw QgsBadRequestException( QStringLiteral( "ParameterMissing" ),
|
||||
QStringLiteral( "I/J parameters are required for GetFeatureInfo" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
if ( i != -1 && j != -1 )
|
||||
{
|
||||
infoPoint.reset( new QgsPointXY() );
|
||||
infoPointToMapCoordinates( i, j, infoPoint.get(), mapSettings );
|
||||
}
|
||||
else if ( filtersDefined )
|
||||
{
|
||||
featuresRect.reset( new QgsRectangle() );
|
||||
}
|
||||
else if ( filterGeomDefined )
|
||||
{
|
||||
filterGeom.reset( new QgsGeometry( QgsGeometry::fromWkt( mWmsParameters.filterGeom() ) ) );
|
||||
}
|
||||
|
||||
//get the layer registered in QgsMapLayerRegistry and apply possible filters
|
||||
( void )layerSet( layersList, stylesList, mapSettings.destinationCrs() );
|
||||
|
||||
//scoped pointer to restore all original layer filters (subsetStrings) when pointer goes out of scope
|
||||
//there's LOTS of potential exit paths here, so we avoid having to restore the filters manually
|
||||
std::unique_ptr< QgsOWSServerFilterRestorer > filterRestorer( new QgsOWSServerFilterRestorer( mAccessControl ) );
|
||||
applyRequestedLayerFilters( layersList, mapSettings, filterRestorer->originalFilters() );
|
||||
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
applyAccessControlLayersFilters( layersList, filterRestorer->originalFilters() );
|
||||
#endif
|
||||
QDomDocument result;
|
||||
|
||||
QDomElement getFeatureInfoElement;
|
||||
QString infoFormat = mParameters.value( QStringLiteral( "INFO_FORMAT" ) );
|
||||
if ( infoFormat.startsWith( QLatin1String( "application/vnd.ogc.gml" ) ) )
|
||||
QgsWmsParameters::Format infoFormat = mWmsParameters.infoFormat();
|
||||
if ( infoFormat == QgsWmsParameters::Format::GML )
|
||||
{
|
||||
getFeatureInfoElement = result.createElement( QStringLiteral( "wfs:FeatureCollection" ) );
|
||||
getFeatureInfoElement.setAttribute( QStringLiteral( "xmlns:wfs" ), QStringLiteral( "http://www.opengis.net/wfs" ) );
|
||||
@ -782,18 +812,22 @@ namespace QgsWms
|
||||
}
|
||||
else
|
||||
{
|
||||
QString featureInfoElemName = mConfigParser->featureInfoDocumentElement( QStringLiteral( "GetFeatureInfoResponse" ) );
|
||||
QString featureInfoElemNS = mConfigParser->featureInfoDocumentElementNS();
|
||||
if ( featureInfoElemNS.isEmpty() )
|
||||
QString featureInfoElemName = QgsServerProjectUtils::wmsFeatureInfoDocumentElement( *mProject );
|
||||
if ( featureInfoElemName.isEmpty() )
|
||||
{
|
||||
featureInfoElemName = QStringLiteral( "GetFeatureInfoResponse" );
|
||||
}
|
||||
QString featureInfoElemNs = QgsServerProjectUtils::wmsFeatureInfoDocumentElementNs( *mProject );
|
||||
if ( featureInfoElemNs.isEmpty() )
|
||||
{
|
||||
getFeatureInfoElement = result.createElement( featureInfoElemName );
|
||||
}
|
||||
else
|
||||
{
|
||||
getFeatureInfoElement = result.createElementNS( featureInfoElemNS, featureInfoElemName );
|
||||
getFeatureInfoElement = result.createElementNS( featureInfoElemNs, featureInfoElemName );
|
||||
}
|
||||
//feature info schema
|
||||
QString featureInfoSchema = mConfigParser->featureInfoSchema();
|
||||
QString featureInfoSchema = QgsServerProjectUtils::wmsFeatureInfoSchema( *mProject );
|
||||
if ( !featureInfoSchema.isEmpty() )
|
||||
{
|
||||
getFeatureInfoElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
|
||||
@ -802,122 +836,92 @@ namespace QgsWms
|
||||
}
|
||||
result.appendChild( getFeatureInfoElement );
|
||||
|
||||
QStringList nonIdentifiableLayers = mConfigParser->identifyDisabledLayers();
|
||||
|
||||
//Render context is needed to determine feature visibility for vector layers
|
||||
QgsRenderContext renderContext = QgsRenderContext::fromMapSettings( mapSettings );
|
||||
|
||||
bool sia2045 = mConfigParser->featureInfoFormatSIA2045();
|
||||
bool sia2045 = QgsServerProjectUtils::wmsInfoFormatSia2045( *mProject );
|
||||
|
||||
//layers can have assigned a different name for GetCapabilities
|
||||
QHash<QString, QString> layerAliasMap = mConfigParser->featureInfoLayerAliasMap();
|
||||
QHash<QString, QString> layerAliasMap = QgsServerProjectUtils::wmsFeatureInfoLayerAliasMap( *mProject );
|
||||
|
||||
QList<QgsMapLayer *> layerList;
|
||||
QgsMapLayer *currentLayer = nullptr;
|
||||
for ( auto layerIt = queryLayerList.constBegin(); layerIt != queryLayerList.constEnd(); ++layerIt )
|
||||
Q_FOREACH ( QString queryLayer, queryLayers )
|
||||
{
|
||||
//create maplayers from sld parser (several layers are possible in case of feature info on a group)
|
||||
layerList = mConfigParser->mapLayerFromStyle( *layerIt, QLatin1String( "" ) );
|
||||
for ( auto layerListIt = layerList.begin() ; layerListIt != layerList.end(); ++layerListIt )
|
||||
Q_FOREACH ( QgsMapLayer *layer, layers )
|
||||
{
|
||||
currentLayer = *layerListIt;
|
||||
if ( !currentLayer || nonIdentifiableLayers.contains( currentLayer->id() ) )
|
||||
if ( queryLayer == layerNickname( *layer ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QgsMapLayer *registeredMapLayer = QgsProject::instance()->mapLayer( currentLayer->id() );
|
||||
if ( registeredMapLayer )
|
||||
{
|
||||
currentLayer = registeredMapLayer;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
if ( !mAccessControl->layerReadPermission( currentLayer ) )
|
||||
{
|
||||
throw QgsSecurityException( QStringLiteral( "You are not allowed to access to the layer: %1" ).arg( currentLayer->name() ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
//skip layer if not visible at current map scale
|
||||
if ( scaleDenominator > 0 && !currentLayer->isInScaleRange( scaleDenominator ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//switch depending on vector or raster
|
||||
QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( currentLayer );
|
||||
|
||||
QDomElement layerElement;
|
||||
if ( infoFormat.startsWith( QLatin1String( "application/vnd.ogc.gml" ) ) )
|
||||
{
|
||||
layerElement = getFeatureInfoElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
layerElement = result.createElement( QStringLiteral( "Layer" ) );
|
||||
QString layerName = currentLayer->name();
|
||||
if ( mConfigParser->useLayerIds() )
|
||||
layerName = currentLayer->id();
|
||||
else if ( !currentLayer->shortName().isEmpty() )
|
||||
layerName = currentLayer->shortName();
|
||||
|
||||
//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() )
|
||||
QDomElement layerElement;
|
||||
if ( infoFormat == QgsWmsParameters::Format::GML )
|
||||
{
|
||||
layerName = layerAliasIt.value();
|
||||
layerElement = getFeatureInfoElement;
|
||||
}
|
||||
layerElement.setAttribute( QStringLiteral( "name" ), layerName );
|
||||
getFeatureInfoElement.appendChild( layerElement );
|
||||
if ( sia2045 ) //the name might not be unique after alias replacement
|
||||
else
|
||||
{
|
||||
layerElement.setAttribute( QStringLiteral( "id" ), currentLayer->id() );
|
||||
}
|
||||
}
|
||||
layerElement = result.createElement( QStringLiteral( "Layer" ) );
|
||||
QString layerName = queryLayer;
|
||||
|
||||
if ( vectorLayer )
|
||||
{
|
||||
if ( !featureInfoFromVectorLayer( vectorLayer, infoPoint.get(), featureCount, result, layerElement, mapSettings, renderContext, version, infoFormat, featuresRect.get(), filterGeom.get() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else //raster layer
|
||||
{
|
||||
if ( infoFormat.startsWith( QLatin1String( "application/vnd.ogc.gml" ) ) )
|
||||
{
|
||||
layerElement = result.createElement( QStringLiteral( "gml:featureMember" )/*wfs:FeatureMember*/ );
|
||||
getFeatureInfoElement.appendChild( layerElement );
|
||||
}
|
||||
|
||||
QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( currentLayer );
|
||||
if ( rasterLayer )
|
||||
{
|
||||
if ( !infoPoint )
|
||||
//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() )
|
||||
{
|
||||
continue;
|
||||
layerName = layerAliasIt.value();
|
||||
}
|
||||
QgsPointXY layerInfoPoint = mapSettings.mapToLayerCoordinates( currentLayer, *( infoPoint.get() ) );
|
||||
if ( !featureInfoFromRasterLayer( rasterLayer, mapSettings, &layerInfoPoint, result, layerElement, version, infoFormat ) )
|
||||
|
||||
layerElement.setAttribute( QStringLiteral( "name" ), layerName );
|
||||
getFeatureInfoElement.appendChild( layerElement );
|
||||
if ( sia2045 ) //the name might not be unique after alias replacement
|
||||
{
|
||||
continue;
|
||||
layerElement.setAttribute( QStringLiteral( "id" ), layer->id() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( layer->type() == QgsMapLayer::VectorLayer )
|
||||
{
|
||||
QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
|
||||
if ( vectorLayer )
|
||||
{
|
||||
if ( !featureInfoFromVectorLayer( vectorLayer, infoPoint.get(), featureCount, result, layerElement, mapSettings, renderContext, version, mWmsParameters.infoFormatAsString(), featuresRect.get(), filterGeom.get() ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
if ( infoFormat == QgsWmsParameters::Format::GML )
|
||||
{
|
||||
layerElement = result.createElement( QStringLiteral( "gml:featureMember" )/*wfs:FeatureMember*/ );
|
||||
getFeatureInfoElement.appendChild( layerElement );
|
||||
}
|
||||
|
||||
QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( layer );
|
||||
if ( rasterLayer )
|
||||
{
|
||||
if ( !infoPoint )
|
||||
{
|
||||
break;
|
||||
}
|
||||
QgsPointXY layerInfoPoint = mapSettings.mapToLayerCoordinates( layer, *( infoPoint.get() ) );
|
||||
if ( !featureInfoFromRasterLayer( rasterLayer, mapSettings, &layerInfoPoint, result, layerElement, version, mWmsParameters.infoFormatAsString() ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( featuresRect )
|
||||
{
|
||||
if ( infoFormat.startsWith( QLatin1String( "application/vnd.ogc.gml" ) ) )
|
||||
if ( infoFormat == QgsWmsParameters::Format::GML )
|
||||
{
|
||||
QDomElement bBoxElem = result.createElement( QStringLiteral( "gml:boundedBy" ) );
|
||||
QDomElement boxElem;
|
||||
int gmlVersion = infoFormat.startsWith( QLatin1String( "application/vnd.ogc.gml/3" ) ) ? 3 : 2;
|
||||
int gmlVersion = mWmsParameters.infoFormatAsString().startsWith( QLatin1String( "application/vnd.ogc.gml/3" ) ) ? 3 : 2;
|
||||
if ( gmlVersion < 3 )
|
||||
{
|
||||
boxElem = QgsOgcUtils::rectangleToGMLBox( featuresRect.get(), result, 8 );
|
||||
@ -947,16 +951,11 @@ namespace QgsWms
|
||||
}
|
||||
}
|
||||
|
||||
if ( sia2045 && infoFormat.compare( QLatin1String( "text/xml" ), Qt::CaseInsensitive ) == 0 )
|
||||
if ( sia2045 && infoFormat == QgsWmsParameters::Format::XML )
|
||||
{
|
||||
convertFeatureInfoToSIA2045( result );
|
||||
}
|
||||
|
||||
//force restoration of original filters
|
||||
filterRestorer.reset();
|
||||
|
||||
QgsProject::instance()->removeAllMapLayers();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1288,8 +1287,8 @@ namespace QgsWms
|
||||
int featureCounter = 0;
|
||||
layer->updateFields();
|
||||
const QgsFields &fields = layer->pendingFields();
|
||||
bool addWktGeometry = mConfigParser && mConfigParser->featureInfoWithWktGeometry();
|
||||
bool segmentizeWktGeometry = mConfigParser && mConfigParser->segmentizeFeatureInfoWktGeometry();
|
||||
bool addWktGeometry = QgsServerProjectUtils::wmsFeatureInfoAddWktGeometry( *mProject );
|
||||
bool segmentizeWktGeometry = QgsServerProjectUtils::wmsFeatureInfoSegmentizeWktGeometry( *mProject );
|
||||
const QSet<QString> &excludedAttributes = layer->excludeAttributesWms();
|
||||
|
||||
QgsFeatureRequest fReq;
|
||||
@ -1385,17 +1384,13 @@ namespace QgsWms
|
||||
outputCrs = mapSettings.destinationCrs();
|
||||
}
|
||||
|
||||
if ( infoFormat == QLatin1String( "application/vnd.ogc.gml" ) )
|
||||
if ( mWmsParameters.infoFormat() == QgsWmsParameters::Format::GML )
|
||||
{
|
||||
bool withGeom = layer->wkbType() != QgsWkbTypes::NoGeometry && addWktGeometry;
|
||||
int version = infoFormat.startsWith( QLatin1String( "application/vnd.ogc.gml/3" ) ) ? 3 : 2;
|
||||
QString typeName = layer->name();
|
||||
if ( mConfigParser && mConfigParser->useLayerIds() )
|
||||
typeName = layer->id();
|
||||
else if ( !layer->shortName().isEmpty() )
|
||||
typeName = layer->shortName();
|
||||
int gmlVersion = infoFormat.startsWith( QLatin1String( "application/vnd.ogc.gml/3" ) ) ? 3 : 2;
|
||||
QString typeName = layerNickname( *layer );
|
||||
QDomElement elem = createFeatureGML(
|
||||
&feature, layer, infoDocument, outputCrs, mapSettings, typeName, withGeom, version
|
||||
&feature, layer, infoDocument, outputCrs, mapSettings, typeName, withGeom, gmlVersion
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
, &attributes
|
||||
#endif
|
||||
@ -1453,14 +1448,14 @@ namespace QgsWms
|
||||
}
|
||||
|
||||
//append feature bounding box to feature info xml
|
||||
if ( layer->wkbType() != QgsWkbTypes::NoGeometry && hasGeometry && mConfigParser )
|
||||
if ( layer->wkbType() != QgsWkbTypes::NoGeometry && hasGeometry )
|
||||
{
|
||||
QDomElement bBoxElem = infoDocument.createElement( QStringLiteral( "BoundingBox" ) );
|
||||
bBoxElem.setAttribute( version == QLatin1String( "1.1.1" ) ? "SRS" : "CRS", outputCrs.authid() );
|
||||
bBoxElem.setAttribute( QStringLiteral( "minx" ), qgsDoubleToString( box.xMinimum(), getWMSPrecision( 8 ) ) );
|
||||
bBoxElem.setAttribute( QStringLiteral( "maxx" ), qgsDoubleToString( box.xMaximum(), getWMSPrecision( 8 ) ) );
|
||||
bBoxElem.setAttribute( QStringLiteral( "miny" ), qgsDoubleToString( box.yMinimum(), getWMSPrecision( 8 ) ) );
|
||||
bBoxElem.setAttribute( QStringLiteral( "maxy" ), qgsDoubleToString( box.yMaximum(), getWMSPrecision( 8 ) ) );
|
||||
bBoxElem.setAttribute( QStringLiteral( "minx" ), qgsDoubleToString( box.xMinimum(), getWMSPrecision() ) );
|
||||
bBoxElem.setAttribute( QStringLiteral( "maxx" ), qgsDoubleToString( box.xMaximum(), getWMSPrecision() ) );
|
||||
bBoxElem.setAttribute( QStringLiteral( "miny" ), qgsDoubleToString( box.yMinimum(), getWMSPrecision() ) );
|
||||
bBoxElem.setAttribute( QStringLiteral( "maxy" ), qgsDoubleToString( box.yMaximum(), getWMSPrecision() ) );
|
||||
featureElement.appendChild( bBoxElem );
|
||||
}
|
||||
|
||||
@ -1484,14 +1479,14 @@ namespace QgsWms
|
||||
{
|
||||
if ( QgsWkbTypes::isCurvedType( abstractGeom->wkbType() ) )
|
||||
{
|
||||
QgsAbstractGeometry *segmentizedGeom = abstractGeom-> segmentize();
|
||||
QgsAbstractGeometry *segmentizedGeom = abstractGeom->segmentize();
|
||||
geom.setGeometry( segmentizedGeom );
|
||||
}
|
||||
}
|
||||
}
|
||||
QDomElement geometryElement = infoDocument.createElement( QStringLiteral( "Attribute" ) );
|
||||
geometryElement.setAttribute( QStringLiteral( "name" ), QStringLiteral( "geometry" ) );
|
||||
geometryElement.setAttribute( QStringLiteral( "value" ), geom.exportToWkt( getWMSPrecision( 8 ) ) );
|
||||
geometryElement.setAttribute( QStringLiteral( "value" ), geom.exportToWkt( getWMSPrecision() ) );
|
||||
geometryElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "derived" ) );
|
||||
featureElement.appendChild( geometryElement );
|
||||
}
|
||||
@ -1540,7 +1535,7 @@ namespace QgsWms
|
||||
attributes = layer->dataProvider()->identify( *infoPoint, QgsRaster::IdentifyFormatValue, mapSettings.extent(), mapSettings.outputSize().width(), mapSettings.outputSize().height() ).results();
|
||||
}
|
||||
|
||||
if ( infoFormat == QLatin1String( "application/vnd.ogc.gml" ) )
|
||||
if ( mWmsParameters.infoFormat() == QgsWmsParameters::Format::GML )
|
||||
{
|
||||
QgsFeature feature;
|
||||
QgsFields fields;
|
||||
@ -1554,14 +1549,10 @@ namespace QgsWms
|
||||
feature.setFields( fields );
|
||||
|
||||
QgsCoordinateReferenceSystem layerCrs = layer->crs();
|
||||
int version = infoFormat.startsWith( QLatin1String( "application/vnd.ogc.gml/3" ) ) ? 3 : 2;
|
||||
QString typeName = layer->name();
|
||||
if ( mConfigParser && mConfigParser->useLayerIds() )
|
||||
typeName = layer->id();
|
||||
else if ( !layer->shortName().isEmpty() )
|
||||
typeName = layer->shortName();
|
||||
int gmlVersion = infoFormat.startsWith( QLatin1String( "application/vnd.ogc.gml/3" ) ) ? 3 : 2;
|
||||
QString typeName = layerNickname( *layer );
|
||||
QDomElement elem = createFeatureGML(
|
||||
&feature, nullptr, infoDocument, layerCrs, mapSettings, typeName, false, version, nullptr );
|
||||
&feature, nullptr, infoDocument, layerCrs, mapSettings, typeName, false, gmlVersion, nullptr );
|
||||
layerElement.appendChild( elem );
|
||||
}
|
||||
else
|
||||
@ -2263,11 +2254,11 @@ namespace QgsWms
|
||||
QDomElement boxElem;
|
||||
if ( version < 3 )
|
||||
{
|
||||
boxElem = QgsOgcUtils::rectangleToGMLBox( &box, doc, 8 );
|
||||
boxElem = QgsOgcUtils::rectangleToGMLBox( &box, doc, getWMSPrecision() );
|
||||
}
|
||||
else
|
||||
{
|
||||
boxElem = QgsOgcUtils::rectangleToGMLEnvelope( &box, doc, 8 );
|
||||
boxElem = QgsOgcUtils::rectangleToGMLEnvelope( &box, doc, getWMSPrecision() );
|
||||
}
|
||||
|
||||
if ( crs.isValid() )
|
||||
@ -2291,11 +2282,11 @@ namespace QgsWms
|
||||
QDomElement gmlElem;
|
||||
if ( version < 3 )
|
||||
{
|
||||
gmlElem = QgsOgcUtils::geometryToGML( geom, doc, 8 );
|
||||
gmlElem = QgsOgcUtils::geometryToGML( geom, doc, getWMSPrecision() );
|
||||
}
|
||||
else
|
||||
{
|
||||
gmlElem = QgsOgcUtils::geometryToGML( geom, doc, QStringLiteral( "GML3" ), 8 );
|
||||
gmlElem = QgsOgcUtils::geometryToGML( geom, doc, QStringLiteral( "GML3" ), getWMSPrecision() );
|
||||
}
|
||||
|
||||
if ( !gmlElem.isNull() )
|
||||
@ -2388,27 +2379,18 @@ namespace QgsWms
|
||||
return imageQuality;
|
||||
}
|
||||
|
||||
int QgsRenderer::getWMSPrecision( int defaultValue = 8 ) const
|
||||
int QgsRenderer::getWMSPrecision() const
|
||||
{
|
||||
// First taken from QGIS project
|
||||
int WMSPrecision = mConfigParser->wmsPrecision();
|
||||
// First taken from QGIS project and the default value is 6
|
||||
int WMSPrecision = QgsServerProjectUtils::wmsFeatureInfoPrecision( *mProject );
|
||||
|
||||
// Then checks if a parameter is given, if so use it instead
|
||||
if ( mParameters.contains( QStringLiteral( "WMS_PRECISION" ) ) )
|
||||
{
|
||||
bool conversionSuccess;
|
||||
int WMSPrecisionParameter;
|
||||
WMSPrecisionParameter = mParameters[ QStringLiteral( "WMS_PRECISION" )].toInt( &conversionSuccess );
|
||||
if ( conversionSuccess )
|
||||
{
|
||||
WMSPrecision = WMSPrecisionParameter;
|
||||
}
|
||||
}
|
||||
if ( WMSPrecision == -1 )
|
||||
{
|
||||
WMSPrecision = defaultValue;
|
||||
}
|
||||
return WMSPrecision;
|
||||
int WMSPrecisionParameter = mWmsParameters.wmsPrecisionAsInt();
|
||||
|
||||
if ( WMSPrecisionParameter > -1 )
|
||||
return WMSPrecisionParameter;
|
||||
else
|
||||
return WMSPrecision;
|
||||
}
|
||||
|
||||
QgsRectangle QgsRenderer::featureInfoSearchRect( QgsVectorLayer *ml, const QgsMapSettings &mapSettings, const QgsRenderContext &rct, const QgsPointXY &infoPoint ) const
|
||||
|
@ -334,7 +334,7 @@ namespace QgsWms
|
||||
int getImageQuality() const;
|
||||
|
||||
//! Return precision to use for GetFeatureInfo request
|
||||
int getWMSPrecision( int defaultValue ) const;
|
||||
int getWMSPrecision() const;
|
||||
|
||||
};
|
||||
|
||||
|
@ -453,6 +453,33 @@ class TestQgsServerAccessControl(unittest.TestCase):
|
||||
str(response).find("<qgs:color>red</qgs:color>") != -1, # spellok
|
||||
"No color in result of GetFeatureInfo\n%s" % response)
|
||||
|
||||
response, headers = self._get_restricted(query_string)
|
||||
self.assertEqual(
|
||||
headers.get("Content-Type"), "text/xml; charset=utf-8",
|
||||
"Content type for GetFeatureInfo is wrong: %s" % headers.get("Content-Type"))
|
||||
self.assertTrue(
|
||||
str(response).find('<ServiceException code="Security">') != -1,
|
||||
"Not allowed do a GetFeatureInfo on Country"
|
||||
)
|
||||
|
||||
query_string = "&".join(["%s=%s" % i for i in list({
|
||||
"MAP": urllib.parse.quote(self.projectPath),
|
||||
"SERVICE": "WMS",
|
||||
"VERSION": "1.1.1",
|
||||
"REQUEST": "GetFeatureInfo",
|
||||
"LAYERS": "Hello",
|
||||
"QUERY_LAYERS": "Hello",
|
||||
"STYLES": "",
|
||||
"FORMAT": "image/png",
|
||||
"BBOX": "-16817707,-6318936.5,5696513,16195283.5",
|
||||
"HEIGHT": "500",
|
||||
"WIDTH": "500",
|
||||
"SRS": "EPSG:3857",
|
||||
"FEATURE_COUNT": "10",
|
||||
"INFO_FORMAT": "application/vnd.ogc.gml",
|
||||
"X": "56",
|
||||
"Y": "144"
|
||||
}.items())])
|
||||
response, headers = self._get_restricted(query_string)
|
||||
self.assertTrue(
|
||||
str(response).find("<qgs:pk>1</qgs:pk>") != -1,
|
||||
@ -1053,6 +1080,33 @@ class TestQgsServerAccessControl(unittest.TestCase):
|
||||
str(response).find("<qgs:pk>1</qgs:pk>") != -1,
|
||||
"No good result in GetFeatureInfo Hello/1\n%s" % response)
|
||||
|
||||
response, headers = self._get_restricted(query_string)
|
||||
self.assertEqual(
|
||||
headers.get("Content-Type"), "text/xml; charset=utf-8",
|
||||
"Content type for GetFeatureInfo is wrong: %s" % headers.get("Content-Type"))
|
||||
self.assertTrue(
|
||||
str(response).find('<ServiceException code="Security">') != -1,
|
||||
"Not allowed do a GetFeatureInfo on Country"
|
||||
)
|
||||
|
||||
query_string = "&".join(["%s=%s" % i for i in list({
|
||||
"SERVICE": "WMS",
|
||||
"VERSION": "1.1.1",
|
||||
"REQUEST": "GetFeatureInfo",
|
||||
"LAYERS": "Hello_SubsetString",
|
||||
"QUERY_LAYERS": "Hello_SubsetString",
|
||||
"STYLES": "",
|
||||
"FORMAT": "image/png",
|
||||
"BBOX": "-16817707,-6318936.5,5696513,16195283.5",
|
||||
"HEIGHT": "500",
|
||||
"WIDTH": "500",
|
||||
"SRS": "EPSG:3857",
|
||||
"FEATURE_COUNT": "10",
|
||||
"INFO_FORMAT": "application/vnd.ogc.gml",
|
||||
"X": "56",
|
||||
"Y": "144",
|
||||
"MAP": urllib.parse.quote(self.projectPath)
|
||||
}.items())])
|
||||
response, headers = self._get_restricted(query_string)
|
||||
self.assertTrue(
|
||||
str(response).find("<qgs:pk>") != -1,
|
||||
|
@ -69,7 +69,16 @@ class TestQgsServerWMS(QgsServerTestBase):
|
||||
for request in ('GetCapabilities', 'GetProjectSettings', 'GetContext'):
|
||||
self.wms_request_compare(request)
|
||||
|
||||
# Test getfeatureinfo response
|
||||
# Test getfeatureinfo response xml (default info_format)
|
||||
self.wms_request_compare('GetFeatureInfo',
|
||||
'&layers=testlayer%20%C3%A8%C3%A9&styles=&' +
|
||||
'info_format=text%2Fxml&transparent=true&' +
|
||||
'width=600&height=400&srs=EPSG%3A3857&bbox=913190.6389747962%2C' +
|
||||
'5606005.488876367%2C913235.426296057%2C5606035.347090538&' +
|
||||
'query_layers=testlayer%20%C3%A8%C3%A9&X=190&Y=320',
|
||||
'wms_getfeatureinfo-text-xml')
|
||||
|
||||
# Test getfeatureinfo response html
|
||||
self.wms_request_compare('GetFeatureInfo',
|
||||
'&layers=testlayer%20%C3%A8%C3%A9&styles=&' +
|
||||
'info_format=text%2Fhtml&transparent=true&' +
|
||||
@ -78,10 +87,10 @@ class TestQgsServerWMS(QgsServerTestBase):
|
||||
'query_layers=testlayer%20%C3%A8%C3%A9&X=190&Y=320',
|
||||
'wms_getfeatureinfo-text-html')
|
||||
|
||||
# Test getfeatureinfo default info_format
|
||||
# Test getfeatureinfo response text
|
||||
self.wms_request_compare('GetFeatureInfo',
|
||||
'&layers=testlayer%20%C3%A8%C3%A9&styles=&' +
|
||||
'transparent=true&' +
|
||||
'info_format=text%2Fplain&transparent=true&' +
|
||||
'width=600&height=400&srs=EPSG%3A3857&bbox=913190.6389747962%2C' +
|
||||
'5606005.488876367%2C913235.426296057%2C5606035.347090538&' +
|
||||
'query_layers=testlayer%20%C3%A8%C3%A9&X=190&Y=320',
|
||||
|
14
tests/testdata/qgis_server/wms_getfeatureinfo-text-xml.txt
vendored
Normal file
14
tests/testdata/qgis_server/wms_getfeatureinfo-text-xml.txt
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
*****
|
||||
Content-Type: text/xml; charset=utf-8
|
||||
|
||||
<GetFeatureInfoResponse>
|
||||
<Layer name="testlayer èé">
|
||||
<Feature id="2">
|
||||
<Attribute value="3" name="id"/>
|
||||
<Attribute value="three" name="name"/>
|
||||
<Attribute value="three èé↓" name="utf8nameè"/>
|
||||
<BoundingBox maxy="5606011.4565" maxx="913204.9128" miny="5606011.4565" CRS="EPSG:3857" minx="913204.9128"/>
|
||||
<Attribute type="derived" value="Point (913204.9128 5606011.4565)" name="geometry"/>
|
||||
</Feature>
|
||||
</Layer>
|
||||
</GetFeatureInfoResponse>
|
Loading…
x
Reference in New Issue
Block a user