[QGIS Commit] r12174 - in trunk/qgis: python/core src/core src/plugins/labeling

svn_qgis at osgeo.org svn_qgis at osgeo.org
Wed Nov 18 13:46:14 EST 2009


Author: wonder
Date: 2009-11-18 13:46:12 -0500 (Wed, 18 Nov 2009)
New Revision: 12174

Modified:
   trunk/qgis/python/core/qgsmaprenderer.sip
   trunk/qgis/python/core/qgsrendercontext.sip
   trunk/qgis/src/core/qgsmaprenderer.cpp
   trunk/qgis/src/core/qgsmaprenderer.h
   trunk/qgis/src/core/qgsrendercontext.cpp
   trunk/qgis/src/core/qgsrendercontext.h
   trunk/qgis/src/core/qgsvectorlayer.cpp
   trunk/qgis/src/core/qgsvectorlayer.h
   trunk/qgis/src/plugins/labeling/labeling.cpp
   trunk/qgis/src/plugins/labeling/labeling.h
   trunk/qgis/src/plugins/labeling/pallabeling.cpp
   trunk/qgis/src/plugins/labeling/pallabeling.h
Log:
Improved labeling engine interface, now connected with QgsMapRenderer instead of individual layers.
Also fixes #2108.


Modified: trunk/qgis/python/core/qgsmaprenderer.sip
===================================================================
--- trunk/qgis/python/core/qgsmaprenderer.sip	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/python/core/qgsmaprenderer.sip	2009-11-18 18:46:12 UTC (rev 12174)
@@ -1,4 +1,31 @@
 
+
+/** Labeling engine interface.
+ * \note Added in QGIS v1.4
+ */
+class QgsLabelingEngineInterface
+{
+%TypeHeaderCode
+#include <qgsmaprenderer.h>
+%End
+
+public:
+  virtual ~QgsLabelingEngineInterface();
+
+  //! called when we're going to start with rendering
+  virtual void init() = 0;
+  //! called when starting rendering of a layer
+  virtual int prepareLayer(QgsVectorLayer* layer, int& attrIndex) = 0;
+  //! called for every feature
+  virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat ) = 0;
+  //! called when the map is drawn and labels should be placed
+  virtual void drawLabeling( QgsRenderContext& context ) = 0;
+  //! called when we're done with rendering
+  virtual void exit() = 0;
+
+};
+
+
 /**
  * \class QgsMapRenderer
  * \brief Class for rendering map layer set
@@ -114,6 +141,15 @@
     //! Accessor for render context
     QgsRenderContext* rendererContext();
 
+    //! Labeling engine (NULL if there's no custom engine)
+    //! \note Added in QGIS v1.4
+    QgsLabelingEngineInterface* labelingEngine();
+
+    //! Set labeling engine. Previous engine (if any) is deleted.
+    //! Takes ownership of the engine.
+    //! Added in QGIS v1.4
+    void setLabelingEngine(QgsLabelingEngineInterface* iface /Transfer/);
+
   signals:
     
     void drawingProgress(int current, int total);

Modified: trunk/qgis/python/core/qgsrendercontext.sip
===================================================================
--- trunk/qgis/python/core/qgsrendercontext.sip	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/python/core/qgsrendercontext.sip	2009-11-18 18:46:12 UTC (rev 12174)
@@ -32,6 +32,9 @@
 
   double rendererScale() const;
 
+  //! Added in QGIS v1.4
+  QgsLabelingEngineInterface* labelingEngine();
+
   //setters
 
   /**Sets coordinate transformation. QgsRenderContext takes ownership and deletes if necessary*/
@@ -44,4 +47,6 @@
   void setRasterScaleFactor(double factor);
   void setRendererScale( double scale );
   void setPainter(QPainter* p);
+  //! Added in QGIS v1.4
+  void setLabelingEngine(QgsLabelingEngineInterface* iface);
 };

Modified: trunk/qgis/src/core/qgsmaprenderer.cpp
===================================================================
--- trunk/qgis/src/core/qgsmaprenderer.cpp	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/src/core/qgsmaprenderer.cpp	2009-11-18 18:46:12 UTC (rev 12174)
@@ -58,6 +58,8 @@
   mDestCRS = new QgsCoordinateReferenceSystem( GEO_EPSG_CRS_ID, QgsCoordinateReferenceSystem::EpsgCrsId ); //WGS 84
 
   mOutputUnits = QgsMapRenderer::Millimeters;
+
+  mLabelingEngine = NULL;
 }
 
 QgsMapRenderer::~QgsMapRenderer()
@@ -65,6 +67,7 @@
   delete mScaleCalculator;
   delete mDistArea;
   delete mDestCRS;
+  delete mLabelingEngine;
 }
 
 
@@ -282,6 +285,10 @@
     mySameAsLastFlag = false;
   }
 
+  mRenderContext.setLabelingEngine(mLabelingEngine);
+  if ( mLabelingEngine )
+    mLabelingEngine->init();
+
   // know we know if this render is just a repeat of the last time, we 
   // can clear caches if it has changed
   if ( !mySameAsLastFlag )
@@ -572,6 +579,12 @@
   // make sure progress bar arrives at 100%!
   emit drawingProgress( 1, 1 );
 
+  if ( mLabelingEngine )
+  {
+    mLabelingEngine->drawLabeling( mRenderContext );
+    mLabelingEngine->exit();
+  }
+
   QgsDebugMsg( "Rendering completed in (seconds): " + QString( "%1" ).arg( renderTime.elapsed() / 1000.0 ) );
 
   mDrawing = false;
@@ -1041,3 +1054,11 @@
 
   return true;
 }
+
+void QgsMapRenderer::setLabelingEngine(QgsLabelingEngineInterface* iface)
+{
+  if (mLabelingEngine)
+    delete mLabelingEngine;
+
+  mLabelingEngine = iface;
+}

Modified: trunk/qgis/src/core/qgsmaprenderer.h
===================================================================
--- trunk/qgis/src/core/qgsmaprenderer.h	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/src/core/qgsmaprenderer.h	2009-11-18 18:46:12 UTC (rev 12174)
@@ -34,7 +34,32 @@
 class QgsCoordinateReferenceSystem;
 class QgsDistanceArea;
 class QgsOverlayObjectPositionManager;
+class QgsVectorLayer;
+class QgsFeature;
 
+/** Labeling engine interface.
+ * \note Added in QGIS v1.4
+ */
+class QgsLabelingEngineInterface
+{
+public:
+  virtual ~QgsLabelingEngineInterface() {}
+
+  //! called when we're going to start with rendering
+  virtual void init() = 0;
+  //! called when starting rendering of a layer
+  virtual int prepareLayer(QgsVectorLayer* layer, int& attrIndex) = 0;
+  //! called for every feature
+  virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat ) = 0;
+  //! called when the map is drawn and labels should be placed
+  virtual void drawLabeling( QgsRenderContext& context ) = 0;
+  //! called when we're done with rendering
+  virtual void exit() = 0;
+
+};
+
+
+
 /** \ingroup core
  * A non GUI class for rendering a map layer set onto a QPainter.
  */
@@ -146,6 +171,15 @@
     //! Accessor for render context
     QgsRenderContext* rendererContext() {return &mRenderContext;}
 
+    //! Labeling engine (NULL if there's no custom engine)
+    //! \note Added in QGIS v1.4
+    QgsLabelingEngineInterface* labelingEngine() { return mLabelingEngine; }
+
+    //! Set labeling engine. Previous engine (if any) is deleted.
+    //! Takes ownership of the engine.
+    //! Added in QGIS v1.4
+    void setLabelingEngine(QgsLabelingEngineInterface* iface);
+
   signals:
 
     void drawingProgress( int current, int total );
@@ -232,6 +266,9 @@
 
     //!Output units
     OutputUnits mOutputUnits;
+
+    //! Labeling engine (NULL by default)
+    QgsLabelingEngineInterface* mLabelingEngine;
 };
 
 #endif

Modified: trunk/qgis/src/core/qgsrendercontext.cpp
===================================================================
--- trunk/qgis/src/core/qgsrendercontext.cpp	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/src/core/qgsrendercontext.cpp	2009-11-18 18:46:12 UTC (rev 12174)
@@ -18,7 +18,15 @@
 
 #include "qgsrendercontext.h"
 
-QgsRenderContext::QgsRenderContext(): mPainter( 0 ), mCoordTransform( 0 ), mDrawEditingInformation( false ), mForceVectorOutput( true ), mRenderingStopped( false ), mScaleFactor( 1.0 ), mRasterScaleFactor( 1.0 )
+QgsRenderContext::QgsRenderContext()
+  : mPainter( 0 ),
+    mCoordTransform( 0 ),
+    mDrawEditingInformation( false ),
+    mForceVectorOutput( true ),
+    mRenderingStopped( false ),
+    mScaleFactor( 1.0 ),
+    mRasterScaleFactor( 1.0 ),
+    mLabelingEngine( NULL )
 {
 
 }

Modified: trunk/qgis/src/core/qgsrendercontext.h
===================================================================
--- trunk/qgis/src/core/qgsrendercontext.h	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/src/core/qgsrendercontext.h	2009-11-18 18:46:12 UTC (rev 12174)
@@ -24,6 +24,8 @@
 
 class QPainter;
 
+class QgsLabelingEngineInterface;
+
 /** \ingroup core
  * Contains information about the context of a rendering operation.
  * The context of a rendering operation defines properties such as
@@ -58,6 +60,9 @@
 
     double rendererScale() const {return mRendererScale;}
 
+    //! Added in QGIS v1.4
+    QgsLabelingEngineInterface* labelingEngine() const { return mLabelingEngine; }
+
     //setters
 
     /**Sets coordinate transformation. QgsRenderContext takes ownership and deletes if necessary*/
@@ -70,6 +75,8 @@
     void setRasterScaleFactor( double factor ) {mRasterScaleFactor = factor;}
     void setRendererScale( double scale ) {mRendererScale = scale;}
     void setPainter( QPainter* p ) {mPainter = p;}
+    //! Added in QGIS v1.4
+    void setLabelingEngine(QgsLabelingEngineInterface* iface) { mLabelingEngine = iface; }
 
   private:
 
@@ -100,6 +107,9 @@
 
     /**Map scale*/
     double mRendererScale;
+
+    /**Labeling engine (can be NULL)*/
+    QgsLabelingEngineInterface* mLabelingEngine;
 };
 
 #endif

Modified: trunk/qgis/src/core/qgsvectorlayer.cpp
===================================================================
--- trunk/qgis/src/core/qgsvectorlayer.cpp	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/src/core/qgsvectorlayer.cpp	2009-11-18 18:46:12 UTC (rev 12174)
@@ -109,8 +109,7 @@
     mVertexMarkerOnlyForSelection( false ),
     mFetching( false ),
     mRendererV2( NULL ),
-    mUsingRendererV2( false ),
-    mLabelingEngine( NULL )
+    mUsingRendererV2( false )
 {
   mActions = new QgsAttributeAction;
 
@@ -686,7 +685,7 @@
       mRendererV2->renderFeature( fet, rendererContext );
 
     if ( labeling )
-      mLabelingEngine->registerFeature( this, fet );
+      rendererContext.labelingEngine()->registerFeature( this, fet );
   }
 
   mRendererV2->stopRender( rendererContext );
@@ -725,7 +724,7 @@
     features[sym].append( fet );
 
     if ( labeling )
-      mLabelingEngine->registerFeature( this, fet );
+      rendererContext.labelingEngine()->registerFeature( this, fet );
   }
 
   // find out the order
@@ -799,10 +798,10 @@
     }
 
     bool labeling = FALSE;
-    if ( mLabelingEngine )
+    if ( rendererContext.labelingEngine() )
     {
       int attrIndex;
-      if ( mLabelingEngine->prepareLayer( this, attrIndex ) )
+      if ( rendererContext.labelingEngine()->prepareLayer( this, attrIndex ) )
       {
         if ( !attributes.contains( attrIndex ) )
           attributes << attrIndex;
@@ -859,10 +858,10 @@
     QgsAttributeList attributes = mRenderer->classificationAttributes();
 
     bool labeling = FALSE;
-    if ( mLabelingEngine )
+    if ( rendererContext.labelingEngine() )
     {
       int attrIndex;
-      if ( mLabelingEngine->prepareLayer( this, attrIndex ) )
+      if ( rendererContext.labelingEngine()->prepareLayer( this, attrIndex ) )
       {
         if ( !attributes.contains( attrIndex ) )
           attributes << attrIndex;
@@ -934,9 +933,9 @@
         //double scale = rendererContext.scaleFactor() /  markerScaleFactor;
         drawFeature( rendererContext, fet, &marker );
 
-        if ( labeling && mLabelingEngine )
+        if ( labeling )
         {
-          mLabelingEngine->registerFeature( this, fet );
+          rendererContext.labelingEngine()->registerFeature( this, fet );
         }
 
         ++featureCount;
@@ -2256,12 +2255,6 @@
   return mLabelOn;
 }
 
-void QgsVectorLayer::setLabelingEngine( QgsLabelingEngineInterface* engine )
-{
-  mLabelingEngine = engine;
-}
-
-
 bool QgsVectorLayer::startEditing()
 {
   if ( !mDataProvider )

Modified: trunk/qgis/src/core/qgsvectorlayer.h
===================================================================
--- trunk/qgis/src/core/qgsvectorlayer.h	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/src/core/qgsvectorlayer.h	2009-11-18 18:46:12 UTC (rev 12174)
@@ -53,18 +53,7 @@
 typedef QSet<int> QgsFeatureIds;
 typedef QSet<int> QgsAttributeIds;
 
-class QgsLabelingEngineInterface
-{
-  public:
-    virtual ~QgsLabelingEngineInterface() {}
-    virtual int prepareLayer( QgsVectorLayer* layer, int& attrIndex ) = 0;
-    virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat ) = 0;
-    //void calculateLabeling() = 0;
-    //void drawLabeling(QgsRenderContext& context) = 0;
-};
 
-
-
 /** \ingroup core
  * Vector layer backed by a data source provider.
  */
@@ -362,9 +351,6 @@
     /** Label is on */
     bool hasLabelsEnabled( void ) const;
 
-    /** Assign a custom labeling engine with layer. Added in v1.4 */
-    void setLabelingEngine( QgsLabelingEngineInterface* engine );
-
     /** Returns true if the provider is in editing mode */
     virtual bool isEditable() const;
 
@@ -747,9 +733,6 @@
     /** Label */
     QgsLabel *mLabel;
 
-    QgsLabelingEngineInterface* mLabelingEngine;
-
-
     /** Display labels */
     bool mLabelOn;
 

Modified: trunk/qgis/src/plugins/labeling/labeling.cpp
===================================================================
--- trunk/qgis/src/plugins/labeling/labeling.cpp	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/src/plugins/labeling/labeling.cpp	2009-11-18 18:46:12 UTC (rev 12174)
@@ -126,29 +126,11 @@
 
   mTool = new LabelingTool( mLBL, mQGisIface->mapCanvas() );
 
-  connect( mQGisIface->mapCanvas(), SIGNAL( renderComplete( QPainter * ) ), this, SLOT( doLabeling( QPainter * ) ) );
+  // map renderer takes ownership of the labeling engine
+  mQGisIface->mapCanvas()->mapRenderer()->setLabelingEngine( mLBL );
 
-  // connect to newly added layers so the labeling hook will be set up
-  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ), this, SLOT( layerWasAdded( QgsMapLayer* ) ) );
-
-  // add labeling hooks to all existing layers
-  QMap<QString, QgsMapLayer*>& layers = QgsMapLayerRegistry::instance()->mapLayers();
-  for ( QMap<QString, QgsMapLayer*>::iterator it = layers.begin(); it != layers.end(); ++it )
-  {
-    QgsMapLayer* layer = it.value();
-    if ( layer->type() == QgsMapLayer::VectorLayer )
-    {
-      QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( layer );
-      vlayer->setLabelingEngine( mLBL );
-    }
-  }
 }
 
-void Labeling::doLabeling( QPainter * painter )
-{
-  mLBL->doLabeling( painter, mQGisIface->mapCanvas()->extent() );
-}
-
 // Slot called when the menu item is triggered
 // If you created more menu items / toolbar buttons in initiGui, you should
 // create a separate handler for each action - this single run() method will
@@ -187,21 +169,6 @@
   mQGisIface->mapCanvas()->unsetMapTool( mTool );
   delete mTool;
 
-  // remove labeling hook from all layers!
-  QMap<QString, QgsMapLayer*>& layers = QgsMapLayerRegistry::instance()->mapLayers();
-  for ( QMap<QString, QgsMapLayer*>::iterator it = layers.begin(); it != layers.end(); ++it )
-  {
-    QgsMapLayer* layer = it.value();
-    if ( layer->type() == QgsMapLayer::VectorLayer )
-    {
-      QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( layer );
-      vlayer->setLabelingEngine( NULL );
-    }
-  }
-
-  disconnect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ), this, SLOT( layerWasAdded( QgsMapLayer* ) ) );
-  disconnect( mQGisIface->mapCanvas(), SIGNAL( renderComplete( QPainter * ) ), this, SLOT( doLabeling( QPainter * ) ) );
-
   // remove the GUI
   mQGisIface->removePluginMenu( "&Labeling", mQActionPointer );
   mQGisIface->removeToolBarIcon( mQActionPointer );
@@ -213,17 +180,8 @@
   delete mActionTool;
   */
 
-  delete mLBL;
-}
+  mQGisIface->mapCanvas()->mapRenderer()->setLabelingEngine( NULL );
 
-void Labeling::layerWasAdded( QgsMapLayer* layer )
-{
-  if ( layer->type() != QgsMapLayer::VectorLayer )
-    return; // not interested in rasters
-
-  QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( layer );
-  // add labeling hook for the newly added layer
-  vlayer->setLabelingEngine( mLBL );
 }
 
 

Modified: trunk/qgis/src/plugins/labeling/labeling.h
===================================================================
--- trunk/qgis/src/plugins/labeling/labeling.h	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/src/plugins/labeling/labeling.h	2009-11-18 18:46:12 UTC (rev 12174)
@@ -58,14 +58,9 @@
     //! unload the plugin
     void unload();
 
-    //! hook to renderComplete signal
-    void doLabeling( QPainter* painter );
-
     //! start labeling map tool
     void setTool();
 
-    void layerWasAdded( QgsMapLayer* theMapLayer );
-
   private:
 
     //! Pointer to the QGIS interface object

Modified: trunk/qgis/src/plugins/labeling/pallabeling.cpp
===================================================================
--- trunk/qgis/src/plugins/labeling/pallabeling.cpp	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/src/plugins/labeling/pallabeling.cpp	2009-11-18 18:46:12 UTC (rev 12174)
@@ -268,14 +268,13 @@
 
   mShowingCandidates = FALSE;
   mShowingAllLabels = FALSE;
-
-  initPal();
 }
 
 
 PalLabeling::~PalLabeling()
 {
-  delete mPal;
+  // make sure we've freed everything
+  exit();
 }
 
 
@@ -357,7 +356,7 @@
 }
 
 
-void PalLabeling::initPal()
+void PalLabeling::init()
 {
   // delete if exists already
   if ( mPal )
@@ -383,6 +382,12 @@
   mPal->setPolyP( mCandPolygon );
 }
 
+void PalLabeling::exit()
+{
+  delete mPal;
+  mPal = NULL;
+}
+
 LayerSettings& PalLabeling::layer( const char* layerName )
 {
   QHash<QgsVectorLayer*, LayerSettings>::iterator lit;
@@ -396,8 +401,10 @@
 }
 
 
-void PalLabeling::doLabeling( QPainter* painter, QgsRectangle extent )
+void PalLabeling::drawLabeling( QgsRenderContext& context )
 {
+  QPainter* painter = context.painter();
+  QgsRectangle extent = context.extent();
 
   QTime t;
   t.start();
@@ -478,8 +485,6 @@
   // labeling is done: clear the active layers hashtable
   mActiveLayers.clear();
 
-  // re-create PAL
-  initPal();
 }
 
 void PalLabeling::numCandidatePositions( int& candPoint, int& candLine, int& candPolygon )

Modified: trunk/qgis/src/plugins/labeling/pallabeling.h
===================================================================
--- trunk/qgis/src/plugins/labeling/pallabeling.h	2009-11-18 18:28:10 UTC (rev 12173)
+++ trunk/qgis/src/plugins/labeling/pallabeling.h	2009-11-18 18:46:12 UTC (rev 12174)
@@ -104,8 +104,6 @@
 
     LayerSettings& layer( const char* layerName );
 
-    void doLabeling( QPainter* painter, QgsRectangle extent );
-
     void numCandidatePositions( int& candPoint, int& candLine, int& candPolygon );
     void setNumCandidatePositions( int candPoint, int candLine, int candPolygon );
 
@@ -123,10 +121,16 @@
 
     // implemented methods from labeling engine interface
 
+    //! called when we're going to start with rendering
+    virtual void init();
     //! hook called when drawing layer before issuing select()
     virtual int prepareLayer( QgsVectorLayer* layer, int& attrIndex );
     //! hook called when drawing for every feature in a layer
     virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat );
+    //! called when the map is drawn and labels should be placed
+    virtual void drawLabeling( QgsRenderContext& context );
+    //! called when we're done with rendering
+    virtual void exit();
 
 
     void drawLabelCandidateRect( pal::LabelPosition* lp, QPainter* painter, const QgsMapToPixel* xform );



More information about the QGIS-commit mailing list