Skip to content

Commit

Permalink
Added option to engine configuration to show candidate labels for eve…
Browse files Browse the repository at this point in the history
…ry feature (as frames).

Added a simple tool that shows candidate's cost on click (in a tooltip).


git-svn-id: http://svn.osgeo.org/qgis/branches/symbology-ng-branch@11019 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder committed Jul 4, 2009
1 parent cc51226 commit 0a6dfa1
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 16 deletions.
4 changes: 4 additions & 0 deletions src/plugins/labeling/engineconfigdialog.cpp
Expand Up @@ -18,6 +18,8 @@ EngineConfigDialog::EngineConfigDialog(PalLabeling* lbl, QWidget* parent)
spinCandPoint->setValue(candPoint);
spinCandLine->setValue(candLine);
spinCandPolygon->setValue(candPolygon);

chkShowCandidates->setChecked( mLBL->isShowingCandidates() );
}


Expand All @@ -30,5 +32,7 @@ void EngineConfigDialog::onOK()
spinCandLine->value(),
spinCandPolygon->value());

mLBL->setShowingCandidates( chkShowCandidates->isChecked() );

accept();
}
31 changes: 30 additions & 1 deletion src/plugins/labeling/engineconfigdialog.ui
Expand Up @@ -27,7 +27,7 @@
<widget class="QComboBox" name="cboSearchMethod">
<item>
<property name="text">
<string>Chain (fastest)</string>
<string>Chain (fast)</string>
</property>
</item>
<item>
Expand All @@ -45,6 +45,11 @@
<string>Popmusic Tabu Chain</string>
</property>
</item>
<item>
<property name="text">
<string>FALP (fastest)</string>
</property>
</item>
</widget>
</item>
</layout>
Expand Down Expand Up @@ -88,6 +93,9 @@
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999</number>
</property>
</widget>
</item>
<item row="1" column="0">
Expand All @@ -105,6 +113,9 @@
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999</number>
</property>
</widget>
</item>
<item row="2" column="0">
Expand All @@ -122,6 +133,9 @@
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999</number>
</property>
</widget>
</item>
</layout>
Expand Down Expand Up @@ -158,6 +172,13 @@
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="chkShowCandidates">
<property name="text">
<string>Show label candidates (for debugging)</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
Expand All @@ -170,6 +191,14 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>cboSearchMethod</tabstop>
<tabstop>spinCandPoint</tabstop>
<tabstop>spinCandLine</tabstop>
<tabstop>spinCandPolygon</tabstop>
<tabstop>chkShowCandidates</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
Expand Down
55 changes: 53 additions & 2 deletions src/plugins/labeling/labeling.cpp
Expand Up @@ -65,13 +65,46 @@ Labeling::~Labeling()
{
}

/////////

#include <qgsmaptool.h>
#include <QMouseEvent>
#include <QToolTip>

class LabelingTool : public QgsMapTool
{
public:
LabelingTool(PalLabeling* lbl, QgsMapCanvas* canvas) : QgsMapTool(canvas), mLBL(lbl) {}

virtual void canvasPressEvent( QMouseEvent * e )
{
const QList<LabelCandidate>& cand = mLBL->candidates();
QPointF pt = e->posF();
for (int i = 0; i < cand.count(); i++)
{
const LabelCandidate& c = cand[i];
if (c.rect.contains(pt))
{
QToolTip::showText( mCanvas->mapToGlobal(e->pos()), QString::number(c.cost), mCanvas);
break;
}
}
}

protected:
PalLabeling* mLBL;
};

///////////


/*
* Initialize the GUI interface for the plugin - this is only called once when the plugin is
* added to the plugin registry in the QGIS application.
*/
void Labeling::initGui()
{
mLBL = new PalLabeling(mQGisIface->mapCanvas());
mLBL = new PalLabeling(mQGisIface->mapCanvas()->mapRenderer());

// Create the action for tool
mQActionPointer = new QAction( QIcon( ":/labeling/labeling.png" ), tr( "Labeling" ), this );
Expand All @@ -83,13 +116,19 @@ void Labeling::initGui()
mQGisIface->addToolBarIcon( mQActionPointer );
mQGisIface->addPluginToMenu( tr( "&Labeling" ), mQActionPointer );

mActionTool = new QAction( "Ltool", this );
mQGisIface->addToolBarIcon( mActionTool );
connect( mActionTool, SIGNAL( triggered() ), this, SLOT( setTool() ) );

mTool = new LabelingTool(mLBL, mQGisIface->mapCanvas());

connect( mQGisIface->mapCanvas(), SIGNAL( renderComplete( QPainter * ) ), this, SLOT( doLabeling( QPainter * ) ) );

}

void Labeling::doLabeling( QPainter * painter )
{
mLBL->doLabeling(painter);
mLBL->doLabeling(painter, mQGisIface->mapCanvas()->extent());
}

// Slot called when the menu item is triggered
Expand Down Expand Up @@ -119,14 +158,26 @@ void Labeling::run()
}
}


void Labeling::setTool()
{
mQGisIface->mapCanvas()->setMapTool(mTool);
}

// Unload the plugin by cleaning up the GUI
void Labeling::unload()
{
mQGisIface->mapCanvas()->unsetMapTool(mTool);
delete mTool;

// remove the GUI
mQGisIface->removePluginMenu( "&Labeling", mQActionPointer );
mQGisIface->removeToolBarIcon( mQActionPointer );
delete mQActionPointer;

mQGisIface->removeToolBarIcon( mActionTool );
delete mActionTool;

delete mLBL;
}

Expand Down
7 changes: 7 additions & 0 deletions src/plugins/labeling/labeling.h
Expand Up @@ -32,6 +32,7 @@ class QToolBar;
class QgisInterface;

class PalLabeling;
class LabelingTool;

class Labeling: public QObject, public QgisPlugin
{
Expand All @@ -58,14 +59,20 @@ class Labeling: public QObject, public QgisPlugin
//! hook to renderComplete signal
void doLabeling(QPainter* painter);

//! start labeling map tool
void setTool();

private:

//! Pointer to the QGIS interface object
QgisInterface *mQGisIface;
//! Pointer to the qaction for this plugin
QAction * mQActionPointer;
QAction * mActionTool;

PalLabeling* mLBL;

LabelingTool* mTool;
};

#endif //Labeling_H
70 changes: 62 additions & 8 deletions src/plugins/labeling/pallabeling.cpp
Expand Up @@ -7,6 +7,8 @@
#include <pal/layer.h>
#include <pal/palgeometry.h>
#include <pal/palexception.h>
#include <pal/problem.h>
#include <pal/labelposition.h>

#include <geos_c.h>

Expand All @@ -15,12 +17,14 @@
#include <QByteArray>
#include <QString>
#include <QFontMetrics>
#include <QTime>
#include <QPainter>

#include <qgsvectorlayer.h>
#include <qgsmaplayerregistry.h>
#include <qgsvectordataprovider.h>
#include <qgsgeometry.h>
#include <qgsmapcanvas.h>
#include <qgsmaprenderer.h>

using namespace pal;

Expand Down Expand Up @@ -105,8 +109,8 @@ void LayerSettings::registerFeature(QgsFeature& f)

// -------------

PalLabeling::PalLabeling(QgsMapCanvas* mapCanvas)
: mMapCanvas(mapCanvas), mPal(NULL)
PalLabeling::PalLabeling(QgsMapRenderer* mapRenderer)
: mMapRenderer(mapRenderer), mPal(NULL)
{

// find out engine defaults
Expand All @@ -121,8 +125,11 @@ PalLabeling::PalLabeling(QgsMapCanvas* mapCanvas)
case POPMUSIC_TABU: mSearch = Popmusic_Tabu; break;
case POPMUSIC_CHAIN: mSearch = Popmusic_Chain; break;
case POPMUSIC_TABU_CHAIN: mSearch = Popmusic_Tabu_Chain; break;
case FALP: mSearch = Falp; break;
}

mShowingCandidates = FALSE;

initPal();
}

Expand Down Expand Up @@ -217,7 +224,7 @@ int PalLabeling::prepareLayerHook(void* context, void* layerContext, int& attrIn
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->xform = thisClass->mMapRenderer->coordinateTransform();
lyr->ptZero = lyr->xform->toMapCoordinates( 0,0 );

return 1; // init successful
Expand Down Expand Up @@ -245,6 +252,7 @@ void PalLabeling::initPal()
case Popmusic_Tabu: s = POPMUSIC_TABU; break;
case Popmusic_Chain: s = POPMUSIC_CHAIN; break;
case Popmusic_Tabu_Chain: s = POPMUSIC_TABU_CHAIN; break;
case Falp: s = FALP; break;
}
mPal->setSearch(s);
//mPal->setSearch(FALP);
Expand All @@ -257,7 +265,7 @@ void PalLabeling::initPal()



void PalLabeling::doLabeling(QPainter* painter)
void PalLabeling::doLabeling(QPainter* painter, QgsRectangle extent)
{

QTime t;
Expand All @@ -274,25 +282,70 @@ void PalLabeling::doLabeling(QPainter* painter)

// do the labeling itself
double scale = 1; // scale denominator
QgsRectangle r = mMapCanvas->extent();
QgsRectangle r = extent;
double bbox[] = { r.xMinimum(), r.yMinimum(), r.xMaximum(), r.yMaximum() };

std::list<Label*>* labels;
pal::Problem* problem;
try
{
labels = mPal->labeller(scale, bbox, NULL, false);
//labels = mPal->labeller(scale, bbox, NULL, false);
problem = mPal->extractProblem(scale, bbox);
if ( problem )
{
// TODO: other methods
problem->chain_search();
labels = problem->getSolution(false);
}
else
labels = new std::list<Label*>();
}
catch ( std::exception& e )
{
std::cerr << "PAL EXCEPTION :-( " << e.what() << std::endl;
return;
}

const QgsMapToPixel* xform = mMapRenderer->coordinateTransform();

// draw rectangles with all candidates
// this is done before actual solution of the problem
// before number of candidates gets reduced
mCandidates.clear();
if (mShowingCandidates && problem)
{
painter->setPen(QColor(0,0,0,64));
painter->setBrush(Qt::NoBrush);
for (int i = 0; i < problem->getNumFeatures(); i++)
{
for (int j = 0; j < problem->getFeatureCandidateCount(i); j++)
{
pal::LabelPosition* lp = problem->getFeatureCandidate(i, j);

QgsPoint outPt = xform->transform(lp->getX(), lp->getY());
QgsPoint outPt2 = xform->transform(lp->getX()+lp->getWidth(), lp->getY()+lp->getHeight());

painter->save();
painter->translate( QPointF(outPt.x(), outPt.y()) );
painter->rotate(-lp->getAlpha() * 180 / M_PI );
QRectF rect(0,0, outPt2.x()-outPt.x(), outPt2.y()-outPt.y());
painter->drawRect(rect);
painter->restore();

// save the rect
rect.moveTo(outPt.x(),outPt.y());
mCandidates.append( LabelCandidate(rect, lp->getCost() * 1000) );
}
}
}

// find the solution
labels = mPal->solveProblem( problem );

std::cout << "LABELING work: " << t.elapsed() << "ms ... labels# " << labels->size() << std::endl;
t.restart();

// draw the labels
const QgsMapToPixel* xform = mMapCanvas->mapRenderer()->coordinateTransform();
std::list<Label*>::iterator it = labels->begin();
for ( ; it != labels->end(); ++it)
{
Expand All @@ -317,6 +370,7 @@ void PalLabeling::doLabeling(QPainter* painter)

std::cout << "LABELING draw: " << t.elapsed() << "ms" << std::endl;

delete problem;
delete labels;

// delete all allocated geometries for features
Expand Down

0 comments on commit 0a6dfa1

Please sign in to comment.