Skip to content
Permalink
Browse files

Revert "[bugfix][wfs] Expand support for 2.0.0 TYPENAMES" (fixes #18882)

This reverts *partially* commit ccb4c80.

The plural form of TYPENAMES is non conformant for the DescribeFeatureType
request of WFS 2.0
The logic of ccb4c80 breaks conformant
servers because they ignore the TYPENAMES parameter and thus return a
DescribeFeatureType response covering all layers of the service, which can
be extremely time consuming.

Changes related to better geometry handling have been kept.
  • Loading branch information
rouault committed May 22, 2018
1 parent 6cf1c50 commit 7511d1ffdb867f3bd19bf0697afa5c49ae6b621d
@@ -14,24 +14,19 @@
***************************************************************************/

#include "qgswfsdescribefeaturetype.h"
#include "qgswfsutils.h"

QgsWFSDescribeFeatureType::QgsWFSDescribeFeatureType( QgsWFSDataSourceURI &uri )
: QgsWfsRequest( uri )
{
}

bool QgsWFSDescribeFeatureType::requestFeatureType( const QString &WFSVersion,
const QString &typeName, bool forceSingularTypeName )
const QString &typeName )
{
QUrl url( mUri.requestUrl( QStringLiteral( "DescribeFeatureType" ) ) );
url.addQueryItem( QStringLiteral( "VERSION" ), WFSVersion );
// The specs are not consistent: is it singular in 1.0.x and plural in 2.0.0?
// see http://docs.opengeospatial.org/is/09-025r2/09-025r2.html#147
if ( ! forceSingularTypeName )
url.addQueryItem( QgsWFSUtils::typeNameParameterForVersion( WFSVersion ).toUpper( ), typeName );
else
url.addQueryItem( QStringLiteral( "TYPENAME" ), typeName );
url.addQueryItem( QStringLiteral( "TYPENAME" ), typeName );

return sendGET( url, true, false );
}

@@ -25,8 +25,7 @@ class QgsWFSDescribeFeatureType : public QgsWfsRequest
explicit QgsWFSDescribeFeatureType( QgsWFSDataSourceURI &uri );

//! Issue the request
bool requestFeatureType( const QString &WFSVersion, const QString &typeName,
bool forceSingularTypeName = false );
bool requestFeatureType( const QString &WFSVersion, const QString &typeName );

protected:
QString errorMessageWithReason( const QString &reason ) override;
@@ -919,7 +919,7 @@ bool QgsWFSProvider::deleteFeatures( const QgsFeatureIds &id )
transactionDoc.appendChild( transactionElem );
//delete element
QDomElement deleteElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "Delete" ) );
deleteElem.setAttribute( QgsWFSUtils::typeNameParameterForVersion( mShared->mWFSVersion ), tname );
deleteElem.setAttribute( QStringLiteral( "typeName" ), tname );
QDomElement filterElem = transactionDoc.createElementNS( QgsWFSConstants::OGC_NAMESPACE, QStringLiteral( "Filter" ) );


@@ -984,7 +984,7 @@ bool QgsWFSProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )
continue;
}
QDomElement updateElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "Update" ) );
updateElem.setAttribute( QgsWFSUtils::typeNameParameterForVersion( mShared->mWFSVersion ), tname );
updateElem.setAttribute( QStringLiteral( "typeName" ), tname );
//Property
QDomElement propertyElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "Property" ) );
QDomElement nameElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "Name" ) );
@@ -1040,7 +1040,6 @@ QString QgsWFSProvider::convertToXML( const QVariant &value )
return valueStr;
}


bool QgsWFSProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_map )
{
//find out typename from uri and strip namespace prefix
@@ -1066,7 +1065,7 @@ bool QgsWFSProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
}

QDomElement updateElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "Update" ) );
updateElem.setAttribute( QgsWFSUtils::typeNameParameterForVersion( mShared->mWFSVersion ), tname );
updateElem.setAttribute( QStringLiteral( "typeName" ), tname );

QgsAttributeMap::const_iterator attMapIt = attIt.value().constBegin();
for ( ; attMapIt != attIt.value().constEnd(); ++attMapIt )
@@ -1159,18 +1158,15 @@ QString QgsWFSProvider::translateMetadataValue( const QString &mdKey, const QVar
{
return value.toString();
}
}
};

bool QgsWFSProvider::describeFeatureType( QString &geometryAttribute,
QgsFields &fields,
QgsWkbTypes::Type &geomType,
bool forceSingularTypeNames )
bool QgsWFSProvider::describeFeatureType( QString &geometryAttribute, QgsFields &fields, QgsWkbTypes::Type &geomType )
{
fields.clear();

QgsWFSDescribeFeatureType describeFeatureType( mShared->mURI );
if ( !describeFeatureType.requestFeatureType( mShared->mWFSVersion,
mShared->mURI.typeName(), forceSingularTypeNames ) )
mShared->mURI.typeName() ) )
{
QgsMessageLog::logMessage( tr( "DescribeFeatureType network request failed for url %1: %2" ).
arg( dataSourceUri(), describeFeatureType.errorMessage() ), tr( "WFS" ) );
@@ -1193,19 +1189,11 @@ bool QgsWFSProvider::describeFeatureType( QString &geometryAttribute,
mShared->mURI.typeName(),
geometryAttribute, fields, geomType, errorMsg ) )
{
// If 2.0.0, let's assume it was a server that only accepted TYPENAME singular form
// and try with that ...
if ( ! forceSingularTypeNames && mShared->mWFSVersion.startsWith( '2' ) )
{
return QgsWFSProvider::describeFeatureType( geometryAttribute,
fields,
geomType,
true );
}
QgsMessageLog::logMessage( tr( "Analysis of DescribeFeatureType response failed for url %1: %2" ).
arg( dataSourceUri(), errorMsg ), tr( "WFS" ) );
return false;
}

return true;
}

@@ -1479,8 +1467,7 @@ QDomElement QgsWFSProvider::createTransactionElement( QDomDocument &doc ) const
describeFeatureTypeURL.addQueryItem( QStringLiteral( "REQUEST" ), QStringLiteral( "DescribeFeatureType" ) );
}
describeFeatureTypeURL.addQueryItem( QStringLiteral( "VERSION" ), QStringLiteral( "1.0.0" ) );
//TODO: proper support of 2.0.0, for now hardcoded
describeFeatureTypeURL.addQueryItem( QgsWFSUtils::typeNameParameterForVersion( WfsVersion ).toUpper(), mShared->mURI.typeName() );
describeFeatureTypeURL.addQueryItem( QStringLiteral( "TYPENAME" ), mShared->mURI.typeName() );

transactionElem.setAttribute( QStringLiteral( "xsi:schemaLocation" ), mApplicationNamespace + ' '
+ describeFeatureTypeURL.toEncoded() );
@@ -151,7 +151,7 @@ class QgsWFSProvider : public QgsVectorDataProvider
The method gives back the name of
the geometry attribute and the thematic attributes with their types*/
bool describeFeatureType( QString &geometryAttribute,
QgsFields &fields, QgsWkbTypes::Type &geomType, bool forceSingularTypeNames = false );
QgsFields &fields, QgsWkbTypes::Type &geomType );

/**
* For a given typename, reads the name of the geometry attribute, the
@@ -138,19 +138,6 @@ bool QgsWFSUtils::removeDir( const QString &dirName )
return dir.rmdir( dirName );
}

QString QgsWFSUtils::typeNameParameterForVersion( const QString &WfsVersion )
{
// WFS 2.0 uses the plural form TYPENAMES
if ( WfsVersion.startsWith( '2' ) )
{
return QString( "typeNames" );
}
else
{
return QString( "typeName" );
}
}


// We use a keep alive mechanism where every KEEP_ALIVE_DELAY ms we update
// a shared memory segment with the current timestamp. This way, other QGIS
@@ -45,9 +45,6 @@ class QgsWFSUtils
//! Return a unique identifier made from feature content
static QString getMD5( const QgsFeature &f );

//! Return the correct form of typeName(s) according to the specified \a WfsVersion
static QString typeNameParameterForVersion( const QString &WfsVersion );

protected:
friend class QgsWFSUtilsKeepAlive;
static QSharedMemory *createAndAttachSHM();
@@ -65,7 +62,6 @@ class QgsWFSUtils

//! Remove (recursively) a directory.
static bool removeDir( const QString &dirName );

};

//! For internal use of QgsWFSUtils

0 comments on commit 7511d1f

Please sign in to comment.
You can’t perform that action at this time.