[QGIS Commit] r14060 - in branches/threading-branch: python/core src/core src/core/raster src/providers/grass src/providers/wms

svn_qgis at osgeo.org svn_qgis at osgeo.org
Wed Aug 11 10:32:24 EDT 2010


Author: wonder
Date: 2010-08-11 14:32:24 +0000 (Wed, 11 Aug 2010)
New Revision: 14060

Modified:
   branches/threading-branch/python/core/qgsnetworkaccessmanager.sip
   branches/threading-branch/python/core/qgsrasterdataprovider.sip
   branches/threading-branch/src/core/qgsnetworkaccessmanager.cpp
   branches/threading-branch/src/core/qgsnetworkaccessmanager.h
   branches/threading-branch/src/core/qgsrasterdataprovider.h
   branches/threading-branch/src/core/raster/qgsrasterlayer.cpp
   branches/threading-branch/src/providers/grass/qgsgrassrasterprovider.cpp
   branches/threading-branch/src/providers/grass/qgsgrassrasterprovider.h
   branches/threading-branch/src/providers/wms/qgswmsprovider.cpp
   branches/threading-branch/src/providers/wms/qgswmsprovider.h
Log:
Updated WMS provider to work in threaded implementation


Modified: branches/threading-branch/python/core/qgsnetworkaccessmanager.sip
===================================================================
--- branches/threading-branch/python/core/qgsnetworkaccessmanager.sip	2010-08-11 12:23:32 UTC (rev 14059)
+++ branches/threading-branch/python/core/qgsnetworkaccessmanager.sip	2010-08-11 14:32:24 UTC (rev 14060)
@@ -28,6 +28,10 @@
     // and creates that instance on the first call.
     static QgsNetworkAccessManager *instance();
 
+    //! return a new instance of the access manager for use in a worker thread
+    //! the thread is responsible for deleting the object when finished with it
+    static QgsNetworkAccessManager *instanceForWorkerThread() /Factory/;
+
     //! destructor
     ~QgsNetworkAccessManager();
 

Modified: branches/threading-branch/python/core/qgsrasterdataprovider.sip
===================================================================
--- branches/threading-branch/python/core/qgsrasterdataprovider.sip	2010-08-11 12:23:32 UTC (rev 14059)
+++ branches/threading-branch/python/core/qgsrasterdataprovider.sip	2010-08-11 14:32:24 UTC (rev 14060)
@@ -57,7 +57,7 @@
     // TODO: Document this better.
     /** \brief   Renders the layer as an image
      */
-    virtual QImage* draw(const QgsRectangle & viewExtent, int pixelWidth, int pixelHeight) = 0;
+    virtual QImage* draw(QgsRenderContext& context, const QgsRectangle & viewExtent, int pixelWidth, int pixelHeight) = 0;
 
     /** Returns a bitmask containing the supported capabilities
         Note, some capabilities may change depending on whether

Modified: branches/threading-branch/src/core/qgsnetworkaccessmanager.cpp
===================================================================
--- branches/threading-branch/src/core/qgsnetworkaccessmanager.cpp	2010-08-11 12:23:32 UTC (rev 14059)
+++ branches/threading-branch/src/core/qgsnetworkaccessmanager.cpp	2010-08-11 14:32:24 UTC (rev 14060)
@@ -77,6 +77,12 @@
   return smNAM;
 }
 
+QgsNetworkAccessManager *QgsNetworkAccessManager::instanceForWorkerThread()
+{
+  return new QgsNetworkAccessManager();
+}
+
+
 QgsNetworkAccessManager::QgsNetworkAccessManager( QObject *parent )
     : QNetworkAccessManager( parent )
 {

Modified: branches/threading-branch/src/core/qgsnetworkaccessmanager.h
===================================================================
--- branches/threading-branch/src/core/qgsnetworkaccessmanager.h	2010-08-11 12:23:32 UTC (rev 14059)
+++ branches/threading-branch/src/core/qgsnetworkaccessmanager.h	2010-08-11 14:32:24 UTC (rev 14060)
@@ -50,6 +50,10 @@
     // and creates that instance on the first call.
     static QgsNetworkAccessManager *instance();
 
+    //! return a new instance of the access manager for use in a worker thread
+    //! the thread is responsible for deleting the object when finished with it
+    static QgsNetworkAccessManager *instanceForWorkerThread();
+
     //! destructor
     ~QgsNetworkAccessManager();
 

Modified: branches/threading-branch/src/core/qgsrasterdataprovider.h
===================================================================
--- branches/threading-branch/src/core/qgsrasterdataprovider.h	2010-08-11 12:23:32 UTC (rev 14059)
+++ branches/threading-branch/src/core/qgsrasterdataprovider.h	2010-08-11 14:32:24 UTC (rev 14060)
@@ -26,6 +26,7 @@
 
 class QImage;
 class QgsPoint;
+class QgsRenderContext;
 
 /** \ingroup core
  * Base class for raster data providers.
@@ -86,7 +87,7 @@
     // TODO: Document this better.
     /** \brief   Renders the layer as an image
      */
-    virtual QImage* draw( QgsRectangle  const & viewExtent, int pixelWidth, int pixelHeight ) = 0;
+    virtual QImage* draw( QgsRenderContext& context, QgsRectangle  const & viewExtent, int pixelWidth, int pixelHeight ) = 0;
 
     /** Returns a bitmask containing the supported capabilities
         Note, some capabilities may change depending on whether

Modified: branches/threading-branch/src/core/raster/qgsrasterlayer.cpp
===================================================================
--- branches/threading-branch/src/core/raster/qgsrasterlayer.cpp	2010-08-11 12:23:32 UTC (rev 14059)
+++ branches/threading-branch/src/core/raster/qgsrasterlayer.cpp	2010-08-11 14:32:24 UTC (rev 14060)
@@ -1634,7 +1634,7 @@
       QgsDebugMsg( "mapHeight: " + QString::number( rasterPartRect.height(), 'f', 8 ) );
       QgsDebugMsg( "mapUnitsPerPixel: " + QString::number( theQgsMapToPixel.mapUnitsPerPixel() ) );*/
 
-      QImage* image = mDataProvider->draw( rasterPartRect, pixelWidth, pixelHeight );
+      QImage* image = mDataProvider->draw( rendererContext, rasterPartRect, pixelWidth, pixelHeight );
 
       if ( !image )
       {

Modified: branches/threading-branch/src/providers/grass/qgsgrassrasterprovider.cpp
===================================================================
--- branches/threading-branch/src/providers/grass/qgsgrassrasterprovider.cpp	2010-08-11 12:23:32 UTC (rev 14059)
+++ branches/threading-branch/src/providers/grass/qgsgrassrasterprovider.cpp	2010-08-11 14:32:24 UTC (rev 14060)
@@ -81,7 +81,7 @@
   QgsDebugMsg( "QgsGrassRasterProvider: deconstructing." );
 }
 
-QImage* QgsGrassRasterProvider::draw( QgsRectangle  const & viewExtent, int pixelWidth, int pixelHeight )
+QImage* QgsGrassRasterProvider::draw( QgsRenderContext& context, QgsRectangle  const & viewExtent, int pixelWidth, int pixelHeight )
 {
   QgsDebugMsg( "pixelWidth = "  + QString::number( pixelWidth ) );
   QgsDebugMsg( "pixelHeight = "  + QString::number( pixelHeight ) );

Modified: branches/threading-branch/src/providers/grass/qgsgrassrasterprovider.h
===================================================================
--- branches/threading-branch/src/providers/grass/qgsgrassrasterprovider.h	2010-08-11 12:23:32 UTC (rev 14059)
+++ branches/threading-branch/src/providers/grass/qgsgrassrasterprovider.h	2010-08-11 14:32:24 UTC (rev 14060)
@@ -61,7 +61,7 @@
 
     /** \brief   Renders the layer as an image
      */
-    QImage* draw( QgsRectangle  const & viewExtent, int pixelWidth, int pixelHeight );
+    QImage* draw( QgsRenderContext& context, QgsRectangle  const & viewExtent, int pixelWidth, int pixelHeight );
 
     /** return a provider name
 

Modified: branches/threading-branch/src/providers/wms/qgswmsprovider.cpp
===================================================================
--- branches/threading-branch/src/providers/wms/qgswmsprovider.cpp	2010-08-11 12:23:32 UTC (rev 14059)
+++ branches/threading-branch/src/providers/wms/qgswmsprovider.cpp	2010-08-11 14:32:24 UTC (rev 14060)
@@ -21,7 +21,7 @@
 
 /* $Id$ */
 
-#define WMS_THRESHOLD 200  // time to wait for an answer without emitting dataChanged() 
+#define WMS_THRESHOLD 100  // time to wait for an answer without emitting dataChanged()
 
 #include "qgslogger.h"
 #include "qgswmsprovider.h"
@@ -32,6 +32,7 @@
 #include "qgsrectangle.h"
 #include "qgscoordinatereferencesystem.h"
 #include "qgsnetworkaccessmanager.h"
+#include "qgsrendercontext.h"
 
 #include <QNetworkRequest>
 #include <QNetworkReply>
@@ -363,7 +364,7 @@
   }
 }
 
-QImage *QgsWmsProvider::draw( QgsRectangle  const &viewExtent, int pixelWidth, int pixelHeight )
+QImage *QgsWmsProvider::draw( QgsRenderContext& context, QgsRectangle  const &viewExtent, int pixelWidth, int pixelHeight )
 {
   QgsDebugMsg( "Entering." );
 
@@ -383,14 +384,6 @@
     cachedImage = 0;
   }
 
-  // abort running (untiled) request
-  if ( cacheReply )
-  {
-    cacheReply->abort();
-    delete cacheReply;
-    cacheReply = 0;
-  }
-
   // Bounding box in WMS format
   QString bbox;
 
@@ -421,6 +414,8 @@
   cachedViewWidth = pixelWidth;
   cachedViewHeight = pixelHeight;
 
+  networkAccessManager = QgsNetworkAccessManager::instanceForWorkerThread();
+
   QSettings s;
   bool bkLayerCaching = s.value( "/qgis/enable_render_caching", false ).toBool(); // TODO: move this into render context
 
@@ -514,7 +509,7 @@
     QgsDebugMsg( QString( "getmap: %1" ).arg( url ) );
     QNetworkRequest request( url );
     request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
-    cacheReply = QgsNetworkAccessManager::instance()->get( request );
+    cacheReply = networkAccessManager->get( request );
     connect( cacheReply, SIGNAL( finished() ), this, SLOT( cacheReplyFinished() ) );
     connect( cacheReply, SIGNAL( downloadProgress( qint64, qint64 ) ), this, SLOT( cacheReplyProgress( qint64, qint64 ) ) );
 
@@ -523,12 +518,21 @@
     QTime t;
     t.start();
 
-    while ( cacheReply && ( !bkLayerCaching || t.elapsed() < WMS_THRESHOLD ) )
+    while ( cacheReply && !context.renderingStopped() /*&& ( !bkLayerCaching || t.elapsed() < WMS_THRESHOLD )*/ )
     {
       QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents, WMS_THRESHOLD );
     }
 
     mWaiting = false;
+
+    // abort running request if still running
+    if ( cacheReply )
+    {
+      cacheReply->abort();
+      cacheReply->deleteLater();
+      cacheReply = 0;
+    }
+
   }
   else
   {
@@ -637,7 +641,7 @@
         request.setAttribute( static_cast<QNetworkRequest::Attribute>( QNetworkRequest::User + 2 ), QRectF( x, y, mTileWidth * tres, mTileHeight * tres ) );
 
         QgsDebugMsg( QString( "gettile: %1" ).arg( turl ) );
-        QNetworkReply *reply = QgsNetworkAccessManager::instance()->get( request );
+        QNetworkReply *reply = networkAccessManager->get( request );
         tileReplies << reply;
         connect( reply, SIGNAL( finished() ), this, SLOT( tileReplyFinished() ) );
 
@@ -653,7 +657,7 @@
 
     // draw everything that is retrieved within a second
     // and the rest asynchronously
-    while ( !tileReplies.isEmpty() && ( !bkLayerCaching || t.elapsed() < WMS_THRESHOLD ) )
+    while ( !tileReplies.isEmpty() && !context.renderingStopped()  /*&& ( !bkLayerCaching || t.elapsed() < WMS_THRESHOLD )*/ )
     {
       QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents, WMS_THRESHOLD );
     }
@@ -669,6 +673,9 @@
 #endif
   }
 
+  delete networkAccessManager;
+  networkAccessManager = NULL;
+
   return cachedImage;
 }
 
@@ -711,7 +718,7 @@
       reply->deleteLater();
 
       QgsDebugMsg( QString( "redirected gettile: %1" ).arg( redirect.toString() ) );
-      reply = QgsNetworkAccessManager::instance()->get( request );
+      reply = networkAccessManager->get( request );
       tileReplies << reply;
 
       connect( reply, SIGNAL( finished() ), this, SLOT( tileReplyFinished() ) );
@@ -781,6 +788,13 @@
 
 void QgsWmsProvider::cacheReplyFinished()
 {
+  QgsDebugMsg( "entered." );
+  if ( cacheReply == 0 )
+  {
+    QgsDebugMsg( "cacheReply has been already deleted." );
+    return;
+  }
+
   if ( cacheReply->error() == QNetworkReply::NoError )
   {
     QVariant redirect = cacheReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
@@ -789,7 +803,7 @@
       cacheReply->deleteLater();
 
       QgsDebugMsg( QString( "redirected getmap: %1" ).arg( redirect.toString() ) );
-      cacheReply = QgsNetworkAccessManager::instance()->get( QNetworkRequest( redirect.toUrl() ) );
+      cacheReply = networkAccessManager->get( QNetworkRequest( redirect.toUrl() ) );
       connect( cacheReply, SIGNAL( finished() ), this, SLOT( cacheReplyFinished() ) );
       return;
     }

Modified: branches/threading-branch/src/providers/wms/qgswmsprovider.h
===================================================================
--- branches/threading-branch/src/providers/wms/qgswmsprovider.h	2010-08-11 12:23:32 UTC (rev 14059)
+++ branches/threading-branch/src/providers/wms/qgswmsprovider.h	2010-08-11 14:32:24 UTC (rev 14060)
@@ -457,7 +457,7 @@
      *  \warning A pointer to an QImage is used, as a plain QImage seems to have difficulty being
      *           shared across library boundaries
      */
-    QImage *draw( QgsRectangle const &  viewExtent, int pixelWidth, int pixelHeight );
+    QImage *draw( QgsRenderContext& context, QgsRectangle const &  viewExtent, int pixelWidth, int pixelHeight );
 
     /** Return the extent for this data layer
     */
@@ -926,6 +926,8 @@
 
     //! supported formats for GetFeatureInfo in order of preference
     QStringList mSupportedGetFeatureFormats;
+
+    QNetworkAccessManager* networkAccessManager;
 };
 
 #endif



More information about the QGIS-commit mailing list