Skip to content

Commit d5f167f

Browse files
committed
Propagate WMS identify GML schema error and show it in results, fixes part of #8724
1 parent 491231e commit d5f167f

File tree

5 files changed

+137
-84
lines changed

5 files changed

+137
-84
lines changed

src/core/qgserror.cpp

+22-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ QString QgsError::message( QgsErrorMessage::Format theFormat ) const
5757
// and there are no local not commited changes
5858
QString hash = QString( QGis::QGIS_DEV_VERSION );
5959
QString remote = QString( QGS_GIT_REMOTE_URL );
60-
QgsDebugMsg( "remote = " + remote );
6160
if ( !hash.isEmpty() && !remote.isEmpty() && remote.contains( "github.com" ) )
6261
{
6362
QString path = remote.remove( QRegExp( ".*github.com[:/]" ) ).remove( ".git" );
@@ -79,9 +78,29 @@ QString QgsError::message( QgsErrorMessage::Format theFormat ) const
7978

8079
if ( theFormat == QgsErrorMessage::Text )
8180
{
82-
str += m.tag() + " " + m.message();
81+
if ( !str.isEmpty() )
82+
{
83+
str += "\n"; // new message
84+
}
85+
if ( !m.tag().isEmpty() )
86+
{
87+
str += m.tag() + " ";
88+
}
89+
str += m.message();
8390
#ifdef QGISDEBUG
84-
str += QString( "\nat %1 : %2 : %3" ).arg( file ).arg( m.line() ).arg( m.function() );
91+
QString where;
92+
if ( !file.isEmpty() )
93+
{
94+
where += QString( "file: %1 row: %2" ).arg( file ).arg( m.line() );
95+
}
96+
if ( !m.function().isEmpty() )
97+
{
98+
where += QString( "function %1:" ).arg( m.function() );
99+
}
100+
if ( !where.isEmpty() )
101+
{
102+
str += QString( " (%1)" ).arg( where );
103+
}
85104
#endif
86105
}
87106
else // QgsErrorMessage::Html

src/core/qgsgmlschema.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "qgsgmlschema.h"
1616
#include "qgsrectangle.h"
1717
#include "qgscoordinatereferencesystem.h"
18+
#include "qgserror.h"
1819
#include "qgsgeometry.h"
1920
#include "qgslogger.h"
2021
#include "qgsnetworkaccessmanager.h"
@@ -337,8 +338,17 @@ bool QgsGmlSchema::guessSchema( const QByteArray &data )
337338
XML_SetElementHandler( p, QgsGmlSchema::start, QgsGmlSchema::end );
338339
XML_SetCharacterDataHandler( p, QgsGmlSchema::chars );
339340
int atEnd = 1;
340-
XML_Parse( p, data.constData(), data.size(), atEnd );
341-
return 0;
341+
int res = XML_Parse( p, data.constData(), data.size(), atEnd );
342+
343+
if ( res == 0 )
344+
{
345+
QString err = QString( XML_ErrorString( XML_GetErrorCode( p ) ) );
346+
QgsDebugMsg( QString( "XML_Parse returned %1 error %2" ).arg( res ).arg( err ) );
347+
mError = QgsError( err, "GML schema" );
348+
mError.append( tr( "Cannot guess schema" ) );
349+
}
350+
351+
return res != 0;
342352
}
343353

344354
void QgsGmlSchema::startElement( const XML_Char* el, const XML_Char** attr )

src/core/qgsgmlschema.h

+7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "qgis.h"
2020
#include "qgsapplication.h"
2121
#include "qgsdataprovider.h"
22+
#include "qgserror.h"
2223
#include "qgsfeature.h"
2324
#include "qgsfield.h"
2425
#include "qgslogger.h"
@@ -97,6 +98,9 @@ class CORE_EXPORT QgsGmlSchema: public QObject
9798
/** Get list of geometry attributes for type/class name */
9899
QStringList geometryAttributes( const QString & typeName );
99100

101+
/** Get error if parseXSD() or guessSchema() failed */
102+
QgsError error() const { return mError; }
103+
100104
private:
101105

102106
enum ParseMode
@@ -199,6 +203,9 @@ class CORE_EXPORT QgsGmlSchema: public QObject
199203

200204
/* Feature classes map with element paths as keys */
201205
QMap<QString, QgsGmlFeatureClass> mFeatureClassMap;
206+
207+
/* Error set if something failed */
208+
QgsError mError;
202209
};
203210

204211
#endif

src/gui/qgsmaptoolidentify.cpp

+88-78
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,6 @@ bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, Qg
376376

377377
QMap< QString, QString > attributes, derivedAttributes;
378378

379-
QMap<int, QVariant> values;
380-
381379
QgsRaster::IdentifyFormat format = QgsRasterDataProvider::identifyFormatFromName( layer->customProperty( "identify/format" ).toString() );
382380

383381
// check if the format is really supported otherwise use first supported format
@@ -390,12 +388,13 @@ bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, Qg
390388
else return false;
391389
}
392390

391+
QgsRasterIdentifyResult identifyResult;
393392
// We can only use context (extent, width, height) if layer is not reprojected,
394393
// otherwise we don't know source resolution (size).
395394
if ( mCanvas->hasCrsTransformEnabled() && dprovider->crs() != mCanvas->mapRenderer()->destinationCrs() )
396395
{
397396
viewExtent = toLayerCoordinates( layer, viewExtent );
398-
values = dprovider->identify( point, format ).results();
397+
identifyResult = dprovider->identify( point, format );
399398
}
400399
else
401400
{
@@ -418,106 +417,117 @@ bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, Qg
418417
QgsDebugMsg( QString( "width = %1 height = %2" ).arg( width ).arg( height ) );
419418
QgsDebugMsg( QString( "xRes = %1 yRes = %2 mapUnitsPerPixel = %3" ).arg( viewExtent.width() / width ).arg( viewExtent.height() / height ).arg( mapUnitsPerPixel ) );
420419

421-
values = dprovider->identify( point, format, viewExtent, width, height ).results();
420+
identifyResult = dprovider->identify( point, format, viewExtent, width, height );
422421
}
423422

424423
derivedAttributes.insert( tr( "(clicked coordinate)" ), point.toString() );
425424

426-
//QString type = tr( "Raster" );
427-
QgsGeometry geometry;
428-
if ( format == QgsRaster::IdentifyFormatValue )
425+
if ( identifyResult.isValid() )
429426
{
430-
foreach ( int bandNo, values.keys() )
427+
QMap<int, QVariant> values = identifyResult.results();
428+
QgsGeometry geometry;
429+
if ( format == QgsRaster::IdentifyFormatValue )
431430
{
432-
QString valueString;
433-
if ( values.value( bandNo ).isNull() )
434-
{
435-
valueString = tr( "no data" );
436-
}
437-
else
431+
foreach ( int bandNo, values.keys() )
438432
{
439-
double value = values.value( bandNo ).toDouble();
440-
valueString = QgsRasterBlock::printValue( value );
433+
QString valueString;
434+
if ( values.value( bandNo ).isNull() )
435+
{
436+
valueString = tr( "no data" );
437+
}
438+
else
439+
{
440+
double value = values.value( bandNo ).toDouble();
441+
valueString = QgsRasterBlock::printValue( value );
442+
}
443+
attributes.insert( dprovider->generateBandName( bandNo ), valueString );
441444
}
442-
attributes.insert( dprovider->generateBandName( bandNo ), valueString );
445+
QString label = layer->name();
446+
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
443447
}
444-
QString label = layer->name();
445-
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
446-
}
447-
else if ( format == QgsRaster::IdentifyFormatFeature )
448-
{
449-
foreach ( int i, values.keys() )
448+
else if ( format == QgsRaster::IdentifyFormatFeature )
450449
{
451-
QVariant value = values.value( i );
452-
if ( value.type() == QVariant::Bool && !value.toBool() )
450+
foreach ( int i, values.keys() )
453451
{
454-
// sublayer not visible or not queryable
455-
continue;
456-
}
452+
QVariant value = values.value( i );
453+
if ( value.type() == QVariant::Bool && !value.toBool() )
454+
{
455+
// sublayer not visible or not queryable
456+
continue;
457+
}
457458

458-
if ( value.type() == QVariant::String )
459-
{
460-
// error
461-
// TODO: better error reporting
462-
QString label = layer->subLayers().value( i );
463-
attributes.clear();
464-
attributes.insert( tr( "Error" ), value.toString() );
459+
if ( value.type() == QVariant::String )
460+
{
461+
// error
462+
// TODO: better error reporting
463+
QString label = layer->subLayers().value( i );
464+
attributes.clear();
465+
attributes.insert( tr( "Error" ), value.toString() );
465466

466-
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
467-
continue;
468-
}
467+
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
468+
continue;
469+
}
469470

470-
// list of feature stores for a single sublayer
471-
QgsFeatureStoreList featureStoreList = values.value( i ).value<QgsFeatureStoreList>();
471+
// list of feature stores for a single sublayer
472+
QgsFeatureStoreList featureStoreList = values.value( i ).value<QgsFeatureStoreList>();
472473

473-
foreach ( QgsFeatureStore featureStore, featureStoreList )
474-
{
475-
foreach ( QgsFeature feature, featureStore.features() )
474+
foreach ( QgsFeatureStore featureStore, featureStoreList )
476475
{
477-
attributes.clear();
478-
// WMS sublayer and feature type, a sublayer may contain multiple feature types.
479-
// Sublayer name may be the same as layer name and feature type name
480-
// may be the same as sublayer. We try to avoid duplicities in label.
481-
QString sublayer = featureStore.params().value( "sublayer" ).toString();
482-
QString featureType = featureStore.params().value( "featureType" ).toString();
483-
// Strip UMN MapServer '_feature'
484-
featureType.remove( "_feature" );
485-
QStringList labels;
486-
if ( sublayer.compare( layer->name(), Qt::CaseInsensitive ) != 0 )
476+
foreach ( QgsFeature feature, featureStore.features() )
487477
{
488-
labels << sublayer;
478+
attributes.clear();
479+
// WMS sublayer and feature type, a sublayer may contain multiple feature types.
480+
// Sublayer name may be the same as layer name and feature type name
481+
// may be the same as sublayer. We try to avoid duplicities in label.
482+
QString sublayer = featureStore.params().value( "sublayer" ).toString();
483+
QString featureType = featureStore.params().value( "featureType" ).toString();
484+
// Strip UMN MapServer '_feature'
485+
featureType.remove( "_feature" );
486+
QStringList labels;
487+
if ( sublayer.compare( layer->name(), Qt::CaseInsensitive ) != 0 )
488+
{
489+
labels << sublayer;
490+
}
491+
if ( featureType.compare( sublayer, Qt::CaseInsensitive ) != 0 || labels.isEmpty() )
492+
{
493+
labels << featureType;
494+
495+
496+
}
497+
498+
QMap< QString, QString > derAttributes = derivedAttributes;
499+
derAttributes.unite( featureDerivedAttributes( &feature, layer ) );
500+
501+
IdentifyResult identifyResult( qobject_cast<QgsMapLayer *>( layer ), labels.join( " / " ), featureStore.fields(), feature, derAttributes );
502+
503+
identifyResult.mParams.insert( "getFeatureInfoUrl", featureStore.params().value( "getFeatureInfoUrl" ) );
504+
results->append( identifyResult );
489505
}
490-
if ( featureType.compare( sublayer, Qt::CaseInsensitive ) != 0 || labels.isEmpty() )
491-
{
492-
labels << featureType;
493-
494-
495-
}
496-
497-
QMap< QString, QString > derAttributes = derivedAttributes;
498-
derAttributes.unite( featureDerivedAttributes( &feature, layer ) );
499-
500-
IdentifyResult identifyResult( qobject_cast<QgsMapLayer *>( layer ), labels.join( " / " ), featureStore.fields(), feature, derAttributes );
501-
502-
identifyResult.mParams.insert( "getFeatureInfoUrl", featureStore.params().value( "getFeatureInfoUrl" ) );
503-
results->append( identifyResult );
504506
}
505507
}
506508
}
507-
}
508-
else // text or html
509-
{
510-
QgsDebugMsg( QString( "%1 html or text values" ).arg( values.size() ) );
511-
foreach ( int bandNo, values.keys() )
509+
else // text or html
512510
{
513-
QString value = values.value( bandNo ).toString();
514-
attributes.clear();
515-
attributes.insert( "", value );
511+
QgsDebugMsg( QString( "%1 html or text values" ).arg( values.size() ) );
512+
foreach ( int bandNo, values.keys() )
513+
{
514+
QString value = values.value( bandNo ).toString();
515+
attributes.clear();
516+
attributes.insert( "", value );
516517

517-
QString label = layer->subLayers().value( bandNo );
518-
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
518+
QString label = layer->subLayers().value( bandNo );
519+
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
520+
}
519521
}
520522
}
523+
else
524+
{
525+
attributes.clear();
526+
QString value = identifyResult.error().message( QgsErrorMessage::Text );
527+
attributes.insert( tr( "Error" ), value );
528+
QString label = tr( "Identify error" );
529+
results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
530+
}
521531

522532
return true;
523533
}

src/providers/wms/qgswmsprovider.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -4315,7 +4315,14 @@ QgsRasterIdentifyResult QgsWmsProvider::identify( const QgsPoint & thePoint, Qgs
43154315
else
43164316
{
43174317
// guess from GML
4318-
gmlSchema.guessSchema( mIdentifyResultBodies.value( gmlPart ) );
4318+
bool ok = gmlSchema.guessSchema( mIdentifyResultBodies.value( gmlPart ) );
4319+
if ( ! ok )
4320+
{
4321+
QgsError err = gmlSchema.error();
4322+
err.append( tr( "Cannot identify" ) );
4323+
QgsDebugMsg( "guess schema error: " + err.message() );
4324+
return QgsRasterIdentifyResult( err );
4325+
}
43194326
}
43204327

43214328
QStringList featureTypeNames = gmlSchema.typeNames();

0 commit comments

Comments
 (0)