diff --git a/src/core/qgsgml.cpp b/src/core/qgsgml.cpp index b0e4015de1ea..955675b3cc90 100644 --- a/src/core/qgsgml.cpp +++ b/src/core/qgsgml.cpp @@ -856,7 +856,7 @@ void QgsGmlStreamingParser::endElement( const XML_Char* el ) const int localNameLen = ( pszSep ) ? ( int )( elLen - nsLen ) - 1 : elLen; ParseMode theParseMode( mParseModeStack.isEmpty() ? none : mParseModeStack.top() ); - mDimension = mDimensionStack.isEmpty() ? 0 : mDimensionStack.top() ; + mDimension = mDimensionStack.isEmpty() ? 0 : mDimensionStack.pop() ; const bool isGMLNS = ( nsLen == mGMLNameSpaceURI.size() && mGMLNameSpaceURIPtr && memcmp( el, mGMLNameSpaceURIPtr, nsLen ) == 0 ); diff --git a/src/providers/wfs/qgswfsfeatureiterator.cpp b/src/providers/wfs/qgswfsfeatureiterator.cpp index 562ae4ec93a0..22b5c7ae4071 100644 --- a/src/providers/wfs/qgswfsfeatureiterator.cpp +++ b/src/providers/wfs/qgswfsfeatureiterator.cpp @@ -436,6 +436,7 @@ void QgsWFSFeatureDownloader::run( bool serializeFeatures, int maxFeatures ) int pagingIter = 1; QString gmlIdFirstFeatureFirstIter; bool disablePaging = false; + // Top level loop to do feature paging in WFS 2 while ( true ) { success = true; @@ -456,9 +457,14 @@ void QgsWFSFeatureDownloader::run( bool serializeFeatures, int maxFeatures ) false /* cache */ ); int featureCountForThisResponse = 0; + bool bytesStillAvailableInReply = false; + // Loop until there is no data coming from the current request while ( true ) { - loop.exec( QEventLoop::ExcludeUserInputEvents ); + if ( !bytesStillAvailableInReply ) + { + loop.exec( QEventLoop::ExcludeUserInputEvents ); + } if ( mStop ) { interrupted = true; @@ -475,7 +481,10 @@ void QgsWFSFeatureDownloader::run( bool serializeFeatures, int maxFeatures ) bool finished = false; if ( mReply ) { - data = mReply->readAll(); + // Limit the number of bytes to process at once, to avoid the GML parser to + // create too many objects. + data = mReply->read( 10 * 1024 * 1024 ); + bytesStillAvailableInReply = mReply->bytesAvailable() > 0; } else { diff --git a/src/providers/wfs/qgswfsrequest.cpp b/src/providers/wfs/qgswfsrequest.cpp index b725fbb8d9e0..0f7e66477cff 100644 --- a/src/providers/wfs/qgswfsrequest.cpp +++ b/src/providers/wfs/qgswfsrequest.cpp @@ -24,6 +24,8 @@ #include #include // just for testin file:// fake_qgis_http_endpoint hack +const qint64 READ_BUFFER_SIZE_HINT = 1024 * 1024; + QgsWFSRequest::QgsWFSRequest( const QString& theUri ) : mUri( theUri ) , mReply( nullptr ) @@ -116,6 +118,7 @@ bool QgsWFSRequest::sendGET( const QUrl& url, bool synchronous, bool forceRefres } mReply = QgsNetworkAccessManager::instance()->get( request ); + mReply->setReadBufferSize( READ_BUFFER_SIZE_HINT ); if ( !mUri.auth().setAuthorizationReply( mReply ) ) { mErrorCode = QgsWFSRequest::NetworkError; @@ -167,6 +170,7 @@ bool QgsWFSRequest::sendPOST( const QUrl& url, const QString& contentTypeHeader, request.setHeader( QNetworkRequest::ContentTypeHeader, contentTypeHeader ); mReply = QgsNetworkAccessManager::instance()->post( request, data ); + mReply->setReadBufferSize( READ_BUFFER_SIZE_HINT ); if ( !mUri.auth().setAuthorizationReply( mReply ) ) { mErrorCode = QgsWFSRequest::NetworkError; @@ -257,6 +261,7 @@ void QgsWFSRequest::replyFinished() QgsDebugMsg( QString( "redirected: %1 forceRefresh=%2" ).arg( redirect.toString() ).arg( mForceRefresh ) ); mReply = QgsNetworkAccessManager::instance()->get( request ); + mReply->setReadBufferSize( READ_BUFFER_SIZE_HINT ); if ( !mUri.auth().setAuthorizationReply( mReply ) ) { mResponse.clear();