[QGIS Commit] r10906 - in branches/symbology-ng-branch/src: core
plugins/labeling
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Fri Jun 12 07:45:21 EDT 2009
Author: wonder
Date: 2009-06-12 07:45:20 -0400 (Fri, 12 Jun 2009)
New Revision: 10906
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/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:
Features for labeling are now extracted in the main drawing loop (using a pair of hooks).
This avoids one more iteration through the layer.
Modified: branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp 2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp 2009-06-12 11:45:20 UTC (rev 10906)
@@ -105,7 +105,9 @@
mLabelOn( false ),
mFetching( false ),
mRendererV2( NULL ),
- mUsingRendererV2( false )
+ mUsingRendererV2( false ),
+ mLabelingPrepareLayerHook( NULL ),
+ mLabelingRegisterFeatureHook( NULL )
{
mActions = new QgsAttributeAction;
@@ -696,11 +698,29 @@
QgsFeature fet;
QgsAttributeList attributes = mRendererV2->usedAttributes();
+
+ bool labeling = FALSE;
+ if (mLabelingPrepareLayerHook)
+ {
+ int attrIndex;
+ if (mLabelingPrepareLayerHook(mLabelingContext, mLabelingLayerContext, attrIndex))
+ {
+ if (!attributes.contains(attrIndex))
+ attributes << attrIndex;
+ labeling = TRUE;
+ }
+ }
+
select( attributes, rendererContext.extent() );
while ( nextFeature( fet ) )
{
mRendererV2->renderFeature(fet, rendererContext);
+
+ if (labeling && mLabelingRegisterFeatureHook)
+ {
+ mLabelingRegisterFeatureHook(fet, mLabelingLayerContext);
+ }
}
mRendererV2->stopRender(rendererContext);
@@ -739,6 +759,19 @@
int featureCount = 0;
QgsFeature fet;
QgsAttributeList attributes = mRenderer->classificationAttributes();
+
+ bool labeling = FALSE;
+ if (mLabelingPrepareLayerHook)
+ {
+ int attrIndex;
+ if (mLabelingPrepareLayerHook(mLabelingContext, mLabelingLayerContext, attrIndex))
+ {
+ if (!attributes.contains(attrIndex))
+ attributes << attrIndex;
+ labeling = TRUE;
+ }
+ }
+
select( attributes, rendererContext.extent() );
try
@@ -801,6 +834,11 @@
rendererContext.rasterScaleFactor(),
rendererContext.drawEditingInformation() );
+ if (labeling && mLabelingRegisterFeatureHook)
+ {
+ mLabelingRegisterFeatureHook(fet, mLabelingLayerContext);
+ }
+
++featureCount;
}
}
@@ -2087,6 +2125,18 @@
return mLabelOn;
}
+void QgsVectorLayer::setLabelingHooks(LabelingPrepareLayerHook prepareLayerHook,
+ LabelingRegisterFeatureHook registerFeatureHook,
+ void* context,
+ void* layerContext)
+{
+ mLabelingPrepareLayerHook = prepareLayerHook;
+ mLabelingRegisterFeatureHook = registerFeatureHook;
+ mLabelingContext = context;
+ mLabelingLayerContext = layerContext;
+}
+
+
bool QgsVectorLayer::startEditing()
{
if ( !mDataProvider )
Modified: branches/symbology-ng-branch/src/core/qgsvectorlayer.h
===================================================================
--- branches/symbology-ng-branch/src/core/qgsvectorlayer.h 2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/core/qgsvectorlayer.h 2009-06-12 11:45:20 UTC (rev 10906)
@@ -54,6 +54,10 @@
typedef QSet<int> QgsFeatureIds;
typedef QSet<int> QgsAttributeIds;
+typedef int (*LabelingPrepareLayerHook)(void*, void*, int&);
+typedef void (*LabelingRegisterFeatureHook)(QgsFeature&, void*);
+
+
/** \ingroup core
* Vector layer backed by a data source provider.
*/
@@ -340,6 +344,11 @@
/** Label is on */
bool hasLabelsEnabled( void ) const;
+ void setLabelingHooks(LabelingPrepareLayerHook prepareLayerHook,
+ LabelingRegisterFeatureHook registerFeatureHook,
+ void* mLabelingContext,
+ void* mLabelingLayerContext);
+
/** Returns true if the provider is in editing mode */
virtual bool isEditable() const;
@@ -667,6 +676,12 @@
/** Label */
QgsLabel *mLabel;
+ LabelingPrepareLayerHook mLabelingPrepareLayerHook;
+ LabelingRegisterFeatureHook mLabelingRegisterFeatureHook;
+ void* mLabelingContext;
+ void* mLabelingLayerContext;
+
+
/** Display labels */
bool mLabelOn;
Modified: branches/symbology-ng-branch/src/plugins/labeling/labeling.cpp
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/labeling.cpp 2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/plugins/labeling/labeling.cpp 2009-06-12 11:45:20 UTC (rev 10906)
@@ -89,17 +89,6 @@
void Labeling::doLabeling( QPainter * painter )
{
- int w = painter->device()->width();
- int h = painter->device()->height();
-
-
- QgsMapLayer* layer = mQGisIface->activeLayer();
- if (layer == NULL || layer->type() != QgsMapLayer::VectorLayer)
- {
- painter->drawLine(0,0,w,h);
- return;
- }
-
mLBL->doLabeling(painter);
}
Modified: branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp 2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp 2009-06-12 11:45:20 UTC (rev 10906)
@@ -42,7 +42,7 @@
populatePlacementMethods();
populateFieldNames();
- PalLabeling::LayerSettings lyr = lbl->layer(layerId);
+ LayerSettings lyr = lbl->layer(layerId);
if (!lyr.layerId.isEmpty())
{
// load the labeling settings
@@ -74,12 +74,12 @@
return static_cast<QgsVectorLayer*>(layer);
}
-PalLabeling::LayerSettings LabelingGui::layerSettings()
+LayerSettings LabelingGui::layerSettings()
{
- PalLabeling::LayerSettings lyr;
+ LayerSettings lyr;
lyr.layerId = mLayerId;
lyr.fieldName = cboFieldName->currentText();
- lyr.placement = (PalLabeling::Placement) cboPlacement->itemData(cboPlacement->currentIndex()).toInt();
+ lyr.placement = (LayerSettings::Placement) cboPlacement->itemData(cboPlacement->currentIndex()).toInt();
lyr.textColor = btnTextColor->color();
lyr.textFont = lblFontPreview->font();
lyr.enabled = chkEnableLabeling->isChecked();
@@ -94,18 +94,18 @@
switch (layer()->geometryType())
{
case QGis::Point:
- cboPlacement->addItem(tr("Around the point"), QVariant(PalLabeling::AroundPoint));
+ cboPlacement->addItem(tr("Around the point"), QVariant(LayerSettings::AroundPoint));
break;
case QGis::Line:
- cboPlacement->addItem(tr("On the line"), QVariant(PalLabeling::OnLine));
- cboPlacement->addItem(tr("Around the line"), QVariant(PalLabeling::AroundLine));
+ cboPlacement->addItem(tr("On the line"), QVariant(LayerSettings::OnLine));
+ cboPlacement->addItem(tr("Around the line"), QVariant(LayerSettings::AroundLine));
break;
case QGis::Polygon:
- cboPlacement->addItem(tr("Horizontal"), QVariant(PalLabeling::Horizontal));
- cboPlacement->addItem(tr("Free"), QVariant(PalLabeling::Free));
- cboPlacement->addItem(tr("Around the centroid"), QVariant(PalLabeling::AroundPoint));
- cboPlacement->addItem(tr("On the perimeter"), QVariant(PalLabeling::OnLine));
- cboPlacement->addItem(tr("Around the perimeter"), QVariant(PalLabeling::AroundLine));
+ cboPlacement->addItem(tr("Horizontal"), QVariant(LayerSettings::Horizontal));
+ cboPlacement->addItem(tr("Free"), QVariant(LayerSettings::Free));
+ cboPlacement->addItem(tr("Around the centroid"), QVariant(LayerSettings::AroundPoint));
+ cboPlacement->addItem(tr("On the perimeter"), QVariant(LayerSettings::OnLine));
+ cboPlacement->addItem(tr("Around the perimeter"), QVariant(LayerSettings::AroundLine));
break;
}
}
Modified: branches/symbology-ng-branch/src/plugins/labeling/labelinggui.h
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/labelinggui.h 2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/plugins/labeling/labelinggui.h 2009-06-12 11:45:20 UTC (rev 10906)
@@ -35,7 +35,7 @@
LabelingGui( PalLabeling* lbl, QString layerId, QWidget* parent );
~LabelingGui();
- PalLabeling::LayerSettings layerSettings();
+ LayerSettings layerSettings();
public slots:
void changeTextColor();
Modified: branches/symbology-ng-branch/src/plugins/labeling/pallabeling.cpp
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/pallabeling.cpp 2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/plugins/labeling/pallabeling.cpp 2009-06-12 11:45:20 UTC (rev 10906)
@@ -59,12 +59,48 @@
int mId;
};
+// -------------
+LayerSettings::LayerSettings()
+ : palLayer(NULL), fontMetrics(NULL)
+{
+}
+LayerSettings::~LayerSettings()
+{
+ // pal layer is deleted internally in PAL
+ delete fontMetrics;
+}
+
+void LayerSettings::calculateLabelSize(QString text, double& labelX, double& labelY)
+{
+ //QFontMetrics fontMetrics(textFont);
+ QRect labelRect = /*QRect(0,0,20,20);*/ fontMetrics->boundingRect(text);
+
+ // 2px border...
+ QgsPoint ptSize = xform->toMapCoordinates( labelRect.width()+2,labelRect.height()+2 );
+ labelX = fabs(ptSize.x()-ptZero.x());
+ labelY = fabs(ptSize.y()-ptZero.y());
+}
+
+void LayerSettings::registerFeature(QgsFeature& f)
+{
+ QString labelText = f.attributeMap()[fieldIndex].toString();
+ double labelX, labelY; // will receive label size
+ calculateLabelSize(labelText, labelX, labelY);
+
+ //std::cout << labelX << " " << labelY << std::endl;
+ MyLabel* lbl = new MyLabel(f.id(), labelText, GEOSGeom_clone( f.geometry()->asGeos() ) );
+
+ // register feature to the layer
+ palLayer->registerFeature(lbl->strId(), lbl, labelX, labelY);
+}
+
+
// -------------
PalLabeling::PalLabeling(QgsMapCanvas* mapCanvas)
- : mMapCanvas(mapCanvas)
+ : mMapCanvas(mapCanvas), mPal(NULL)
{
// find out engine defaults
Pal p;
@@ -79,11 +115,31 @@
case POPMUSIC_CHAIN: mSearch = Popmusic_Chain; break;
case POPMUSIC_TABU_CHAIN: mSearch = Popmusic_Tabu_Chain; break;
}
+
+ initPal();
}
+
+PalLabeling::~PalLabeling()
+{
+ delete mPal;
+
+ // make sure to remove hooks from all layers
+ while (mLayers.count())
+ {
+ removeLayer(mLayers[0].layerId);
+ }
+}
+
+
void PalLabeling::addLayer(LayerSettings layerSettings)
{
mLayers.append(layerSettings);
+
+ 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)
@@ -92,13 +148,16 @@
{
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;
}
}
}
-PalLabeling::LayerSettings PalLabeling::layer(QString layerId)
+LayerSettings PalLabeling::layer(QString layerId)
{
for (int i = 0; i < mLayers.count(); i++)
{
@@ -111,71 +170,63 @@
}
-int PalLabeling::prepareLayer(Pal& pal, const LayerSettings& lyr)
+
+int PalLabeling::prepareLayerHook(void* context, void* layerContext, int& attrIndex)
{
- if (!lyr.enabled)
- return 0;
+ PalLabeling* thisClass = (PalLabeling*) context;
+ LayerSettings* lyr = (LayerSettings*) layerContext;
- QgsVectorLayer* vlayer = (QgsVectorLayer*) QgsMapLayerRegistry::instance()->mapLayer(lyr.layerId);
+ QgsVectorLayer* vlayer = (QgsVectorLayer*) QgsMapLayerRegistry::instance()->mapLayer(lyr->layerId);
if (vlayer == NULL)
return 0;
- QgsAttributeList attrs;
-
- int fldName = vlayer->dataProvider()->fieldNameIndex(lyr.fieldName);
- if (fldName == -1)
+ // find out which field will be needed
+ int fldIndex = vlayer->dataProvider()->fieldNameIndex(lyr->fieldName);
+ if (fldIndex == -1)
return 0;
- attrs << fldName;
- vlayer->select(attrs, mMapCanvas->extent());
+ attrIndex = fldIndex;
// how to place the labels
Arrangement arrangement;
- switch (lyr.placement)
+ switch (lyr->placement)
{
- case AroundPoint: arrangement = P_POINT; break;
- case OnLine: arrangement = P_LINE; break;
- case AroundLine: arrangement = P_LINE_AROUND; break;
- case Horizontal: arrangement = P_HORIZ; break;
- case Free: arrangement = P_FREE; break;
+ case LayerSettings::AroundPoint: arrangement = P_POINT; break;
+ case LayerSettings::OnLine: arrangement = P_LINE; break;
+ case LayerSettings::AroundLine: arrangement = P_LINE_AROUND; break;
+ case LayerSettings::Horizontal: arrangement = P_HORIZ; break;
+ case LayerSettings::Free: arrangement = P_FREE; break;
}
// create the pal layer
- double priority = 1 - lyr.priority/10.0; // convert 0..10 --> 1..0
- Layer* l = pal.addLayer(lyr.layerId.toLocal8Bit().data(), -1, -1, arrangement, METER, priority, lyr.obstacle, true, true);
+ double priority = 1 - lyr->priority/10.0; // convert 0..10 --> 1..0
+ Layer* l = thisClass->mPal->addLayer(lyr->layerId.toLocal8Bit().data(), -1, -1, arrangement, METER, priority, lyr->obstacle, true, true);
- QFontMetrics fm(lyr.textFont);
+ // 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->mMapCanvas->mapRenderer()->coordinateTransform();
+ lyr->ptZero = lyr->xform->toMapCoordinates( 0,0 );
- QgsFeature f;
- int feats = 0;
- const QgsMapToPixel* xform = mMapCanvas->mapRenderer()->coordinateTransform();
- QgsPoint ptZero = xform->toMapCoordinates( 0,0 );
+ return 1; // init successful
+}
- while (vlayer->nextFeature(f))
- {
- QString labelText = f.attributeMap()[fldName].toString();
- QRect labelRect = fm.boundingRect(labelText);
- //std::cout << "bound: " << labelRect.width() << "x" << labelRect.height() << std::endl;
- // 2px border...
- QgsPoint ptSize = xform->toMapCoordinates( labelRect.width()+2,labelRect.height()+2 );
- double labelX = fabs(ptSize.x()-ptZero.x());
- double labelY = fabs(ptSize.y()-ptZero.y());
- //std::cout << "L " << labelX << " " << labelY << std::endl;
-
- MyLabel* lbl = new MyLabel(f.id(), labelText, GEOSGeom_clone( f.geometry()->asGeos() ) );
-
- // TODO: owner of the id?
- l->registerFeature(lbl->strId(), lbl, labelX, labelY);
- feats++;
- }
-
- return feats;
+void PalLabeling::registerFeatureHook(QgsFeature& f, void* layerContext)
+{
+ LayerSettings* lyr = (LayerSettings*) layerContext;
+ lyr->registerFeature(f);
}
-void PalLabeling::doLabeling(QPainter* painter)
+void PalLabeling::initPal()
{
- Pal p;
+ // delete if exists already
+ if (mPal)
+ delete mPal;
+
+ mPal = new Pal;
SearchMethod s;
switch (mSearch)
@@ -185,32 +236,31 @@
case Popmusic_Chain: s = POPMUSIC_CHAIN; break;
case Popmusic_Tabu_Chain: s = POPMUSIC_TABU_CHAIN; break;
}
- p.setSearch(s);
+ mPal->setSearch(s);
// set number of candidates generated per feature
- p.setPointP(mCandPoint);
- p.setLineP(mCandLine);
- p.setPolyP(mCandPolygon);
+ mPal->setPointP(mCandPoint);
+ mPal->setLineP(mCandLine);
+ mPal->setPolyP(mCandPolygon);
+}
- //p.setSearch(POPMUSIC_TABU_CHAIN);// this is really slow! // default is CHAIN (worst, fastest)
- // TODO: API 0.2 - no mention about changing map units!
- // pal map units = METER by default ... change setMapUnit
- //p.setMapUnit(METER);
- // pal label units ... to be chosen
- // pal dist label - pixels?
+
+void PalLabeling::doLabeling(QPainter* painter)
+{
+
QTime t;
t.start();
- int feats = 0;
+ // make sure to delete fontmetrics otherwise it crashes inside Qt when drawing... :-(
+ // probably gets invalid when setting fonts in the label drawing loop
for (int i = 0; i < mLayers.count(); i++)
{
- feats += prepareLayer(p, mLayers.at(i));
+ LayerSettings& lyr = mLayers[i];
+ delete lyr.fontMetrics;
+ lyr.fontMetrics = NULL;
}
- std::cout << "LABELING prepare: " << t.elapsed() << "ms" << std::endl;
- t.restart();
-
// do the labeling itself
double scale = 1; // scale denominator
QgsRectangle r = mMapCanvas->extent();
@@ -219,7 +269,7 @@
std::list<Label*>* labels;
try
{
- labels = p.labeller(scale, bbox, NULL, false);
+ labels = mPal->labeller(scale, bbox, NULL, false);
}
catch ( std::exception e )
{
@@ -227,14 +277,9 @@
return;
}
- std::cout << "LABELING work: " << t.elapsed() << "ms" << std::endl;
- std::cout << "-->> " << labels->size() << "/" << feats << std::endl;
+ std::cout << "LABELING work: " << t.elapsed() << "ms ... labels# " << labels->size() << std::endl;
t.restart();
- QFontMetrics fm = painter->fontMetrics();
- QRect labelRect = fm.boundingRect("X"); // dummy text to find out height
- int baseline = labelRect.bottom(); // how many pixels of the text are below the baseline
-
// draw the labels
const QgsMapToPixel* xform = mMapCanvas->mapRenderer()->coordinateTransform();
std::list<Label*>::iterator it = labels->begin();
@@ -251,7 +296,7 @@
painter->save();
painter->setPen( lyr.textColor );
painter->setFont( lyr.textFont );
- painter->translate( QPointF(outPt.x()+1, outPt.y()-1-baseline) );
+ painter->translate( QPointF(outPt.x()+1, outPt.y()-1-lyr.fontBaseline) );
painter->rotate(-label->getRotation() * 180 / M_PI );
painter->drawText(0,0, ((MyLabel*)label->getGeometry())->text());
painter->restore();
@@ -263,6 +308,9 @@
std::cout << "LABELING draw: " << t.elapsed() << "ms" << std::endl;
delete labels;
+
+ // re-create PAL
+ initPal();
}
void PalLabeling::numCandidatePositions(int& candPoint, int& candLine, int& candPolygon)
Modified: branches/symbology-ng-branch/src/plugins/labeling/pallabeling.h
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/pallabeling.h 2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/plugins/labeling/pallabeling.h 2009-06-12 11:45:20 UTC (rev 10906)
@@ -11,35 +11,59 @@
namespace pal
{
class Pal;
+ class Layer;
}
+class QgsMapToPixel;
+class QgsFeature;
+#include "qgspoint.h"
+
+
+class LayerSettings
+{
+public:
+ LayerSettings();
+ ~LayerSettings();
+
+ enum Placement
+ {
+ AroundPoint, // Point / Polygon
+ OnLine, // Line / Polygon
+ AroundLine, // Line / Polygon
+ Horizontal, // Polygon
+ Free // Polygon
+ };
+
+ QString layerId;
+ QString fieldName;
+ Placement placement;
+ QFont textFont;
+ QColor textColor;
+ bool enabled;
+ int priority; // 0 = low, 10 = high
+ bool obstacle; // whether it's an obstacle
+
+ // called from register feature hook
+ void calculateLabelSize(QString text, double& labelX, double& labelY);
+
+ // implementation of register feature hook
+ void registerFeature(QgsFeature& f);
+
+ // temporary stuff: set when layer gets prepared
+ pal::Layer* palLayer;
+ int fieldIndex;
+ QFontMetrics* fontMetrics;
+ int fontBaseline;
+ const QgsMapToPixel* xform;
+ QgsPoint ptZero;
+};
+
class PalLabeling
{
public:
PalLabeling(QgsMapCanvas* mapCanvas);
+ ~PalLabeling();
- enum Placement
- {
- AroundPoint, // Point / Polygon
- OnLine, // Line / Polygon
- AroundLine, // Line / Polygon
- Horizontal, // Polygon
- Free // Polygon
- };
-
- struct LayerSettings
- {
- //LayerSettings()
- QString layerId;
- QString fieldName;
- Placement placement;
- QFont textFont;
- QColor textColor;
- bool enabled;
- int priority; // 0 = low, 10 = high
- bool obstacle; // whether it's an obstacle
- };
-
void doLabeling(QPainter* painter);
void addLayer(LayerSettings layerSettings);
@@ -56,14 +80,23 @@
void setSearchMethod(Search s);
Search searchMethod() const;
+
+ //! hook called when drawing layer before issuing select()
+ static int prepareLayerHook(void* context, void* layerContext, int& attrIndex);
+ //! hook called when drawing for every feature in a layer
+ static void registerFeatureHook(QgsFeature& f, void* layerContext);
+
protected:
- int prepareLayer(pal::Pal& pal, const LayerSettings& lyr);
+ void initPal();
+
protected:
QList<LayerSettings> mLayers;
QgsMapCanvas* mMapCanvas;
int mCandPoint, mCandLine, mCandPolygon;
Search mSearch;
+
+ pal::Pal* mPal;
};
#endif // PALLABELING_H
More information about the QGIS-commit
mailing list