feature-2892.diff

patch to port wfs source select and provider to QgsNetworkAccessManager - Jürgen Fischer, 2010-07-24 01:02 PM

Download (24.2 KB)

View differences:

src/plugins/wfs/qgswfssourceselect.h (working copy)
23 23

  
24 24
class QgisInterface;
25 25
class QgsGenericProjectionSelector;
26
class QNetworkReply;
26 27

  
27 28
class QgsWFSSourceSelect: public QDialog, private Ui::QgsWFSSourceSelectBase
28 29
{
......
30 31

  
31 32
  public:
32 33

  
33
    enum REQUEST_ENCODING
34
    {
35
      GET,
36
      POST,
37
      SOAP /*Note that this goes also through HTTP POST but additionally uses soap envelope and friends*/
38
    };
39

  
40 34
    QgsWFSSourceSelect( QWidget* parent, QgisInterface* iface );
41 35
    ~QgsWFSSourceSelect();
42 36

  
......
50 44
    stores the CRS for the typename in the form 'EPSG:XXXX'*/
51 45
    std::map<QString, std::list<QString> > mAvailableCRS;
52 46
    QAbstractButton* btnAdd;
47
    QNetworkReply *mCapabilitiesReply;
48

  
53 49
    void populateConnectionList();
54 50

  
55 51
    /**Returns the best suited CRS from a set of authority ids
......
59 55
    @return the authority id of the crs or an empty string in case of error*/
60 56
    QString getPreferredCrs( const QSet<QString>& crsSet ) const;
61 57

  
62
    /**Makes a GetCapabilities and returns the typenamse and crs supported by the server.
63
       @param typenames a list of layers provided by the server
64
       @param crs a list of crs supported by the server. The place in the list corresponds to the
65
       typenames list (means that the crs list at position 0 is a crs for typename at position 0 etc.)
66
       @param title title list
67
       @param abstract textual descriptions for the types
68
       @return 0 in case of success*/
69
    int 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 );
70
    //encoding specific methods of getCapabilities
71
    int getCapabilitiesGET( QString uri, std::list<QString>& typenames, std::list< std::list<QString> >& crs, std::list<QString>& titles, std::list<QString>& abstracts );
72
    int getCapabilitiesPOST( const QString& uri, std::list<QString>& typenames, std::list< std::list<QString> >& crs, std::list<QString>& titles, std::list<QString>& abstracts );
73
    int getCapabilitiesSOAP( const QString& uri, std::list<QString>& typenames, std::list< std::list<QString> >& crs, std::list<QString>& titles, std::list<QString>& abstracts );
74

  
75 58
  private slots:
76 59
    void addEntryToServerList();
77 60
    void modifyEntryOfServerList();
......
81 64
    void changeCRS();
82 65
    void changeCRSFilter();
83 66
    void on_cmbConnections_activated( int index );
67
    void capabilitiesReplyFinished();
68
    void capabilitiesReplyProgress( qint64, qint64 );
84 69

  
85 70
    void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
86 71
};
src/plugins/wfs/qgswfssourceselect.cpp (working copy)
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 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
}
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 );
144 148

  
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";
149
      mCapabilitiesReply->deleteLater();
150
      mCapabilitiesReply = QgsNetworkAccessManager::instance()->get( request );
148 151

  
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
  }
152
      connect( mCapabilitiesReply, SIGNAL( finished() ), this, SLOT( capabilitiesReplyFinished() ) );
153
      connect( mCapabilitiesReply, SIGNAL( downloadProgress( qint64, qint64 ) ), this, SLOT( capabilitiesReplyProgress( qint64, qint64 ) ) );
154
      return;
155
    }
157 156

  
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
  }
157
    QByteArray buffer = mCapabilitiesReply->readAll();
166 158

  
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
  }
159
    QgsDebugMsg( "parsing capabilities: " + buffer );
177 160

  
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
185

  
186
    //Name
187
    QDomNodeList nameList = featureTypeElem.elementsByTagNameNS( WFS_NAMESPACE, "Name" );
188
    if ( nameList.length() > 0 )
161
    QString capabilitiesDocError;
162
    QDomDocument capabilitiesDocument;
163
    if ( capabilitiesDocument.setContent( buffer, true, &capabilitiesDocError ) )
189 164
    {
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 )
200
    {
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;
209 172

  
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
    }
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
216 180

  
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
    }
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
          }
223 204

  
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 )
227
    {
228
      featureCRSList.push_back( srsList.at( i ).toElement().text() );
229
    }
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
          }
230 211

  
231
    crs.push_back( featureCRSList );
232
    typenames.push_back( tname );
233
    titles.push_back( title );
234
    abstracts.push_back( abstract );
235
  }
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
          }
236 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
          }
237 225

  
238
  //print out result for a test
239
  QgsDebugMsg( result );
226
          crs.push_back( featureCRSList );
227
          typenames.push_back( tname );
228
          titles.push_back( title );
229
          abstracts.push_back( abstract );
230
        }
240 231

  
241
  return 0;
242
}
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
        }
243 245

  
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...
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
        }
258

  
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
280
    {
281
      QMessageBox::critical( 0, tr( "Capabilities document is not valid" ), capabilitiesDocError );
282
    }
283
  }
284
  else
285
  {
286
    QMessageBox::critical( 0, tr( "GetCapabilities Error" ), mCapabilitiesReply->errorString() );
287
  }
288

  
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 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 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
src/providers/wfs/qgswfsdata.cpp (working copy)
16 16
#include "qgsrectangle.h"
17 17
#include "qgscoordinatereferencesystem.h"
18 18
#include "qgsgeometry.h"
19
#include "qgshttptransaction.h"
20 19
#include "qgslogger.h"
20

  
21 21
#include <QBuffer>
22 22
#include <QUrl>
23 23
#include <QList>
......
103 103
    mHttp.setHost( requestUrl.host() );
104 104
  }
105 105

  
106
  QgsHttpTransaction::applyProxySettings( mHttp, mUri );
107

  
108 106
  //find out if there is a QGIS main window. If yes, display a progress dialog
109 107
  QProgressDialog* progressDialog = 0;
110 108
  QWidget* mainWindow = findMainWindow();
src/providers/wfs/qgswfsprovider.cpp (working copy)
15 15
 *                                                                         *
16 16
 ***************************************************************************/
17 17

  
18
#define WFS_THRESHOLD 200
19

  
18 20
#include "qgsapplication.h"
19 21
#include "qgsfeature.h"
20 22
#include "qgsfield.h"
21 23
#include "qgsgeometry.h"
22
#include "qgshttptransaction.h"
23 24
#include "qgscoordinatereferencesystem.h"
24 25
#include "qgswfsdata.h"
25 26
#include "qgswfsprovider.h"
26 27
#include "qgsspatialindex.h"
27 28
#include "qgslogger.h"
29
#include "qgsnetworkaccessmanager.h"
30

  
28 31
#include <QDomDocument>
29 32
#include <QDomNodeList>
33
#include <QNetworkRequest>
34
#include <QNetworkReply>
30 35
#include <QFile>
31 36
#include <QWidget>
32 37
#include <cfloat>
......
38 43
static const QString GML_NAMESPACE = "http://www.opengis.net/gml";
39 44

  
40 45
QgsWFSProvider::QgsWFSProvider( const QString& uri )
41
    : QgsVectorDataProvider( uri ), mUseIntersect( false ), mSourceCRS( 0 ), mFeatureCount( 0 ), mValid( true )
46
    : QgsVectorDataProvider( uri )
47
    , mReplyFinished( true )
48
    , mUseIntersect( false )
49
    , mSourceCRS( 0 )
50
    , mFeatureCount( 0 )
51
    , mValid( true )
42 52
{
43 53
  mSpatialIndex = new QgsSpatialIndex;
44 54
  if ( getFeature( uri ) == 0 )
......
110 120
  }
111 121
}
112 122

  
113

  
114

  
115 123
QGis::WkbType QgsWFSProvider::geometryType() const
116 124
{
117 125
  return mWKBType;
......
222 230
  {
223 231
    case QgsWFSProvider::GET:
224 232
      return describeFeatureTypeGET( uri, geometryAttribute, fields );
225
    case QgsWFSProvider::POST:
226
      return describeFeatureTypePOST( uri, geometryAttribute, fields );
227
    case QgsWFSProvider::SOAP:
228
      return describeFeatureTypeSOAP( uri, geometryAttribute, fields );
229 233
    case QgsWFSProvider::FILE:
230 234
      return describeFeatureTypeFile( uri, geometryAttribute, fields );
231 235
  }
......
234 238

  
235 239
int QgsWFSProvider::getFeatureGET( const QString& uri, const QString& geometryAttribute )
236 240
{
237
#if 0 //the old and slower method with DOM
238
  //assemble request string
239
  QString request = uri /*+ "&OUTPUTFORMAT=gml3"*/; //use gml2 as it is supported by most wfs servers
240
  QByteArray result;
241
  QgsHttpTransaction http( request );
242
  http.getSynchronously( result );
243

  
244
  QDomDocument getFeatureDocument;
245
  if ( !getFeatureDocument.setContent( result, true ) )
246
  {
247
    return 1; //error
248
  }
249

  
250
  QDomElement featureCollectionElement = getFeatureDocument.documentElement();
251

  
252
  //get and set Extent
253
  if ( getExtentFromGML2( &mExtent, featureCollectionElement ) != 0 )
254
  {
255
    return 3;
256
  }
257

  
258
  setCRSFromGML2( featureCollectionElement );
259

  
260
  if ( getFeaturesFromGML2( featureCollectionElement, geometryAttribute ) != 0 )
261
  {
262
    return 4;
263
  }
264

  
265
  return 0;
266
#endif
267

  
268 241
  //the new and faster method with the expat SAX parser
269 242

  
270 243
  //allows fast searchings with attribute name. Also needed is attribute Index and type infos
......
315 288
  return 0;
316 289
}
317 290

  
318
int QgsWFSProvider::getFeaturePOST( const QString& uri, const QString& geometryAttribute )
319
{
320
  return 1; //soon...
321
}
322

  
323
int QgsWFSProvider::getFeatureSOAP( const QString& uri, const QString& geometryAttribute )
324
{
325
  return 1; //soon...
326
}
327

  
328 291
int QgsWFSProvider::getFeatureFILE( const QString& uri, const QString& geometryAttribute )
329 292
{
330 293
  QFile gmlFile( uri );
......
362 325

  
363 326
int QgsWFSProvider::describeFeatureTypeGET( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
364 327
{
365
  QByteArray result;
366
  QgsHttpTransaction http( uri );
367
  if ( !http.getSynchronously( result ) )
328
  Q_ASSERT( mReplyFinished );
329
  mReplyFinished = false;
330

  
331
  QNetworkRequest request( uri );
332
  QNetworkReply *reply = QgsNetworkAccessManager::instance()->get( request );
333

  
334
  connect( reply, SIGNAL( finished() ), this, SLOT( featureTypeFinished() ) );
335

  
336
  while ( !mReplyFinished )
368 337
  {
369
    return 1;
338
    QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents, WFS_THRESHOLD );
370 339
  }
371
  QDomDocument describeFeatureDocument;
372 340

  
373
  if ( !describeFeatureDocument.setContent( result, true ) )
341
  QByteArray response = reply->readAll();
342

  
343
  reply->deleteLater();
344

  
345
  QgsDebugMsg( "feature type: " + response );
346

  
347
  QDomDocument describeFeatureDocument;
348
  if ( !describeFeatureDocument.setContent( response, true ) )
374 349
  {
375 350
    return 2;
376 351
  }
......
380 355
    return 3;
381 356
  }
382 357

  
358

  
383 359
  return 0;
384 360
}
385 361

  
386
int QgsWFSProvider::describeFeatureTypePOST( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
362
void QgsWFSProvider::featureTypeFinished()
387 363
{
388
  return 1; //soon...
364
  Q_ASSERT( !mReplyFinished );
365
  mReplyFinished = true;
389 366
}
390 367

  
391
int QgsWFSProvider::describeFeatureTypeSOAP( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
392
{
393
  return 1; //soon...
394
}
395 368

  
396 369
int QgsWFSProvider::describeFeatureTypeFile( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
397 370
{
src/providers/wfs/qgswfsprovider.h (working copy)
36 36
    enum REQUEST_ENCODING
37 37
    {
38 38
      GET,
39
      POST,
40
      SOAP,/*Note that this goes also through HTTP POST but additionally uses soap envelope and friends*/
41 39
      FILE  //reads from a file on disk
42 40
    };
43 41

  
......
99 97
     and emits the dataReadProgressMessage signal*/
100 98
    void handleWFSProgressMessage( int done, int total );
101 99

  
100
    void featureTypeFinished();
102 101

  
102
  private:
103
    bool mReplyFinished;
104

  
103 105
  protected:
104 106
    QgsFieldMap mFields;
105 107
    /**The encoding used for request/response. Can be GET, POST or SOAP*/
......
126 128
    /**Flag if provider is valid*/
127 129
    bool mValid;
128 130

  
129

  
130 131
    /**Collects information about the field types. Is called internally from QgsWFSProvider::getFeature. The method delegates the work to request specific ones and gives back the name of the geometry attribute and the thematic attributes with their types*/
131 132
    int describeFeatureType( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
132 133