mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Improved labeling engine interface, now connected with QgsMapRenderer instead of individual layers.
Also fixes #2108. git-svn-id: http://svn.osgeo.org/qgis/trunk@12174 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
ae722e7dca
commit
c1676d5137
@ -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 @@ class QgsMapRenderer : QObject
|
||||
//! 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);
|
||||
|
@ -32,6 +32,9 @@ class QgsRenderContext
|
||||
|
||||
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 @@ class QgsRenderContext
|
||||
void setRasterScaleFactor(double factor);
|
||||
void setRendererScale( double scale );
|
||||
void setPainter(QPainter* p);
|
||||
//! Added in QGIS v1.4
|
||||
void setLabelingEngine(QgsLabelingEngineInterface* iface);
|
||||
};
|
||||
|
@ -58,6 +58,8 @@ QgsMapRenderer::QgsMapRenderer()
|
||||
mDestCRS = new QgsCoordinateReferenceSystem( GEO_EPSG_CRS_ID, QgsCoordinateReferenceSystem::EpsgCrsId ); //WGS 84
|
||||
|
||||
mOutputUnits = QgsMapRenderer::Millimeters;
|
||||
|
||||
mLabelingEngine = NULL;
|
||||
}
|
||||
|
||||
QgsMapRenderer::~QgsMapRenderer()
|
||||
@ -65,6 +67,7 @@ QgsMapRenderer::~QgsMapRenderer()
|
||||
delete mScaleCalculator;
|
||||
delete mDistArea;
|
||||
delete mDestCRS;
|
||||
delete mLabelingEngine;
|
||||
}
|
||||
|
||||
|
||||
@ -282,6 +285,10 @@ void QgsMapRenderer::render( QPainter* painter )
|
||||
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 @@ void QgsMapRenderer::render( QPainter* painter )
|
||||
// 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 @@ bool QgsMapRenderer::writeXML( QDomNode & theNode, QDomDocument & theDoc )
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgsMapRenderer::setLabelingEngine(QgsLabelingEngineInterface* iface)
|
||||
{
|
||||
if (mLabelingEngine)
|
||||
delete mLabelingEngine;
|
||||
|
||||
mLabelingEngine = iface;
|
||||
}
|
||||
|
@ -34,6 +34,31 @@ class QgsScaleCalculator;
|
||||
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 @@ class CORE_EXPORT QgsMapRenderer : public QObject
|
||||
//! 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 @@ class CORE_EXPORT QgsMapRenderer : public QObject
|
||||
|
||||
//!Output units
|
||||
OutputUnits mOutputUnits;
|
||||
|
||||
//! Labeling engine (NULL by default)
|
||||
QgsLabelingEngineInterface* mLabelingEngine;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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 )
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -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 @@ class CORE_EXPORT QgsRenderContext
|
||||
|
||||
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 @@ class CORE_EXPORT QgsRenderContext
|
||||
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 @@ class CORE_EXPORT QgsRenderContext
|
||||
|
||||
/**Map scale*/
|
||||
double mRendererScale;
|
||||
|
||||
/**Labeling engine (can be NULL)*/
|
||||
QgsLabelingEngineInterface* mLabelingEngine;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -109,8 +109,7 @@ QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
|
||||
mVertexMarkerOnlyForSelection( false ),
|
||||
mFetching( false ),
|
||||
mRendererV2( NULL ),
|
||||
mUsingRendererV2( false ),
|
||||
mLabelingEngine( NULL )
|
||||
mUsingRendererV2( false )
|
||||
{
|
||||
mActions = new QgsAttributeAction;
|
||||
|
||||
@ -686,7 +685,7 @@ void QgsVectorLayer::drawRendererV2( QgsRenderContext& rendererContext, bool lab
|
||||
mRendererV2->renderFeature( fet, rendererContext );
|
||||
|
||||
if ( labeling )
|
||||
mLabelingEngine->registerFeature( this, fet );
|
||||
rendererContext.labelingEngine()->registerFeature( this, fet );
|
||||
}
|
||||
|
||||
mRendererV2->stopRender( rendererContext );
|
||||
@ -725,7 +724,7 @@ void QgsVectorLayer::drawRendererV2Levels( QgsRenderContext& rendererContext, bo
|
||||
features[sym].append( fet );
|
||||
|
||||
if ( labeling )
|
||||
mLabelingEngine->registerFeature( this, fet );
|
||||
rendererContext.labelingEngine()->registerFeature( this, fet );
|
||||
}
|
||||
|
||||
// find out the order
|
||||
@ -799,10 +798,10 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
|
||||
}
|
||||
|
||||
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 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
|
||||
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 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
|
||||
//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 @@ bool QgsVectorLayer::hasLabelsEnabled( void ) const
|
||||
return mLabelOn;
|
||||
}
|
||||
|
||||
void QgsVectorLayer::setLabelingEngine( QgsLabelingEngineInterface* engine )
|
||||
{
|
||||
mLabelingEngine = engine;
|
||||
}
|
||||
|
||||
|
||||
bool QgsVectorLayer::startEditing()
|
||||
{
|
||||
if ( !mDataProvider )
|
||||
|
@ -53,17 +53,6 @@ typedef QList<int> QgsAttributeList;
|
||||
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 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
/** 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 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
/** Label */
|
||||
QgsLabel *mLabel;
|
||||
|
||||
QgsLabelingEngineInterface* mLabelingEngine;
|
||||
|
||||
|
||||
/** Display labels */
|
||||
bool mLabelOn;
|
||||
|
||||
|
@ -126,27 +126,9 @@ void Labeling::initGui()
|
||||
|
||||
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
|
||||
@ -187,21 +169,6 @@ void Labeling::unload()
|
||||
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 @@ void Labeling::unload()
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,14 +58,9 @@ class Labeling: public QObject, public QgisPlugin
|
||||
//! 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
|
||||
|
@ -268,14 +268,13 @@ PalLabeling::PalLabeling( QgsMapRenderer* mapRenderer )
|
||||
|
||||
mShowingCandidates = FALSE;
|
||||
mShowingAllLabels = FALSE;
|
||||
|
||||
initPal();
|
||||
}
|
||||
|
||||
|
||||
PalLabeling::~PalLabeling()
|
||||
{
|
||||
delete mPal;
|
||||
// make sure we've freed everything
|
||||
exit();
|
||||
}
|
||||
|
||||
|
||||
@ -357,7 +356,7 @@ void PalLabeling::registerFeature( QgsVectorLayer* layer, QgsFeature& f )
|
||||
}
|
||||
|
||||
|
||||
void PalLabeling::initPal()
|
||||
void PalLabeling::init()
|
||||
{
|
||||
// delete if exists already
|
||||
if ( mPal )
|
||||
@ -383,6 +382,12 @@ void PalLabeling::initPal()
|
||||
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 @@ LayerSettings& PalLabeling::layer( const char* layerName )
|
||||
}
|
||||
|
||||
|
||||
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 @@ void PalLabeling::doLabeling( QPainter* painter, QgsRectangle extent )
|
||||
// labeling is done: clear the active layers hashtable
|
||||
mActiveLayers.clear();
|
||||
|
||||
// re-create PAL
|
||||
initPal();
|
||||
}
|
||||
|
||||
void PalLabeling::numCandidatePositions( int& candPoint, int& candLine, int& candPolygon )
|
||||
|
@ -104,8 +104,6 @@ class PalLabeling : public QgsLabelingEngineInterface
|
||||
|
||||
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 @@ class PalLabeling : public QgsLabelingEngineInterface
|
||||
|
||||
// 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 );
|
||||
|
Loading…
x
Reference in New Issue
Block a user