[GIS] Getting shapefile extent from standalone PyQGIS script

pyqgisqgis-processingstandalone

I am trying to obtain the extent of a polygon in a shapefile. I am running a standalone script which will create a grid based on the extent of the polygon. I have tried 2 methods: one from the example QGIS script Hex grid from layer bounds:

input = processing.getObject(input)

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()

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

And one from the Developer's Cookbook which also includes the script I am trying to run:

import os, sys, glob

from qgis.core import *
from qgis.gui import QgsMapCanvas
from PyQt4.QtGui import *
app = QApplication([])
QgsApplication.setPrefixPath("C:\\OSGeo4W64\\apps\\qgis", True)
QgsApplication.initQgis()

from os.path import expanduser
home = expanduser("~")

#   Folder path of the Results for shapefiles
path_dir = home + "\Desktop\Test\\"
path_res = path_dir + "Results\\"

# Prepare processing framework 
sys.path.append( home + '/.qgis2/python/plugins' )

# Get an iface object
canvas = QgsMapCanvas()
from processing.tests.qgis_interface import QgisInterface
iface = QgisInterface( canvas )

# Initialize the Processing plugin passing an iface object
from processing.ProcessingPlugin import ProcessingPlugin
plugin = ProcessingPlugin(iface)
from processing.tools import *

Cellsize = 1000
District = path_dir + "Input district shapefile\\" + "District.shp"
input = District
centerx = (input.xMin() + input.xMax()) / 2
centery = (input.yMin() + input.yMax()) / 2
width = input.xMax() - input.xMin()
height = input.yMax() - input.yMin()

def run():

    outputs_1=general.runalg("qgis:creategrid", Cellsize, Cellsize, width, height, centerx, centery, 1, 'EPSG:7405', None)
    outputs_2=general.runalg("qgis:fieldcalculator", outputs_1['SAVENAME'], 'ID', 1, 10, 0, True, '$rownum', None)
    outputs_3=general.runalg("qgis:deletecolumn", outputs_2['OUTPUT_LAYER'], 'longitude', None)
    outputs_4=general.runalg("qgis:deletecolumn", outputs_3['SAVENAME'], 'latitude', path_res  + "/" + "grid.shp")

run()
QgsApplication.exitQgis()
app.exit()

In both cases, an error is produced:

AttributeError: 'str' object has no attribute 'extent'

AttributeError: 'str' object has no attribute 'xMin'


Using the answer posted by @gcarrillo, here is the working script:

import os, sys, glob

from qgis.core import *
from qgis.gui import QgsMapCanvas
from PyQt4.QtGui import *
app = QApplication([])
QgsApplication.setPrefixPath("C:\\OSGeo4W64\\apps\\qgis", True)
QgsApplication.initQgis()

from os.path import expanduser
home = expanduser("~")

#   Folder path of the Results for shapefiles
path_dir = home + "\Desktop\Test\\"
path_res = path_dir + "Results\\"

# Prepare processing framework 
sys.path.append( home + '/.qgis2/python/plugins' )

# Get an iface object
canvas = QgsMapCanvas()
from processing.tests.qgis_interface import QgisInterface
iface = QgisInterface( canvas )

# Initialize the Processing plugin passing an iface object
from processing.ProcessingPlugin import ProcessingPlugin
plugin = ProcessingPlugin(iface)
from processing.tools import *

Cellsize = 1000
layerPath = path_dir + "Input district shapefile\\" + "Districts.shp"
extent = QgsVectorLayer( layerPath, '', 'ogr' ).extent()

centerx = (extent.xMinimum() + extent.xMaximum()) / 2
centery = (extent.yMinimum() + extent.yMaximum()) / 2
width = extent.xMaximum() - extent.xMinimum()
height = extent.yMaximum() - extent.yMinimum()

def run():

    outputs_1=general.runalg("qgis:creategrid", Cellsize, Cellsize, width, height, centerx, centery, 1, 'EPSG:7405', None)
    outputs_2=general.runalg("qgis:fieldcalculator", outputs_1['SAVENAME'], 'ID', 1, 10, 0, True, '$rownum', None)
    outputs_3=general.runalg("qgis:deletecolumn", outputs_2['OUTPUT_LAYER'], 'longitude', None)
    outputs_4=general.runalg("qgis:deletecolumn", outputs_3['SAVENAME'], 'latitude', path_res  + "/" + "grid.shp")

run()
QgsApplication.exitQgis()
app.exit()

Best Answer

This should be enough to get the extent of your Shapefile:

layerPath = path_dir + "Input district shapefile\\" + "District.shp"
extent = QgsVectorLayer( layerPath, '', 'ogr' ).extent()

The result is a QgsRectangle object, which has xMinimum(), xMaximum(), yMinimum(), and yMaximum() methods.