6

I'm trying to convert a vectorlayer (point- shapefile) to a raster-dataset (tiff) using python gdal-library in qgis.

On Graphical UserInterface I simple choose the menue "raster->conversion->rasterize". To get what I want, I fill in the file names in tool dialog box and choose "resolution in map units per pixel" horizonthal: 0.033 and vertical: 0.0164. That works fine, but when I try to script I orientated on documentation and adapted the code from source: http://pcjericks.github.io/py-gdalogr-cookbook/raster_layers.html#convert-an-ogr-file-to-a-raster like this:

# 1. Define pixel_size and NoData value of new raster
NoData_value = -9999
x_res = 0.03333378
y_res = 0.01666641
pixel_size = 1

# 2. Filenames for in- and output
_in = r"C:/Users/.../hoppla.shp"
_out = r"C:/Users/.../hoppla.tif"

# 3. Open Shapefile
source_ds = ogr.Open(_in)
source_layer = source_ds.GetLayer()
x_min, x_max, y_min, y_max = source_layer.GetExtent()

# 4. Create Target - TIFF
_raster = gdal.GetDriverByName('GTiff').Create(_out, x_res, y_res, 1, gdal.GDT_Byte)
_raster.SetGeoTransform((x_min, pixel_size, 0, y_max, 0, -pixel_size))
_band = _raster.GetRasterBand(1)
_band.SetNoDataValue(NoData_value)

# 5. Rasterize
gdal.RasterizeLayer(_raster, [1], source_layer, burn_values=[0])

It results in error message:

Traceback (most recent call last):
  File "", line 1, in 
  File "C:/Users/.../test.py", line 73, in 
    _raster = gdal.GetDriverByName('GTiff').Create(_out, x_res, y_res, 1, gdal.GDT_Byte)
  File "C:\PROGRA~1\QGISBR~1\apps\Python27\lib\site-packages\osgeo\gdal.py", line 388, in Create
    return _gdal.Driver_Create(self, *args, **kwargs)
TypeError: in method 'Driver_Create', argument 3 of type 'int'

It doesn't accept float values for x_res and y_res,
but how can I enter the proper geometry for my dataset?

Additional Info:

QGIS 2.6.1 Brighton on Win7
crs: WGS84 - epsg4326
input shape horizonthal point distance: 0.03333378 units
input shape vertical point distance: 0.01666641 units
1
  • x_res and y_res are not well chosen names in the example because I suppose that they tell the number of pixels in the target image. Therefore only integers are accepted.
    – user30184
    Feb 19, 2015 at 19:41

1 Answer 1

5

It's telling you it doesn't like your values as int, they round to 0 and you can't have a 0 row, 0 column raster. That's because you're supplying the cell size and not the rows and columns. When you create a dataset it needs to know how many rows and columns it is, you then tell it how big the cells are in the geotransform:

# 1. Define pixel_size and NoData value of new raster
NoData_value = -9999
x_res = 0.03333378 # assuming these are the cell sizes
y_res = 0.01666641 # change as appropriate
pixel_size = 1

# 2. Filenames for in- and output
_in = r"C:/Users/.../hoppla.shp"
_out = r"C:/Users/.../hoppla.tif"

# 3. Open Shapefile
source_ds = ogr.Open(_in)
source_layer = source_ds.GetLayer()
x_min, x_max, y_min, y_max = source_layer.GetExtent()

# 4. Create Target - TIFF
cols = int( (x_max - x_min) / x_res )
rows = int( (y_max - y_min) / y_res )

_raster = gdal.GetDriverByName('GTiff').Create(_out, cols, rows, 1, gdal.GDT_Byte)
_raster.SetGeoTransform((x_min, x_res, 0, y_max, 0, -y_res))
_band = _raster.GetRasterBand(1)
_band.SetNoDataValue(NoData_value)


# 5. Rasterize why is the burn value 0... isn't that the same as the background?
gdal.RasterizeLayer(_raster, [1], source_layer, burn_values=[0])

I don't know what the spatial reference of your input is so I don't know if your X and Y cell sizes are appropriate. Yes, you can have different cell sizes for X and Y. If your cell size should be 1 then change the values to 1 or just make cols = int(x_max - x_min) and rows = int(y_max - y_min) as anything divided by 1 is unchanged... but the create raster still needs an int value.

4
  • Your comment about underscores is incorrect. Those variables only exist in the current scope; that scope may be a method, a module, or a class. Regardless of what kind of scope it currently is, they won't automatically override any variables in the gdal, ogr, or any other modules. They could overwrite module variables from inside a class or method, but they'd have to be declared as global inside that scope to do so. They could shadow module variables without the global declaration of course, but this is usually harmless.
    – jpmc26
    May 2, 2018 at 23:16
  • @jpmc26 if an internal variable exists declaring a module variable with the same name will cause problems if they are both in scope, in C this is called overriding, python won't issue an error as it assumes you know what you're doing deliberately overriding a known variable.. granted there aren't many in python as almost everything is in a module but just think what would happen if you set __base = -1. May 2, 2018 at 23:35
  • ? Never heard of __base and can't find any docs on it. print(__base) gives a NameError. Within a class, that name also triggers mangling, which means each class would have its own copy if it wasn't NameErroring. But anyway, the fact that variables are scoped locally to modules is exactly why this is a non-issue. And few automatic variables in Python begin with a single underscore. Most are surrounded by double underscores. In fact, a single underscore is the recommended convention for "internal use" variables: python.org/dev/peps/pep-0008/#descriptive-naming-styles.
    – jpmc26
    May 2, 2018 at 23:54
  • @jpmc26 print locals() - see stackoverflow.com/questions/430811/… ok, __base isn't python, or maybe it has something to do with one of the APIs I work with, consider if you set a local variable __main__ to -1 instead. The document you refer to is a style guide but I concede your point, a single underscore seems to be ok, it's the double underscore you should avoid. I'll take that out of my answer. It seems the double underscore needs to be escaped in comments. May 3, 2018 at 0:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.