mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Propagate WMS identify GML schema error and show it in results, fixes part of #8724
This commit is contained in:
parent
491231e600
commit
d5f167f1db
@ -57,7 +57,6 @@ QString QgsError::message( QgsErrorMessage::Format theFormat ) const
|
||||
// and there are no local not commited changes
|
||||
QString hash = QString( QGis::QGIS_DEV_VERSION );
|
||||
QString remote = QString( QGS_GIT_REMOTE_URL );
|
||||
QgsDebugMsg( "remote = " + remote );
|
||||
if ( !hash.isEmpty() && !remote.isEmpty() && remote.contains( "github.com" ) )
|
||||
{
|
||||
QString path = remote.remove( QRegExp( ".*github.com[:/]" ) ).remove( ".git" );
|
||||
@ -79,9 +78,29 @@ QString QgsError::message( QgsErrorMessage::Format theFormat ) const
|
||||
|
||||
if ( theFormat == QgsErrorMessage::Text )
|
||||
{
|
||||
str += m.tag() + " " + m.message();
|
||||
if ( !str.isEmpty() )
|
||||
{
|
||||
str += "\n"; // new message
|
||||
}
|
||||
if ( !m.tag().isEmpty() )
|
||||
{
|
||||
str += m.tag() + " ";
|
||||
}
|
||||
str += m.message();
|
||||
#ifdef QGISDEBUG
|
||||
str += QString( "\nat %1 : %2 : %3" ).arg( file ).arg( m.line() ).arg( m.function() );
|
||||
QString where;
|
||||
if ( !file.isEmpty() )
|
||||
{
|
||||
where += QString( "file: %1 row: %2" ).arg( file ).arg( m.line() );
|
||||
}
|
||||
if ( !m.function().isEmpty() )
|
||||
{
|
||||
where += QString( "function %1:" ).arg( m.function() );
|
||||
}
|
||||
if ( !where.isEmpty() )
|
||||
{
|
||||
str += QString( " (%1)" ).arg( where );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else // QgsErrorMessage::Html
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "qgsgmlschema.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgscoordinatereferencesystem.h"
|
||||
#include "qgserror.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsnetworkaccessmanager.h"
|
||||
@ -337,8 +338,17 @@ bool QgsGmlSchema::guessSchema( const QByteArray &data )
|
||||
XML_SetElementHandler( p, QgsGmlSchema::start, QgsGmlSchema::end );
|
||||
XML_SetCharacterDataHandler( p, QgsGmlSchema::chars );
|
||||
int atEnd = 1;
|
||||
XML_Parse( p, data.constData(), data.size(), atEnd );
|
||||
return 0;
|
||||
int res = XML_Parse( p, data.constData(), data.size(), atEnd );
|
||||
|
||||
if ( res == 0 )
|
||||
{
|
||||
QString err = QString( XML_ErrorString( XML_GetErrorCode( p ) ) );
|
||||
QgsDebugMsg( QString( "XML_Parse returned %1 error %2" ).arg( res ).arg( err ) );
|
||||
mError = QgsError( err, "GML schema" );
|
||||
mError.append( tr( "Cannot guess schema" ) );
|
||||
}
|
||||
|
||||
return res != 0;
|
||||
}
|
||||
|
||||
void QgsGmlSchema::startElement( const XML_Char* el, const XML_Char** attr )
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "qgis.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsdataprovider.h"
|
||||
#include "qgserror.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsfield.h"
|
||||
#include "qgslogger.h"
|
||||
@ -97,6 +98,9 @@ class CORE_EXPORT QgsGmlSchema: public QObject
|
||||
/** Get list of geometry attributes for type/class name */
|
||||
QStringList geometryAttributes( const QString & typeName );
|
||||
|
||||
/** Get error if parseXSD() or guessSchema() failed */
|
||||
QgsError error() const { return mError; }
|
||||
|
||||
private:
|
||||
|
||||
enum ParseMode
|
||||
@ -199,6 +203,9 @@ class CORE_EXPORT QgsGmlSchema: public QObject
|
||||
|
||||
/* Feature classes map with element paths as keys */
|
||||
QMap<QString, QgsGmlFeatureClass> mFeatureClassMap;
|
||||
|
||||
/* Error set if something failed */
|
||||
QgsError mError;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -376,8 +376,6 @@ bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, Qg
|
||||
|
||||
QMap< QString, QString > attributes, derivedAttributes;
|
||||
|
||||
QMap<int, QVariant> values;
|
||||
|
||||
QgsRaster::IdentifyFormat format = QgsRasterDataProvider::identifyFormatFromName( layer->customProperty( "identify/format" ).toString() );
|
||||
|
||||
// check if the format is really supported otherwise use first supported format
|
||||
@ -390,12 +388,13 @@ bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, Qg
|
||||
else return false;
|
||||
}
|
||||
|
||||
QgsRasterIdentifyResult identifyResult;
|
||||
// We can only use context (extent, width, height) if layer is not reprojected,
|
||||
// otherwise we don't know source resolution (size).
|
||||
if ( mCanvas->hasCrsTransformEnabled() && dprovider->crs() != mCanvas->mapRenderer()->destinationCrs() )
|
||||
{
|
||||
viewExtent = toLayerCoordinates( layer, viewExtent );
|
||||
values = dprovider->identify( point, format ).results();
|
||||
identifyResult = dprovider->identify( point, format );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -418,106 +417,117 @@ bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, Qg
|
||||
QgsDebugMsg( QString( "width = %1 height = %2" ).arg( width ).arg( height ) );
|
||||
QgsDebugMsg( QString( "xRes = %1 yRes = %2 mapUnitsPerPixel = %3" ).arg( viewExtent.width() / width ).arg( viewExtent.height() / height ).arg( mapUnitsPerPixel ) );
|
||||
|
||||
values = dprovider->identify( point, format, viewExtent, width, height ).results();
|
||||
identifyResult = dprovider->identify( point, format, viewExtent, width, height );
|
||||
}
|
||||
|
||||
derivedAttributes.insert( tr( "(clicked coordinate)" ), point.toString() );
|
||||
|
||||
//QString type = tr( "Raster" );
|
||||
QgsGeometry geometry;
|
||||
if ( format == QgsRaster::IdentifyFormatValue )
|
||||
if ( identifyResult.isValid() )
|
||||
{
|
||||
foreach ( int bandNo, values.keys() )
|
||||
QMap<int, QVariant> values = identifyResult.results();
|
||||
QgsGeometry geometry;
|
||||
if ( format == QgsRaster::IdentifyFormatValue )
|
||||
{
|
||||
QString valueString;
|
||||
if ( values.value( bandNo ).isNull() )
|
||||
foreach ( int bandNo, values.keys() )
|
||||
{
|
||||
valueString = tr( "no data" );
|
||||
}
|
||||
else
|
||||
{
|
||||
double value = values.value( bandNo ).toDouble();
|
||||
valueString = QgsRasterBlock::printValue( value );
|
||||
}
|
||||
attributes.insert( dprovider->generateBandName( bandNo ), valueString );
|
||||
}
|
||||
QString label = layer->name();
|
||||
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
|
||||
}
|
||||
else if ( format == QgsRaster::IdentifyFormatFeature )
|
||||
{
|
||||
foreach ( int i, values.keys() )
|
||||
{
|
||||
QVariant value = values.value( i );
|
||||
if ( value.type() == QVariant::Bool && !value.toBool() )
|
||||
{
|
||||
// sublayer not visible or not queryable
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( value.type() == QVariant::String )
|
||||
{
|
||||
// error
|
||||
// TODO: better error reporting
|
||||
QString label = layer->subLayers().value( i );
|
||||
attributes.clear();
|
||||
attributes.insert( tr( "Error" ), value.toString() );
|
||||
|
||||
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
// list of feature stores for a single sublayer
|
||||
QgsFeatureStoreList featureStoreList = values.value( i ).value<QgsFeatureStoreList>();
|
||||
|
||||
foreach ( QgsFeatureStore featureStore, featureStoreList )
|
||||
{
|
||||
foreach ( QgsFeature feature, featureStore.features() )
|
||||
QString valueString;
|
||||
if ( values.value( bandNo ).isNull() )
|
||||
{
|
||||
valueString = tr( "no data" );
|
||||
}
|
||||
else
|
||||
{
|
||||
double value = values.value( bandNo ).toDouble();
|
||||
valueString = QgsRasterBlock::printValue( value );
|
||||
}
|
||||
attributes.insert( dprovider->generateBandName( bandNo ), valueString );
|
||||
}
|
||||
QString label = layer->name();
|
||||
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
|
||||
}
|
||||
else if ( format == QgsRaster::IdentifyFormatFeature )
|
||||
{
|
||||
foreach ( int i, values.keys() )
|
||||
{
|
||||
QVariant value = values.value( i );
|
||||
if ( value.type() == QVariant::Bool && !value.toBool() )
|
||||
{
|
||||
// sublayer not visible or not queryable
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( value.type() == QVariant::String )
|
||||
{
|
||||
// error
|
||||
// TODO: better error reporting
|
||||
QString label = layer->subLayers().value( i );
|
||||
attributes.clear();
|
||||
// WMS sublayer and feature type, a sublayer may contain multiple feature types.
|
||||
// Sublayer name may be the same as layer name and feature type name
|
||||
// may be the same as sublayer. We try to avoid duplicities in label.
|
||||
QString sublayer = featureStore.params().value( "sublayer" ).toString();
|
||||
QString featureType = featureStore.params().value( "featureType" ).toString();
|
||||
// Strip UMN MapServer '_feature'
|
||||
featureType.remove( "_feature" );
|
||||
QStringList labels;
|
||||
if ( sublayer.compare( layer->name(), Qt::CaseInsensitive ) != 0 )
|
||||
attributes.insert( tr( "Error" ), value.toString() );
|
||||
|
||||
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
// list of feature stores for a single sublayer
|
||||
QgsFeatureStoreList featureStoreList = values.value( i ).value<QgsFeatureStoreList>();
|
||||
|
||||
foreach ( QgsFeatureStore featureStore, featureStoreList )
|
||||
{
|
||||
foreach ( QgsFeature feature, featureStore.features() )
|
||||
{
|
||||
labels << sublayer;
|
||||
attributes.clear();
|
||||
// WMS sublayer and feature type, a sublayer may contain multiple feature types.
|
||||
// Sublayer name may be the same as layer name and feature type name
|
||||
// may be the same as sublayer. We try to avoid duplicities in label.
|
||||
QString sublayer = featureStore.params().value( "sublayer" ).toString();
|
||||
QString featureType = featureStore.params().value( "featureType" ).toString();
|
||||
// Strip UMN MapServer '_feature'
|
||||
featureType.remove( "_feature" );
|
||||
QStringList labels;
|
||||
if ( sublayer.compare( layer->name(), Qt::CaseInsensitive ) != 0 )
|
||||
{
|
||||
labels << sublayer;
|
||||
}
|
||||
if ( featureType.compare( sublayer, Qt::CaseInsensitive ) != 0 || labels.isEmpty() )
|
||||
{
|
||||
labels << featureType;
|
||||
|
||||
|
||||
}
|
||||
|
||||
QMap< QString, QString > derAttributes = derivedAttributes;
|
||||
derAttributes.unite( featureDerivedAttributes( &feature, layer ) );
|
||||
|
||||
IdentifyResult identifyResult( qobject_cast<QgsMapLayer *>( layer ), labels.join( " / " ), featureStore.fields(), feature, derAttributes );
|
||||
|
||||
identifyResult.mParams.insert( "getFeatureInfoUrl", featureStore.params().value( "getFeatureInfoUrl" ) );
|
||||
results->append( identifyResult );
|
||||
}
|
||||
if ( featureType.compare( sublayer, Qt::CaseInsensitive ) != 0 || labels.isEmpty() )
|
||||
{
|
||||
labels << featureType;
|
||||
|
||||
|
||||
}
|
||||
|
||||
QMap< QString, QString > derAttributes = derivedAttributes;
|
||||
derAttributes.unite( featureDerivedAttributes( &feature, layer ) );
|
||||
|
||||
IdentifyResult identifyResult( qobject_cast<QgsMapLayer *>( layer ), labels.join( " / " ), featureStore.fields(), feature, derAttributes );
|
||||
|
||||
identifyResult.mParams.insert( "getFeatureInfoUrl", featureStore.params().value( "getFeatureInfoUrl" ) );
|
||||
results->append( identifyResult );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // text or html
|
||||
{
|
||||
QgsDebugMsg( QString( "%1 html or text values" ).arg( values.size() ) );
|
||||
foreach ( int bandNo, values.keys() )
|
||||
else // text or html
|
||||
{
|
||||
QString value = values.value( bandNo ).toString();
|
||||
attributes.clear();
|
||||
attributes.insert( "", value );
|
||||
QgsDebugMsg( QString( "%1 html or text values" ).arg( values.size() ) );
|
||||
foreach ( int bandNo, values.keys() )
|
||||
{
|
||||
QString value = values.value( bandNo ).toString();
|
||||
attributes.clear();
|
||||
attributes.insert( "", value );
|
||||
|
||||
QString label = layer->subLayers().value( bandNo );
|
||||
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
|
||||
QString label = layer->subLayers().value( bandNo );
|
||||
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
attributes.clear();
|
||||
QString value = identifyResult.error().message( QgsErrorMessage::Text );
|
||||
attributes.insert( tr( "Error" ), value );
|
||||
QString label = tr( "Identify error" );
|
||||
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -4315,7 +4315,14 @@ QgsRasterIdentifyResult QgsWmsProvider::identify( const QgsPoint & thePoint, Qgs
|
||||
else
|
||||
{
|
||||
// guess from GML
|
||||
gmlSchema.guessSchema( mIdentifyResultBodies.value( gmlPart ) );
|
||||
bool ok = gmlSchema.guessSchema( mIdentifyResultBodies.value( gmlPart ) );
|
||||
if ( ! ok )
|
||||
{
|
||||
QgsError err = gmlSchema.error();
|
||||
err.append( tr( "Cannot identify" ) );
|
||||
QgsDebugMsg( "guess schema error: " + err.message() );
|
||||
return QgsRasterIdentifyResult( err );
|
||||
}
|
||||
}
|
||||
|
||||
QStringList featureTypeNames = gmlSchema.typeNames();
|
||||
|
Loading…
x
Reference in New Issue
Block a user