mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-16 00:05:54 -05:00
Merge pull request #39368 from elpaso/wfs-t-1.1
Fix WFS-T 1.1.0 support
This commit is contained in:
commit
a0711d710d
@ -108,6 +108,7 @@ Returns the "test connection" button.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
virtual QString wfsSettingsKey( const QString &base, const QString &connectionName ) const;
|
virtual QString wfsSettingsKey( const QString &base, const QString &connectionName ) const;
|
||||||
%Docstring
|
%Docstring
|
||||||
Returns the QSettings key for WFS related settings for the connection.
|
Returns the QSettings key for WFS related settings for the connection.
|
||||||
|
|||||||
@ -1173,7 +1173,8 @@ QDomElement QgsOgcUtils::geometryToGML( const QgsGeometry &geometry, QDomDocumen
|
|||||||
return geometryToGML( geometry, doc, ( format == QLatin1String( "GML2" ) ) ? GML_2_1_2 : GML_3_2_1, QString(), false, QString(), precision );
|
return geometryToGML( geometry, doc, ( format == QLatin1String( "GML2" ) ) ? GML_2_1_2 : GML_3_2_1, QString(), false, QString(), precision );
|
||||||
}
|
}
|
||||||
|
|
||||||
QDomElement QgsOgcUtils::geometryToGML( const QgsGeometry &geometry, QDomDocument &doc,
|
QDomElement QgsOgcUtils::geometryToGML( const QgsGeometry &geometry,
|
||||||
|
QDomDocument &doc,
|
||||||
GMLVersion gmlVersion,
|
GMLVersion gmlVersion,
|
||||||
const QString &srsName,
|
const QString &srsName,
|
||||||
bool invertAxisOrientation,
|
bool invertAxisOrientation,
|
||||||
|
|||||||
@ -166,6 +166,7 @@ void QgsNewHttpConnection::wfsVersionCurrentIndexChanged( int index )
|
|||||||
txtPageSize->setEnabled( cbxWfsFeaturePaging->isChecked() && ( index == WFS_VERSION_MAX || index >= WFS_VERSION_1_1 ) );
|
txtPageSize->setEnabled( cbxWfsFeaturePaging->isChecked() && ( index == WFS_VERSION_MAX || index >= WFS_VERSION_1_1 ) );
|
||||||
cbxWfsIgnoreAxisOrientation->setEnabled( index != WFS_VERSION_1_0 && index != WFS_VERSION_API_FEATURES_1_0 );
|
cbxWfsIgnoreAxisOrientation->setEnabled( index != WFS_VERSION_1_0 && index != WFS_VERSION_API_FEATURES_1_0 );
|
||||||
cbxWfsInvertAxisOrientation->setEnabled( index != WFS_VERSION_API_FEATURES_1_0 );
|
cbxWfsInvertAxisOrientation->setEnabled( index != WFS_VERSION_API_FEATURES_1_0 );
|
||||||
|
wfsUseGml2EncodingForTransactions()->setEnabled( index == WFS_VERSION_1_1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsNewHttpConnection::wfsFeaturePagingStateChanged( int state )
|
void QgsNewHttpConnection::wfsFeaturePagingStateChanged( int state )
|
||||||
@ -256,6 +257,11 @@ QCheckBox *QgsNewHttpConnection::wfsPagingEnabledCheckBox()
|
|||||||
return cbxWfsFeaturePaging;
|
return cbxWfsFeaturePaging;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QCheckBox *QgsNewHttpConnection::wfsUseGml2EncodingForTransactions()
|
||||||
|
{
|
||||||
|
return cbxWfsUseGml2EncodingForTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
QLineEdit *QgsNewHttpConnection::wfsPageSizeLineEdit()
|
QLineEdit *QgsNewHttpConnection::wfsPageSizeLineEdit()
|
||||||
{
|
{
|
||||||
return txtPageSize;
|
return txtPageSize;
|
||||||
@ -281,6 +287,8 @@ void QgsNewHttpConnection::updateServiceSpecificSettings()
|
|||||||
cbxWmsIgnoreReportedLayerExtents->setChecked( settings.value( wmsKey + QStringLiteral( "/ignoreReportedLayerExtents" ), false ).toBool() );
|
cbxWmsIgnoreReportedLayerExtents->setChecked( settings.value( wmsKey + QStringLiteral( "/ignoreReportedLayerExtents" ), false ).toBool() );
|
||||||
cbxWfsIgnoreAxisOrientation->setChecked( settings.value( wfsKey + "/ignoreAxisOrientation", false ).toBool() );
|
cbxWfsIgnoreAxisOrientation->setChecked( settings.value( wfsKey + "/ignoreAxisOrientation", false ).toBool() );
|
||||||
cbxWfsInvertAxisOrientation->setChecked( settings.value( wfsKey + "/invertAxisOrientation", false ).toBool() );
|
cbxWfsInvertAxisOrientation->setChecked( settings.value( wfsKey + "/invertAxisOrientation", false ).toBool() );
|
||||||
|
cbxWfsUseGml2EncodingForTransactions->setChecked( settings.value( wfsKey + "/preferCoordinatesForWfsT11", false ).toBool() );
|
||||||
|
|
||||||
cbxWmsIgnoreAxisOrientation->setChecked( settings.value( wmsKey + "/ignoreAxisOrientation", false ).toBool() );
|
cbxWmsIgnoreAxisOrientation->setChecked( settings.value( wmsKey + "/ignoreAxisOrientation", false ).toBool() );
|
||||||
cbxWmsInvertAxisOrientation->setChecked( settings.value( wmsKey + "/invertAxisOrientation", false ).toBool() );
|
cbxWmsInvertAxisOrientation->setChecked( settings.value( wmsKey + "/invertAxisOrientation", false ).toBool() );
|
||||||
cbxIgnoreGetFeatureInfoURI->setChecked( settings.value( wmsKey + "/ignoreGetFeatureInfoURI", false ).toBool() );
|
cbxIgnoreGetFeatureInfoURI->setChecked( settings.value( wmsKey + "/ignoreGetFeatureInfoURI", false ).toBool() );
|
||||||
@ -463,6 +471,7 @@ void QgsNewHttpConnection::accept()
|
|||||||
{
|
{
|
||||||
settings.setValue( wfsKey + "/ignoreAxisOrientation", cbxWfsIgnoreAxisOrientation->isChecked() );
|
settings.setValue( wfsKey + "/ignoreAxisOrientation", cbxWfsIgnoreAxisOrientation->isChecked() );
|
||||||
settings.setValue( wfsKey + "/invertAxisOrientation", cbxWfsInvertAxisOrientation->isChecked() );
|
settings.setValue( wfsKey + "/invertAxisOrientation", cbxWfsInvertAxisOrientation->isChecked() );
|
||||||
|
settings.setValue( wfsKey + "/preferCoordinatesForWfsT11", cbxWfsUseGml2EncodingForTransactions->isChecked() );
|
||||||
}
|
}
|
||||||
if ( mTypes & ConnectionWms || mTypes & ConnectionWcs )
|
if ( mTypes & ConnectionWms || mTypes & ConnectionWcs )
|
||||||
{
|
{
|
||||||
|
|||||||
@ -150,6 +150,12 @@ class GUI_EXPORT QgsNewHttpConnection : public QDialog, private Ui::QgsNewHttpCo
|
|||||||
*/
|
*/
|
||||||
QCheckBox *wfsPagingEnabledCheckBox() SIP_SKIP;
|
QCheckBox *wfsPagingEnabledCheckBox() SIP_SKIP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the "Use GML2 encoding for transactions" checkbox
|
||||||
|
* \since QGIS 3.16
|
||||||
|
*/
|
||||||
|
QCheckBox *wfsUseGml2EncodingForTransactions() SIP_SKIP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the "WFS page size" edit
|
* Returns the "WFS page size" edit
|
||||||
* \since QGIS 3.2
|
* \since QGIS 3.2
|
||||||
|
|||||||
@ -53,6 +53,13 @@ QgsWfsConnection::QgsWfsConnection( const QString &connName )
|
|||||||
settings.value( key + "/" + QgsWFSConstants::SETTINGS_PAGING_ENABLED, true ).toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" ) );
|
settings.value( key + "/" + QgsWFSConstants::SETTINGS_PAGING_ENABLED, true ).toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( settings.contains( key + "/" + QgsWFSConstants::SETTINGS_WFST_1_1_PREFER_COORDINATES ) )
|
||||||
|
{
|
||||||
|
mUri.removeParam( QgsWFSConstants::URI_PARAM_WFST_1_1_PREFER_COORDINATES ); // setParam allow for duplicates!
|
||||||
|
mUri.setParam( QgsWFSConstants::URI_PARAM_WFST_1_1_PREFER_COORDINATES,
|
||||||
|
settings.value( key + "/" + QgsWFSConstants::SETTINGS_WFST_1_1_PREFER_COORDINATES, true ).toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" ) );
|
||||||
|
}
|
||||||
|
|
||||||
QgsDebugMsgLevel( QStringLiteral( "WFS full uri: '%1'." ).arg( QString( mUri.uri() ) ), 4 );
|
QgsDebugMsgLevel( QStringLiteral( "WFS full uri: '%1'." ).arg( QString( mUri.uri() ) ), 4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@ const QString QgsWFSConstants::URI_PARAM_VALIDATESQLFUNCTIONS( QStringLiteral( "
|
|||||||
const QString QgsWFSConstants::URI_PARAM_HIDEDOWNLOADPROGRESSDIALOG( QStringLiteral( "hideDownloadProgressDialog" ) );
|
const QString QgsWFSConstants::URI_PARAM_HIDEDOWNLOADPROGRESSDIALOG( QStringLiteral( "hideDownloadProgressDialog" ) );
|
||||||
const QString QgsWFSConstants::URI_PARAM_PAGING_ENABLED( "pagingEnabled" );
|
const QString QgsWFSConstants::URI_PARAM_PAGING_ENABLED( "pagingEnabled" );
|
||||||
const QString QgsWFSConstants::URI_PARAM_PAGE_SIZE( "pageSize" );
|
const QString QgsWFSConstants::URI_PARAM_PAGE_SIZE( "pageSize" );
|
||||||
|
const QString QgsWFSConstants::URI_PARAM_WFST_1_1_PREFER_COORDINATES( "preferCoordinatesForWfsT11" );
|
||||||
|
|
||||||
const QString QgsWFSConstants::VERSION_AUTO( QStringLiteral( "auto" ) );
|
const QString QgsWFSConstants::VERSION_AUTO( QStringLiteral( "auto" ) );
|
||||||
|
|
||||||
@ -48,3 +49,4 @@ const QString QgsWFSConstants::SETTINGS_VERSION( QStringLiteral( "version" ) );
|
|||||||
const QString QgsWFSConstants::SETTINGS_MAXNUMFEATURES( QStringLiteral( "maxnumfeatures" ) );
|
const QString QgsWFSConstants::SETTINGS_MAXNUMFEATURES( QStringLiteral( "maxnumfeatures" ) );
|
||||||
const QString QgsWFSConstants::SETTINGS_PAGING_ENABLED( QStringLiteral( "pagingenabled" ) );
|
const QString QgsWFSConstants::SETTINGS_PAGING_ENABLED( QStringLiteral( "pagingenabled" ) );
|
||||||
const QString QgsWFSConstants::SETTINGS_PAGE_SIZE( QStringLiteral( "pagesize" ) );
|
const QString QgsWFSConstants::SETTINGS_PAGE_SIZE( QStringLiteral( "pagesize" ) );
|
||||||
|
const QString QgsWFSConstants::SETTINGS_WFST_1_1_PREFER_COORDINATES( QStringLiteral( "preferCoordinatesForWfsT11" ) );
|
||||||
|
|||||||
@ -48,6 +48,7 @@ struct QgsWFSConstants
|
|||||||
static const QString URI_PARAM_HIDEDOWNLOADPROGRESSDIALOG;
|
static const QString URI_PARAM_HIDEDOWNLOADPROGRESSDIALOG;
|
||||||
static const QString URI_PARAM_PAGING_ENABLED;
|
static const QString URI_PARAM_PAGING_ENABLED;
|
||||||
static const QString URI_PARAM_PAGE_SIZE;
|
static const QString URI_PARAM_PAGE_SIZE;
|
||||||
|
static const QString URI_PARAM_WFST_1_1_PREFER_COORDINATES;
|
||||||
|
|
||||||
//
|
//
|
||||||
static const QString VERSION_AUTO;
|
static const QString VERSION_AUTO;
|
||||||
@ -58,6 +59,7 @@ struct QgsWFSConstants
|
|||||||
static const QString SETTINGS_MAXNUMFEATURES;
|
static const QString SETTINGS_MAXNUMFEATURES;
|
||||||
static const QString SETTINGS_PAGING_ENABLED;
|
static const QString SETTINGS_PAGING_ENABLED;
|
||||||
static const QString SETTINGS_PAGE_SIZE;
|
static const QString SETTINGS_PAGE_SIZE;
|
||||||
|
static const QString SETTINGS_WFST_1_1_PREFER_COORDINATES;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QGSWFSCONSTANTS_H
|
#endif // QGSWFSCONSTANTS_H
|
||||||
|
|||||||
@ -373,6 +373,13 @@ bool QgsWFSDataSourceURI::hideDownloadProgressDialog() const
|
|||||||
return mURI.hasParam( QgsWFSConstants::URI_PARAM_HIDEDOWNLOADPROGRESSDIALOG );
|
return mURI.hasParam( QgsWFSConstants::URI_PARAM_HIDEDOWNLOADPROGRESSDIALOG );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QgsWFSDataSourceURI::preferCoordinatesForWfst11() const
|
||||||
|
{
|
||||||
|
return mURI.hasParam( QgsWFSConstants::URI_PARAM_WFST_1_1_PREFER_COORDINATES ) &&
|
||||||
|
mURI.param( QgsWFSConstants::URI_PARAM_WFST_1_1_PREFER_COORDINATES ).toUpper() == QLatin1String( "TRUE" );
|
||||||
|
}
|
||||||
|
|
||||||
QString QgsWFSDataSourceURI::build( const QString &baseUri,
|
QString QgsWFSDataSourceURI::build( const QString &baseUri,
|
||||||
const QString &typeName,
|
const QString &typeName,
|
||||||
const QString &crsString,
|
const QString &crsString,
|
||||||
|
|||||||
@ -113,6 +113,9 @@ class QgsWFSDataSourceURI
|
|||||||
//! Whether to hide download progress dialog in QGIS main app. Defaults to false
|
//! Whether to hide download progress dialog in QGIS main app. Defaults to false
|
||||||
bool hideDownloadProgressDialog() const;
|
bool hideDownloadProgressDialog() const;
|
||||||
|
|
||||||
|
//! Whether to use "coordinates" instead of "pos" and "posList" for WFS-T 1.1 transactions (ESRI mapserver)
|
||||||
|
bool preferCoordinatesForWfst11() const;
|
||||||
|
|
||||||
//! Returns authorization parameters
|
//! Returns authorization parameters
|
||||||
const QgsAuthorizationSettings &auth() const { return mAuth; }
|
const QgsAuthorizationSettings &auth() const { return mAuth; }
|
||||||
|
|
||||||
|
|||||||
@ -787,6 +787,49 @@ void QgsWFSProvider::reloadProviderData()
|
|||||||
mShared->invalidateCache();
|
mShared->invalidateCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDomElement QgsWFSProvider::geometryElement( const QgsGeometry &geometry, QDomDocument &transactionDoc )
|
||||||
|
{
|
||||||
|
QDomElement gmlElem;
|
||||||
|
|
||||||
|
// Determine axis orientation and gml version
|
||||||
|
bool applyAxisInversion;
|
||||||
|
QgsOgcUtils::GMLVersion gmlVersion;
|
||||||
|
|
||||||
|
if ( mShared->mWFSVersion.startsWith( QLatin1String( "1.1" ) ) )
|
||||||
|
{
|
||||||
|
// WFS 1.1.0 uses preferably GML 3, but ESRI mapserver in 2020 doesn't like it so we stick to GML2
|
||||||
|
if ( ! mShared->mServerPrefersCoordinatesForTransactions_1_1 )
|
||||||
|
{
|
||||||
|
gmlVersion = QgsOgcUtils::GML_3_1_0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gmlVersion = QgsOgcUtils::GML_2_1_2;
|
||||||
|
}
|
||||||
|
// For servers like Geomedia and QGIS Server that advertise EPSG:XXXX in capabilities even in WFS 1.1 or 2.0
|
||||||
|
// cpabilities useEPSGColumnFormat is set.
|
||||||
|
// We follow GeoServer convention here which is to treat EPSG:4326 as lon/lat
|
||||||
|
applyAxisInversion = ( crs().hasAxisInverted() && ! mShared->mURI.ignoreAxisOrientation() && ! mShared->mCaps.useEPSGColumnFormat )
|
||||||
|
|| mShared->mURI.invertAxisOrientation();
|
||||||
|
}
|
||||||
|
else // 1.0
|
||||||
|
{
|
||||||
|
gmlVersion = QgsOgcUtils::GML_2_1_2;
|
||||||
|
applyAxisInversion = mShared->mURI.invertAxisOrientation();
|
||||||
|
}
|
||||||
|
|
||||||
|
gmlElem = QgsOgcUtils::geometryToGML(
|
||||||
|
geometry,
|
||||||
|
transactionDoc,
|
||||||
|
gmlVersion,
|
||||||
|
mShared->srsName(),
|
||||||
|
applyAxisInversion,
|
||||||
|
QString()
|
||||||
|
);
|
||||||
|
|
||||||
|
return gmlElem;
|
||||||
|
}
|
||||||
|
|
||||||
QgsWkbTypes::Type QgsWFSProvider::wkbType() const
|
QgsWkbTypes::Type QgsWFSProvider::wkbType() const
|
||||||
{
|
{
|
||||||
return mShared->mWKBType;
|
return mShared->mWKBType;
|
||||||
@ -877,10 +920,10 @@ bool QgsWFSProvider::addFeatures( QgsFeatureList &flist, Flags flags )
|
|||||||
{
|
{
|
||||||
the_geom.convertToMultiType();
|
the_geom.convertToMultiType();
|
||||||
}
|
}
|
||||||
QDomElement gmlElem = QgsOgcUtils::geometryToGML( the_geom, transactionDoc );
|
|
||||||
if ( !gmlElem.isNull() )
|
const QDomElement gmlElem { geometryElement( the_geom, transactionDoc ) };
|
||||||
|
if ( ! gmlElem.isNull() )
|
||||||
{
|
{
|
||||||
gmlElem.setAttribute( QStringLiteral( "srsName" ), crs().authid() );
|
|
||||||
geomElem.appendChild( gmlElem );
|
geomElem.appendChild( gmlElem );
|
||||||
featureElem.appendChild( geomElem );
|
featureElem.appendChild( geomElem );
|
||||||
}
|
}
|
||||||
@ -1045,9 +1088,9 @@ bool QgsWFSProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )
|
|||||||
nameElem.appendChild( nameText );
|
nameElem.appendChild( nameText );
|
||||||
propertyElem.appendChild( nameElem );
|
propertyElem.appendChild( nameElem );
|
||||||
QDomElement valueElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "Value" ) );
|
QDomElement valueElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "Value" ) );
|
||||||
QDomElement gmlElem = QgsOgcUtils::geometryToGML( geomIt.value(), transactionDoc );
|
|
||||||
gmlElem.setAttribute( QStringLiteral( "srsName" ), crs().authid() );
|
valueElem.appendChild( geometryElement( geomIt.value(), transactionDoc ) );
|
||||||
valueElem.appendChild( gmlElem );
|
|
||||||
propertyElem.appendChild( valueElem );
|
propertyElem.appendChild( valueElem );
|
||||||
updateElem.appendChild( propertyElem );
|
updateElem.appendChild( propertyElem );
|
||||||
|
|
||||||
@ -1264,6 +1307,8 @@ bool QgsWFSProvider::describeFeatureType( QString &geometryAttribute, QgsFields
|
|||||||
|
|
||||||
QByteArray response = describeFeatureType.response();
|
QByteArray response = describeFeatureType.response();
|
||||||
|
|
||||||
|
QgsDebugMsgLevel( response, 4 );
|
||||||
|
|
||||||
QDomDocument describeFeatureDocument;
|
QDomDocument describeFeatureDocument;
|
||||||
QString errorMsg;
|
QString errorMsg;
|
||||||
if ( !describeFeatureDocument.setContent( response, true, &errorMsg ) )
|
if ( !describeFeatureDocument.setContent( response, true, &errorMsg ) )
|
||||||
@ -1580,6 +1625,8 @@ bool QgsWFSProvider::sendTransactionDocument( const QDomDocument &doc, QDomDocum
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QgsDebugMsgLevel( doc.toString(), 4 );
|
||||||
|
|
||||||
QgsWFSTransactionRequest request( mShared->mURI );
|
QgsWFSTransactionRequest request( mShared->mURI );
|
||||||
return request.send( doc, serverResponse );
|
return request.send( doc, serverResponse );
|
||||||
}
|
}
|
||||||
@ -1587,10 +1634,16 @@ bool QgsWFSProvider::sendTransactionDocument( const QDomDocument &doc, QDomDocum
|
|||||||
QDomElement QgsWFSProvider::createTransactionElement( QDomDocument &doc ) const
|
QDomElement QgsWFSProvider::createTransactionElement( QDomDocument &doc ) const
|
||||||
{
|
{
|
||||||
QDomElement transactionElem = doc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "Transaction" ) );
|
QDomElement transactionElem = doc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "Transaction" ) );
|
||||||
// QString WfsVersion = mShared->mWFSVersion;
|
const QString WfsVersion = mShared->mWFSVersion;
|
||||||
// For now: hardcoded to 1.0.0
|
// only 1.1.0 and 1.0.0 are supported
|
||||||
QString WfsVersion = QStringLiteral( "1.0.0" );
|
if ( WfsVersion == QStringLiteral( "1.1.0" ) )
|
||||||
transactionElem.setAttribute( QStringLiteral( "version" ), WfsVersion );
|
{
|
||||||
|
transactionElem.setAttribute( QStringLiteral( "version" ), WfsVersion );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transactionElem.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0.0" ) );
|
||||||
|
}
|
||||||
transactionElem.setAttribute( QStringLiteral( "service" ), QStringLiteral( "WFS" ) );
|
transactionElem.setAttribute( QStringLiteral( "service" ), QStringLiteral( "WFS" ) );
|
||||||
transactionElem.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
|
transactionElem.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
|
||||||
|
|
||||||
@ -1634,19 +1687,70 @@ bool QgsWFSProvider::transactionSuccess( const QDomDocument &serverResponse ) co
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDomNodeList transactionResultList = documentElem.elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "TransactionResult" ) );
|
const QString WfsVersion = mShared->mWFSVersion;
|
||||||
if ( transactionResultList.size() < 1 )
|
|
||||||
|
if ( WfsVersion == QStringLiteral( "1.1.0" ) )
|
||||||
{
|
{
|
||||||
|
const QDomNodeList transactionSummaryList = documentElem.elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "TransactionSummary" ) );
|
||||||
|
if ( transactionSummaryList.size() < 1 )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDomElement transactionElement { transactionSummaryList.at( 0 ).toElement() };
|
||||||
|
QDomNodeList totalInserted = transactionElement.elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "totalInserted" ) );
|
||||||
|
QDomNodeList totalUpdated = transactionElement.elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "totalUpdated" ) );
|
||||||
|
QDomNodeList totalDeleted = transactionElement.elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "totalDeleted" ) );
|
||||||
|
if ( totalInserted.size() > 0 && totalInserted.at( 0 ).toElement().text().toInt() > 0 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( totalUpdated.size() > 0 && totalUpdated.at( 0 ).toElement().text().toInt() > 0 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( totalDeleted.size() > 0 && totalDeleted.at( 0 ).toElement().text().toInt() > 0 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle wrong QGIS server response (capital initial letter)
|
||||||
|
totalInserted = transactionElement.elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "TotalInserted" ) );
|
||||||
|
totalUpdated = transactionElement.elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "TotalUpdated" ) );
|
||||||
|
totalDeleted = transactionElement.elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "TotalDeleted" ) );
|
||||||
|
if ( totalInserted.size() > 0 && totalInserted.at( 0 ).toElement().text().toInt() > 0 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( totalUpdated.size() > 0 && totalUpdated.at( 0 ).toElement().text().toInt() > 0 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( totalDeleted.size() > 0 && totalDeleted.at( 0 ).toElement().text().toInt() > 0 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const QDomNodeList transactionResultList = documentElem.elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "TransactionResult" ) );
|
||||||
|
if ( transactionResultList.size() < 1 )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDomNodeList statusList = transactionResultList.at( 0 ).toElement().elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "Status" ) );
|
||||||
|
if ( statusList.size() < 1 )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return statusList.at( 0 ).firstChildElement().localName() == QLatin1String( "SUCCESS" );
|
||||||
}
|
}
|
||||||
|
|
||||||
QDomNodeList statusList = transactionResultList.at( 0 ).toElement().elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "Status" ) );
|
|
||||||
if ( statusList.size() < 1 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return statusList.at( 0 ).firstChildElement().localName() == QLatin1String( "SUCCESS" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList QgsWFSProvider::insertedFeatureIds( const QDomDocument &serverResponse ) const
|
QStringList QgsWFSProvider::insertedFeatureIds( const QDomDocument &serverResponse ) const
|
||||||
@ -1663,7 +1767,17 @@ QStringList QgsWFSProvider::insertedFeatureIds( const QDomDocument &serverRespon
|
|||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDomNodeList insertResultList = rootElem.elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, QStringLiteral( "InsertResult" ) );
|
// Handles WFS 1.1.0
|
||||||
|
QString insertResultTagName;
|
||||||
|
if ( mShared->mWFSVersion == QStringLiteral( "1.1.0" ) )
|
||||||
|
{
|
||||||
|
insertResultTagName = QStringLiteral( "InsertResults" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
insertResultTagName = QStringLiteral( "InsertResult" );
|
||||||
|
}
|
||||||
|
QDomNodeList insertResultList = rootElem.elementsByTagNameNS( QgsWFSConstants::WFS_NAMESPACE, insertResultTagName );
|
||||||
for ( int i = 0; i < insertResultList.size(); ++i )
|
for ( int i = 0; i < insertResultList.size(); ++i )
|
||||||
{
|
{
|
||||||
QDomNodeList featureIdList = insertResultList.at( i ).toElement().elementsByTagNameNS( QgsWFSConstants::OGC_NAMESPACE, QStringLiteral( "FeatureId" ) );
|
QDomNodeList featureIdList = insertResultList.at( i ).toElement().elementsByTagNameNS( QgsWFSConstants::OGC_NAMESPACE, QStringLiteral( "FeatureId" ) );
|
||||||
@ -1850,6 +1964,14 @@ void QgsWFSProvider::handleException( const QDomDocument &serverResponse )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WFS 1.1.0
|
||||||
|
if ( exceptionElem.tagName() == QLatin1String( "TransactionResponse" ) )
|
||||||
|
{
|
||||||
|
pushError( tr( "Unsuccessful service response: no features were added, deleted or changed." ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( exceptionElem.tagName() == QLatin1String( "ExceptionReport" ) )
|
if ( exceptionElem.tagName() == QLatin1String( "ExceptionReport" ) )
|
||||||
{
|
{
|
||||||
QDomElement exception = exceptionElem.firstChildElement( QStringLiteral( "Exception" ) );
|
QDomElement exception = exceptionElem.firstChildElement( QStringLiteral( "Exception" ) );
|
||||||
|
|||||||
@ -140,6 +140,11 @@ class QgsWFSProvider final: public QgsVectorDataProvider
|
|||||||
|
|
||||||
friend class QgsWFSFeatureSource;
|
friend class QgsWFSFeatureSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the geometry element
|
||||||
|
*/
|
||||||
|
QDomElement geometryElement( const QgsGeometry &geometry, QDomDocument &transactionDoc );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//! String used to define a subset of the layer
|
//! String used to define a subset of the layer
|
||||||
|
|||||||
@ -27,6 +27,7 @@ QgsWFSSharedData::QgsWFSSharedData( const QString &uri )
|
|||||||
, mURI( uri )
|
, mURI( uri )
|
||||||
{
|
{
|
||||||
mHideProgressDialog = mURI.hideDownloadProgressDialog();
|
mHideProgressDialog = mURI.hideDownloadProgressDialog();
|
||||||
|
mServerPrefersCoordinatesForTransactions_1_1 = mURI.preferCoordinatesForWfst11();
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsWFSSharedData::~QgsWFSSharedData()
|
QgsWFSSharedData::~QgsWFSSharedData()
|
||||||
|
|||||||
@ -89,6 +89,11 @@ class QgsWFSSharedData : public QObject, public QgsBackgroundCachedSharedData
|
|||||||
*/
|
*/
|
||||||
bool mGetFeatureEPSGDotHonoursEPSGOrder = false;
|
bool mGetFeatureEPSGDotHonoursEPSGOrder = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the server (typically ESRI with WFS-T 1.1 in 2020) does not like "pos" and "posList", and requires "coordinates" for WFS 1.1 transactions
|
||||||
|
*/
|
||||||
|
bool mServerPrefersCoordinatesForTransactions_1_1 = false;
|
||||||
|
|
||||||
//! Geometry type of the features in this layer
|
//! Geometry type of the features in this layer
|
||||||
QgsWkbTypes::Type mWKBType = QgsWkbTypes::Unknown;
|
QgsWkbTypes::Type mWKBType = QgsWkbTypes::Unknown;
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>448</width>
|
<width>448</width>
|
||||||
<height>761</height>
|
<height>815</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -173,9 +173,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QComboBox" name="cmbVersion"/>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
<item row="0" column="2">
|
||||||
<widget class="QPushButton" name="mWfsVersionDetectButton">
|
<widget class="QPushButton" name="mWfsVersionDetectButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -183,42 +180,45 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="5" column="0" colspan="3">
|
||||||
<widget class="QLabel" name="lblMaxNumFeatures">
|
|
||||||
<property name="text">
|
|
||||||
<string>Max. number of features</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1" colspan="2">
|
|
||||||
<widget class="QLineEdit" name="txtMaxNumFeatures">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>Enter a number to limit the maximum number of features retrieved per feature request. If let to empty, no limit is set.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="lblPageSize">
|
|
||||||
<property name="text">
|
|
||||||
<string>Page size</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1" colspan="2">
|
|
||||||
<widget class="QLineEdit" name="txtPageSize">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>Enter a number to limit the maximum number of features retrieved in a single GetFeature request when paging is enabled. If let to empty, server default will apply.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0" colspan="3">
|
|
||||||
<widget class="QCheckBox" name="cbxWfsIgnoreAxisOrientation">
|
<widget class="QCheckBox" name="cbxWfsIgnoreAxisOrientation">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Ignore axis orientation (WFS 1.1/WFS 2.0)</string>
|
<string>Ignore axis orientation (WFS 1.1/WFS 2.0)</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="3">
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="lblMaxNumFeatures">
|
||||||
|
<property name="text">
|
||||||
|
<string>Max. number of features</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="cmbVersion"/>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="txtPageSize">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Enter a number to limit the maximum number of features retrieved in a single GetFeature request when paging is enabled. If let to empty, server default will apply.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0" colspan="3">
|
||||||
|
<widget class="QCheckBox" name="cbxWfsInvertAxisOrientation">
|
||||||
|
<property name="text">
|
||||||
|
<string>Invert axis orientation</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="lblPageSize">
|
||||||
|
<property name="text">
|
||||||
|
<string>Page size</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" colspan="3">
|
||||||
<widget class="QCheckBox" name="cbxWfsFeaturePaging">
|
<widget class="QCheckBox" name="cbxWfsFeaturePaging">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Enable feature paging</string>
|
<string>Enable feature paging</string>
|
||||||
@ -228,10 +228,20 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0" colspan="3">
|
<item row="2" column="1" colspan="2">
|
||||||
<widget class="QCheckBox" name="cbxWfsInvertAxisOrientation">
|
<widget class="QLineEdit" name="txtMaxNumFeatures">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Enter a number to limit the maximum number of features retrieved per feature request. If let to empty, no limit is set.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="cbxWfsUseGml2EncodingForTransactions">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>This might be necessary on some <span style=" font-weight:600;">broken</span> ESRI map servers when using WFS-T 1.1.0.</p></body></html></string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Invert axis orientation</string>
|
<string>Use GML2 encoding for transactions</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@ -43,6 +43,9 @@ from qgis.testing import (start_app,
|
|||||||
unittest
|
unittest
|
||||||
)
|
)
|
||||||
from providertestbase import ProviderTestCase
|
from providertestbase import ProviderTestCase
|
||||||
|
from utilities import unitTestDataPath
|
||||||
|
|
||||||
|
TEST_DATA_DIR = unitTestDataPath()
|
||||||
|
|
||||||
|
|
||||||
def sanitize(endpoint, x):
|
def sanitize(endpoint, x):
|
||||||
@ -4705,6 +4708,67 @@ Can't recognize service requested.
|
|||||||
self.assertEqual(len(logger.messages()), 1, logger.messages())
|
self.assertEqual(len(logger.messages()), 1, logger.messages())
|
||||||
self.assertTrue("InvalidFormat: Can't recognize service requested." in logger.messages()[0].decode('UTF-8'), logger.messages())
|
self.assertTrue("InvalidFormat: Can't recognize service requested." in logger.messages()[0].decode('UTF-8'), logger.messages())
|
||||||
|
|
||||||
|
def testWFST11(self):
|
||||||
|
"""Test WFS-T 1.1 (read-write) taken from a geoserver session"""
|
||||||
|
|
||||||
|
endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_WFS_T_1_1_transaction'
|
||||||
|
|
||||||
|
shutil.copy(os.path.join(TEST_DATA_DIR, 'provider', 'wfst-1-1', 'getcapabilities.xml'), sanitize(endpoint, '?SERVICE=WFS?REQUEST=GetCapabilities?VERSION=1.1.0'))
|
||||||
|
shutil.copy(os.path.join(TEST_DATA_DIR, 'provider', 'wfst-1-1', 'describefeaturetype_polygons.xml'), sanitize(endpoint, '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.1.0&TYPENAME=ws1:polygons'))
|
||||||
|
|
||||||
|
vl = QgsVectorLayer("url='http://" + endpoint + "' typename='ws1:polygons' version='1.1.0'", 'test', 'WFS')
|
||||||
|
self.assertTrue(vl.isValid())
|
||||||
|
self.assertEqual(vl.featureCount(), 0)
|
||||||
|
|
||||||
|
self.assertEqual(vl.dataProvider().capabilities(),
|
||||||
|
QgsVectorDataProvider.AddFeatures
|
||||||
|
| QgsVectorDataProvider.ChangeAttributeValues
|
||||||
|
| QgsVectorDataProvider.ChangeGeometries
|
||||||
|
| QgsVectorDataProvider.DeleteFeatures
|
||||||
|
| QgsVectorDataProvider.SelectAtId)
|
||||||
|
|
||||||
|
# Transaction response failure (no modifications)
|
||||||
|
shutil.copy(os.path.join(TEST_DATA_DIR, 'provider', 'wfst-1-1', 'transaction_response_empty.xml'), sanitize(endpoint, '?SERVICE=WFS&POSTDATA=<Transaction xmlns="http:__www.opengis.net_wfs" xmlns:xsi="http:__www.w3.org_2001_XMLSchema-instance" xmlns:gml="http:__www.opengis.net_gml" xmlns:ws1="ws1" xsi:schemaLocation="ws1 http:__fake_qgis_http_endpoint?REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=ws1:polygons" version="1.1.0" service="WFS"><Insert xmlns="http:__www.opengis.net_wfs"><polygons xmlns="ws1"_><_Insert><_Transaction>'))
|
||||||
|
|
||||||
|
(ret, _) = vl.dataProvider().addFeatures([QgsFeature()])
|
||||||
|
self.assertFalse(ret)
|
||||||
|
self.assertEqual(vl.featureCount(), 0)
|
||||||
|
|
||||||
|
# Test add features for real
|
||||||
|
# Transaction response with 1 feature added
|
||||||
|
shutil.copy(os.path.join(TEST_DATA_DIR, 'provider', 'wfst-1-1', 'transaction_response_feature_added.xml'), sanitize(endpoint, '?SERVICE=WFS&POSTDATA=<Transaction xmlns="http:__www.opengis.net_wfs" xmlns:xsi="http:__www.w3.org_2001_XMLSchema-instance" xmlns:gml="http:__www.opengis.net_gml" xmlns:ws1="ws1" xsi:schemaLocation="ws1 http:__fake_qgis_http_endpoint?REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=ws1:polygons" version="1.1.0" service="WFS"><Insert xmlns="http:__www.opengis.net_wfs"><polygons xmlns="ws1"><name xmlns="ws1">one<_name><value xmlns="ws1">1<_value><geometry xmlns="ws1"><gml:Polygon srsName="urn:ogc:def:crs:EPSG::4326"><gml:exterior><gml:LinearRing><gml:posList srsDimension="2">45 9 45 10 46 10 46 9 45 9<_gml:posList><_gml:LinearRing><_gml:exterior><_gml:Polygon><_geometry><_polygons><_Insert><_Transaction>'))
|
||||||
|
|
||||||
|
feat = QgsFeature(vl.fields())
|
||||||
|
feat.setAttribute('name', 'one')
|
||||||
|
feat.setAttribute('value', 1)
|
||||||
|
feat.setGeometry(QgsGeometry.fromWkt('Polygon ((9 45, 10 45, 10 46, 9 46, 9 45))'))
|
||||||
|
(ret, features) = vl.dataProvider().addFeatures([feat])
|
||||||
|
self.assertEqual(features[0].attributes(), ['one', 1])
|
||||||
|
self.assertEqual(vl.featureCount(), 1)
|
||||||
|
|
||||||
|
# Test change attributes
|
||||||
|
# Transaction response with 1 feature changed
|
||||||
|
shutil.copy(os.path.join(TEST_DATA_DIR, 'provider', 'wfst-1-1', 'transaction_response_feature_changed.xml'), sanitize(endpoint, '?SERVICE=WFS&POSTDATA=<Transaction xmlns="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xmlns:ws1="ws1" xsi:schemaLocation="ws1 http://fake_qgis_http_endpoint?REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=ws1:polygons" version="1.1.0" service="WFS"><Update xmlns="http://www.opengis.net/wfs" typeName="ws1:polygons"><Property xmlns="http://www.opengis.net/wfs"><Name xmlns="http://www.opengis.net/wfs">ws1:name</Name><Value xmlns="http://www.opengis.net/wfs">one-one-one</Value></Property><Property xmlns="http://www.opengis.net/wfs"><Name xmlns="http://www.opengis.net/wfs">ws1:value</Name><Value xmlns="http://www.opengis.net/wfs">111</Value></Property><Filter xmlns="http://www.opengis.net/ogc"><FeatureId xmlns="http://www.opengis.net/ogc" fid="123"/></Filter></Update></Transaction>'))
|
||||||
|
|
||||||
|
self.assertTrue(vl.dataProvider().changeAttributeValues({1: {0: 'one-one-one', 1: 111}}))
|
||||||
|
self.assertEqual(next(vl.dataProvider().getFeatures()).attributes(), ['one-one-one', 111])
|
||||||
|
|
||||||
|
# Test change geometry
|
||||||
|
# Transaction response with 1 feature changed
|
||||||
|
shutil.copy(os.path.join(TEST_DATA_DIR, 'provider', 'wfst-1-1', 'transaction_response_feature_changed.xml'), sanitize(endpoint, '?SERVICE=WFS&POSTDATA=<Transaction xmlns="http:__www.opengis.net_wfs" xmlns:xsi="http:__www.w3.org_2001_XMLSchema-instance" xmlns:gml="http:__www.opengis.net_gml" xmlns:ws1="ws1" xsi:schemaLocation="ws1 http:__fake_qgis_http_endpoint?REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=ws1:polygons" version="1.1.0" service="WFS"><Update xmlns="http:__www.opengis.net_wfs" typeName="ws1:polygons"><Property xmlns="http:__www.opengis.net_wfs"><Name xmlns="http:__www.opengis.net_wfs">ws1:geometry<_Name><Value xmlns="http:__www.opengis.net_wfs"><gml:Polygon srsName="urn:ogc:def:crs:EPSG::4326"><gml:exterior><gml:LinearRing><gml:posList srsDimension="2">46 10 46 11 47 11 47 10 46 10<_gml:posList><_gml:LinearRing><_gml:exterior><_gml:Polygon><_Value><_Property><Filter xmlns="http:__www.opengis.net_ogc"><FeatureId xmlns="http:__www.opengis.net_ogc" fid="123"_><_Filter><_Update><_Transaction>'))
|
||||||
|
|
||||||
|
new_geom = QgsGeometry.fromWkt('Polygon ((10 46, 11 46, 11 47, 10 47, 10 46))')
|
||||||
|
|
||||||
|
self.assertTrue(vl.dataProvider().changeGeometryValues({1: new_geom}))
|
||||||
|
self.assertEqual(next(vl.dataProvider().getFeatures()).geometry().asWkt(), new_geom.asWkt())
|
||||||
|
|
||||||
|
# Test delete feature
|
||||||
|
# Transaction response with 1 feature deleted
|
||||||
|
shutil.copy(os.path.join(TEST_DATA_DIR, 'provider', 'wfst-1-1', 'transaction_response_feature_deleted.xml'), sanitize(endpoint, '?SERVICE=WFS&POSTDATA=<Transaction xmlns="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xmlns:ws1="ws1" xsi:schemaLocation="ws1 http://fake_qgis_http_endpoint?REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=ws1:polygons" version="1.1.0" service="WFS"><Delete xmlns="http://www.opengis.net/wfs" typeName="ws1:polygons"><Filter xmlns="http://www.opengis.net/ogc"><FeatureId xmlns="http://www.opengis.net/ogc" fid="123"/></Filter></Delete></Transaction>'))
|
||||||
|
|
||||||
|
self.assertTrue(vl.dataProvider().deleteFeatures([1]))
|
||||||
|
self.assertEqual(vl.featureCount(), 0)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
@ -60,9 +60,12 @@ qgis_app = start_app()
|
|||||||
|
|
||||||
class TestWFST(unittest.TestCase):
|
class TestWFST(unittest.TestCase):
|
||||||
|
|
||||||
|
VERSION = '1.0.0'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
"""Run before all tests"""
|
"""Run before all tests"""
|
||||||
|
|
||||||
cls.port = QGIS_SERVER_PORT
|
cls.port = QGIS_SERVER_PORT
|
||||||
# Create tmp folder
|
# Create tmp folder
|
||||||
cls.temp_path = tempfile.mkdtemp()
|
cls.temp_path = tempfile.mkdtemp()
|
||||||
@ -92,11 +95,13 @@ class TestWFST(unittest.TestCase):
|
|||||||
cls.port = int(re.findall(br':(\d+)', line)[0])
|
cls.port = int(re.findall(br':(\d+)', line)[0])
|
||||||
assert cls.port != 0
|
assert cls.port != 0
|
||||||
# Wait for the server process to start
|
# Wait for the server process to start
|
||||||
assert waitServer('http://127.0.0.1:%s' % cls.port), "Server is not responding!"
|
assert waitServer('http://127.0.0.1:%s' %
|
||||||
|
cls.port), "Server is not responding!"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
"""Run after all tests"""
|
"""Run after all tests"""
|
||||||
|
|
||||||
cls.server.terminate()
|
cls.server.terminate()
|
||||||
cls.server.wait()
|
cls.server.wait()
|
||||||
del cls.server
|
del cls.server
|
||||||
@ -107,10 +112,12 @@ class TestWFST(unittest.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Run before each test."""
|
"""Run before each test."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
"""Run after each test."""
|
"""Run after each test."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -118,6 +125,7 @@ class TestWFST(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
Delete all features from a vector layer
|
Delete all features from a vector layer
|
||||||
"""
|
"""
|
||||||
|
|
||||||
layer = cls._getLayer(layer_name)
|
layer = cls._getLayer(layer_name)
|
||||||
layer.startEditing()
|
layer.startEditing()
|
||||||
layer.deleteFeatures([f.id() for f in layer.getFeatures()])
|
layer.deleteFeatures([f.id() for f in layer.getFeatures()])
|
||||||
@ -129,6 +137,7 @@ class TestWFST(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
OGR Layer factory
|
OGR Layer factory
|
||||||
"""
|
"""
|
||||||
|
|
||||||
path = cls.testdata_path + layer_name + '.shp'
|
path = cls.testdata_path + layer_name + '.shp'
|
||||||
layer = QgsVectorLayer(path, layer_name, "ogr")
|
layer = QgsVectorLayer(path, layer_name, "ogr")
|
||||||
assert layer.isValid()
|
assert layer.isValid()
|
||||||
@ -139,6 +148,7 @@ class TestWFST(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
WFS layer factory
|
WFS layer factory
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if layer_name is None:
|
if layer_name is None:
|
||||||
layer_name = 'wfs_' + type_name
|
layer_name = 'wfs_' + type_name
|
||||||
parms = {
|
parms = {
|
||||||
@ -146,7 +156,7 @@ class TestWFST(unittest.TestCase):
|
|||||||
'typename': type_name,
|
'typename': type_name,
|
||||||
'url': 'http://127.0.0.1:%s/?map=%s' % (cls.port,
|
'url': 'http://127.0.0.1:%s/?map=%s' % (cls.port,
|
||||||
cls.project_path),
|
cls.project_path),
|
||||||
'version': 'auto',
|
'version': cls.VERSION,
|
||||||
'table': '',
|
'table': '',
|
||||||
# 'sql': '',
|
# 'sql': '',
|
||||||
}
|
}
|
||||||
@ -160,6 +170,7 @@ class TestWFST(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
Find the feature and return it, raise exception if not found
|
Find the feature and return it, raise exception if not found
|
||||||
"""
|
"""
|
||||||
|
|
||||||
request = QgsFeatureRequest(QgsExpression("%s=%s" % (attr_name,
|
request = QgsFeatureRequest(QgsExpression("%s=%s" % (attr_name,
|
||||||
attr_value)))
|
attr_value)))
|
||||||
try:
|
try:
|
||||||
@ -172,21 +183,36 @@ class TestWFST(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
Check features were added
|
Check features were added
|
||||||
"""
|
"""
|
||||||
|
|
||||||
wfs_layer.dataProvider().addFeatures(features)
|
wfs_layer.dataProvider().addFeatures(features)
|
||||||
layer = self._getLayer(layer.name())
|
layer = self._getLayer(layer.name())
|
||||||
self.assertTrue(layer.isValid())
|
self.assertTrue(layer.isValid())
|
||||||
self.assertEqual(layer.featureCount(), len(features))
|
self.assertEqual(layer.featureCount(), len(features))
|
||||||
self.assertEqual(wfs_layer.dataProvider().featureCount(), len(features))
|
self.assertEqual(
|
||||||
|
wfs_layer.dataProvider().featureCount(), len(features))
|
||||||
|
|
||||||
|
ogr_features = [f for f in layer.dataProvider().getFeatures()]
|
||||||
|
|
||||||
|
# Verify features from the layers
|
||||||
|
for f in ogr_features:
|
||||||
|
geom = next(wfs_layer.dataProvider().getFeatures(QgsFeatureRequest(
|
||||||
|
QgsExpression('"id" = %s' % f.attribute('id'))))).geometry()
|
||||||
|
self.assertEqual(geom.boundingBox(), f.geometry().boundingBox())
|
||||||
|
|
||||||
def _checkUpdateFeatures(self, wfs_layer, old_features, new_features):
|
def _checkUpdateFeatures(self, wfs_layer, old_features, new_features):
|
||||||
"""
|
"""
|
||||||
Check features can be updated
|
Check features can be updated
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for i in range(len(old_features)):
|
for i in range(len(old_features)):
|
||||||
f = self._getFeatureByAttribute(wfs_layer, 'id', old_features[i]['id'])
|
f = self._getFeatureByAttribute(
|
||||||
self.assertTrue(wfs_layer.dataProvider().changeGeometryValues({f.id(): new_features[i].geometry()}))
|
wfs_layer, 'id', old_features[i]['id'])
|
||||||
self.assertTrue(wfs_layer.dataProvider().changeAttributeValues({f.id(): {0: new_features[i]['id']}}))
|
self.assertTrue(wfs_layer.dataProvider().changeGeometryValues(
|
||||||
self.assertTrue(wfs_layer.dataProvider().changeAttributeValues({f.id(): {1: new_features[i]['name']}}))
|
{f.id(): new_features[i].geometry()}))
|
||||||
|
self.assertTrue(wfs_layer.dataProvider().changeAttributeValues(
|
||||||
|
{f.id(): {0: new_features[i]['id']}}))
|
||||||
|
self.assertTrue(wfs_layer.dataProvider().changeAttributeValues(
|
||||||
|
{f.id(): {1: new_features[i]['name']}}))
|
||||||
|
|
||||||
def _checkMatchFeatures(self, wfs_layer, features):
|
def _checkMatchFeatures(self, wfs_layer, features):
|
||||||
"""
|
"""
|
||||||
@ -202,6 +228,7 @@ class TestWFST(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
Delete features
|
Delete features
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ids = []
|
ids = []
|
||||||
for f in features:
|
for f in features:
|
||||||
wf = self._getFeatureByAttribute(layer, 'id', f['id'])
|
wf = self._getFeatureByAttribute(layer, 'id', f['id'])
|
||||||
@ -212,6 +239,7 @@ class TestWFST(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
Perform all test steps on the layer.
|
Perform all test steps on the layer.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.assertEqual(wfs_layer.featureCount(), 0)
|
self.assertEqual(wfs_layer.featureCount(), 0)
|
||||||
self._checkAddFeatures(wfs_layer, layer, old_features)
|
self._checkAddFeatures(wfs_layer, layer, old_features)
|
||||||
self._checkMatchFeatures(wfs_layer, old_features)
|
self._checkMatchFeatures(wfs_layer, old_features)
|
||||||
@ -226,6 +254,7 @@ class TestWFST(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
Adds some points, then check and clear all
|
Adds some points, then check and clear all
|
||||||
"""
|
"""
|
||||||
|
|
||||||
layer_name = 'test_point'
|
layer_name = 'test_point'
|
||||||
layer = self._getLayer(layer_name)
|
layer = self._getLayer(layer_name)
|
||||||
wfs_layer = self._getWFSLayer(layer_name)
|
wfs_layer = self._getWFSLayer(layer_name)
|
||||||
@ -248,6 +277,7 @@ class TestWFST(unittest.TestCase):
|
|||||||
Adds some points, then check.
|
Adds some points, then check.
|
||||||
Modify 2 points, then checks and clear all
|
Modify 2 points, then checks and clear all
|
||||||
"""
|
"""
|
||||||
|
|
||||||
layer_name = 'test_point'
|
layer_name = 'test_point'
|
||||||
layer = self._getLayer(layer_name)
|
layer = self._getLayer(layer_name)
|
||||||
wfs_layer = self._getWFSLayer(layer_name)
|
wfs_layer = self._getWFSLayer(layer_name)
|
||||||
@ -276,15 +306,18 @@ class TestWFST(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
Adds some polygons, then check and clear all
|
Adds some polygons, then check and clear all
|
||||||
"""
|
"""
|
||||||
|
|
||||||
layer_name = 'test_polygon'
|
layer_name = 'test_polygon'
|
||||||
layer = self._getLayer(layer_name)
|
layer = self._getLayer(layer_name)
|
||||||
wfs_layer = self._getWFSLayer(layer_name)
|
wfs_layer = self._getWFSLayer(layer_name)
|
||||||
feat1 = QgsFeature(wfs_layer.fields())
|
feat1 = QgsFeature(wfs_layer.fields())
|
||||||
feat1['id'] = 11
|
feat1['id'] = 11
|
||||||
feat1['name'] = 'name 11'
|
feat1['name'] = 'name 11'
|
||||||
feat1.setGeometry(QgsGeometry.fromRect(QgsRectangle(QgsPointXY(9, 45), QgsPointXY(10, 46))))
|
feat1.setGeometry(QgsGeometry.fromRect(
|
||||||
|
QgsRectangle(QgsPointXY(9, 45), QgsPointXY(10, 46))))
|
||||||
feat2 = QgsFeature(wfs_layer.fields())
|
feat2 = QgsFeature(wfs_layer.fields())
|
||||||
feat2.setGeometry(QgsGeometry.fromRect(QgsRectangle(QgsPointXY(9.5, 45.5), QgsPointXY(10.5, 46.5))))
|
feat2.setGeometry(QgsGeometry.fromRect(QgsRectangle(
|
||||||
|
QgsPointXY(9.5, 45.5), QgsPointXY(10.5, 46.5))))
|
||||||
feat2['id'] = 12
|
feat2['id'] = 12
|
||||||
feat2['name'] = 'name 12'
|
feat2['name'] = 'name 12'
|
||||||
old_features = [feat1, feat2]
|
old_features = [feat1, feat2]
|
||||||
@ -292,7 +325,8 @@ class TestWFST(unittest.TestCase):
|
|||||||
new_feat1 = QgsFeature(wfs_layer.fields())
|
new_feat1 = QgsFeature(wfs_layer.fields())
|
||||||
new_feat1['id'] = 121
|
new_feat1['id'] = 121
|
||||||
new_feat1['name'] = 'name 121'
|
new_feat1['name'] = 'name 121'
|
||||||
new_feat1.setGeometry(QgsGeometry.fromRect(QgsRectangle(QgsPointXY(10, 46), QgsPointXY(11.5, 47.5))))
|
new_feat1.setGeometry(QgsGeometry.fromRect(
|
||||||
|
QgsRectangle(QgsPointXY(10, 46), QgsPointXY(11.5, 47.5))))
|
||||||
new_features = [new_feat1, feat2]
|
new_features = [new_feat1, feat2]
|
||||||
self._testLayer(wfs_layer, layer, old_features, new_features)
|
self._testLayer(wfs_layer, layer, old_features, new_features)
|
||||||
|
|
||||||
@ -300,15 +334,18 @@ class TestWFST(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
Adds some lines, then check and clear all
|
Adds some lines, then check and clear all
|
||||||
"""
|
"""
|
||||||
|
|
||||||
layer_name = 'test_linestring'
|
layer_name = 'test_linestring'
|
||||||
layer = self._getLayer(layer_name)
|
layer = self._getLayer(layer_name)
|
||||||
wfs_layer = self._getWFSLayer(layer_name)
|
wfs_layer = self._getWFSLayer(layer_name)
|
||||||
feat1 = QgsFeature(wfs_layer.fields())
|
feat1 = QgsFeature(wfs_layer.fields())
|
||||||
feat1['id'] = 11
|
feat1['id'] = 11
|
||||||
feat1['name'] = 'name 11'
|
feat1['name'] = 'name 11'
|
||||||
feat1.setGeometry(QgsGeometry.fromPolylineXY([QgsPointXY(9, 45), QgsPointXY(10, 46)]))
|
feat1.setGeometry(QgsGeometry.fromPolylineXY(
|
||||||
|
[QgsPointXY(9, 45), QgsPointXY(10, 46)]))
|
||||||
feat2 = QgsFeature(wfs_layer.fields())
|
feat2 = QgsFeature(wfs_layer.fields())
|
||||||
feat2.setGeometry(QgsGeometry.fromPolylineXY([QgsPointXY(9.5, 45.5), QgsPointXY(10.5, 46.5)]))
|
feat2.setGeometry(QgsGeometry.fromPolylineXY(
|
||||||
|
[QgsPointXY(9.5, 45.5), QgsPointXY(10.5, 46.5)]))
|
||||||
feat2['id'] = 12
|
feat2['id'] = 12
|
||||||
feat2['name'] = 'name 12'
|
feat2['name'] = 'name 12'
|
||||||
old_features = [feat1, feat2]
|
old_features = [feat1, feat2]
|
||||||
@ -316,10 +353,17 @@ class TestWFST(unittest.TestCase):
|
|||||||
new_feat1 = QgsFeature(wfs_layer.fields())
|
new_feat1 = QgsFeature(wfs_layer.fields())
|
||||||
new_feat1['id'] = 121
|
new_feat1['id'] = 121
|
||||||
new_feat1['name'] = 'name 121'
|
new_feat1['name'] = 'name 121'
|
||||||
new_feat1.setGeometry(QgsGeometry.fromPolylineXY([QgsPointXY(9.8, 45.8), QgsPointXY(10.8, 46.8)]))
|
new_feat1.setGeometry(QgsGeometry.fromPolylineXY(
|
||||||
|
[QgsPointXY(9.8, 45.8), QgsPointXY(10.8, 46.8)]))
|
||||||
new_features = [new_feat1, feat2]
|
new_features = [new_feat1, feat2]
|
||||||
self._testLayer(wfs_layer, layer, old_features, new_features)
|
self._testLayer(wfs_layer, layer, old_features, new_features)
|
||||||
|
|
||||||
|
|
||||||
|
class TestWFST11(TestWFST):
|
||||||
|
"""Same tests for WFS 1.1"""
|
||||||
|
|
||||||
|
VERSION = '1.1.0'
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
15
tests/testdata/provider/wfst-1-1/describefeaturetype_polygons.xml
vendored
Normal file
15
tests/testdata/provider/wfst-1-1/describefeaturetype_polygons.xml
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xmlns:ws1="ws1" elementFormDefault="qualified" targetNamespace="ws1">
|
||||||
|
<xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://localhost:8600/geoserver/schemas/gml/3.1.1/base/gml.xsd"/>
|
||||||
|
<xsd:complexType name="polygonsType">
|
||||||
|
<xsd:complexContent>
|
||||||
|
<xsd:extension base="gml:AbstractFeatureType">
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element maxOccurs="1" minOccurs="0" name="geometry" nillable="true" type="gml:SurfacePropertyType"/>
|
||||||
|
<xsd:element maxOccurs="1" minOccurs="0" name="name" nillable="true" type="xsd:string"/>
|
||||||
|
<xsd:element maxOccurs="1" minOccurs="0" name="value" nillable="true" type="xsd:int"/>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:extension>
|
||||||
|
</xsd:complexContent>
|
||||||
|
</xsd:complexType>
|
||||||
|
<xsd:element name="polygons" substitutionGroup="gml:_Feature" type="ws1:polygonsType"/>
|
||||||
|
</xsd:schema>
|
||||||
474
tests/testdata/provider/wfst-1-1/getcapabilities.xml
vendored
Normal file
474
tests/testdata/provider/wfst-1-1/getcapabilities.xml
vendored
Normal file
@ -0,0 +1,474 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- this is a sample response from geoserver,
|
||||||
|
OperationsMetadata was commented out because of fake endpoints -->
|
||||||
|
<wfs:WFS_Capabilities version="1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://www.opengis.net/wfs"
|
||||||
|
xmlns:wfs="http://www.opengis.net/wfs"
|
||||||
|
xmlns:ows="http://www.opengis.net/ows"
|
||||||
|
xmlns:gml="http://www.opengis.net/gml"
|
||||||
|
xmlns:ogc="http://www.opengis.net/ogc"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:8600/geoserver/schemas/wfs/1.1.0/wfs.xsd"
|
||||||
|
xmlns:ws1="ws1" updateSequence="34">
|
||||||
|
<ows:ServiceIdentification>
|
||||||
|
<ows:Title/>
|
||||||
|
<ows:Abstract/>
|
||||||
|
<ows:ServiceType>WFS</ows:ServiceType>
|
||||||
|
<ows:ServiceTypeVersion>1.1.0</ows:ServiceTypeVersion>
|
||||||
|
<ows:Fees/>
|
||||||
|
<ows:AccessConstraints/>
|
||||||
|
</ows:ServiceIdentification>
|
||||||
|
<ows:ServiceProvider>
|
||||||
|
<ows:ProviderName/>
|
||||||
|
<ows:ServiceContact>
|
||||||
|
<ows:IndividualName/>
|
||||||
|
<ows:PositionName/>
|
||||||
|
<ows:ContactInfo>
|
||||||
|
<ows:Phone>
|
||||||
|
<ows:Voice/>
|
||||||
|
<ows:Facsimile/>
|
||||||
|
</ows:Phone>
|
||||||
|
<ows:Address>
|
||||||
|
<ows:DeliveryPoint/>
|
||||||
|
<ows:City/>
|
||||||
|
<ows:AdministrativeArea/>
|
||||||
|
<ows:PostalCode/>
|
||||||
|
<ows:Country/>
|
||||||
|
<ows:ElectronicMailAddress/>
|
||||||
|
</ows:Address>
|
||||||
|
</ows:ContactInfo>
|
||||||
|
</ows:ServiceContact>
|
||||||
|
</ows:ServiceProvider>
|
||||||
|
<!-- commented because of fake urls
|
||||||
|
<ows:OperationsMetadata>
|
||||||
|
<ows:Operation name="GetCapabilities">
|
||||||
|
<ows:DCP>
|
||||||
|
<ows:HTTP>
|
||||||
|
<ows:Get xlink:href="http://localhost:8600/geoserver/ws1/wfs"/>
|
||||||
|
<ows:Post xlink:href="http://localhost:8600/geoserver/ws1/wfs"/>
|
||||||
|
</ows:HTTP>
|
||||||
|
</ows:DCP>
|
||||||
|
<ows:Parameter name="AcceptVersions">
|
||||||
|
<ows:Value>1.1.0</ows:Value>
|
||||||
|
</ows:Parameter>
|
||||||
|
<ows:Parameter name="AcceptFormats">
|
||||||
|
<ows:Value>text/xml</ows:Value>
|
||||||
|
</ows:Parameter>
|
||||||
|
<ows:Parameter name="Sections">
|
||||||
|
<ows:Value>ServiceIdentification</ows:Value>
|
||||||
|
<ows:Value>ServiceProvider</ows:Value>
|
||||||
|
<ows:Value>OperationsMetadata</ows:Value>
|
||||||
|
<ows:Value>FeatureTypeList</ows:Value>
|
||||||
|
<ows:Value>Filter_Capabilities</ows:Value>
|
||||||
|
</ows:Parameter>
|
||||||
|
</ows:Operation>
|
||||||
|
<ows:Operation name="DescribeFeatureType">
|
||||||
|
<ows:DCP>
|
||||||
|
<ows:HTTP>
|
||||||
|
<ows:Get xlink:href="http://localhost:8600/geoserver/ws1/wfs"/>
|
||||||
|
<ows:Post xlink:href="http://localhost:8600/geoserver/ws1/wfs"/>
|
||||||
|
</ows:HTTP>
|
||||||
|
</ows:DCP>
|
||||||
|
<ows:Parameter name="outputFormat">
|
||||||
|
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
|
||||||
|
</ows:Parameter>
|
||||||
|
</ows:Operation>
|
||||||
|
<ows:Operation name="GetFeature">
|
||||||
|
<ows:DCP>
|
||||||
|
<ows:HTTP>
|
||||||
|
<ows:Get xlink:href="http://localhost:8600/geoserver/ws1/wfs"/>
|
||||||
|
<ows:Post xlink:href="http://localhost:8600/geoserver/ws1/wfs"/>
|
||||||
|
</ows:HTTP>
|
||||||
|
</ows:DCP>
|
||||||
|
<ows:Parameter name="resultType">
|
||||||
|
<ows:Value>results</ows:Value>
|
||||||
|
<ows:Value>hits</ows:Value>
|
||||||
|
</ows:Parameter>
|
||||||
|
<ows:Parameter name="outputFormat">
|
||||||
|
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
|
||||||
|
<ows:Value>GML2</ows:Value>
|
||||||
|
<ows:Value>KML</ows:Value>
|
||||||
|
<ows:Value>SHAPE-ZIP</ows:Value>
|
||||||
|
<ows:Value>application/gml+xml; version=3.2</ows:Value>
|
||||||
|
<ows:Value>application/json</ows:Value>
|
||||||
|
<ows:Value>application/vnd.google-earth.kml xml</ows:Value>
|
||||||
|
<ows:Value>application/vnd.google-earth.kml+xml</ows:Value>
|
||||||
|
<ows:Value>csv</ows:Value>
|
||||||
|
<ows:Value>gml3</ows:Value>
|
||||||
|
<ows:Value>gml32</ows:Value>
|
||||||
|
<ows:Value>json</ows:Value>
|
||||||
|
<ows:Value>text/javascript</ows:Value>
|
||||||
|
<ows:Value>text/xml; subtype=gml/2.1.2</ows:Value>
|
||||||
|
<ows:Value>text/xml; subtype=gml/3.2</ows:Value>
|
||||||
|
</ows:Parameter>
|
||||||
|
<ows:Constraint name="LocalTraverseXLinkScope">
|
||||||
|
<ows:Value>2</ows:Value>
|
||||||
|
</ows:Constraint>
|
||||||
|
</ows:Operation>
|
||||||
|
<ows:Operation name="GetGmlObject">
|
||||||
|
<ows:DCP>
|
||||||
|
<ows:HTTP>
|
||||||
|
<ows:Get xlink:href="http://localhost:8600/geoserver/ws1/wfs"/>
|
||||||
|
<ows:Post xlink:href="http://localhost:8600/geoserver/ws1/wfs"/>
|
||||||
|
</ows:HTTP>
|
||||||
|
</ows:DCP>
|
||||||
|
</ows:Operation>
|
||||||
|
<ows:Operation name="Transaction">
|
||||||
|
<ows:DCP>
|
||||||
|
<ows:HTTP>
|
||||||
|
<ows:Get xlink:href="http://localhost:8600/geoserver/ws1/wfs"/>
|
||||||
|
<ows:Post xlink:href="http://localhost:8600/geoserver/ws1/wfs"/>
|
||||||
|
</ows:HTTP>
|
||||||
|
</ows:DCP>
|
||||||
|
<ows:Parameter name="inputFormat">
|
||||||
|
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
|
||||||
|
</ows:Parameter>
|
||||||
|
<ows:Parameter name="idgen">
|
||||||
|
<ows:Value>GenerateNew</ows:Value>
|
||||||
|
<ows:Value>UseExisting</ows:Value>
|
||||||
|
<ows:Value>ReplaceDuplicate</ows:Value>
|
||||||
|
</ows:Parameter>
|
||||||
|
<ows:Parameter name="releaseAction">
|
||||||
|
<ows:Value>ALL</ows:Value>
|
||||||
|
<ows:Value>SOME</ows:Value>
|
||||||
|
</ows:Parameter>
|
||||||
|
</ows:Operation>
|
||||||
|
</ows:OperationsMetadata-->
|
||||||
|
<FeatureTypeList>
|
||||||
|
<Operations>
|
||||||
|
<Operation>Query</Operation>
|
||||||
|
<Operation>Insert</Operation>
|
||||||
|
<Operation>Update</Operation>
|
||||||
|
<Operation>Delete</Operation>
|
||||||
|
</Operations>
|
||||||
|
<FeatureType xmlns:ws1="ws1">
|
||||||
|
<Name>ws1:polygons</Name>
|
||||||
|
<Title>polygons</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<ows:Keywords>
|
||||||
|
<ows:Keyword>features</ows:Keyword>
|
||||||
|
<ows:Keyword>polygons</ows:Keyword>
|
||||||
|
</ows:Keywords>
|
||||||
|
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
|
||||||
|
<ows:WGS84BoundingBox>
|
||||||
|
<ows:LowerCorner>-180.0 -90.0</ows:LowerCorner>
|
||||||
|
<ows:UpperCorner>180.0 90.0</ows:UpperCorner>
|
||||||
|
</ows:WGS84BoundingBox>
|
||||||
|
</FeatureType>
|
||||||
|
</FeatureTypeList>
|
||||||
|
<ogc:Filter_Capabilities>
|
||||||
|
<ogc:Spatial_Capabilities>
|
||||||
|
<ogc:GeometryOperands>
|
||||||
|
<ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand>
|
||||||
|
<ogc:GeometryOperand>gml:Point</ogc:GeometryOperand>
|
||||||
|
<ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand>
|
||||||
|
<ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand>
|
||||||
|
</ogc:GeometryOperands>
|
||||||
|
<ogc:SpatialOperators>
|
||||||
|
<ogc:SpatialOperator name="Disjoint"/>
|
||||||
|
<ogc:SpatialOperator name="Equals"/>
|
||||||
|
<ogc:SpatialOperator name="DWithin"/>
|
||||||
|
<ogc:SpatialOperator name="Beyond"/>
|
||||||
|
<ogc:SpatialOperator name="Intersects"/>
|
||||||
|
<ogc:SpatialOperator name="Touches"/>
|
||||||
|
<ogc:SpatialOperator name="Crosses"/>
|
||||||
|
<ogc:SpatialOperator name="Within"/>
|
||||||
|
<ogc:SpatialOperator name="Contains"/>
|
||||||
|
<ogc:SpatialOperator name="Overlaps"/>
|
||||||
|
<ogc:SpatialOperator name="BBOX"/>
|
||||||
|
</ogc:SpatialOperators>
|
||||||
|
</ogc:Spatial_Capabilities>
|
||||||
|
<ogc:Scalar_Capabilities>
|
||||||
|
<ogc:LogicalOperators/>
|
||||||
|
<ogc:ComparisonOperators>
|
||||||
|
<ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
|
||||||
|
<ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
|
||||||
|
<ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
|
||||||
|
<ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
|
||||||
|
<ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
|
||||||
|
<ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
|
||||||
|
<ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
|
||||||
|
<ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
|
||||||
|
<ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
|
||||||
|
</ogc:ComparisonOperators>
|
||||||
|
<ogc:ArithmeticOperators>
|
||||||
|
<ogc:SimpleArithmetic/>
|
||||||
|
<ogc:Functions>
|
||||||
|
<ogc:FunctionNames>
|
||||||
|
<ogc:FunctionName nArgs="1">abs</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">abs_2</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">abs_3</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">abs_4</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">acos</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">AddCoverages</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">Affine</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">Aggregate</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">area</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">area2</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">AreaGrid</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">asin</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">atan</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">atan2</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">attributeCount</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">BandMerge</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">BandSelect</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-6">BarnesSurface</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">between</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">boundary</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">boundaryDimension</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="0">boundedBy</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">Bounds</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">buffer</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">BufferFeatureCollection</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">bufferWithSegments</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="7">Categorize</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">ceil</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">centroid</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">classify</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">ClassifyByRange</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">Clip</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">CollectGeometries</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">Collection_Average</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">Collection_Bounds</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">Collection_Count</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">Collection_Max</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">Collection_Median</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">Collection_Min</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">Collection_Nearest</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">Collection_Sum</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">Collection_Unique</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">Concatenate</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">contains</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">Contour</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">contrast</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">convert</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">convexHull</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">ConvolveCoverage</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">cos</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">Count</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">CoverageClassStats</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">CropCoverage</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">crosses</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">darken</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">dateDifference</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">dateFormat</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">dateParse</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">densify</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">desaturate</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">difference</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">dimension</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">disjoint</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">disjoint3D</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">distance</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">distance3D</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">double2bool</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">endAngle</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">endPoint</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">env</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">envelope</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">EqualArea</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">EqualInterval</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">equalsExact</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">equalsExactTolerance</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">equalTo</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">exp</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">exteriorRing</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">Feature</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">FeatureClassStats</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">floor</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="0">geometry</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">geometryType</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">geomFromWKT</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">geomLength</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-3">GeorectifyCoverage</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">GetFullCoverage</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">getGeometryN</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">getX</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">getY</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">getz</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">grayscale</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">greaterEqualThan</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">greaterThan</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-3">Grid</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-5">Heatmap</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">hsl</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="0">id</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">IEEEremainder</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">if_then_else</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="0">Import</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">in</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="11">in10</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">in2</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="4">in3</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="5">in4</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="6">in5</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="7">in6</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="8">in7</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="9">in8</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="10">in9</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">inArray</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">InclusionFeatureCollection</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">int2bbool</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">int2ddouble</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">interiorPoint</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">interiorRingN</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-5">Interpolate</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">intersection</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">IntersectionFeatureCollection</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">intersects</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">intersects3D</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">isClosed</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="0">isCoverage</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">isEmpty</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">isInstanceOf</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">isLike</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">isNull</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">isometric</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">isRing</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">isSimple</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">isValid</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">isWithinDistance</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">isWithinDistance3D</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">Jenks</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">Jiffle</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">jsonPointer</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">labelPoint</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">lapply</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">length</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">lessEqualThan</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">lessThan</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">lighten</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">list</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">listMultiply</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">litem</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">literate</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">log</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="4">LRSGeocode</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-4">LRSMeasure</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="5">LRSSegment</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">max</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">max_2</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">max_3</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">max_4</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">min</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">min_2</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">min_3</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">min_4</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">mincircle</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">minimumdiameter</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">minrectangle</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">mix</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">modulo</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">MultiplyCoverages</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">Nearest</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">NormalizeCoverage</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">not</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">notEqualTo</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">numberFormat</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="5">numberFormat2</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">numGeometries</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">numInteriorRing</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">numPoints</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">octagonalenvelope</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">offset</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">overlaps</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">PagedUnique</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">parameter</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">parseBoolean</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">parseDouble</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">parseInt</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">parseLong</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">pgNearest</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="0">pi</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">PointBuffers</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">pointN</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-7">PointStacker</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">PolygonExtraction</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">polygonize</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">PolyLabeller</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">pow</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">property</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">PropertyExists</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">Quantile</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">Query</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="0">random</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">RangeLookup</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">RasterAsPointCollection</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">RasterZonalStatistics</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-6">RasterZonalStatistics2</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="5">Recode</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">RectangularClip</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">relate</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">relatePattern</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">reproject</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">ReprojectGeometry</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-3">rescaleToPixels</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">rint</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">round</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">round_2</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">roundDouble</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">saturate</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-5">ScaleCoverage</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">setCRS</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">shade</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">simplify</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">sin</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">size</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">Snap</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">spin</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">splitPolygon</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">sqrt</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">StandardDeviation</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">startAngle</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">startPoint</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">StoreCoverage</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="4">strAbbreviate</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">strCapitalize</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">strConcat</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">strDefaultIfBlank</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">strEndsWith</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">strEqualsIgnoreCase</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">strIndexOf</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="4">stringTemplate</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">strLastIndexOf</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">strLength</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">strMatches</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">strPosition</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="4">strReplace</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">strStartsWith</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">strStripAccents</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">strSubstring</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">strSubstringStart</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">strToLowerCase</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">strToUpperCase</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">strTrim</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">strTrim2</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-1">strURLEncode</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">StyleCoverage</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">symDifference</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">tan</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">tint</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">toDegrees</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">toRadians</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">touches</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">toWKT</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">Transform</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">TransparencyFill</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-2">union</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">UnionFeatureCollection</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">Unique</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">UniqueInterval</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="-4">VectorToRaster</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="3">VectorZonalStatistics</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="1">vertices</ogc:FunctionName>
|
||||||
|
<ogc:FunctionName nArgs="2">within</ogc:FunctionName>
|
||||||
|
</ogc:FunctionNames>
|
||||||
|
</ogc:Functions>
|
||||||
|
</ogc:ArithmeticOperators>
|
||||||
|
</ogc:Scalar_Capabilities>
|
||||||
|
<ogc:Id_Capabilities>
|
||||||
|
<ogc:FID/>
|
||||||
|
<ogc:EID/>
|
||||||
|
</ogc:Id_Capabilities>
|
||||||
|
</ogc:Filter_Capabilities>
|
||||||
|
</wfs:WFS_Capabilities>
|
||||||
8
tests/testdata/provider/wfst-1-1/transaction_add_features_polygons_empty.xml
vendored
Normal file
8
tests/testdata/provider/wfst-1-1/transaction_add_features_polygons_empty.xml
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<Transaction xmlns="http://www.opengis.net_wfs"
|
||||||
|
xmlns:xsi="http://www.w3.org_2001_XMLSchema-instance"
|
||||||
|
xmlns:gml="http://www.opengis.net_gml"
|
||||||
|
xmlns:ws1="ws1" xsi:schemaLocation="ws1 http://localhost:8600_geoserver_ws1_wfs?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=ws1:polygons" version="1.1.0" service="WFS">
|
||||||
|
<Insert xmlns="http:__www.opengis.net_wfs">
|
||||||
|
<polygons xmlns="ws1"/>
|
||||||
|
</Insert>
|
||||||
|
</Transaction>
|
||||||
19
tests/testdata/provider/wfst-1-1/transaction_response_empty.xml
vendored
Normal file
19
tests/testdata/provider/wfst-1-1/transaction_response_empty.xml
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<wfs:TransactionResponse xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:wfs="http://www.opengis.net/wfs"
|
||||||
|
xmlns:gml="http://www.opengis.net/gml"
|
||||||
|
xmlns:ogc="http://www.opengis.net/ogc"
|
||||||
|
xmlns:ows="http://www.opengis.net/ows"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:8600/geoserver/schemas/wfs/1.1.0/wfs.xsd">
|
||||||
|
<wfs:TransactionSummary>
|
||||||
|
<wfs:totalInserted>0</wfs:totalInserted>
|
||||||
|
<wfs:totalUpdated>0</wfs:totalUpdated>
|
||||||
|
<wfs:totalDeleted>0</wfs:totalDeleted>
|
||||||
|
</wfs:TransactionSummary>
|
||||||
|
<wfs:InsertResults>
|
||||||
|
<wfs:Feature>
|
||||||
|
<ogc:FeatureId fid="none"/>
|
||||||
|
</wfs:Feature>
|
||||||
|
</wfs:InsertResults>
|
||||||
|
</wfs:TransactionResponse>
|
||||||
20
tests/testdata/provider/wfst-1-1/transaction_response_feature_added.xml
vendored
Normal file
20
tests/testdata/provider/wfst-1-1/transaction_response_feature_added.xml
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<wfs:TransactionResponse xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:wfs="http://www.opengis.net/wfs"
|
||||||
|
xmlns:gml="http://www.opengis.net/gml"
|
||||||
|
xmlns:ogc="http://www.opengis.net/ogc"
|
||||||
|
xmlns:ows="http://www.opengis.net/ows"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:8600/geoserver/schemas/wfs/1.1.0/wfs.xsd">
|
||||||
|
<wfs:TransactionSummary>
|
||||||
|
<wfs:totalInserted>1</wfs:totalInserted>
|
||||||
|
<wfs:totalUpdated>0</wfs:totalUpdated>
|
||||||
|
<wfs:totalDeleted>0</wfs:totalDeleted>
|
||||||
|
</wfs:TransactionSummary>
|
||||||
|
<wfs:TransactionResults/>
|
||||||
|
<wfs:InsertResults>
|
||||||
|
<wfs:Feature>
|
||||||
|
<ogc:FeatureId fid="123"/>
|
||||||
|
</wfs:Feature>
|
||||||
|
</wfs:InsertResults>
|
||||||
|
</wfs:TransactionResponse>
|
||||||
14
tests/testdata/provider/wfst-1-1/transaction_response_feature_changed.xml
vendored
Normal file
14
tests/testdata/provider/wfst-1-1/transaction_response_feature_changed.xml
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<wfs:TransactionResponse xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:wfs="http://www.opengis.net/wfs"
|
||||||
|
xmlns:gml="http://www.opengis.net/gml"
|
||||||
|
xmlns:ogc="http://www.opengis.net/ogc"
|
||||||
|
xmlns:ows="http://www.opengis.net/ows"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:8600/geoserver/schemas/wfs/1.1.0/wfs.xsd">
|
||||||
|
<wfs:TransactionSummary>
|
||||||
|
<wfs:totalInserted>0</wfs:totalInserted>
|
||||||
|
<wfs:totalUpdated>1</wfs:totalUpdated>
|
||||||
|
<wfs:totalDeleted>0</wfs:totalDeleted>
|
||||||
|
</wfs:TransactionSummary>
|
||||||
|
</wfs:TransactionResponse>
|
||||||
14
tests/testdata/provider/wfst-1-1/transaction_response_feature_deleted.xml
vendored
Normal file
14
tests/testdata/provider/wfst-1-1/transaction_response_feature_deleted.xml
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<wfs:TransactionResponse xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:wfs="http://www.opengis.net/wfs"
|
||||||
|
xmlns:gml="http://www.opengis.net/gml"
|
||||||
|
xmlns:ogc="http://www.opengis.net/ogc"
|
||||||
|
xmlns:ows="http://www.opengis.net/ows"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:8600/geoserver/schemas/wfs/1.1.0/wfs.xsd">
|
||||||
|
<wfs:TransactionSummary>
|
||||||
|
<wfs:totalInserted>0</wfs:totalInserted>
|
||||||
|
<wfs:totalUpdated>0</wfs:totalUpdated>
|
||||||
|
<wfs:totalDeleted>1</wfs:totalDeleted>
|
||||||
|
</wfs:TransactionSummary>
|
||||||
|
</wfs:TransactionResponse>
|
||||||
Loading…
x
Reference in New Issue
Block a user