6

Is there a QGIS Python binding for generating a grid programmatically without using the GUI?

  • grid of points or grid of polygons ? – gene Dec 9 '13 at 17:25
  • @gene Preferably grid of polygons. – Orestis Tsinalis Dec 10 '13 at 12:44
  • "without GUI" do you mean "using the QGIS API from command line without having to start QGIS itself"? – underdark Dec 14 '13 at 15:21
  • @underdark Yes, exactly. – Orestis Tsinalis Dec 16 '13 at 15:06
9

From an existing layer:

enter image description here

1) you can use processing with the algorithm "qgis:creategrid" as in the "Hex grid from layer bounds" in Processing/Scripts/Example scripts. (look at Processing-Help / qgis / creategrid.rst)

squared grid

import processing
layer = canvas.layer(0)
cellsize = 1000
input = processing.getobject(layer.name())
centerx = (input.extent().xMinimum() + input.extent().xMaximum()) / 2
centery = (input.extent().yMinimum() + input.extent().yMaximum()) / 2
width = (input.extent().xMaximum() - input.extent().xMinimum())
height = (input.extent().yMaximum() - input.extent().yMinimum())
grid="/yourpath/grid.shp"
processing.runandload("qgis:creategrid", cellsize, cellsize, width, height, centerx, centery, 1, input.crs().authid(), grid)

enter image description here

rectangular grid

.....
cellsizex = 500
cellsizey = 1000
.....
processing.runandload("qgis:creategrid", cellsizex, cellsizey, width, height, centerx, centery, 1, input.crs().authid(), grid)

enter image description here

For other types of grids change the value in runalg (0,1,2,3 = Rectangle (line), Rectangle (polygon), Diamond (polygon), Hexagon (polygon)):

For Hexagonal grid

....
processing.runandload("qgis:creategrid", cellsize, cellsize, width, height, centerx, centery, 3, input.crs().authid(), grid)

enter image description here

2) You can adapt the script of ustroetz in Create a square grid polygon shapefile with python

part of my class to create a memory layer limited here to the geometry of Polygons:

class Crea_layer(object):
    def __init__(self,name,type):
        self.type=type
        self.name = name
        self.layer =  QgsVectorLayer(self.type, self.name , "memory")
        self.pr =self.layer.dataProvider() 
    def create_poly(self,points):
        self.seg = QgsFeature()  
        self.seg.setGeometry(QgsGeometry.fromPolygon([points]))
        self.pr.addFeatures( [self.seg] )
        self.layer.updateExtents()
    @property
    def disp_layer(self):
        QgsMapLayerRegistry.instance().addMapLayers([self.layer])

The script to create a squared grid layer from an existing layer:

from math import ceil
canvas= qgis.utils.iface.mapCanvas()
# first layer
layer = canvas.layer(0)
xmin,ymin,xmax,ymax = layer.extent().toRectF().getCoords()
gridWidth = 1000
gridHeight = 1000
rows = ceil((ymax-ymin)/gridHeight)
cols = ceil((xmax-xmin)/gridWidth)
ringXleftOrigin = xmin
ringXrightOrigin = xmin + gridWidth
ringYtopOrigin = ymax
ringYbottomOrigin = ymax-gridHeight
pol = Crea_layer("grid", "Polygon")
for i in range(int(cols)):
    # reset envelope for rows
    ringYtop = ringYtopOrigin
    ringYbottom =ringYbottomOrigin
    for j in range(int(rows)):
        poly = [QgsPoint(ringXleftOrigin, ringYtop),QgsPoint(ringXrightOrigin, ringYtop),QgsPoint(ringXrightOrigin, ringYbottom),QgsPoint(ringXleftOrigin, ringYbottom),QgsPoint(ringXleftOrigin, ringYtop)] 
        pol.create_poly(poly) 
        ringYtop = ringYtop - gridHeight
        ringYbottom = ringYbottom - gridHeight
    ringXleftOrigin = ringXleftOrigin + gridWidth
    ringXrightOrigin = ringXrightOrigin + gridWidth

pol.disp_layer

Result:

enter image description here

But you can modify the script using numpy in place of math ceil and int

import numpy as np
rows = (ymax-ymin)/gridHeight
cols = (xmax-xmin)/gridWidth
for i in np.arange(cols):
    ....
    for j in np.arange(rows):
         ....

and if you don't understand xmin,ymin,xmax,ymax = layer.extent().toRectF().getCoords()

xmin = layer.extent().xMinimum()
xmax = layer.extent().xMaximum()
ymin = layer.extent().yMinimum()
ymax = layer.extent().yMaximum()
# = in one line
xmin,ymin,xmax,ymax = layer.extent().toRectF().getCoords()

and to go faster, you can even use the gridding functions of numpy

4

You can also create a Vector Grid

To Create the Vector Grid using the extents of the Vector Layer, we use:

processing.runalg('qgis:vectorgrid', extent, step_x, step_y, type, output)

from https://docs.qgis.org/2.8/en/docs/user_manual/processing_algs/qgis/vector_creation_tools.html#create-grid

Here is the code on how to achieve the desired result, please note this will work on all vector layers, not just point vector Layers

cellsize = 0.0001 #Cell Size in WGS 84 will be 10 x 10 meters 
crs = "EPSG:4326" #WGS 84 System 
input = processing.getObject(gridbh.name()) #Use the processing.getObject to get information from our vector layer
xmin = (input.extent().xMinimum()) #extract the minimum x coord from our layer
xmax =  (input.extent().xMaximum()) #extract our maximum x coord from our layer
ymin = (input.extent().yMinimum()) #extract our minimum y coord from our layer
ymax = (input.extent().yMaximum()) #extract our maximum y coord from our layer
#prepare the extent in a format the VectorGrid tool can interpret (xmin,xmax,ymin,ymax)
extent = str(xmin)+ ',' + str(xmax)+ ',' +str(ymin)+ ',' +str(ymax)  
grid="PATH_FOR_VECTORGRID_CREATION"
processing.runalg('qgis:vectorgrid',  extent, cellsize, cellsize,  0, grid)

enter image description here

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.