5

Overall Question: How can I get the rendered tif image to keep the modifications seen in the image produced by map canvas?


I am writing a standalone Python script. I have simplified my code below for debugging purposes. Its purpose is to load a shapefile vector layer, in my case SOUNDG.shp, of the geometry type 'point', and then serve a tif image of the vector layer SOUNDG.

I have experimented with QgsMapCanvas thoroughly and can confirm that this specific vector layer is correctly displayed in the canvas; thus, paths to my file and the creation of a vector layer object are correct. Now, I am abandoning canvas entirely and am transitioning to solely relying on serving up a tif image through my script. I am keeping my modifications of the vector layer in my script as well (the depth values).

Canvas Image of SOUNDG point data

As you can see I have modified the vector layer corresponding to depth values. canvas image

Tif image

In contrast to canvas, when rendering to tif in my script, as seen below, my SOUNDG.tif image is a blank white image. There is nothing displayed. In addition, I receive no error messages. blank image

I have tried rendering multiple layers of other geometries (lines and polygons) to tif and they are rendered with no issues at all. All layers are visible. My only issue lies with vector layers that have point geometries - they aren't visible when rendered to tif.

How can I fix this? (Using only script)

Here is my code based off of PyQgis' Cookbook:

# supply path to qgis install location
QgsApplication.setPrefixPath('/usr', True)
# create a reference to the QgsApplication, setting the
# second argument to False disables the GUI
app = QgsApplication([], True)
# load providers
app.initQgis()

# create image
img = QImage(QSize(800, 600), QImage.Format_ARGB32_Premultiplied)

# set image's background color
color = QColor(255, 255, 255)
img.fill(color.rgb())

# create painter
p = QPainter()
p.begin(img)
p.setRenderHint(QPainter.Antialiasing)
renderer = QgsMapRenderer()

# keep track of all layer IDs
mapLayers = []

# create vector layer object
layer = QgsVectorLayer('/ENC_ROOT/US6SP10M/shapefiles/SOUNDG.shp',\
                       'SOUNDG', 'ogr')
QgsMapLayerRegistry.instance().addMapLayer(layer)
mapLayers.append(layer.id())
renderer.setLayerSet(mapLayers)

# set extent
rect = QgsRectangle(renderer.fullExtent())
rect.scale(1.1)
renderer.setExtent(rect)

# set output size
renderer.setOutputSize(img.size(), img.logicalDpiX())

# do the rendering
renderer.render(p)

p.end()

# save image'
img.save("/ENC_ROOT/US6SP10M/shapefiles/SOUNDG.tif", "tif")

app.exitQgis()

I noticed this occurs when also rendering to 'png', or rather, any method of rasterization.

UPDATE: I've begun to experiment with the gdal_rasterize route:

def rasterize(layer, source_dir, output_dir):
# this renders the point to tif correctly but no modifications are considered
call(['gdal_rasterize', '-a', 'DEPTH', '-ts', '800', '600', '-l', layer, source_dir, output_dir])

This method now gives me a .tif image that displays points in a black and white format. When I create modifications to the point layer, such as replacing the dots with ints representing water depths, is there a way such that those modifications would still hold in the rasterized .tif version?

Tif image using gdal_rasterizegdal_rasterize


I've spent numerous edits trying to make this a smooth read and very understandable. If you aren't up voting it then that is telling me that something isn't clear for you. Please make that clear so that I can edit the post as needed; this will hopefully bring me to someone who does have an answer.


  • Why don't you simply use gdal_rasterize? Re-inventing the wheel is no good idea if you have little time. – AndreJ Jul 19 '16 at 18:41
  • I need to modify these vector layers such as changing marker symbology and appearance. Would a simple gdal_rasterize keep these changes? I've already modified numerous vector layers, all that is needed is to rasterize it. And also, that's kind of the question I'm having here, is what I'm asking for 'reinventing the wheel'? There is a simple method to create a tif which works for the rest of the layers, hence, I'm curious if this 'point' issue is a known issue or not. No one seems to have an issue with it, thus, there must be something going on that I'm unaware of. – GreyEyedPallas Jul 19 '16 at 18:47
  • This question might be related: gis.stackexchange.com/questions/198287/… – AndreJ Jul 19 '16 at 18:58
  • Although it gives some alternatives. It seems as though if I go the routes stated in the link you provided, I may not be able to keep my modifications of the layer – GreyEyedPallas Jul 20 '16 at 18:31
  • 1
    Rasterize does not seem to fit, since you want to apply styling to your data. Have you thought about using the print composer? It can output georeferenced tif as well. – AndreJ Jul 21 '16 at 18:48
5

I think that your issue is only a "Zoom In" problem. I'm going to render to tif these random points with Raster-> Conversion -> Rasterize (Vector to Raster) Tool (cell resolution 30 x 30) of QGIS; equivalent to your standalone Python script.

enter image description here

Loaded raster layer looks as if no point had been rasterized.

enter image description here

However, with point layer as first layer, 'Zoom In' (very low scale) in whatever point and its corresponding rasterized cell appears.

enter image description here

  • I'm sorry I don't think I quite understand. I've tried zooming into my tif image and I still don't see any points. – GreyEyedPallas Jul 18 '16 at 13:13
  • I also ran my code then loaded the .tif image as a raster layer in QGIS and still had no success in seeing points. (I tried zooming in as well) – GreyEyedPallas Jul 18 '16 at 14:55
  • I've run into that problem too. It seems like it is a bug creating a new image. If you use an already created image it will work fine. – caiohamamura Jul 18 '16 at 18:28
  • The bug you are talking about is only an issue when running these process specifically through QGIS. I am only using Python scripting to generate this so that is not the issue. – GreyEyedPallas Jul 19 '16 at 16:14
3

In case there are those who may run into the same issue, here is my solution (that works beautifully!)

from qgis.core import *
from qgis.gui import *
from PyQt4.QtCore import *

source_dir = '/home/cassandra/desktop/file_formats/ENC_ROOT/US6SP10M/shapefiles/SOUNDG.shp'
name = 'SOUNDG'
output_dir = '/home/cassandra/desktop/file_formats/ENC_ROOT/US6SP10M/shapefiles/SOUNDG.tif'

# initiate canvas for debugging purposes
# supply path to qgis install location
QgsApplication.setPrefixPath('/usr', True)
# create a reference to the QgsApplication, setting the
# second argument to False disables the GUI
app = QgsApplication([], True)
# load providers
app.initQgis()
# create Qt mapCanvas widget
canvas = QgsMapCanvas()
canvas.setCanvasColor(Qt.white)
# enable this for smooth rendering
canvas.enableAntiAliasing(True)

# load vector layer into canvas
layer = QgsVectorLayer(source_dir, name, 'ogr')
# register the vector layer to the layer registry
QgsMapLayerRegistry.instance().addMapLayer(layer)

# set extent of canvas as well as what layers you would like to display
canvas.setExtent(layer.extent())
canvas.setLayerSet([QgsMapCanvasLayer(layer)])
canvas.refresh()

# rendering my map canvas to tif image
settings = canvas.mapSettings()
settings.setLayers([layer.id()])
job = QgsMapRendererParallelJob(settings)
job.start()
job.waitForFinished()
image = job.renderedImage()
image.save(output_dir)

app.exitQgis()
  • So you had to use QgsMapCanvas after all? Did you submit a bug ticket? – caiohamamura Jul 23 '16 at 7:52
  • I'm still a bit unsure as to what is going on under the hood of these working statements, but yes, I think I am relying on QgsMapCanvas. and No I did not, but I will go ahead and do that. – GreyEyedPallas Jul 24 '16 at 16:17
  • I recommend the suggested method as opposite to saveToImage() because using it with a custom QgsMapCanvas() give back unreadable images – Enrico Ferreguti Mar 13 '17 at 12:30

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.