2

I am currently trying to put together compositions using inputs from two different map canvases. One is from a canvas built and controlled via a plugin, the other is the the main QGIS canvas (accessed via iface).

At this stage I am just playing around to try and figure out basic mechanics (no real attention to placements etc), and most code is modelled on the cookbook and other similar snippets

I am trying to do it by creating two QgsComposerMap objects (requires two QgsComposition objects initialised from each of the map canvases), then adding them both to one composition and rendering.

This method appears to work (I get a render of both sources on the same page, with size and position controlled by the QgsComposerMap settings), however one part renders horribly pixellated and blurry. It is always the the ComposerMap that doesnt have the 'pageRender' composition as the parent. The problem occurs regardless of scales, extents etc from what I have been able to test

render = canvas.mapSettings()
planrender = maincanvas.mapSettings()

#initialise composition
c = QgsComposition(render)
cp = QgsComposition(planrender)
#add section map item
x, y = 0, 0
w, h = c.paperWidth(), c.paperHeight()
composerMap = QgsComposerMap(c, x ,y, w, h)
c.addComposerMap(composerMap)

#add plan map item
x, y = 0, c.paperHeight()/2
w, h = c.paperWidth(), (c.paperHeight()/2)
composerMapPlan = QgsComposerMap(cp, x ,y, w, h)
composerMapPlan.setMapCanvas(maincanvas)
c.addComposerMap(composerMapPlan)

dpi = c.printResolution()
dpmm = dpi / 25.4
width = int(dpmm * c.paperWidth())
height = int(dpmm * c.paperHeight())

# create output image and initialize it
image = QImage(QtCore.QSize(width, height), QImage.Format_ARGB32)
image.setDotsPerMeterX(dpmm * 1000)
image.setDotsPerMeterY(dpmm * 1000)
image.fill(0)

# render the composition
imagePainter = QPainter(image)

c.renderPage(imagePainter,0)

#try with draw function
#sectsize = QtCore.QSizeF(width, (height/2))
#plansize = QtCore.QSizeF(width, (height/2))
#sectextent = canvas.extent()
#planextent = maincanvas.extent()

#composerMap.draw(imagePainter, sectextent, sectsize, dpi)
#composerMapPlan.draw(imagePainter, planextent, plansize, dpi)

imagePainter.end()

image.save("out.tiff", "tiff")

The commented out section is where i tried using the QgsComposerMap.draw(xxx)method, and this renders the objects correctly, however ignores the placement within the composition, and so draws the two maps over each other

Anyone got any ideas on what I'm doing wrong here or how to better approach the code?

2

After some more experimenting and some looking through the source code, I found what I was doing wrong- The second Composition object needed "setPlotStyle" set to "Print". This is handled automatically by the renderPage method, and so why it isnt a problem for the composition used to render.

render = canvas.mapSettings()
planrender = maincanvas.mapSettings()

#initialise composition
c = QgsComposition(render)
cp = QgsComposition(planrender)
cp.setPlotStyle(QgsComposition.Print) ##this is the critical change
#add section map item
x, y = 0, 0
w, h = c.paperWidth(), c.paperHeight()
composerMap = QgsComposerMap(c, x ,y, w, h)
c.addComposerMap(composerMap)

#add plan map item
x, y = 0, c.paperHeight()/2
w, h = c.paperWidth(), (c.paperHeight()/2)
composerMapPlan = QgsComposerMap(cp, x ,y, w, h)
c.addComposerMap(composerMapPlan)
  • 2
    Just a note - it's great that this approach worked, but you're likely to get all sorts of weird behavior using this method (adding an item to a different composition from the one it was created using). Unfortunately there's currently no other way to achieve what you're after, but expect instabilities! – ndawson May 3 '15 at 21:59
  • Thanks @ndawson, I was actually surprised that it did work. I had figured there was no "proper" way of doing what I wanted, given the ComposerMap object is created using a Composition object (and not a canvas object that I would have intuitively expected. Its a shame that multiple canvases arent supported in the composer, although I can see that its not a likely scenario given the 'philosophy' behind the design and operation of QGIS – valheran May 5 '15 at 8:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.