3

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

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)
  • 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? – sirgeo Oct 5 '16 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? – GeospatialPython.com Oct 6 '16 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

  • 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. – sirgeo Oct 5 '16 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. – ahmadhanb Oct 5 '16 at 7:09
  • Please check the updated answer. I provided a sample of the output in my output folder. – ahmadhanb Oct 5 '16 at 7:13
  • i got the tfws to generate finally... had to create a second reference map for some reason. – sirgeo Oct 5 '16 at 15:43

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.