4

Have several hundred grid views with OpenLayers WMS that are being exported in QGIS using Project> "Save as Image". Doing it manually selecting individual grids, "zoom to selected", Project tab> "Save as Image", save as tiff, repeat...

Seems Python could automate this with a simple script yes?

Screen shot example

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Oct 5, 2016 at 1:29

2 Answers 2

5

Since you asked for a python script, you can get rid of the mouse clicks using the PyQGIS Atlas API. The following example loops through the features in a layer, sets up a map composition, and outputs each map view as a PNG image:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
coverage = "/Users/joellawhead/qgis_data/atlas/grid.shp"
atlasPattern = "/Users/joellawhead/qgis_data/atlas/output_"
# Load the map layer. This example uses a shapefile
# but you can use any supported QGIS layer.
vlyr = QgsVectorLayer(coverage, "grid", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(vlyr)
# Set up the map renderer
mr = QgsMapRenderer()
mr.setLayerSet([vlyr.id()])
mr.setProjectionsEnabled(True)
mr.setMapUnits(QGis.DecimalDegrees)
crs = QgsCoordinateReferenceSystem()
crs.createFromSrid(4326)
mr.setDestinationCrs(crs)
# Create a composition object which
# handles layouts and pages
c = QgsComposition(mr)
c.setPaperSize(297, 210)
# Set up the symbology for the shapefile.
# Not necessary for a WMS
gray = { "color": "155,155,155" }
mapSym = QgsFillSymbolV2.createSimple(gray)
renderer = QgsSingleSymbolRendererV2(mapSym)
vlyr.setRendererV2(renderer)
# Put the composer in "atlas" mode to
# zoom to features automatically.
atlasMap = QgsComposerMap(c, 20, 20, 130, 130)
atlasMap.setFrameEnabled(True)
c.addComposerMap(atlasMap)
# Configure the atlas
atlas = c.atlasComposition()
atlas.setCoverageLayer(vlyr)
atlas.setHideCoverage(False)
atlas.setEnabled(True)
c.setAtlasMode(QgsComposition.ExportAtlas)
# Optional overview map on each image
ov = QgsComposerMap(c, 180, 20, 50, 50)
ov.setFrameEnabled(True)
ov.setOverviewFrameMap(atlasMap.id())
c.addComposerMap(ov)
rect = QgsRectangle(vlyr.extent())
ov.setNewExtent(rect)
# Yellow extent box for overview map
yellow = { "color": "255,255,0,255" }
ovSym = QgsFillSymbolV2.createSimple(yellow)
ov.setOverviewFrameMapSymbol(ovSym)
# Label the map image with an attribute column
lbl = QgsComposerLabel(c)
c.addComposerLabel(lbl)
lbl.setText("[% \"GRID_ID\" %]")
lbl.setFont(QgsFontUtils.getStandardTestFont())
lbl.adjustSizeToText()
lbl.setSceneRect(QRectF(150, 5, 60, 15))
# Some more page composition info
atlasMap.setAtlasDriven(True)
atlasMap.setAtlasScalingMode(QgsComposerMap.Auto)
atlasMap.setAtlasMargin(0.10)
# Loop through each feature to zoom and create an image.
atlas.setFilenamePattern("'%s' || $feature" % atlasPattern)
atlas.beginRender()
for i in range(0, atlas.numFeatures()):
 atlas.prepareForFeature(i)
 filename = atlas.currentFilename() + ".png"
 print "Writing file %s" % filename
 filenames.append(filename)
 img = c.printPageAsRaster(0)
 img.save(filename, 'png')
atlas.endRender()

If you have a large number of features, you could extend this script to output a PDF map book. For this you can use the PyPDF2 library. You would replace the "for" loop with the following code and additional code that outputs each view as a PDF, combines them into a single PDF, and then deletes the individual PDFs:

atlas.setFilenamePattern("'%s' || $feature" % atlasPattern)
atlas.beginRender()
for i in range(0, atlas.numFeatures()):
 atlas.prepareForFeature(i)
 filename = atlas.currentFilename() + ".pdf"
 print "Writing file %s" % filename
 filenames.append(filename)
 c.exportAsPDF(filename)
atlas.endRender()
output = PyPDF2.PdfFileWriter()
for f in filenames:
 pdf = open(f, "rb")
 page = PyPDF2.PdfFileReader(pdf)
 output.addPage(page.getPage(0))
 os.remove(f)
print "Writing final mapbook..."
book = open(mapbook, "wb")
output.write(book)
answered Oct 5, 2016 at 4:40
2
  • I changed the code lines 5 and 6 to my input grid and output folders, pasted it into Python Console, and it just adds the grid with nothing else happening... i am a Python novice, what are the missing steps here? Commented Oct 5, 2016 at 15:42
  • Keep in mind the output "folder" is actually a path with a file name prefix. Also, what version of QGIS and what platform are you using? Commented Oct 6, 2016 at 15:09
5

The solution does not require python as the best solution is use Atlas generation tab and use each grid as an extent to export to an image, as you can see below:

enter image description here

The Atlas generation is located in the print composer:

enter image description here

Here is a great tutorial on how to use Atlas generation. Under the Atlas menu in the toolbar, you can use Atlas Preview, the check the output.

Once you get satisfied with the extent and result, use Export Atlas as Images located under the Atlas menu in the toolbar.

Also, Here is the output in the directory when Export World File is checked when exporting to tiff format, I have the tfw file as well:

enter image description here

answered Oct 5, 2016 at 2:01
4
  • Any idea why it is not writing a world file even though "Save world file" is checked? Need to have a world file (tfw) for all the tiffs, otherwise i think this will work. Commented Oct 5, 2016 at 6:37
  • @sirgeo but the (.tfw) is written in my case. I have both .tif and tfw in the output folder. I am using QGIS 2.14.7 LTR. Commented Oct 5, 2016 at 7:09
  • Please check the updated answer. I provided a sample of the output in my output folder. Commented Oct 5, 2016 at 7:13
  • i got the tfws to generate finally... had to create a second reference map for some reason. Commented Oct 5, 2016 at 15:43

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.