19
19
#include " qgswfssourceselect.h"
20
20
#include " qgsnewhttpconnection.h"
21
21
#include " qgsgenericprojectionselector.h"
22
- #include " qgshttptransaction.h"
23
22
#include " qgscontexthelp.h"
24
23
#include " qgsproject.h"
25
24
#include " qgscoordinatereferencesystem.h"
26
25
#include " qgslogger.h"
27
26
#include " qgsmapcanvas.h" // for current view extent
27
+ #include " qgsnetworkaccessmanager.h"
28
+
28
29
#include < QDomDocument>
29
30
#include < QListWidgetItem>
30
31
#include < QMessageBox>
31
32
#include < QSettings>
33
+ #include < QNetworkRequest>
34
+ #include < QNetworkReply>
32
35
33
36
static const QString WFS_NAMESPACE = " http://www.opengis.net/wfs" ;
34
37
35
- QgsWFSSourceSelect::QgsWFSSourceSelect ( QWidget* parent, QgisInterface* iface ): QDialog( parent ), mIface( iface )
38
+ QgsWFSSourceSelect::QgsWFSSourceSelect ( QWidget* parent, QgisInterface* iface )
39
+ : QDialog( parent )
40
+ , mIface( iface )
41
+ , mCapabilitiesReply( 0 )
36
42
{
37
43
setupUi ( this );
38
44
btnAdd = buttonBox->button ( QDialogButtonBox::Ok );
@@ -128,127 +134,165 @@ QString QgsWFSSourceSelect::getPreferredCrs( const QSet<QString>& crsSet ) const
128
134
return *( crsSet.constBegin () );
129
135
}
130
136
131
- int QgsWFSSourceSelect::getCapabilities ( const QString& uri, QgsWFSSourceSelect::REQUEST_ENCODING e, std::list<QString>& typenames, std::list< std::list<QString> >& crs, std::list<QString>& titles, std::list<QString>& abstracts )
137
+ void QgsWFSSourceSelect::capabilitiesReplyFinished ( )
132
138
{
133
- switch ( e )
139
+ if ( mCapabilitiesReply -> error () == QNetworkReply::NoError )
134
140
{
135
- case QgsWFSSourceSelect::GET:
136
- return getCapabilitiesGET ( uri, typenames, crs, titles, abstracts );
137
- case QgsWFSSourceSelect::POST:
138
- return getCapabilitiesPOST ( uri, typenames, crs, titles, abstracts );
139
- case QgsWFSSourceSelect::SOAP:
140
- return getCapabilitiesSOAP ( uri, typenames, crs, titles, abstracts );
141
- }
142
- return 1 ;
143
- }
144
-
145
- int QgsWFSSourceSelect::getCapabilitiesGET ( QString uri, std::list<QString>& typenames, std::list< std::list<QString> >& crs, std::list<QString>& titles, std::list<QString>& abstracts )
146
- {
147
- QString request = uri + " SERVICE=WFS&REQUEST=GetCapabilities&VERSION=1.0.0" ;
141
+ QVariant redirect = mCapabilitiesReply ->attribute ( QNetworkRequest::RedirectionTargetAttribute );
142
+ if ( !redirect.isNull () )
143
+ {
144
+ QgsDebugMsg ( " redirecting to " + redirect.toUrl ().toString () );
145
+ QNetworkRequest request ( redirect.toUrl () );
146
+ request.setAttribute ( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork );
147
+ request.setAttribute ( QNetworkRequest::CacheSaveControlAttribute, true );
148
148
149
- QByteArray result;
150
- QgsHttpTransaction http ( request );
151
- if ( !http.getSynchronously ( result ) )
152
- {
153
- QMessageBox::critical ( 0 , tr ( " Error" ),
154
- tr ( " Could not download capabilities document: " ) + http.errorString () );
155
- return 1 ;
156
- }
149
+ mCapabilitiesReply ->deleteLater ();
150
+ mCapabilitiesReply = QgsNetworkAccessManager::instance ()->get ( request );
157
151
158
- QDomDocument capabilitiesDocument;
159
- QString capabilitiesDocError;
160
- if ( !capabilitiesDocument.setContent ( result, true , &capabilitiesDocError ) )
161
- {
162
- QMessageBox::critical ( 0 , tr ( " Error" ),
163
- tr ( " Capabilities document is not valid: " ) + capabilitiesDocError );
164
- return 1 ;
165
- }
152
+ connect ( mCapabilitiesReply , SIGNAL ( finished () ), this , SLOT ( capabilitiesReplyFinished () ) );
153
+ connect ( mCapabilitiesReply , SIGNAL ( downloadProgress ( qint64, qint64 ) ), this , SLOT ( capabilitiesReplyProgress ( qint64, qint64 ) ) );
154
+ return ;
155
+ }
166
156
167
- QDomElement doc = capabilitiesDocument.documentElement ();
168
- if ( doc.tagName () == " ExceptionReport" )
169
- {
170
- QDomNode ex = doc.firstChild ();
171
- QString exc = ex.toElement ().attribute (" exceptionCode" , " Exception" );
172
- QDomElement ext = ex.firstChild ().toElement ();
173
- QMessageBox::critical ( 0 , tr ( " Error" ),
174
- exc + " : " + ext.firstChild ().nodeValue () );
175
- return 1 ;
176
- }
157
+ QByteArray buffer = mCapabilitiesReply ->readAll ();
177
158
178
- // get the <FeatureType> elements
179
- QDomNodeList featureTypeList = capabilitiesDocument.elementsByTagNameNS ( WFS_NAMESPACE, " FeatureType" );
180
- for ( unsigned int i = 0 ; i < featureTypeList.length (); ++i )
181
- {
182
- QString tname, title, abstract;
183
- QDomElement featureTypeElem = featureTypeList.at ( i ).toElement ();
184
- std::list<QString> featureCRSList; // CRS list for this feature
159
+ QgsDebugMsg ( " parsing capabilities: " + buffer );
185
160
186
- // Name
187
- QDomNodeList nameList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " Name" );
188
- if ( nameList.length () > 0 )
189
- {
190
- tname = nameList.at ( 0 ).toElement ().text ();
191
- // strip away namespace prefixes
192
- /* if ( tname.contains( ":" ) )
193
- {
194
- tname = tname.section( ":", 1, 1 );
195
- }*/
196
- }
197
- // Title
198
- QDomNodeList titleList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " Title" );
199
- if ( titleList.length () > 0 )
161
+ QString capabilitiesDocError;
162
+ QDomDocument capabilitiesDocument;
163
+ if ( capabilitiesDocument.setContent ( buffer, true , &capabilitiesDocError ) )
200
164
{
201
- title = titleList.at ( 0 ).toElement ().text ();
202
- }
203
- // Abstract
204
- QDomNodeList abstractList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " Abstract" );
205
- if ( abstractList.length () > 0 )
206
- {
207
- abstract = abstractList.at ( 0 ).toElement ().text ();
208
- }
165
+ QDomElement doc = capabilitiesDocument.documentElement ();
166
+ if ( doc.tagName () != " ExceptionReport" )
167
+ {
168
+ std::list<QString> typenames;
169
+ std::list< std::list<QString> > crs;
170
+ std::list<QString> titles;
171
+ std::list<QString> abstracts;
172
+
173
+ // get the <FeatureType> elements
174
+ QDomNodeList featureTypeList = capabilitiesDocument.elementsByTagNameNS ( WFS_NAMESPACE, " FeatureType" );
175
+ for ( unsigned int i = 0 ; i < featureTypeList.length (); ++i )
176
+ {
177
+ QString tname, title, abstract;
178
+ QDomElement featureTypeElem = featureTypeList.at ( i ).toElement ();
179
+ std::list<QString> featureCRSList; // CRS list for this feature
180
+
181
+ // Name
182
+ QDomNodeList nameList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " Name" );
183
+ if ( nameList.length () > 0 )
184
+ {
185
+ tname = nameList.at ( 0 ).toElement ().text ();
186
+ // strip away namespace prefixes
187
+ /* if ( tname.contains( ":" ) )
188
+ {
189
+ tname = tname.section( ":", 1, 1 );
190
+ }*/
191
+ }
192
+ // Title
193
+ QDomNodeList titleList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " Title" );
194
+ if ( titleList.length () > 0 )
195
+ {
196
+ title = titleList.at ( 0 ).toElement ().text ();
197
+ }
198
+ // Abstract
199
+ QDomNodeList abstractList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " Abstract" );
200
+ if ( abstractList.length () > 0 )
201
+ {
202
+ abstract = abstractList.at ( 0 ).toElement ().text ();
203
+ }
204
+
205
+ // DefaultSRS is always the first entry in the feature srs list
206
+ QDomNodeList defaultCRSList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " DefaultSRS" );
207
+ if ( defaultCRSList.length () > 0 )
208
+ {
209
+ featureCRSList.push_back ( defaultCRSList.at ( 0 ).toElement ().text () );
210
+ }
211
+
212
+ // OtherSRS
213
+ QDomNodeList otherCRSList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " OtherSRS" );
214
+ for ( unsigned int i = 0 ; i < otherCRSList.length (); ++i )
215
+ {
216
+ featureCRSList.push_back ( otherCRSList.at ( i ).toElement ().text () );
217
+ }
218
+
219
+ // Support <SRS> for compatibility with older versions
220
+ QDomNodeList srsList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " SRS" );
221
+ for ( unsigned int i = 0 ; i < srsList.length (); ++i )
222
+ {
223
+ featureCRSList.push_back ( srsList.at ( i ).toElement ().text () );
224
+ }
225
+
226
+ crs.push_back ( featureCRSList );
227
+ typenames.push_back ( tname );
228
+ titles.push_back ( title );
229
+ abstracts.push_back ( abstract );
230
+ }
209
231
210
- // DefaultSRS is always the first entry in the feature srs list
211
- QDomNodeList defaultCRSList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " DefaultSRS" );
212
- if ( defaultCRSList.length () > 0 )
213
- {
214
- featureCRSList.push_back ( defaultCRSList.at ( 0 ).toElement ().text () );
215
- }
232
+ // insert the available CRS into mAvailableCRS
233
+ mAvailableCRS .clear ();
234
+ std::list<QString>::const_iterator typeNameIter;
235
+ std::list< std::list<QString> >::const_iterator crsIter;
236
+ for ( typeNameIter = typenames.begin (), crsIter = crs.begin (); typeNameIter != typenames.end (); ++typeNameIter, ++crsIter )
237
+ {
238
+ std::list<QString> currentCRSList;
239
+ for ( std::list<QString>::const_iterator it = crsIter->begin (); it != crsIter->end (); ++it )
240
+ {
241
+ currentCRSList.push_back ( *it );
242
+ }
243
+ mAvailableCRS .insert ( std::make_pair ( *typeNameIter, currentCRSList ) );
244
+ }
216
245
217
- // OtherSRS
218
- QDomNodeList otherCRSList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " OtherSRS" );
219
- for ( unsigned int i = 0 ; i < otherCRSList.length (); ++i )
220
- {
221
- featureCRSList.push_back ( otherCRSList.at ( i ).toElement ().text () );
222
- }
246
+ // insert the typenames, titles and abstracts into the tree view
247
+ std::list<QString>::const_iterator t_it = titles.begin ();
248
+ std::list<QString>::const_iterator n_it = typenames.begin ();
249
+ std::list<QString>::const_iterator a_it = abstracts.begin ();
250
+ for ( ; t_it != titles.end (); ++t_it, ++n_it, ++a_it )
251
+ {
252
+ QTreeWidgetItem* newItem = new QTreeWidgetItem ();
253
+ newItem->setText ( 0 , *t_it );
254
+ newItem->setText ( 1 , *n_it );
255
+ newItem->setText ( 2 , *a_it );
256
+ treeWidget->addTopLevelItem ( newItem );
257
+ }
223
258
224
- // Support <SRS> for compatibility with older versions
225
- QDomNodeList srsList = featureTypeElem.elementsByTagNameNS ( WFS_NAMESPACE, " SRS" );
226
- for ( unsigned int i = 0 ; i < srsList.length (); ++i )
259
+ if ( typenames.size () > 0 )
260
+ {
261
+ btnAdd->setEnabled ( true );
262
+ treeWidget->setCurrentItem ( treeWidget->topLevelItem ( 0 ) );
263
+ btnChangeSpatialRefSys->setEnabled ( true );
264
+ }
265
+ else
266
+ {
267
+ QMessageBox::information ( 0 , tr ( " No Layers" ), tr ( " capabilities document contained no layers." ) );
268
+ btnAdd->setEnabled ( false );
269
+ }
270
+ }
271
+ else
272
+ {
273
+ QDomNode ex = doc.firstChild ();
274
+ QString exc = ex.toElement ().attribute ( " exceptionCode" , " Exception" );
275
+ QDomElement ext = ex.firstChild ().toElement ();
276
+ QMessageBox::critical ( 0 , tr ( " Error" ), exc + " : " + ext.firstChild ().nodeValue () );
277
+ }
278
+ }
279
+ else
227
280
{
228
- featureCRSList. push_back ( srsList. at ( i ). toElement (). text () );
281
+ QMessageBox::critical ( 0 , tr ( " Capabilities document is not valid " ), capabilitiesDocError );
229
282
}
230
-
231
- crs.push_back ( featureCRSList );
232
- typenames.push_back ( tname );
233
- titles.push_back ( title );
234
- abstracts.push_back ( abstract );
283
+ }
284
+ else
285
+ {
286
+ QMessageBox::critical ( 0 , tr ( " GetCapabilities Error" ), mCapabilitiesReply ->errorString () );
235
287
}
236
288
237
-
238
- // print out result for a test
239
- QgsDebugMsg ( result );
240
-
241
- return 0 ;
242
- }
243
-
244
- int QgsWFSSourceSelect::getCapabilitiesPOST ( const QString& uri, std::list<QString>& typenames, std::list< std::list<QString> >& crs, std::list<QString>& titles, std::list<QString>& abstracts )
245
- {
246
- return 1 ; // soon...
289
+ btnConnect->setEnabled ( true );
290
+ mCapabilitiesReply ->deleteLater ();
291
+ mCapabilitiesReply = 0 ;
247
292
}
248
293
249
- int QgsWFSSourceSelect::getCapabilitiesSOAP ( const QString& uri, std::list<QString>& typenames, std::list< std::list<QString> >& crs, std::list<QString>& titles, std::list<QString>& abstracts )
294
+ void QgsWFSSourceSelect::capabilitiesReplyProgress ( qint64, qint64 )
250
295
{
251
- return 1 ; // soon...
252
296
}
253
297
254
298
void QgsWFSSourceSelect::addEntryToServerList ()
@@ -296,11 +340,6 @@ void QgsWFSSourceSelect::connectToServer()
296
340
QgsDebugMsg ( QString ( " url is: %1" ).arg ( mUri ) );
297
341
298
342
// make a GetCapabilities request
299
- std::list<QString> typenames;
300
- std::list< std::list<QString> > crsList;
301
- std::list<QString> titles;
302
- std::list<QString> abstracts;
303
-
304
343
// modify mUri to add '?' or '&' at the end if it is not already there
305
344
if ( !( mUri .contains ( " ?" ) ) )
306
345
{
@@ -311,51 +350,17 @@ void QgsWFSSourceSelect::connectToServer()
311
350
mUri .append ( " &" );
312
351
}
313
352
314
- if ( getCapabilities ( mUri , QgsWFSSourceSelect::GET, typenames, crsList, titles, abstracts ) != 0 )
315
- {
316
- QgsDebugMsg ( " error during GetCapabilities request" );
317
- }
318
-
319
- // insert the available CRS into mAvailableCRS
320
- mAvailableCRS .clear ();
321
- std::list<QString>::const_iterator typeNameIter;
322
- std::list< std::list<QString> >::const_iterator crsIter;
323
- for ( typeNameIter = typenames.begin (), crsIter = crsList.begin (); typeNameIter != typenames.end (); ++typeNameIter, ++crsIter )
324
- {
325
- std::list<QString> currentCRSList;
326
- for ( std::list<QString>::const_iterator it = crsIter->begin (); it != crsIter->end (); ++it )
327
- {
328
- currentCRSList.push_back ( *it );
329
- }
330
- mAvailableCRS .insert ( std::make_pair ( *typeNameIter, currentCRSList ) );
331
- }
332
-
333
- // insert the typenames, titles and abstracts into the tree view
353
+ btnConnect->setEnabled ( false );
334
354
treeWidget->clear ();
335
- std::list<QString>::const_iterator t_it = titles.begin ();
336
- std::list<QString>::const_iterator n_it = typenames.begin ();
337
- std::list<QString>::const_iterator a_it = abstracts.begin ();
338
- for ( ; t_it != titles.end (); ++t_it, ++n_it, ++a_it )
339
- {
340
- QTreeWidgetItem* newItem = new QTreeWidgetItem ();
341
- newItem->setText ( 0 , *t_it );
342
- newItem->setText ( 1 , *n_it );
343
- newItem->setText ( 2 , *a_it );
344
- treeWidget->addTopLevelItem ( newItem );
345
- }
346
355
347
- if ( typenames.size () > 0 )
348
- {
349
- btnAdd->setEnabled ( true );
350
- treeWidget->setCurrentItem ( treeWidget->topLevelItem ( 0 ) );
351
- btnChangeSpatialRefSys->setEnabled ( true );
352
- }
353
- else
354
- {
355
- btnAdd->setEnabled ( false );
356
- }
356
+ QNetworkRequest request ( mUri + " SERVICE=WFS&REQUEST=GetCapabilities&VERSION=1.0.0" );
357
+ request.setAttribute ( QNetworkRequest::CacheSaveControlAttribute, true );
358
+ mCapabilitiesReply = QgsNetworkAccessManager::instance ()->get ( request );
359
+ connect ( mCapabilitiesReply , SIGNAL ( finished () ), this , SLOT ( capabilitiesReplyFinished () ) );
360
+ connect ( mCapabilitiesReply , SIGNAL ( downloadProgress ( qint64, qint64 ) ), this , SLOT ( capabilitiesReplyProgress ( qint64, qint64 ) ) );
357
361
}
358
362
363
+
359
364
void QgsWFSSourceSelect::addLayer ()
360
365
{
361
366
// get selected entry in lstWidget
0 commit comments