10

I am writing a stand-alone application in Python/QGIS that simply creates maps.

I want to load vector/raster layers, set symbology, set extent

At the moment, that is all!

Currently I am just using the simple rendering technique outlined here: http://www.qgis.org/pyqgis-cookbook/composer.html#simple-rendering

I have failed, however, at adapting this code to define a specific extent. I provide the code below.

The only examples that I can find that show how to change extent involve creating a MapCanvas. ...But I am not certain that this is something I want to do considering I am just making very simple maps...and it seems to introduce a whole new set of complications. Surely there is an easy way to define extent via the 'simple rendering' technique?

Becky

from qgis.core import *
from qgis.utils import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtCore import QFileInfo, QSettings
QgsApplication.setPrefixPath('/Applications/QGIS-1.9.app/Contents/MacOS', True)
QgsApplication.initQgis()
province = QgsVectorLayer('/filepath/Province_studyUTM36S.shp' , 'layer', 'ogr')
town = QgsVectorLayer('/filepath/TownPolygons_UTM36S.shp' , 'layer', 'ogr')
road = QgsVectorLayer('/filepath/Roads_UTM36S.shp' , 'layer', 'ogr')
QgsMapLayerRegistry.instance().addMapLayer(province)
QgsMapLayerRegistry.instance().addMapLayer(road)
QgsMapLayerRegistry.instance().addMapLayer(town)
rasterFile = '/filepath/Landsat.tif'
fileInfo = QFileInfo(rasterFile)
baseName = fileInfo.baseName()
rlayer = QgsRasterLayer(rasterFile, baseName)
QgsMapLayerRegistry.instance().addMapLayer(rlayer)
img = QImage(QSize(800,600), QImage.Format_ARGB32_Premultiplied) 
color = QColor(255,255,255) 
img.fill(color.rgb()) 
p = QPainter() 
p.begin(img) 
p.setRenderHint(QPainter.Antialiasing) 
render = QgsMapRenderer() 
ID = [ rlayer.getLayerID(), town.getLayerID(), road.getLayerID(), province.getLayerID()] 
render.setLayerSet(ID) 
rect = QgsRectangle(render.fullExtent()) 
rect.scale(1.1) 
render.setExtent(rect) 
render.setOutputSize(img.size(), img.logicalDpiX()) 
render.render(p) 
p.end() 
img.save("/filepath/first_render.png","png")
asked Jul 26, 2013 at 7:25
6
  • Have you tried to create the QgsRectangle with map coordinates instead of pixel coordinates? Commented Jul 26, 2013 at 8:28
  • The datasets are in WGS84 UTM36S ....and the values I have put in are metres which is correct? Commented Jul 26, 2013 at 10:46
  • What is the output you get from your program - does it show the full extent of all layers? Commented Jul 26, 2013 at 11:03
  • Yes - full extent. But I would like to make maps showing 'zoomed-in' areas ...to show the details of a raster Commented Jul 26, 2013 at 11:19
  • Try to call renderer.setDestinationCrs() to tell the renderer in what CRS the extent is specified. Commented Jul 26, 2013 at 12:01

3 Answers 3

5

Perhaps it would suffice for you to simply save the map canvas as an image after zooming to the extent of interest. Making use of mapCanvas() doesn't add too many lines of code and would export a simple PNG.

From the python console, this code would produce a simple screen capture of the area oriented around a selected feature, all active layers, and any activated labels:

qgis.utils.iface.actionZoomToSelected().trigger()
qgis.utils.iface.mapCanvas().zoomScale(1000)
qgis.utils.iface.mapCanvas().saveAsImage('test.png', None, 'PNG') 
answered Jul 16, 2014 at 5:27
2

If you know the coordinates of your rectangles, you can uses following code:

zoomRectangle = QgsRectangle(pos[0]-offset, pos[1]-offset,pos[0]+offset,pos[1]+offset)
self.canvas.setExtent(zoomRectangle)
self.canvas.refresh()

here, for you, just use

self.canvas.setExtent(rect)

And just for precision:

self.canvas = qgis.utils.iface.mapCanvas()

or equally for plugin, not pyqgis console

self.canvas = self.iface.mapCanvas()
answered Nov 6, 2014 at 7:09
2

QGIS 3

project_path = "D://my_project.qgs"
# load the project, load project instance (pi)
pi = QgsProject.instance()
pi.read(project_path)
# get the project's layout
plm = pi.layoutManager()
layout = plm.layoutByName("my_layout") # your layout name
#get reference map
refmap = layout.referenceMap()
xmin = ...you
ymin = ...provide
xmax = ...these coordinates
ymax = ...in your maps CRS
# set extent
bb = QgsRectangle(xmin, ymin, xmax, ymax )
refmap.setExtent(bb)
answered Jun 21, 2018 at 15:44

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.