As with my previous tutorials, the entire project can be checked out from the QGIS Subversion repository using the following command:
svn co https://svn.qgis.org/repos/qgis/trunk/code_examples/5_using_rubber_band_with_canvas
In the working directory for the tutorial code you will find a number of files including c++ sources, icons and a simple data file under data. There is also the .ui file for the main window.
Note: You will need to edit the .pro file in the above svn directory to match your system.
#include <qgsrubberband.h>Next I added a couple of slots to handle events from the show and hide rubber band tool buttons that I added to the main window:
// next are tools overloaded from base class void on_mpToolShowRubberBand_clicked(); void on_mpToolHideRubberBand_clicked();Also I've added a class member for our rubber band:
QgsRubberBand * mpRubberBand;All pretty straightforward so far. Lets go over to the implementation file, mainwindow.cpp. First you will see a new include:
#include <qgspoint.h>This is needed because we will be using QgsPoint objects to define the vertices of our rubber band. The code that follows sets up the main window and toolbars as covered in previous tutorials. Towards the end of the constructor you will see we initialise the rubber band member:
//create the rubber band bool myPolygonFlag=true; mpRubberBand = new QgsRubberBand(mpMapCanvas, myPolygonFlag ); mpRubberBand->show();I've written it a bit more verbosely than necessary to make it clear. The rubber band constructor needs two parameters; the QgsMapCanvas on to which our rubber band will be drawn, and a boolean indicating whether the rubber band is a polygon or not. In the case that the rubber band is a polygon it will always close the gap between first and last points. Next I wired up the two toolButtons I added using Qt4 Designer to the mainwindowbase.ui file. Lets look at the show event first:
void MainWindow::on_mpToolShowRubberBand_clicked() { QgsPoint myPoint1 = mpMapCanvas->getCoordinateTransform()->toMapCoordinates(10, 10); mpRubberBand->addPoint(myPoint1); QgsPoint myPoint2 = mpMapCanvas->getCoordinateTransform()->toMapCoordinates(20, 10); mpRubberBand->addPoint(myPoint2); QgsPoint myPoint3 = mpMapCanvas->getCoordinateTransform()->toMapCoordinates(20, 20); mpRubberBand->addPoint(myPoint3); QgsPoint myPoint4 = mpMapCanvas->getCoordinateTransform()->toMapCoordinates(10, 20); mpRubberBand->addPoint(myPoint4); }We are specifying here to draw a 10x10 pixel box, starting its top left corner at 10,10 pixels from the corner of the map canvase. So whats all that coordinate transform stuff about then? The rubber band operates in the spatial reference system of the associated canvas. In other words when you specify the coordinates of vertices it should be in map units, not in screen pixel coordinates. Fortunately there is an easy way to translate from screen coordinates to map coordinates. First we get the QgsMapToPixel instance from the map canvas. Next we call its toMapCoordinates(int,int) method which will return a QgsPoint. For each point I create I am just adding it to the rubber band. Because I am walking around the corners of a square, the end result will be a square drawn on screen. Remember that we specified our rubber band is a polygon in the constructor, so there is no need to create a 5th point to close the polygon - its automaticall closed for us! Now that we know how to create a QgsRubberBand, we should also show how to remove it from the canvas again. This is illustrated in the next method:
void MainWindow::on_mpToolHideRubberBand_clicked() { bool myPolygonFlag=true; mpRubberBand->reset(myPolygonFlag); }Ok so thats pretty easy - just call reset on the rubber band. When you do so you need to respecify whether the rubber band is to operate in polyline or polygon mode. Lastly you should note that you are responsible for managing the memory allocated to the rubber band, this you will see that in the destructor for mainwindow.cpp I have the following:
delete mpRubberBand;You are not limited to only one QgsRubberBand instance either - you can add as many as you like. In the screenshot below I added a second rubber band: Well I hope you find lots of cool uses for QgsRubberBand - feel free to let us know in the comments below how you are using it. Thats the end of tutorial5!
mkdir -p qgis_example3.app/Contents/MacOS/share/qgis/resources/ cp -r /Applications/qgis.app/Contents/MacOS/share/qgis/resources/* \ qgis_example3.app/Contents/MacOS/share/qgis/resources/