I'm writing a C++ application using QGIS API and I would like to improve the performance.
I want to render 5 layers:
- one raster layer using gdal to load Bing/Google Map tiles
- 4 custom QgsMapLayer (using plugin layer type) to draw different lines/polygons/points in WGS84.
For now, each of these layer is added to the MapCanvas, using:
QgsMapLayerRegistry::instance()->addMapLayer(customLayer); QList <QgsMapCanvasLayer> myLayerSet; myLayerSet.append(QgsMapCanvasLayer(cutomLayer,TRUE)); setLayerSet(myLayerSet);
On the canvas, I can have map tools, like panning, zoom in/out. I use custom layers because I want to easily decorate lines and polygons, using QPainter. This works, and I'm able to display what i want, where i want (using coordinate transforms from WGS84 to pseudo mercator).
My problem is: one of my custom layers draws a GPS point with some circles around it.
This layer is refreshed every second. To refresh my layer, I use the
canvas->refresh(), but that refreshes all other layers as well, and by consequence, the GDAL layer. This takes a lot of time and it's not necessary.
I have read some posts here mentioning the use of
layer->setImageCache(), or by sub-classing QgsMapCanvasItem. Unfortunately, none of theses solutions works as I expect.
setImageCache apparently doesn't work at all, or I don't know how to use it properly.
Sub-classing QgsMapCanvasItem allows me to implement the layers that need frequent refresh, and refresh them without refresh Raster Layer but:
- when panning the map, drawn objects don't follow the map (as a rubberBand can).
- when i use zoom in/out, the selection rectangle erase what was drawn on my canvasItem, without triggering a redraw.
I don't see how to do that, even if this subject seems relatively common.
Am i on the right way or is there a better way?
thanks to Nathan, my problem is resolved, and i confirm that custom QgsMapCanvasItem is the solution to independently refresh some layers.
just keep in mind to use toCanvasCoordinates(), and implement boundingRect() properly.