[QGIS Commit] r11291 - in branches/symbology-ng-branch/src: core
plugins/labeling
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Sat Aug 8 12:02:43 EDT 2009
Author: wonder
Date: 2009-08-08 12:02:41 -0400 (Sat, 08 Aug 2009)
New Revision: 11291
Modified:
branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp
branches/symbology-ng-branch/src/core/qgsvectorlayer.h
branches/symbology-ng-branch/src/plugins/labeling/labeling.cpp
branches/symbology-ng-branch/src/plugins/labeling/labeling.h
branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp
branches/symbology-ng-branch/src/plugins/labeling/labelinggui.h
branches/symbology-ng-branch/src/plugins/labeling/pallabeling.cpp
branches/symbology-ng-branch/src/plugins/labeling/pallabeling.h
Log:
Labeling hooks replaced with labeling engine interface (nicer solution).
Added loading/saving of labeling into the project files (using layer's custom properties)
Modified: branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp 2009-08-07 11:58:50 UTC (rev 11290)
+++ branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp 2009-08-08 16:02:41 UTC (rev 11291)
@@ -111,8 +111,7 @@
mActiveCommand( NULL ),
mRendererV2( NULL ),
mUsingRendererV2( false ),
- mLabelingPrepareLayerHook( NULL ),
- mLabelingRegisterFeatureHook( NULL )
+ mLabelingEngine( NULL )
{
mActions = new QgsAttributeAction;
@@ -687,7 +686,7 @@
mRendererV2->renderFeature(fet, rendererContext);
if ( labeling )
- mLabelingRegisterFeatureHook(fet, mLabelingLayerContext);
+ mLabelingEngine->registerFeature(this, fet);
}
mRendererV2->stopRender(rendererContext);
@@ -712,7 +711,7 @@
features[sym].append( fet );
if ( labeling )
- mLabelingRegisterFeatureHook(fet, mLabelingLayerContext);
+ mLabelingEngine->registerFeature(this, fet);
}
// find out the order
@@ -773,10 +772,10 @@
QgsDebugMsg("attrs: " + QString::number(attributes[0]));
bool labeling = FALSE;
- if ( mLabelingPrepareLayerHook && mLabelingRegisterFeatureHook )
+ if ( mLabelingEngine )
{
int attrIndex;
- if (mLabelingPrepareLayerHook(mLabelingContext, mLabelingLayerContext, attrIndex))
+ if (mLabelingEngine->prepareLayer(this, attrIndex))
{
if (!attributes.contains(attrIndex))
attributes << attrIndex;
@@ -831,10 +830,10 @@
QgsAttributeList attributes = mRenderer->classificationAttributes();
bool labeling = FALSE;
- if (mLabelingPrepareLayerHook)
+ if (mLabelingEngine)
{
int attrIndex;
- if (mLabelingPrepareLayerHook(mLabelingContext, mLabelingLayerContext, attrIndex))
+ if (mLabelingEngine->prepareLayer(this, attrIndex))
{
if (!attributes.contains(attrIndex))
attributes << attrIndex;
@@ -911,9 +910,9 @@
rendererContext.rasterScaleFactor(),
rendererContext.drawEditingInformation() );
- if (labeling && mLabelingRegisterFeatureHook)
+ if (labeling && mLabelingEngine)
{
- mLabelingRegisterFeatureHook(fet, mLabelingLayerContext);
+ mLabelingEngine->registerFeature(this, fet);
}
++featureCount;
@@ -2229,15 +2228,9 @@
return mLabelOn;
}
-void QgsVectorLayer::setLabelingHooks(LabelingPrepareLayerHook prepareLayerHook,
- LabelingRegisterFeatureHook registerFeatureHook,
- void* context,
- void* layerContext)
+void QgsVectorLayer::setLabelingEngine(QgsLabelingEngineInterface* engine)
{
- mLabelingPrepareLayerHook = prepareLayerHook;
- mLabelingRegisterFeatureHook = registerFeatureHook;
- mLabelingContext = context;
- mLabelingLayerContext = layerContext;
+ mLabelingEngine = engine;
}
Modified: branches/symbology-ng-branch/src/core/qgsvectorlayer.h
===================================================================
--- branches/symbology-ng-branch/src/core/qgsvectorlayer.h 2009-08-07 11:58:50 UTC (rev 11290)
+++ branches/symbology-ng-branch/src/core/qgsvectorlayer.h 2009-08-08 16:02:41 UTC (rev 11291)
@@ -53,10 +53,18 @@
typedef QSet<int> QgsFeatureIds;
typedef QSet<int> QgsAttributeIds;
-typedef int (*LabelingPrepareLayerHook)(void*, void*, int&);
-typedef void (*LabelingRegisterFeatureHook)(QgsFeature&, void*);
+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.
*/
@@ -348,10 +356,7 @@
/** Label is on */
bool hasLabelsEnabled( void ) const;
- void setLabelingHooks(LabelingPrepareLayerHook prepareLayerHook,
- LabelingRegisterFeatureHook registerFeatureHook,
- void* mLabelingContext,
- void* mLabelingLayerContext);
+ void setLabelingEngine(QgsLabelingEngineInterface* engine);
/** Returns true if the provider is in editing mode */
virtual bool isEditable() const;
@@ -733,10 +738,7 @@
/** Label */
QgsLabel *mLabel;
- LabelingPrepareLayerHook mLabelingPrepareLayerHook;
- LabelingRegisterFeatureHook mLabelingRegisterFeatureHook;
- void* mLabelingContext;
- void* mLabelingLayerContext;
+ QgsLabelingEngineInterface* mLabelingEngine;
/** Display labels */
Modified: branches/symbology-ng-branch/src/plugins/labeling/labeling.cpp
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/labeling.cpp 2009-08-07 11:58:50 UTC (rev 11290)
+++ branches/symbology-ng-branch/src/plugins/labeling/labeling.cpp 2009-08-08 16:02:41 UTC (rev 11291)
@@ -23,6 +23,7 @@
#include <qgisgui.h>
#include <qgsmapcanvas.h>
#include <qgsvectorlayer.h>
+#include <qgsmaplayerregistry.h>
#include "labeling.h"
#include "labelinggui.h"
@@ -124,6 +125,20 @@
connect( mQGisIface->mapCanvas(), SIGNAL( renderComplete( QPainter * ) ), this, SLOT( doLabeling( QPainter * ) ) );
+ // 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 )
@@ -143,15 +158,14 @@
QMessageBox::warning(mQGisIface->mainWindow(), "Labeling", "Please select a vector layer first.");
return;
}
- //QgsVectorLayer* vlayer = static_cast<QgsVectorLayer*>(layer);
+ QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>(layer);
- LabelingGui myPluginGui( mLBL, layer->getLayerID(), mQGisIface->mainWindow() );
+ LabelingGui myPluginGui( mLBL, vlayer, mQGisIface->mainWindow() );
if (myPluginGui.exec())
{
- // alter labeling
- mLBL->removeLayer(layer->getLayerID());
- mLBL->addLayer( myPluginGui.layerSettings() );
+ // alter labeling - save the changes
+ myPluginGui.layerSettings().writeToLayer(vlayer);
// trigger refresh
mQGisIface->mapCanvas()->refresh();
@@ -170,6 +184,21 @@
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 );
@@ -181,7 +210,17 @@
delete mLBL;
}
+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: branches/symbology-ng-branch/src/plugins/labeling/labeling.h
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/labeling.h 2009-08-07 11:58:50 UTC (rev 11290)
+++ branches/symbology-ng-branch/src/plugins/labeling/labeling.h 2009-08-08 16:02:41 UTC (rev 11291)
@@ -24,6 +24,8 @@
//QGIS includes
#include "../qgisplugin.h"
+#include "qgsmaplayer.h" // for MOC
+
//forward declarations
class QAction;
class QPainter;
@@ -62,6 +64,8 @@
//! start labeling map tool
void setTool();
+ void layerWasAdded( QgsMapLayer* theMapLayer );
+
private:
//! Pointer to the QGIS interface object
Modified: branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp 2009-08-07 11:58:50 UTC (rev 11290)
+++ branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp 2009-08-08 16:02:41 UTC (rev 11291)
@@ -32,8 +32,8 @@
-LabelingGui::LabelingGui( PalLabeling* lbl, QString layerId, QWidget* parent )
- : QDialog( parent ), mLBL( lbl ), mLayerId( layerId )
+LabelingGui::LabelingGui( PalLabeling* lbl, QgsVectorLayer* layer, QWidget* parent )
+ : QDialog( parent ), mLBL( lbl ), mLayer( layer )
{
setupUi( this );
@@ -45,7 +45,7 @@
connect(btnEngineSettings, SIGNAL(clicked()), this, SLOT(showEngineConfigDialog()) );
// set placement methods page based on geometry type
- switch (layer()->geometryType())
+ switch (layer->geometryType())
{
case QGis::Point:
stackedPlacement->setCurrentWidget(pagePoint);
@@ -62,77 +62,69 @@
populateFieldNames();
- const LayerSettings& lyr = lbl->layer(layerId);
- if (!lyr.layerId.isEmpty())
+ // load labeling settings from layer
+ LayerSettings lyr;
+ lyr.readFromLayer(layer);
+
+ // placement
+ switch (lyr.placement)
{
- // load the labeling settings
+ case LayerSettings::AroundPoint:
+ radAroundPoint->setChecked(true);
+ radAroundCentroid->setChecked(true);
+ spinDistPoint->setValue(lyr.dist);
+ //spinAngle->setValue(lyr.angle);
+ break;
+ case LayerSettings::OverPoint:
+ radOverPoint->setChecked(true);
+ radOverCentroid->setChecked(true);
+ break;
+ case LayerSettings::Line:
+ radLineParallel->setChecked(true);
+ radPolygonPerimeter->setChecked(true);
- // placement
- switch (lyr.placement)
- {
- case LayerSettings::AroundPoint:
- radAroundPoint->setChecked(true);
- radAroundCentroid->setChecked(true);
- spinDistPoint->setValue(lyr.dist);
- //spinAngle->setValue(lyr.angle);
- break;
- case LayerSettings::OverPoint:
- radOverPoint->setChecked(true);
- radOverCentroid->setChecked(true);
- break;
- case LayerSettings::Line:
- radLineParallel->setChecked(true);
- radPolygonPerimeter->setChecked(true);
+ spinDistLine->setValue(lyr.dist);
+ chkLineAbove->setChecked( lyr.placementFlags & LayerSettings::AboveLine );
+ chkLineBelow->setChecked( lyr.placementFlags & LayerSettings::BelowLine );
+ chkLineOn->setChecked( lyr.placementFlags & LayerSettings::OnLine );
+ if ( lyr.placementFlags & LayerSettings::MapOrientation )
+ radOrientationMap->setChecked(true);
+ else
+ radOrientationLine->setChecked(true);
+ break;
+ case LayerSettings::Curved:
+ radLineCurved->setChecked(true);
+ break;
+ case LayerSettings::Horizontal:
+ radPolygonHorizontal->setChecked(true);
+ radLineHorizontal->setChecked(true);
+ break;
+ case LayerSettings::Free:
+ radPolygonFree->setChecked(true);
+ break;
+ default:
+ Q_ASSERT(0 && "NOOO!");
+ }
- spinDistLine->setValue(lyr.dist);
- chkLineAbove->setChecked( lyr.placementFlags & LayerSettings::AboveLine );
- chkLineBelow->setChecked( lyr.placementFlags & LayerSettings::BelowLine );
- chkLineOn->setChecked( lyr.placementFlags & LayerSettings::OnLine );
- if ( lyr.placementFlags & LayerSettings::MapOrientation )
- radOrientationMap->setChecked(true);
- else
- radOrientationLine->setChecked(true);
- break;
- case LayerSettings::Curved:
- radLineCurved->setChecked(true);
- break;
- case LayerSettings::Horizontal:
- radPolygonHorizontal->setChecked(true);
- radLineHorizontal->setChecked(true);
- break;
- case LayerSettings::Free:
- radPolygonFree->setChecked(true);
- break;
- default:
- Q_ASSERT(0 && "NOOO!");
- }
+ cboFieldName->setCurrentIndex( cboFieldName->findText(lyr.fieldName) );
+ chkEnableLabeling->setChecked( lyr.enabled );
+ sliderPriority->setValue( lyr.priority );
+ chkNoObstacle->setChecked( !lyr.obstacle );
+ chkLabelPerFeaturePart->setChecked( lyr.labelPerPart );
- cboFieldName->setCurrentIndex( cboFieldName->findText(lyr.fieldName) );
- chkEnableLabeling->setChecked( lyr.enabled );
- sliderPriority->setValue( lyr.priority );
- chkNoObstacle->setChecked( !lyr.obstacle );
- chkLabelPerFeaturePart->setChecked( lyr.labelPerPart );
-
- bool scaleBased = (lyr.scaleMin != 0 && lyr.scaleMax != 0);
- chkScaleBasedVisibility->setChecked(scaleBased);
- if (scaleBased)
- {
- spinScaleMin->setValue(lyr.scaleMin);
- spinScaleMax->setValue(lyr.scaleMax);
- }
-
- bool buffer = (lyr.bufferSize != 0);
- chkBuffer->setChecked(buffer);
- if (buffer)
- spinBufferSize->setValue(lyr.bufferSize);
- }
- else
+ bool scaleBased = (lyr.scaleMin != 0 && lyr.scaleMax != 0);
+ chkScaleBasedVisibility->setChecked(scaleBased);
+ if (scaleBased)
{
- // set enabled by default
- chkEnableLabeling->setChecked( true );
-
+ spinScaleMin->setValue(lyr.scaleMin);
+ spinScaleMax->setValue(lyr.scaleMax);
}
+ bool buffer = (lyr.bufferSize != 0);
+ chkBuffer->setChecked(buffer);
+ if (buffer)
+ spinBufferSize->setValue(lyr.bufferSize);
+
btnTextColor->setColor( lyr.textColor );
btnBufferColor->setColor( lyr.bufferColor );
updateFont( lyr.textFont );
@@ -157,18 +149,9 @@
{
}
-QgsVectorLayer* LabelingGui::layer()
-{
- QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer(mLayerId);
- if (layer == NULL || layer->type() != QgsMapLayer::VectorLayer)
- return NULL;
- return static_cast<QgsVectorLayer*>(layer);
-}
-
LayerSettings LabelingGui::layerSettings()
{
LayerSettings lyr;
- lyr.layerId = mLayerId;
lyr.fieldName = cboFieldName->currentText();
lyr.dist = 0;
@@ -249,7 +232,7 @@
void LabelingGui::populateFieldNames()
{
- QgsFieldMap fields = layer()->dataProvider()->fields();
+ QgsFieldMap fields = mLayer->dataProvider()->fields();
for (QgsFieldMap::iterator it = fields.begin(); it != fields.end(); it++)
{
cboFieldName->addItem(it->name());
Modified: branches/symbology-ng-branch/src/plugins/labeling/labelinggui.h
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/labelinggui.h 2009-08-07 11:58:50 UTC (rev 11290)
+++ branches/symbology-ng-branch/src/plugins/labeling/labelinggui.h 2009-08-08 16:02:41 UTC (rev 11291)
@@ -21,9 +21,7 @@
#include <QDialog>
#include <ui_labelingguibase.h>
-//class PalLabeling;
class QgsVectorLayer;
-//struct PalLabeling::LayerSettings;
#include "pallabeling.h"
@@ -32,7 +30,7 @@
Q_OBJECT
public:
- LabelingGui( PalLabeling* lbl, QString layerId, QWidget* parent );
+ LabelingGui( PalLabeling* lbl, QgsVectorLayer* layer, QWidget* parent );
~LabelingGui();
LayerSettings layerSettings();
@@ -52,11 +50,9 @@
void populateFieldNames();
void updateFont(QFont font);
- QgsVectorLayer* layer();
-
private:
PalLabeling* mLBL;
- QString mLayerId;
+ QgsVectorLayer* mLayer;
};
#endif
Modified: branches/symbology-ng-branch/src/plugins/labeling/pallabeling.cpp
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/pallabeling.cpp 2009-08-07 11:58:50 UTC (rev 11290)
+++ branches/symbology-ng-branch/src/plugins/labeling/pallabeling.cpp 2009-08-08 16:02:41 UTC (rev 11291)
@@ -89,13 +89,24 @@
LayerSettings::LayerSettings()
: palLayer(NULL), fontMetrics(NULL), ct(NULL)
{
+ placement = AroundPoint;
+ placementFlags = 0;
+ //textFont = QFont();
+ textColor = Qt::black;
+ enabled = false;
+ priority = 5;
+ obstacle = true;
+ dist = 0;
+ scaleMin = 0;
+ scaleMax = 0;
+ bufferSize = 1;
bufferColor = Qt::white;
+ labelPerPart = false;
}
LayerSettings::LayerSettings(const LayerSettings& s)
{
// copy only permanent stuff
- layerId = s.layerId;
fieldName = s.fieldName;
placement = s.placement;
placementFlags = s.placementFlags;
@@ -124,6 +135,72 @@
delete ct;
}
+static QColor _readColor(QgsVectorLayer* layer, QString property)
+{
+ int r = layer->customProperty(property+"R").toInt();
+ int g = layer->customProperty(property+"G").toInt();
+ int b = layer->customProperty(property+"B").toInt();
+ return QColor(r,g,b);
+}
+
+static void _writeColor(QgsVectorLayer* layer, QString property, QColor color)
+{
+ layer->setCustomProperty(property+"R", color.red());
+ layer->setCustomProperty(property+"G", color.green());
+ layer->setCustomProperty(property+"B", color.blue());
+}
+
+void LayerSettings::readFromLayer(QgsVectorLayer* layer)
+{
+ if (layer->customProperty("labeling").toString() != QString("pal"))
+ return; // there's no information available
+
+ fieldName = layer->customProperty("labeling/fieldName").toString();
+ placement = (Placement) layer->customProperty("labeling/placement").toInt();
+ placementFlags = layer->customProperty("labeling/placementFlags").toUInt();
+ QString fontFamily = layer->customProperty("labeling/fontFamily").toString();
+ int fontSize = layer->customProperty("labeling/fontSize").toInt();
+ int fontWeight = layer->customProperty("labeling/fontWeight").toInt();
+ bool fontItalic = layer->customProperty("labeling/fontItalic").toBool();
+ textFont = QFont(fontFamily, fontSize, fontWeight, fontItalic);
+ textColor = _readColor(layer, "labeling/textColor");
+ enabled = layer->customProperty("labeling/enabled").toBool();
+ priority = layer->customProperty("labeling/priority").toInt();
+ obstacle = layer->customProperty("labeling/obstacle").toBool();
+ dist = layer->customProperty("labeling/dist").toDouble();
+ scaleMin = layer->customProperty("labeling/scaleMin").toInt();
+ scaleMax = layer->customProperty("labeling/scaleMax").toInt();
+ bufferSize = layer->customProperty("labeling/bufferSize").toInt();
+ bufferColor = _readColor(layer, "labeling/bufferColor");
+ labelPerPart = layer->customProperty("labeling/labelPerPart").toInt();
+}
+
+void LayerSettings::writeToLayer(QgsVectorLayer* layer)
+{
+ // this is a mark that labeling information is present
+ layer->setCustomProperty("labeling", "pal");
+
+ layer->setCustomProperty("labeling/fieldName", fieldName);
+ layer->setCustomProperty("labeling/placement", placement);
+ layer->setCustomProperty("labeling/placementFlags", (unsigned int)placementFlags);
+
+ layer->setCustomProperty("labeling/fontFamily", textFont.family());
+ layer->setCustomProperty("labeling/fontSize", textFont.pointSize());
+ layer->setCustomProperty("labeling/fontWeight", textFont.weight());
+ layer->setCustomProperty("labeling/fontItalic", textFont.italic());
+
+ _writeColor(layer, "labeling/textColor", textColor);
+ layer->setCustomProperty("labeling/enabled", enabled);
+ layer->setCustomProperty("labeling/priority", priority);
+ layer->setCustomProperty("labeling/obstacle", obstacle);
+ layer->setCustomProperty("labeling/dist", dist);
+ layer->setCustomProperty("labeling/scaleMin", scaleMin);
+ layer->setCustomProperty("labeling/scaleMax", scaleMax);
+ layer->setCustomProperty("labeling/bufferSize", bufferSize);
+ _writeColor(layer, "labeling/bufferColor", bufferColor);
+ layer->setCustomProperty("labeling/labelPerPart", labelPerPart);
+}
+
void LayerSettings::calculateLabelSize(QString text, double& labelX, double& labelY)
{
//QFontMetrics fontMetrics(textFont);
@@ -195,76 +272,32 @@
PalLabeling::~PalLabeling()
{
delete mPal;
-
- // make sure to remove hooks from all layers
- while (mLayers.count())
- {
- removeLayer(mLayers[0].layerId);
- }
}
-void PalLabeling::addLayer(LayerSettings layerSettings)
+int PalLabeling::prepareLayer(QgsVectorLayer* layer, int& attrIndex)
{
- mLayers.append(layerSettings);
+ // start with a temporary settings class, find out labeling info
+ LayerSettings lyrTmp;
+ lyrTmp.readFromLayer(layer);
- QgsVectorLayer* vlayer = (QgsVectorLayer*) QgsMapLayerRegistry::instance()->mapLayer(layerSettings.layerId);
-
- LayerSettings& lyr = mLayers[ mLayers.count()-1 ]; // make sure we have the right pointer
- vlayer->setLabelingHooks(PalLabeling::prepareLayerHook, PalLabeling::registerFeatureHook, this, &lyr);
-}
-
-void PalLabeling::removeLayer(QString layerId)
-{
- for (int i = 0; i < mLayers.count(); i++)
- {
- if (mLayers.at(i).layerId == layerId)
- {
- QgsVectorLayer* vlayer = (QgsVectorLayer*) QgsMapLayerRegistry::instance()->mapLayer(mLayers.at(i).layerId);
- if (vlayer) { vlayer->setLabelingHooks(NULL, NULL, NULL, NULL); }
-
- mLayers.removeAt(i);
- return;
- }
- }
-}
-
-const LayerSettings& PalLabeling::layer(QString layerId)
-{
- for (int i = 0; i < mLayers.count(); i++)
- {
- if (mLayers.at(i).layerId == layerId)
- {
- return mLayers.at(i);
- }
- }
- return mInvalidLayer;
-}
-
-
-
-int PalLabeling::prepareLayerHook(void* context, void* layerContext, int& attrIndex)
-{
- PalLabeling* thisClass = (PalLabeling*) context;
- LayerSettings* lyr = (LayerSettings*) layerContext;
-
- if (!lyr->enabled)
+ if (!lyrTmp.enabled)
return 0;
- QgsVectorLayer* vlayer = (QgsVectorLayer*) QgsMapLayerRegistry::instance()->mapLayer(lyr->layerId);
- if (vlayer == NULL)
- return 0;
-
// find out which field will be needed
- int fldIndex = vlayer->dataProvider()->fieldNameIndex(lyr->fieldName);
+ int fldIndex = layer->dataProvider()->fieldNameIndex(lyrTmp.fieldName);
if (fldIndex == -1)
return 0;
attrIndex = fldIndex;
+ // add layer settings to the pallabeling hashtable: <QgsVectorLayer*, LayerSettings>
+ mActiveLayers.insert(layer, lyrTmp);
+ // start using the reference to the layer in hashtable instead of local instance
+ LayerSettings& lyr = mActiveLayers[layer];
// how to place the labels
Arrangement arrangement;
- switch (lyr->placement)
+ switch (lyr.placement)
{
case LayerSettings::AroundPoint: arrangement = P_POINT; break;
case LayerSettings::OverPoint: arrangement = P_POINT_OVER; break;
@@ -275,42 +308,44 @@
}
// create the pal layer
- double priority = 1 - lyr->priority/10.0; // convert 0..10 --> 1..0
+ double priority = 1 - lyr.priority/10.0; // convert 0..10 --> 1..0
double min_scale = -1, max_scale = -1;
- if (lyr->scaleMin != 0 && lyr->scaleMax != 0)
+ if (lyr.scaleMin != 0 && lyr.scaleMax != 0)
{
- min_scale = lyr->scaleMin;
- max_scale = lyr->scaleMax;
+ min_scale = lyr.scaleMin;
+ max_scale = lyr.scaleMax;
}
- Layer* l = thisClass->mPal->addLayer(lyr->layerId.toLocal8Bit().data(), min_scale, max_scale, arrangement, METER, priority, lyr->obstacle, true, true);
+ Layer* l = mPal->addLayer(layer->getLayerID().toLocal8Bit().data(),
+ min_scale, max_scale, arrangement,
+ METER, priority, lyr.obstacle, true, true);
- if ( lyr->placementFlags )
- l->setArrangementFlags( lyr->placementFlags );
+ if ( lyr.placementFlags )
+ l->setArrangementFlags( lyr.placementFlags );
// set label mode (label per feature is the default)
- l->setLabelMode( lyr->labelPerPart ? Layer::LabelPerFeaturePart : Layer::LabelPerFeature );
+ l->setLabelMode( lyr.labelPerPart ? Layer::LabelPerFeaturePart : Layer::LabelPerFeature );
// save the pal layer to our layer context (with some additional info)
- lyr->palLayer = l;
- lyr->fieldIndex = fldIndex;
- lyr->fontMetrics = new QFontMetrics(lyr->textFont);
- lyr->fontBaseline = lyr->fontMetrics->boundingRect("X").bottom(); // dummy text to find out how many pixels of the text are below the baseline
- lyr->xform = thisClass->mMapRenderer->coordinateTransform();
- if (thisClass->mMapRenderer->hasCrsTransformEnabled())
- lyr->ct = new QgsCoordinateTransform( vlayer->srs(), thisClass->mMapRenderer->destinationSrs() );
+ lyr.palLayer = l;
+ lyr.fieldIndex = fldIndex;
+ lyr.fontMetrics = new QFontMetrics(lyr.textFont);
+ lyr.fontBaseline = lyr.fontMetrics->boundingRect("X").bottom(); // dummy text to find out how many pixels of the text are below the baseline
+ lyr.xform = mMapRenderer->coordinateTransform();
+ if (mMapRenderer->hasCrsTransformEnabled())
+ lyr.ct = new QgsCoordinateTransform( layer->srs(), mMapRenderer->destinationSrs() );
else
- lyr->ct = NULL;
- lyr->ptZero = lyr->xform->toMapCoordinates( 0,0 );
- lyr->ptOne = lyr->xform->toMapCoordinates( 1,0 );
+ lyr.ct = NULL;
+ lyr.ptZero = lyr.xform->toMapCoordinates( 0,0 );
+ lyr.ptOne = lyr.xform->toMapCoordinates( 1,0 );
return 1; // init successful
}
-void PalLabeling::registerFeatureHook(QgsFeature& f, void* layerContext)
+
+void PalLabeling::registerFeature(QgsVectorLayer* layer, QgsFeature& f)
{
- LayerSettings* lyr = (LayerSettings*) layerContext;
- lyr->registerFeature(f);
+ mActiveLayers[layer].registerFeature(f);
}
@@ -339,6 +374,17 @@
mPal->setPolyP(mCandPolygon);
}
+LayerSettings& PalLabeling::layer(const char* layerName)
+{
+ QHash<QgsVectorLayer*, LayerSettings>::iterator lit;
+ for (lit = mActiveLayers.begin(); lit != mActiveLayers.end(); ++lit)
+ {
+ LayerSettings& lyr = lit.value();
+ if (lyr.palLayer->getName() == layerName)
+ return lyr;
+ }
+ return mInvalidLayerSettings;
+}
void PalLabeling::doLabeling(QPainter* painter, QgsRectangle extent)
@@ -361,6 +407,7 @@
catch ( std::exception& e )
{
std::cerr << "PAL EXCEPTION :-( " << e.what() << std::endl;
+ mActiveLayers.clear(); // clean up
return;
}
@@ -409,13 +456,16 @@
delete labels;
// delete all allocated geometries for features
- for (int i = 0; i < mLayers.count(); i++)
+ QHash<QgsVectorLayer*, LayerSettings>::iterator lit;
+ for (lit = mActiveLayers.begin(); lit != mActiveLayers.end(); ++lit)
{
- LayerSettings& lyr = mLayers[i];
+ LayerSettings& lyr = lit.value();
for (QList<MyLabel*>::iterator git = lyr.geometries.begin(); git != lyr.geometries.end(); ++git)
delete *git;
lyr.geometries.clear();
}
+ // labeling is done: clear the active layers hashtable
+ mActiveLayers.clear();
// re-create PAL
initPal();
Modified: branches/symbology-ng-branch/src/plugins/labeling/pallabeling.h
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/pallabeling.h 2009-08-07 11:58:50 UTC (rev 11290)
+++ branches/symbology-ng-branch/src/plugins/labeling/pallabeling.h 2009-08-08 16:02:41 UTC (rev 11291)
@@ -23,6 +23,8 @@
class QgsFeature;
#include "qgspoint.h"
+#include "qgsvectorlayer.h" // definition of QgsLabelingEngineInterface
+
class MyLabel;
class LayerSettings
@@ -50,10 +52,9 @@
MapOrientation = 8
};
- QString layerId;
QString fieldName;
Placement placement;
- unsigned long placementFlags;
+ unsigned int placementFlags;
QFont textFont;
QColor textColor;
bool enabled;
@@ -71,6 +72,9 @@
// implementation of register feature hook
void registerFeature(QgsFeature& f);
+ void readFromLayer(QgsVectorLayer* layer);
+ void writeToLayer(QgsVectorLayer* layer);
+
// temporary stuff: set when layer gets prepared
pal::Layer* palLayer;
int fieldIndex;
@@ -91,20 +95,16 @@
double cost;
};
-class PalLabeling
+class PalLabeling : public QgsLabelingEngineInterface
{
public:
PalLabeling(QgsMapRenderer* renderer);
~PalLabeling();
+ LayerSettings& layer(const char* layerName);
+
void doLabeling(QPainter* painter, QgsRectangle extent);
- void addLayer(LayerSettings layerSettings);
-
- void removeLayer(QString layerId);
-
- const LayerSettings& layer(QString layerId);
-
void numCandidatePositions(int& candPoint, int& candLine, int& candPolygon);
void setNumCandidatePositions(int candPoint, int candLine, int candPolygon);
@@ -120,10 +120,12 @@
bool isShowingAllLabels() const { return mShowingAllLabels; }
void setShowingAllLabels(bool showing) { mShowingAllLabels = showing; }
+ // implemented methods from labeling engine interface
+
//! hook called when drawing layer before issuing select()
- static int prepareLayerHook(void* context, void* layerContext, int& attrIndex);
+ virtual int prepareLayer(QgsVectorLayer* layer, int& attrIndex);
//! hook called when drawing for every feature in a layer
- static void registerFeatureHook(QgsFeature& f, void* layerContext);
+ virtual void registerFeature(QgsVectorLayer* layer, QgsFeature& feat);
void drawLabelCandidateRect( pal::LabelPosition* lp, QPainter* painter, const QgsMapToPixel* xform );
@@ -135,9 +137,10 @@
void initPal();
protected:
- QList<LayerSettings> mLayers;
- LayerSettings mInvalidLayer;
-
+ // temporary hashtable of layer settings, being filled during labeling, cleared once labeling's done
+ QHash<QgsVectorLayer*, LayerSettings> mActiveLayers;
+ LayerSettings mInvalidLayerSettings;
+
QgsMapRenderer* mMapRenderer;
int mCandPoint, mCandLine, mCandPolygon;
Search mSearch;
More information about the QGIS-commit
mailing list