Skip to content

Commit 9040ec1

Browse files
committedApr 5, 2016
[FEATURE] [WFS provider] Major overhaul to add WFS 1.1 and 2.0 support
First part of qgis/QGIS-Enhancement-Proposals#53 (QEP 35: WFS provider enhancements) Improvements: - Version autodetection - On-disk caching of downloaded features - Background download and progressive rendering - WFS 1.1 and 2.0 support - WFS 2.0 GetFeature paging - Add provider tests Fixes: - #10106: Panning a non-cached WFS layer causes selection to change - #9444: WFS client not requesting new features when not-cached #14156: WFS non cached: infinite flashing - #9450 : New WFS connection option - Max number of features returned - #14122: Implement WFS 2.0 client provider (partial. no joins or stored queries) Not in scope: WFS-T 1.1 and 2.0. But WFS-T 1.0 kept (and tested)
1 parent 62bd406 commit 9040ec1

34 files changed

+5226
-1752
lines changed
 

‎ci/travis/linux/qt5/blacklist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ PyQgsVectorFileWriter
6666
PyQgsVectorLayer
6767
PyQgsVirtualLayerDefinition
6868
PyQgsVirtualLayerProvider
69+
PyQgsWFSProvider
6970
PyQgsZonalStatistics
7071
qgis_alignrastertest
7172
qgis_composereffectstest

‎src/core/qgsowsconnection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class CORE_EXPORT QgsOWSConnection : public QObject
5959
//! @deprecated use mConnectionInfo instead
6060
Q_DECL_DEPRECATED QString connectionInfo();
6161

62-
private:
62+
protected:
6363
QgsDataSourceURI mUri;
6464
QString mService;
6565
};

‎src/core/qgsvectorlayer.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,23 @@ struct CORE_EXPORT QgsVectorJoinInfo
195195
*
196196
* Used to access data provided by a web feature service.
197197
*
198-
* The url can be a HTTP url to a WFS 1.0.0 server or a GML2 data file path.
199-
* Examples are http://foobar/wfs or /foo/bar/file.gml
200-
*
201-
* If a GML2 file path is provided the driver will attempt to read the schema from a
202-
* file in the same directory with the same basename + “.xsd”. This xsd file must be
203-
* in the same format as a WFS describe feature type response. If no xsd file is provide
204-
* then the driver will attempt to guess the attribute types from the file.
205-
*
206-
* In the case of a HTTP URL the ‘FILTER’ query string parameter can be used to filter
198+
* The url can be a HTTP url to a WFS server (legacy, e.g. http://foobar/wfs?TYPENAME=xxx&SRSNAME=yyy[&FILTER=zzz]), or,
199+
* starting with QGIS 2.16, a URI constructed using the QgsDataSourceURI class with the following parameters :
200+
* - url=string (mandatory): HTTP url to a WFS server endpoint. e.g http://foobar/wfs
201+
* - typename=string (mandatory): WFS typename
202+
* - srsname=string (recommended): SRS like 'EPSG:XXXX'
203+
* - username=string
204+
* - password=string
205+
* - authcfg=string
206+
* - version=auto/1.0.0/1.1.0/2.0.0
207+
* - filter=string: QGIS expression or OGC/FES filter
208+
* - retrictToRequestBBOX=1: to download only features in the view extent (or more generally
209+
* in the bounding box of the feature iterator)
210+
* - maxNumFeatures=number
211+
* - IgnoreAxisOrientation=1: to ignore EPSG axis order for WFS 1.1 or 2.0
212+
* - InvertAxisOrientation=1: to invert axis order
213+
*
214+
* The ‘FILTER’ query string parameter can be used to filter
207215
* the WFS feature type. The ‘FILTER’ key value can either be a QGIS expression
208216
* or an OGC XML filter. If the value is set to a QGIS expression the driver will
209217
* turn it into OGC XML filter before passing it to the WFS server. Beware the

‎src/gui/qgsnewhttpconnection.cpp

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ QgsNewHttpConnection::QgsNewHttpConnection(
5050
cmbDpiMode->addItem( tr( "UMN" ) );
5151
cmbDpiMode->addItem( tr( "GeoServer" ) );
5252

53+
cmbVersion->clear();
54+
cmbVersion->addItem( tr( "Auto-detect" ) );
55+
cmbVersion->addItem( tr( "1.0" ) );
56+
cmbVersion->addItem( tr( "1.1" ) );
57+
cmbVersion->addItem( tr( "2.0" ) );
58+
5359
mAuthConfigSelect = new QgsAuthConfigSelect( this );
5460
tabAuth->insertTab( 1, mAuthConfigSelect, tr( "Configurations" ) );
5561

@@ -92,7 +98,18 @@ QgsNewHttpConnection::QgsNewHttpConnection(
9298
}
9399
cmbDpiMode->setCurrentIndex( dpiIdx );
94100

101+
QString version = settings.value( key + "/version" ).toString();
102+
int versionIdx = 0; // AUTO
103+
if ( version == "1.0.0" )
104+
versionIdx = 1;
105+
else if ( version == "1.1.0" )
106+
versionIdx = 2;
107+
else if ( version == "2.0.0" )
108+
versionIdx = 3;
109+
cmbVersion->setCurrentIndex( versionIdx );
110+
95111
txtReferer->setText( settings.value( key + "/referer" ).toString() );
112+
txtMaxNumFeatures->setText( settings.value( key + "/maxnumfeatures" ).toString() );
96113

97114
txtUserName->setText( settings.value( credentialsKey + "/username" ).toString() );
98115
txtPassword->setText( settings.value( credentialsKey + "/password" ).toString() );
@@ -107,6 +124,20 @@ QgsNewHttpConnection::QgsNewHttpConnection(
107124

108125
if ( mBaseKey != "/Qgis/connections-wms/" )
109126
{
127+
if ( mBaseKey != "/Qgis/connections-wcs/" &&
128+
mBaseKey != "/Qgis/connections-wfs/" )
129+
{
130+
cbxIgnoreAxisOrientation->setVisible( false );
131+
cbxInvertAxisOrientation->setVisible( false );
132+
mGroupBox->layout()->removeWidget( cbxIgnoreAxisOrientation );
133+
mGroupBox->layout()->removeWidget( cbxInvertAxisOrientation );
134+
}
135+
136+
if ( mBaseKey == "/Qgis/connections-wfs/" )
137+
{
138+
cbxIgnoreAxisOrientation->setText( tr( "Ignore axis orientation (WFS 1.1/WFS 2.0)" ) );
139+
}
140+
110141
if ( mBaseKey == "/Qgis/connections-wcs/" )
111142
{
112143
cbxIgnoreGetMapURI->setText( tr( "Ignore GetCoverage URI reported in capabilities" ) );
@@ -115,12 +146,8 @@ QgsNewHttpConnection::QgsNewHttpConnection(
115146
else
116147
{
117148
cbxIgnoreGetMapURI->setVisible( false );
118-
cbxIgnoreAxisOrientation->setVisible( false );
119-
cbxInvertAxisOrientation->setVisible( false );
120149
cbxSmoothPixmapTransform->setVisible( false );
121150
mGroupBox->layout()->removeWidget( cbxIgnoreGetMapURI );
122-
mGroupBox->layout()->removeWidget( cbxIgnoreAxisOrientation );
123-
mGroupBox->layout()->removeWidget( cbxInvertAxisOrientation );
124151
mGroupBox->layout()->removeWidget( cbxSmoothPixmapTransform );
125152
}
126153

@@ -136,13 +163,23 @@ QgsNewHttpConnection::QgsNewHttpConnection(
136163
mGroupBox->layout()->removeWidget( txtReferer );
137164
lblReferer->setVisible( false );
138165
mGroupBox->layout()->removeWidget( lblReferer );
166+
}
139167

140-
// Adjust height
141-
int w = width();
142-
adjustSize();
143-
resize( w, height() );
168+
if ( mBaseKey != "/Qgis/connections-wfs/" )
169+
{
170+
cmbVersion->setVisible( false );
171+
mGroupBox->layout()->removeWidget( cmbVersion );
172+
lblMaxNumFeatures->setVisible( false );
173+
mGroupBox->layout()->removeWidget( lblMaxNumFeatures );
174+
txtMaxNumFeatures->setVisible( false );
175+
mGroupBox->layout()->removeWidget( txtMaxNumFeatures );
144176
}
145177

178+
// Adjust height
179+
int w = width();
180+
adjustSize();
181+
resize( w, height() );
182+
146183
on_txtName_textChanged( connName );
147184
}
148185

@@ -219,11 +256,18 @@ void QgsNewHttpConnection::accept()
219256
}
220257

221258
settings.setValue( key + "/url", url.toString() );
222-
if ( mBaseKey == "/Qgis/connections-wms/" || mBaseKey == "/Qgis/connections-wcs/" )
259+
260+
if ( mBaseKey == "/Qgis/connections-wms/" ||
261+
mBaseKey == "/Qgis/connections-wcs/" ||
262+
mBaseKey == "/Qgis/connections-wfs/" )
223263
{
224-
settings.setValue( key + "/ignoreGetMapURI", cbxIgnoreGetMapURI->isChecked() );
225264
settings.setValue( key + "/ignoreAxisOrientation", cbxIgnoreAxisOrientation->isChecked() );
226265
settings.setValue( key + "/invertAxisOrientation", cbxInvertAxisOrientation->isChecked() );
266+
}
267+
268+
if ( mBaseKey == "/Qgis/connections-wms/" || mBaseKey == "/Qgis/connections-wcs/" )
269+
{
270+
settings.setValue( key + "/ignoreGetMapURI", cbxIgnoreGetMapURI->isChecked() );
227271
settings.setValue( key + "/smoothPixmapTransform", cbxSmoothPixmapTransform->isChecked() );
228272

229273
int dpiMode = 0;
@@ -252,6 +296,28 @@ void QgsNewHttpConnection::accept()
252296
{
253297
settings.setValue( key + "/ignoreGetFeatureInfoURI", cbxIgnoreGetFeatureInfoURI->isChecked() );
254298
}
299+
if ( mBaseKey == "/Qgis/connections-wfs/" )
300+
{
301+
QString version = "auto";
302+
switch ( cmbVersion->currentIndex() )
303+
{
304+
case 0:
305+
version = "auto";
306+
break;
307+
case 1:
308+
version = "1.0.0";
309+
break;
310+
case 2:
311+
version = "1.1.0";
312+
break;
313+
case 3:
314+
version = "2.0.0";
315+
break;
316+
}
317+
settings.setValue( key + "/version", version );
318+
319+
settings.setValue( key + "/maxnumfeatures", txtMaxNumFeatures->text() );
320+
}
255321

256322
settings.setValue( key + "/referer", txtReferer->text() );
257323

‎src/providers/wfs/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ SET(WFS_SRCS
88
qgswfsdataitems.cpp
99
qgswfsfeatureiterator.cpp
1010
qgswfssourceselect.cpp
11+
qgswfsrequest.cpp
12+
qgswfsconnection.cpp
13+
qgswfsdatasourceuri.cpp
14+
qgswfsconstants.cpp
15+
qgswfsdescribefeaturetype.cpp
16+
qgswfsshareddata.cpp
17+
qgswfstransactionrequest.cpp
18+
qgswfsutils.cpp
1119
)
1220

1321
SET (WFS_MOC_HDRS
@@ -16,6 +24,11 @@ SET (WFS_MOC_HDRS
1624
qgswfsprovider.h
1725
qgswfsfeatureiterator.h
1826
qgswfssourceselect.h
27+
qgswfsrequest.h
28+
qgswfsdescribefeaturetype.h
29+
qgswfstransactionrequest.h
30+
qgswfsshareddata.h
31+
qgswfsutils.h
1932
)
2033

2134
########################################################
@@ -27,6 +40,7 @@ INCLUDE_DIRECTORIES (
2740
../../core
2841
../../core/auth
2942
../../core/geometry
43+
../../core/symbology-ng # needed by qgsvectorfilewriter.h
3044
../../gui
3145
../../gui/auth
3246
${CMAKE_CURRENT_BINARY_DIR}/../../ui
@@ -37,6 +51,8 @@ INCLUDE_DIRECTORIES(SYSTEM
3751
${EXPAT_INCLUDE_DIR}
3852
${QSCINTILLA_INCLUDE_DIR}
3953
${QCA_INCLUDE_DIR}
54+
${GDAL_INCLUDE_DIR} # needed by qgsvectorfilewriter.h
55+
${SQLITE3_INCLUDE_DIR}
4056
)
4157

4258
ADD_LIBRARY (wfsprovider MODULE ${WFS_SRCS} ${WFS_MOC_SRCS})

0 commit comments

Comments
 (0)
Please sign in to comment.