2

I'm building a standalone pyQGIS script which creates a PNG from a Shapefile. During the creation process, I apply a style defined in a qml file (saved from QGIS). Below is an extract of the qml files where the color and the linewidth of the lines are described.

...
<renderer-v2 attr="meanNO2" forceraster="0" symbollevels="0" type="graduatedSymbol" graduatedMethod="GraduatedColor" enableorderby="0">
  <ranges>
    <range render="true" symbol="0" lower="0.000000000000000" upper="20.000000000000000" label=" 0.0000 - 38.7500 "/>
    <range render="true" symbol="1" lower="20.000000000000000" upper="50.000000000000000" label=" 38.7500 - 77.5000 "/>
    <range render="true" symbol="2" lower="50.000000000000000" upper="65.000000000000000" label=" 77.5000 - 116.2500 "/>
    <range render="true" symbol="3" lower="65.000000000000000" upper="100.000000000000000" label=" 116.2500 - 155.0000 "/>
    <range render="true" symbol="4" lower="100.000000000000000" upper="150.000000000000000" label=" 155.0000 - 193.7500 "/>
    <range render="true" symbol="5" lower="150.000000000000000" upper="200.000000000000000" label=" 193.7500 - 232.5000 "/>
    <range render="true" symbol="6" lower="200.000000000000000" upper="300.000000000000000" label=" 232.5000 - 271.2500 "/>
    <range render="true" symbol="7" lower="300.000000000000000" upper="310.000000000000000" label=" 271.2500 - 310.0000 "/>
  </ranges>
  <symbols>
    <symbol alpha="1" clip_to_extent="1" type="line" name="0">
      <layer pass="0" class="SimpleLine" locked="0">
        <prop k="capstyle" v="square"/>
        <prop k="customdash" v="5;2"/>
        <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
        <prop k="customdash_unit" v="MM"/>
        <prop k="draw_inside_polygon" v="0"/>
        <prop k="joinstyle" v="bevel"/>
        <prop k="line_color" v="245,66,40,255"/>
        <prop k="line_style" v="solid"/>
        <prop k="line_width" v="0.26"/>
        <prop k="line_width_unit" v="MM"/>
        <prop k="offset" v="0"/>
        <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
        <prop k="offset_unit" v="MM"/>
        <prop k="use_custom_dash" v="0"/>
        <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
      </layer>
    </symbol>
    <symbol alpha="1" clip_to_extent="1" type="line" name="1">
    ...

By applying this qml file, I'm able to color the lines but not to alter the linewidth, e.g., if I change:

  <prop k="line_width" v="0.26"/>

to:

  <prop k="line_width" v="1.06"/>

the output PNG looks exactly the same!

Below is the pyQGIS script I wrote (mostly by combining answers from stackexchange):

from qgis.core import *
import qgis.utils
from PyQt4.QtCore import QSize
from PyQt4.QtGui import QPainter, QImage, QColor
from PyQt4.QtCore import QFileInfo, Qt

app = QgsApplication([],True)
# supply path to where is your qgis installed
QgsApplication.setPrefixPath("/usr/", True)
# load providers
QgsApplication.initQgis()

fname = "/path/to/shapefile.shp"

layer = QgsVectorLayer(fname,'layer','ogr')
if not layer.isValid():
        print "layer not valid, please check the file path:\n"+fname
        exit

layer.loadNamedStyle( '/path/to/styleFile.qml')

img = QImage(QSize(1927,1607),QImage.Format_ARGB32)

QgsMapLayerRegistry.instance().addMapLayer(layer)

img.fill(Qt.transparent)

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

render = QgsMapRenderer()

lst = [layer.id()]  # add ID of every layer                                             
render.setLayerSet(lst)

# Extract a sub portion of the shapefile
rect = QgsRectangle(-19567.88,6706890.61,-4891.97,6719120.53)

render.setExtent(rect)
render.setOutputSize(img.size(), img.logicalDpiX())
render.render(p)

p.end()

img.save('/path/to/image.png',"png")

I tried unsuccessfully an alternative based on what is suggested here

symbols = layer.rendererV2().symbols()
for symbol in symbols:
    symbol.setWidth(1.06)

Does anyone have an idea what is going on?

  • Maybe you need to refresh the canvas after changing the properties. Have you tried that? Try layer.triggerRepaint() to make sure the layer is redraw. – jgrocha Aug 30 '17 at 12:19
  • Thanks! Just tried it (at different positions within the script) without effects on the final output. – Boris Quennehen Aug 30 '17 at 12:39

Your Answer

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

Browse other questions tagged or ask your own question.