4

I want to create a grid with a python script in PyQgis. I have the layer from which I want to take the extent.

it seems that there is different formula : The one from QGIS doc : https://docs.qgis.org/2.6/en/docs/user_manual/processing_algs/qgis/vector_creation_tools/creategrid.html

processing.runalg('qgis:creategrid', type, width, height, hspacing, vspacing, centerx, centery, crs, output)

The one I found on different forums with a string for extent : processing.runalg('qgis:creategrid', type, extent, hspacing, vspacing, crs, output)

I tried both and I always got :problem answer

I tried it from my script and from the console.

Here is my code if it can help :

#!/usr/bin/env Python
from glob import glob
from os import path
import numpy as np
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from qgis.core import *
from qgis.utils import iface
import processing


class Grid:
def __init__(self, iface,crs):
    """Initialize using the qgis.utils.iface
    object passed from the console.

    """
    self.iface = iface
    self.crs=crs

def new_grid(self,cellsizex,cellsizey,extent,centerx,centery,grid_out):
    processing.runalg('qgis:creategrid', type=1, extent=extent, hspacing=cellsizex, vspacing=cellsizey, crs=self.crs, output=grid_out)


class Extent:
def __init__(self, iface):
    """Initialize using the qgis.utils.iface
    object passed from the console.

    """
    self.iface = iface

def main(self):

    pabs= "K:\Histo_Europe_All" #path absolu
    path=pabs+"\0_Quadrillage\extent_eu.shp"
    name_l="extent_eu"

    layer=QgsVectorLayer(path,name_l, "ogr")

    extent = QgsVectorLayer( path, '', 'ogr' ).extent()

    cellsize = 1000
    centerx = (extent.xMinimum() + extent.xMaximum()) / 2
    centery = (extent.yMinimum() + extent.yMaximum()) / 20

    #first method
    width = (extent.xMaximum() - extent.xMinimum())
    height = (extent.yMaximum() - extent.yMinimum())/10

    #second method
    extent2 = str(extent.xMinimum())+ ',' + str(extent.xMaximum())+ ',' +str(ymin)+ ',' +str(extent.yMaximum())  

    cellsizex = 0,002775
    cellsizey = 0,002775
    ymin=extent.yMinimum()+ 0,8 * (extent.yMaximum() - extent.yMinimum())



    grid=pabs+"\1_Grids\Grid0.shp"
    g=Grid(self.iface,layer.crs().authid())
    g.new_grid(cellsizex,cellsizey,extent2,centerx,centery,grid)

Don't mind the missing spaces at the beginning of the classes, they do exist in my code.

I edit my question based on comments. I also gave up the extent as QGIS advise width and height. My code is now the following :

class Grid:
def __init__(self, iface,crs):
    """Initialize using the qgis.utils.iface
    object passed from the console.

    """
    self.iface = iface
    self.crs=crs

def new_grid(self,cellsizex,cellsizey,width,height,centerx,centery,grid_out):
    #processing.runalg("qgis:creategrid", cellsizex, cellsizey, width, height, centerx, centery, 1, layer.crs().authid(), grid_out)
    #processing.runalg('qgis:creategrid', width, height, cellsizex, cellsizey, centerx, centery,"EPSG:4326", grid_out)
    #processing.runalg('qgis:creategrid', type=1, extent=extent, hspacing=cellsizex, vspacing=cellsizey, crs=self.crs, output=grid_out)
    processing.runalg('qgis:creategrid', 1, width,height, cellsizex, cellsizey, self.crs, output=grid_out)

class Extent:
def __init__(self, iface):
    """Initialize using the qgis.utils.iface
    object passed from the console.

    """
    self.iface = iface

def main(self):

    pabs= "K:/Histo_Europe_All" #path absolu
    path=pabs+"/0_Quadrillage/extent_eu.shp"
    name_l="extent_eu"

    layer=QgsVectorLayer(path,name_l, "ogr")

    extent = QgsVectorLayer( path, '', 'ogr' ).extent()

    cellsize = 1000
    centerx = (extent.xMinimum() + extent.xMaximum()) / 2
    centery = (extent.yMinimum() + extent.yMaximum()) / 20
    width = (extent.xMaximum() - extent.xMinimum())
    height = (extent.yMaximum() - extent.yMinimum())/10
    print(width)
    print(height)

    cellsizex = 0.002775
    cellsizey = 0.002775
    ymin=extent.yMinimum()+ 0.8 * (extent.yMaximum() - extent.yMinimum())
    extent2 = str(extent.xMinimum())+ ',' + str(extent.xMaximum())+ ',' +str(ymin)+ ',' +str(extent.yMaximum())  

    grid=pabs+"/1_Grids/Grid0.shp"
    g=Grid(self.iface,layer.crs().authid())
    g.new_grid(cellsizex,cellsizey,width,height,centerx,centery,grid)

Now it answers : Error: Wrong parameter value: 40.967325 (width)

  • I think self.crs=self.layer.crs.authid() should instead be self.crs=self.layer.crs().authid() – Joseph Jun 27 '17 at 12:07
  • Is it ok in my edited post? – J.Delannoy Jun 27 '17 at 12:10
  • Any particular reason why you are using two different classes instead of putting those functions into one? – Joseph Jun 28 '17 at 9:51
  • 1
    Edited my post with a slightly more concise version. Seems to work fine for me so hopefully for you too :) – Joseph Jun 28 '17 at 10:49
  • 1
    Yes it works now !!! Thank you very much for your help. If ever someone else is interested : with this version of QGIS I can't use centerx and centery some I made calcuatation so as to the extent of my grid is different to the one of my layer. For example : ymin=ymin+(ymax-ymin)/2 – J.Delannoy Jun 28 '17 at 11:26
2

I think there's a couple of things you could try:

  • In your new_grid() function, replace the processing line with the following (if you want to assign variables such as type=1 etc. then you should use a dictionary as described in this post:

    processing.runalg('qgis:creategrid', 1, extent, cellsizex, cellsizey, self.crs, output=grid_out)
    
  • When defining a path for your output, either include the raw string (r) or use a single forward slash to escape:

    grid=pabs+"/1_Grids/Grid0.shp"
    

Edit:

Made some changes to your code which might help (unfortunately, I can't test it at the moment):

class Grid:
def __init__(self, iface):
    """Initialize using the qgis.utils.iface
    object passed from the console.
    """
    self.iface = iface

def new_grid(self,cellsizex,cellsizey,layer_extent,crs,grid_out):
    processing.runalg('qgis:creategrid', 1, layer_extent, cellsizex, cellsizey, crs, grid_out)

class Extent:
def __init__(self, iface):
    """Initialize using the qgis.utils.iface
    object passed from the console.
    """
    self.iface = iface

def main(self):
    pabs= "K:/Histo_Europe_All" #path absolu
    path=pabs+"/0_Quadrillage/extent_eu.shp"
    name_l="extent_eu"

    layer=QgsVectorLayer(path,name_l, "ogr")
    crs=layer.crs().authid()

    extent = layer.extent()
    xmin = extent.xMinimum()
    xmax = extent.xMaximum()
    ymin = extent.yMinimum()
    ymax = extent.yMaximum()

    cellsizex = 0.002775
    cellsizey = 0.002775

    grid=pabs+"/1_Grids/Grid0.shp"
    g=Grid(self.iface)
    g.new_grid(cellsizex,cellsizey,"%f,%f,%f,%f"% (xmin,xmax,ymin,ymax),crs,grid)

Edit 2:

Combined both classes into one, did a quick test and works fine for me so hopefully it will for you too.

class Grid:
    def __init__(self, iface):
        """Initialize using the qgis.utils.iface
        object passed from the console.
        """
        self.iface = iface

    def main(self):
        pabs = "K:/Histo_Europe_All" #path absolu
        path = pabs+"/0_Quadrillage/extent_eu.shp"
        grid = pabs+"/1_Grids/Grid0.shp"
        name_l = "extent_eu"

        layer = QgsVectorLayer(path,name_l, "ogr")
        crs = layer.crs().authid()
        extent = layer.extent()
        xmin = extent.xMinimum()
        xmax = extent.xMaximum()
        ymin = extent.yMinimum()
        ymax = extent.yMaximum()

        cellsizex = 0.002775
        cellsizey = 0.002775

        processing.runalg('qgis:creategrid', 1, "%f,%f,%f,%f"% (xmin,xmax,ymin,ymax), cellsizex, cellsizey, crs, grid)

Then use self.main() to call the function.

  • I should have said that i also tried this way, sorry. I just tried the dictionary thing because I was wondering if the problem came from the fact that I included center parameters. So I retried with your proposition, I still get the same error. – J.Delannoy Jun 27 '17 at 11:36
  • @J.Delannoy - No problem! Did you also use decimal points instead of commas in your cellsizes? (i.e. 0,002775 to 0.002775) – Joseph Jun 27 '17 at 11:37
  • Yes I tried it too, it does not change the error message though. – J.Delannoy Jun 27 '17 at 11:42
  • As I put exactly the sames parameters it asks in its error message, that must be a problem of type, no ? My parameters are numbers except the extent, the crs and the output which are strings. – J.Delannoy Jun 27 '17 at 11:50
  • @J.Delannoy - Try using self.crs=crs.authid() – Joseph Jun 27 '17 at 11:53

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.