Adding a custom shape to the map

The QGIS composer has an object for drawing and styling nonspatial shapes, including rectangles, ellipses, and triangles. In this recipe, we'll add some rectangles filled with different colors, which will resemble a simple bar chart, as an example of using shapes.

Getting ready

Download the zipped shapefile for this map from https://geospatialpython.googlecode.com/svn/Mississippi.zip and extract it to your qgis_data directory, to in a subdirectory named ms.

We will also use the MapComposer library from https://geospatialpython.googlecode.com/svn/MapComposer.py to simplify the creation of the map composition.

Place the file in the .qgis2/python directory within your home directory.

How to do it...

First, we will create a simple map composition with the shapefile. Then, we will define the style properties for our rectangles. Next, we will draw the rectangles, apply the symbols, and render the composition. To do this, we need to perform the following steps:

  1. First, we must import the PyQGIS and Qt GUI libraries as well as the MapComposer library, as follows:
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    from qgis.core import *
    from qgis.gui import *
    import MapComposer
    
  2. Next, we create the map composition by using the shapefile:
    lyr = QgsVectorLayer("/qgis_data/ms/mississippi.shp", "Mississippi", "ogr")
    reg = QgsMapLayerRegistry.instance()
    reg.addMapLayer(lyr)
    mr = iface.mapCanvas().mapRenderer()
    qc = MapComposer.MapComposer(qmlr=reg, qmr=mr)
    
  3. Now, we create three basic fill symbols by building Python dictionaries with color properties and initialize the symbols with these dictionaries:
    red = {'color':'255,0,0,255','color_border':'0,0,0,255'}
    redsym = QgsFillSymbolV2.createSimple(red)
    blue = {'color':'0,0,255,255','color_border':'0,0,0,255'}
    bluesym = QgsFillSymbolV2.createSimple(blue)
    yellow = {'color':'255,255,0,255','color_border':'0,0,0,255'}
    yellowsym = QgsFillSymbolV2.createSimple(yellow)
    
  4. Then, we calculate the y position of the first shape, relative to the map:
    mch = qc.composerMap.rect().height()
    sy = qc.y + mch
    
  5. We create the first shape and set it to the type 1, which is a rectangle:
    qc.shape1 = QgsComposerShape(10,sy-25,10,25,qc.c)
    qc.shape1.setShapeType(1)
    
  6. Next, we tell the shape to use a symbol, set the symbol for one of our three fill symbols, and add the shape to the composition:
    qc.shape1.setUseSymbolV2(True)
    qc.shape1.setShapeStyleSymbol(redsym)
    qc.c.addItem(qc.shape1)
    
  7. We repeat the process with two other shapes, changing their position, size, and symbols to make them look different:
    qc.shape2 = QgsComposerShape(22,sy-18,10,18,qc.c)
    qc.shape2.setShapeType(1)
    qc.shape2.setUseSymbolV2(True)
    qc.shape2.setShapeStyleSymbol(bluesym)
    qc.c.addItem(qc.shape2)
    qc.shape3 = QgsComposerShape(34,sy-12,10,12,qc.c)
    qc.shape3.setShapeType(1)
    qc.shape3.setUseSymbolV2(True)
    qc.shape3.setShapeStyleSymbol(yellowsym)
    qc.c.addItem(qc.shape3)
    
  8. Finally, we output the composition as an image:
    qc.output("/qgis_data/map.jpg", "jpg")
    

Verify that your output image looks similar to the following:

How to do it...

How it works...

This simple graphical output is nearly 40 lines of code. While there may be some limited uses for dealing with these shapes, in most cases, the simpler route will be to just import images. However, it provides a good foundation for a richer graphics API, as QGIS continues to evolve.

There's more...

If you are using fill symbols within a Python plugin in a QGIS version less than 2.6, you must ensure that the symbols are defined in the global scope, or QGIS will crash due to a bug. The easiest way to include the variables in the global scope is to define them immediately after the import statements. It also affects scripts that are run in the Script Runner plugin. This bug was fixed in version 2.6 and subsequent versions.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset