def rasterize( shapes, out_shape=None, fill=0, output=None, transform=DEFAULT_TRANSFORM, all_touched=False, default_value=255): """Returns an image array with points, lines, or polygons burned in. A different value may be specified for each shape. The shapes may be georeferenced or may have image coordinates. An existing image array may be provided, or one may be created. By default, the center of image elements determines whether they are updated, but all touched elements may be optionally updated. :param shapes: an iterator over Fiona style geometry objects (with a default value of 255) or an iterator over (geometry, value) pairs. Values must be unsigned integer type (uint8). :param transform: GDAL style geotransform to be applied to the image. :param out_shape: shape of created image array :param fill: fill value for created image array :param output: alternatively, an existing image array :param all_touched: if True, will rasterize all pixels touched, otherwise will use GDAL default method. :param default_value: value burned in for shapes if not provided as part of shapes. Must be unsigned integer type (uint8). """ if not isinstance(default_value, int) or default_value > 255 or default_value < 0: raise ValueError("default_value %s is not uint8/ubyte" % default_value) geoms = [] for index, entry in enumerate(shapes): if isinstance(entry, (tuple, list)): geometry, value = entry if not isinstance(value, int) or value > 255 or value < 0: raise ValueError( "Shape number %i, value '%s' is not uint8/ubyte" % ( index, value)) geoms.append((geometry, value)) else: geoms.append((entry, default_value)) if out_shape is not None: out = numpy.empty(out_shape, dtype=rasterio.ubyte) out.fill(fill) elif output is not None: if output.dtype.type != rasterio.ubyte: raise ValueError("Output image must be dtype uint8/ubyte") out = output else: raise ValueError("An output image must be provided or specified") with rasterio.drivers(): _rasterize(geoms, out, transform, all_touched) return out
def rasterize(shapes, out_shape=None, fill=0, out=None, transform=IDENTITY, all_touched=False, merge_alg=MergeAlg.replace, default_value=1, dtype=None): """Return an image array with input geometries burned in. Warnings will be raised for any invalid or empty geometries, and an exception will be raised if there are no valid shapes to rasterize. Parameters ---------- shapes : iterable of (`geometry`, `value`) pairs or iterable over geometries. The `geometry` can either be an object that implements the geo interface or GeoJSON-like object. If no `value` is provided the `default_value` will be used. If `value` is `None` the `fill` value will be used. out_shape : tuple or list with 2 integers Shape of output numpy ndarray. fill : int or float, optional Used as fill value for all areas not covered by input geometries. out : numpy ndarray, optional Array of same shape and data type as `source` in which to store results. transform : Affine transformation object, optional Transformation from pixel coordinates of `source` to the coordinate system of the input `shapes`. See the `transform` property of dataset objects. all_touched : boolean, optional If True, all pixels touched by geometries will be burned in. If false, only pixels whose center is within the polygon or that are selected by Bresenham's line algorithm will be burned in. merge_alg : MergeAlg, optional Merge algorithm to use. One of: MergeAlg.replace (default): the new value will overwrite the existing value. MergeAlg.add: the new value will be added to the existing raster. default_value : int or float, optional Used as value for all geometries, if not provided in `shapes`. dtype : rasterio or numpy data type, optional Used as data type for results, if `out` is not provided. Returns ------- numpy ndarray If `out` was not None then `out` is returned, it will have been modified in-place. If `out` was None, this will be a new array. Notes ----- Valid data types for `fill`, `default_value`, `out`, `dtype` and shape values are "int16", "int32", "uint8", "uint16", "uint32", "float32", and "float64". This function requires significant memory resources. The shapes iterator will be materialized to a Python list and another C copy of that list will be made. The `out` array will be copied and additional temporary raster memory equal to 2x the smaller of `out` data or GDAL's max cache size (controlled by GDAL_CACHEMAX, default is 5% of the computer's physical memory) is required. If GDAL max cache size is smaller than the output data, the array of shapes will be iterated multiple times. Performance is thus a linear function of buffer size. For maximum speed, ensure that GDAL_CACHEMAX is larger than the size of `out` or `out_shape`. """ valid_dtypes = ('int16', 'int32', 'uint8', 'uint16', 'uint32', 'float32', 'float64') def format_invalid_dtype(param): return '{0} dtype must be one of: {1}'.format(param, ', '.join(valid_dtypes)) def format_cast_error(param, dtype): return '{0} cannot be cast to specified dtype: {1}'.format( param, dtype) if fill != 0: fill_array = np.array([fill]) if not validate_dtype(fill_array, valid_dtypes): raise ValueError(format_invalid_dtype('fill')) if dtype is not None and not can_cast_dtype(fill_array, dtype): raise ValueError(format_cast_error('fill', dtype)) if default_value != 1: default_value_array = np.array([default_value]) if not validate_dtype(default_value_array, valid_dtypes): raise ValueError(format_invalid_dtype('default_value')) if dtype is not None and not can_cast_dtype(default_value_array, dtype): raise ValueError(format_cast_error('default_vaue', dtype)) if dtype is not None and np.dtype(dtype).name not in valid_dtypes: raise ValueError(format_invalid_dtype('dtype')) valid_shapes = [] shape_values = [] for index, item in enumerate(shapes): if isinstance(item, (tuple, list)): geom, value = item if value is None: value = fill else: geom = item value = default_value geom = getattr(geom, '__geo_interface__', None) or geom if is_valid_geom(geom): shape_values.append(value) geom_type = geom['type'] if geom_type == 'GeometryCollection': # GeometryCollections need to be handled as individual parts to # avoid holes in output: # https://github.com/mapbox/rasterio/issues/1253. # Only 1-level deep since GeoJSON spec discourages nested # GeometryCollections for part in geom['geometries']: valid_shapes.append((part, value)) elif geom_type == 'MultiPolygon': # Same issue as above for poly in geom['coordinates']: valid_shapes.append(({ 'type': 'Polygon', 'coordinates': poly }, value)) else: valid_shapes.append((geom, value)) else: # invalid or empty geometries are skipped and raise a warning instead warnings.warn( 'Invalid or empty shape {} at index {} will not be rasterized.' .format(geom, index), ShapeSkipWarning) if not valid_shapes: raise ValueError('No valid geometry objects found for rasterize') shape_values = np.array(shape_values) if not validate_dtype(shape_values, valid_dtypes): raise ValueError(format_invalid_dtype('shape values')) if dtype is None: dtype = get_minimum_dtype(np.append(shape_values, fill)) elif not can_cast_dtype(shape_values, dtype): raise ValueError(format_cast_error('shape values', dtype)) if out is not None: if np.dtype(out.dtype).name not in valid_dtypes: raise ValueError(format_invalid_dtype('out')) if not can_cast_dtype(shape_values, out.dtype): raise ValueError(format_cast_error('shape values', out.dtype.name)) elif out_shape is not None: if len(out_shape) != 2: raise ValueError('Invalid out_shape, must be 2D') out = np.empty(out_shape, dtype=dtype) out.fill(fill) else: raise ValueError('Either an out_shape or image must be provided') if min(out.shape) == 0: raise ValueError("width and height must be > 0") transform = guard_transform(transform) _rasterize(valid_shapes, out, transform, all_touched, merge_alg) return out
def rasterize(shapes, out_shape=None, fill=0, output=None, transform=DEFAULT_TRANSFORM, all_touched=False, default_value=255): """Returns an image array with points, lines, or polygons burned in. A different value may be specified for each shape. The shapes may be georeferenced or may have image coordinates. An existing image array may be provided, or one may be created. By default, the center of image elements determines whether they are updated, but all touched elements may be optionally updated. :param shapes: an iterator over Fiona style geometry objects (with a default value of 255) or an iterator over (geometry, value) pairs. Values must be unsigned integer type (uint8). :param transform: GDAL style geotransform to be applied to the image. :param out_shape: shape of created image array :param fill: fill value for created image array :param output: alternatively, an existing image array :param all_touched: if True, will rasterize all pixels touched, otherwise will use GDAL default method. :param default_value: value burned in for shapes if not provided as part of shapes. Must be unsigned integer type (uint8). """ if not isinstance(default_value, int) or default_value > 255 or default_value < 0: raise ValueError("default_value %s is not uint8/ubyte" % default_value) geoms = [] for index, entry in enumerate(shapes): if isinstance(entry, (tuple, list)): geometry, value = entry if not isinstance(value, int) or value > 255 or value < 0: raise ValueError( "Shape number %i, value '%s' is not uint8/ubyte" % (index, value)) geoms.append((geometry, value)) else: geoms.append((entry, default_value)) if out_shape is not None: out = numpy.empty(out_shape, dtype=rasterio.ubyte) out.fill(fill) elif output is not None: if output.dtype.type != rasterio.ubyte: raise ValueError("Output image must be dtype uint8/ubyte") out = output else: raise ValueError("An output image must be provided or specified") with rasterio.drivers(): _rasterize(geoms, out, transform, all_touched) return out
def rasterize( shapes, out_shape=None, fill=0, out=None, output=None, transform=IDENTITY, all_touched=False, default_value=1, dtype=None): """ Returns an image array with input geometries burned in. Parameters ---------- shapes : iterable of (geometry, value) pairs or iterable over geometries. `geometry` can either be an object that implements the geo interface or GeoJSON-like object. out_shape : tuple or list Shape of output numpy ndarray. fill : int or float, optional Used as fill value for all areas not covered by input geometries. out : numpy ndarray, optional Array of same shape and data type as `image` in which to store results. output : older alias for `out`, will be removed before 1.0. transform : Affine transformation object, optional Transformation from pixel coordinates of `image` to the coordinate system of the input `shapes`. See the `transform` property of dataset objects. all_touched : boolean, optional If True, all pixels touched by geometries will be burned in. If false, only pixels whose center is within the polygon or that are selected by Bresenham's line algorithm will be burned in. default_value : int or float, optional Used as value for all geometries, if not provided in `shapes`. dtype : rasterio or numpy data type, optional Used as data type for results, if `out` is not provided. Returns ------- out : numpy ndarray Results Notes ----- Valid data types for `fill`, `default_value`, `out`, `dtype` and shape values are rasterio.int16, rasterio.int32, rasterio.uint8, rasterio.uint16, rasterio.uint32, rasterio.float32, rasterio.float64. """ valid_dtypes = ('int16', 'int32', 'uint8', 'uint16', 'uint32', 'float32', 'float64') def get_valid_dtype(values): values_dtype = values.dtype if values_dtype.kind == 'i': values_dtype = np.dtype(get_minimum_int_dtype(values)) if values_dtype.name in valid_dtypes: return values_dtype return None def can_cast_dtype(values, dtype): if values.dtype.name == np.dtype(dtype).name: return True elif values.dtype.kind == 'f': return np.allclose(values, values.astype(dtype)) else: return np.array_equal(values, values.astype(dtype)) if fill != 0: fill_array = np.array([fill]) if get_valid_dtype(fill_array) is None: raise ValueError('fill must be one of these types: %s' % (', '.join(valid_dtypes))) elif dtype is not None and not can_cast_dtype(fill_array, dtype): raise ValueError('fill value cannot be cast to specified dtype') if default_value != 1: default_value_array = np.array([default_value]) if get_valid_dtype(default_value_array) is None: raise ValueError('default_value must be one of these types: %s' % (', '.join(valid_dtypes))) elif dtype is not None and not can_cast_dtype(default_value_array, dtype): raise ValueError('default_value cannot be cast to specified dtype') valid_shapes = [] shape_values = [] for index, item in enumerate(shapes): try: if isinstance(item, (tuple, list)): geom, value = item else: geom = item value = default_value geom = getattr(geom, '__geo_interface__', None) or geom if (not isinstance(geom, dict) or 'type' not in geom or 'coordinates' not in geom): raise ValueError( 'Object %r at index %d is not a geometry object' % (geom, index)) valid_shapes.append((geom, value)) shape_values.append(value) except Exception: log.exception('Exception caught, skipping shape %d', index) if not valid_shapes: raise ValueError('No valid shapes found for rasterize. Shapes must be ' 'valid geometry objects') shape_values = np.array(shape_values) values_dtype = get_valid_dtype(shape_values) if values_dtype is None: raise ValueError('shape values must be one of these dtypes: %s' % (', '.join(valid_dtypes))) if dtype is None: dtype = values_dtype elif np.dtype(dtype).name not in valid_dtypes: raise ValueError('dtype must be one of: %s' % (', '.join(valid_dtypes))) elif not can_cast_dtype(shape_values, dtype): raise ValueError('shape values could not be cast to specified dtype') if output is not None: warnings.warn( "The 'output' keyword arg has been superceded by 'out' " "and will be removed before Rasterio 1.0.", FutureWarning, stacklevel=2) out = out if out is not None else output if out is not None: if np.dtype(out.dtype).name not in valid_dtypes: raise ValueError('Output image dtype must be one of: %s' % (', '.join(valid_dtypes))) if not can_cast_dtype(shape_values, out.dtype): raise ValueError('shape values cannot be cast to dtype of output ' 'image') elif out_shape is not None: out = np.empty(out_shape, dtype=dtype) out.fill(fill) else: raise ValueError('Either an output shape or image must be provided') transform = guard_transform(transform) with rasterio.drivers(): _rasterize(valid_shapes, out, transform.to_gdal(), all_touched) return out
def rasterize(shapes, out_shape=None, fill=0, out=None, transform=IDENTITY, all_touched=False, merge_alg=MergeAlg.replace, default_value=1, dtype=None): """Return an image array with input geometries burned in. Warnings will be raised for any invalid or empty geometries, and an exception will be raised if there are no valid shapes to rasterize. Parameters ---------- shapes : iterable of (geometry, value) pairs or iterable over geometries. `geometry` can either be an object that implements the geo interface or GeoJSON-like object. out_shape : tuple or list with 2 integers Shape of output numpy ndarray. fill : int or float, optional Used as fill value for all areas not covered by input geometries. out : numpy ndarray, optional Array of same shape and data type as `source` in which to store results. transform : Affine transformation object, optional Transformation from pixel coordinates of `source` to the coordinate system of the input `shapes`. See the `transform` property of dataset objects. all_touched : boolean, optional If True, all pixels touched by geometries will be burned in. If false, only pixels whose center is within the polygon or that are selected by Bresenham's line algorithm will be burned in. merge_alg : MergeAlg, optional Merge algorithm to use. One of: MergeAlg.replace (default): the new value will overwrite the existing value. MergeAlg.add: the new value will be added to the existing raster. default_value : int or float, optional Used as value for all geometries, if not provided in `shapes`. dtype : rasterio or numpy data type, optional Used as data type for results, if `out` is not provided. Returns ------- out : numpy ndarray Results Notes ----- Valid data types for `fill`, `default_value`, `out`, `dtype` and shape values are rasterio.int16, rasterio.int32, rasterio.uint8, rasterio.uint16, rasterio.uint32, rasterio.float32, rasterio.float64. """ valid_dtypes = ('int16', 'int32', 'uint8', 'uint16', 'uint32', 'float32', 'float64') def format_invalid_dtype(param): return '{0} dtype must be one of: {1}'.format(param, ', '.join(valid_dtypes)) def format_cast_error(param, dtype): return '{0} cannot be cast to specified dtype: {1}'.format( param, dtype) if fill != 0: fill_array = np.array([fill]) if not validate_dtype(fill_array, valid_dtypes): raise ValueError(format_invalid_dtype('fill')) if dtype is not None and not can_cast_dtype(fill_array, dtype): raise ValueError(format_cast_error('fill', dtype)) if default_value != 1: default_value_array = np.array([default_value]) if not validate_dtype(default_value_array, valid_dtypes): raise ValueError(format_invalid_dtype('default_value')) if dtype is not None and not can_cast_dtype(default_value_array, dtype): raise ValueError(format_cast_error('default_vaue', dtype)) if dtype is not None and np.dtype(dtype).name not in valid_dtypes: raise ValueError(format_invalid_dtype('dtype')) valid_shapes = [] shape_values = [] for index, item in enumerate(shapes): if isinstance(item, (tuple, list)): geom, value = item else: geom = item value = default_value geom = getattr(geom, '__geo_interface__', None) or geom if is_valid_geom(geom): shape_values.append(value) if geom['type'] == 'GeometryCollection': # GeometryCollections need to be handled as individual parts to # avoid holes in output: # https://github.com/mapbox/rasterio/issues/1253. # Only 1-level deep since GeoJSON spec discourages nested # GeometryCollections for part in geom['geometries']: valid_shapes.append((part, value)) else: valid_shapes.append((geom, value)) else: # invalid or empty geometries are skipped and raise a warning instead warnings.warn( 'Invalid or empty shape at index {} will not be rasterized.'. format(index)) if not valid_shapes: raise ValueError('No valid geometry objects found for rasterize') shape_values = np.array(shape_values) if not validate_dtype(shape_values, valid_dtypes): raise ValueError(format_invalid_dtype('shape values')) if dtype is None: dtype = get_minimum_dtype(np.append(shape_values, fill)) elif not can_cast_dtype(shape_values, dtype): raise ValueError(format_cast_error('shape values', dtype)) if out is not None: if np.dtype(out.dtype).name not in valid_dtypes: raise ValueError(format_invalid_dtype('out')) if not can_cast_dtype(shape_values, out.dtype): raise ValueError(format_cast_error('shape values', out.dtype.name)) elif out_shape is not None: if len(out_shape) != 2: raise ValueError('Invalid out_shape, must be 2D') out = np.empty(out_shape, dtype=dtype) out.fill(fill) else: raise ValueError('Either an out_shape or image must be provided') if min(out.shape) == 0: raise ValueError("width and height must be > 0") transform = guard_transform(transform) _rasterize(valid_shapes, out, transform, all_touched, merge_alg) return out
def rasterize(shapes, out_shape=None, fill=0, out=None, transform=IDENTITY, all_touched=False, merge_alg='replace', default_value=1, dtype=None): """Return an image array with input geometries burned in. Parameters ---------- shapes : iterable of (geometry, value) pairs or iterable over geometries. `geometry` can either be an object that implements the geo interface or GeoJSON-like object. out_shape : tuple or list with 2 integers Shape of output numpy ndarray. fill : int or float, optional Used as fill value for all areas not covered by input geometries. out : numpy ndarray, optional Array of same shape and data type as `image` in which to store results. transform : Affine transformation object, optional Transformation from pixel coordinates of `image` to the coordinate system of the input `shapes`. See the `transform` property of dataset objects. all_touched : boolean, optional If True, all pixels touched by geometries will be burned in. If false, only pixels whose center is within the polygon or that are selected by Bresenham's line algorithm will be burned in. merge_alg : str, optional If `replace` (default), the new value will overwrite the existing value. If `add`, the new value will be added to the existing raster. default_value : int or float, optional Used as value for all geometries, if not provided in `shapes`. dtype : rasterio or numpy data type, optional Used as data type for results, if `out` is not provided. Returns ------- out : numpy ndarray Results Notes ----- Valid data types for `fill`, `default_value`, `out`, `dtype` and shape values are rasterio.int16, rasterio.int32, rasterio.uint8, rasterio.uint16, rasterio.uint32, rasterio.float32, rasterio.float64. """ valid_dtypes = ('int16', 'int32', 'uint8', 'uint16', 'uint32', 'float32', 'float64') def format_invalid_dtype(param): return '{0} dtype must be one of: {1}'.format(param, ', '.join(valid_dtypes)) def format_cast_error(param, dtype): return '{0} cannot be cast to specified dtype: {1}'.format( param, dtype) if fill != 0: fill_array = np.array([fill]) if not validate_dtype(fill_array, valid_dtypes): raise ValueError(format_invalid_dtype('fill')) if dtype is not None and not can_cast_dtype(fill_array, dtype): raise ValueError(format_cast_error('fill', dtype)) if default_value != 1: default_value_array = np.array([default_value]) if not validate_dtype(default_value_array, valid_dtypes): raise ValueError(format_invalid_dtype('default_value')) if dtype is not None and not can_cast_dtype(default_value_array, dtype): raise ValueError(format_cast_error('default_vaue', dtype)) if dtype is not None and np.dtype(dtype).name not in valid_dtypes: raise ValueError(format_invalid_dtype('dtype')) valid_shapes = [] shape_values = [] for index, item in enumerate(shapes): if isinstance(item, (tuple, list)): geom, value = item else: geom = item value = default_value geom = getattr(geom, '__geo_interface__', None) or geom # geom must be a valid GeoJSON geometry type and non-empty if not is_valid_geom(geom): raise ValueError( 'Invalid geometry object at index {0}'.format(index)) valid_shapes.append((geom, value)) shape_values.append(value) if not valid_shapes: raise ValueError('No valid geometry objects found for rasterize') shape_values = np.array(shape_values) if not validate_dtype(shape_values, valid_dtypes): raise ValueError(format_invalid_dtype('shape values')) if dtype is None: dtype = get_minimum_dtype(np.append(shape_values, fill)) elif not can_cast_dtype(shape_values, dtype): raise ValueError(format_cast_error('shape values', dtype)) if out is not None: if np.dtype(out.dtype).name not in valid_dtypes: raise ValueError(format_invalid_dtype('out')) if not can_cast_dtype(shape_values, out.dtype): raise ValueError(format_cast_error('shape values', out.dtype.name)) elif out_shape is not None: if len(out_shape) != 2: raise ValueError('Invalid out_shape, must be 2D') out = np.empty(out_shape, dtype=dtype) out.fill(fill) else: raise ValueError('Either an out_shape or image must be provided') if min(out.shape) == 0: raise ValueError("width and height must be > 0") transform = guard_transform(transform) _rasterize(valid_shapes, out, transform.to_gdal(), all_touched, merge_alg) return out
def rasterize(shapes, out_shape=None, fill=0, output=None, transform=IDENTITY, all_touched=False, default_value=255): """Returns an image array with points, lines, or polygons burned in. A different value may be specified for each shape. The shapes may be georeferenced or may have image coordinates. An existing image array may be provided, or one may be created. By default, the center of image elements determines whether they are updated, but all touched elements may be optionally updated. :param shapes: an iterator over Fiona style geometry objects (with a default value of 255) or an iterator over (geometry, value) pairs. Values must be unsigned integer type (uint8). :param transform: GDAL style geotransform to be applied to the image. :param out_shape: shape of created image array :param fill: fill value for created image array :param output: alternatively, an existing image array :param all_touched: if True, will rasterize all pixels touched, otherwise will use GDAL default method. :param default_value: value burned in for shapes if not provided as part of shapes. Must be unsigned integer type (uint8). """ if not isinstance(default_value, int) or (default_value > 255 or default_value < 0): raise ValueError("default_value %s is not uint8/ubyte" % default_value) def shape_source(): """A generator that screens out non-geometric objects and does its best to make sure that no NULLs get through to GDALRasterizeGeometries.""" for index, item in enumerate(shapes): try: if isinstance(item, (tuple, list)): geom, value = item # TODO: relax this for other data types. if not isinstance(value, int) or value > 255 or value < 0: raise ValueError("Shape number %i, value '%s' is not uint8/ubyte" % (index, value)) else: geom = item value = default_value geom = getattr(geom, "__geo_interface__", None) or geom if not isinstance(geom, dict) or "type" not in geom or "coordinates" not in geom: raise ValueError("Object %r at index %d is not a geometric object" % (geom, index)) yield geom, value except Exception: log.exception("Exception caught, skipping shape %d", index) if out_shape is not None: out = np.empty(out_shape, dtype=rasterio.ubyte) out.fill(fill) elif output is not None: if np.dtype(output.dtype) != np.dtype(rasterio.ubyte): raise ValueError("Output image must be dtype uint8/ubyte") out = output else: raise ValueError("An output image must be provided or specified") transform = guard_transform(transform) with rasterio.drivers(): _rasterize(shape_source(), out, transform.to_gdal(), all_touched) return out
def rasterize( shapes, out_shape=None, fill=0, out=None, transform=IDENTITY, all_touched=False, default_value=1, dtype=None): """Return an image array with input geometries burned in. Parameters ---------- shapes : iterable of (geometry, value) pairs or iterable over geometries. `geometry` can either be an object that implements the geo interface or GeoJSON-like object. out_shape : tuple or list with 2 integers Shape of output numpy ndarray. fill : int or float, optional Used as fill value for all areas not covered by input geometries. out : numpy ndarray, optional Array of same shape and data type as `image` in which to store results. transform : Affine transformation object, optional Transformation from pixel coordinates of `image` to the coordinate system of the input `shapes`. See the `transform` property of dataset objects. all_touched : boolean, optional If True, all pixels touched by geometries will be burned in. If false, only pixels whose center is within the polygon or that are selected by Bresenham's line algorithm will be burned in. default_value : int or float, optional Used as value for all geometries, if not provided in `shapes`. dtype : rasterio or numpy data type, optional Used as data type for results, if `out` is not provided. Returns ------- out : numpy ndarray Results Notes ----- Valid data types for `fill`, `default_value`, `out`, `dtype` and shape values are rasterio.int16, rasterio.int32, rasterio.uint8, rasterio.uint16, rasterio.uint32, rasterio.float32, rasterio.float64. """ valid_dtypes = ( 'int16', 'int32', 'uint8', 'uint16', 'uint32', 'float32', 'float64' ) def format_invalid_dtype(param): return '{0} dtype must be one of: {1}'.format( param, ', '.join(valid_dtypes) ) def format_cast_error(param, dtype): return '{0} cannot be cast to specified dtype: {1}'.format(param, dtype) if fill != 0: fill_array = np.array([fill]) if not validate_dtype(fill_array, valid_dtypes): raise ValueError(format_invalid_dtype('fill')) if dtype is not None and not can_cast_dtype(fill_array, dtype): raise ValueError(format_cast_error('fill', dtype)) if default_value != 1: default_value_array = np.array([default_value]) if not validate_dtype(default_value_array, valid_dtypes): raise ValueError(format_invalid_dtype('default_value')) if dtype is not None and not can_cast_dtype(default_value_array, dtype): raise ValueError(format_cast_error('default_vaue', dtype)) if dtype is not None and np.dtype(dtype).name not in valid_dtypes: raise ValueError(format_invalid_dtype('dtype')) valid_shapes = [] shape_values = [] for index, item in enumerate(shapes): if isinstance(item, (tuple, list)): geom, value = item else: geom = item value = default_value geom = getattr(geom, '__geo_interface__', None) or geom # not isinstance(geom, dict) or if 'type' in geom or 'coordinates' in geom: valid_shapes.append((geom, value)) shape_values.append(value) else: raise ValueError( 'Invalid geometry object at index {0}'.format(index) ) if not valid_shapes: raise ValueError('No valid geometry objects found for rasterize') shape_values = np.array(shape_values) if not validate_dtype(shape_values, valid_dtypes): raise ValueError(format_invalid_dtype('shape values')) if dtype is None: dtype = get_minimum_dtype(np.append(shape_values, fill)) elif not can_cast_dtype(shape_values, dtype): raise ValueError(format_cast_error('shape values', dtype)) if out is not None: if np.dtype(out.dtype).name not in valid_dtypes: raise ValueError(format_invalid_dtype('out')) if not can_cast_dtype(shape_values, out.dtype): raise ValueError(format_cast_error('shape values', out.dtype.name)) elif out_shape is not None: if len(out_shape) != 2: raise ValueError('Invalid out_shape, must be 2D') out = np.empty(out_shape, dtype=dtype) out.fill(fill) else: raise ValueError('Either an out_shape or image must be provided') transform = guard_transform(transform) _rasterize(valid_shapes, out, transform.to_gdal(), all_touched) return out
def rasterize(shapes, out_shape=None, fill=0, output=None, transform=IDENTITY, all_touched=False, default_value=255): """Returns an image array with points, lines, or polygons burned in. A different value may be specified for each shape. The shapes may be georeferenced or may have image coordinates. An existing image array may be provided, or one may be created. By default, the center of image elements determines whether they are updated, but all touched elements may be optionally updated. :param shapes: an iterator over Fiona style geometry objects (with a default value of 255) or an iterator over (geometry, value) pairs. Values must be unsigned integer type (uint8). :param transform: GDAL style geotransform to be applied to the image. :param out_shape: shape of created image array :param fill: fill value for created image array :param output: alternatively, an existing image array :param all_touched: if True, will rasterize all pixels touched, otherwise will use GDAL default method. :param default_value: value burned in for shapes if not provided as part of shapes. Must be unsigned integer type (uint8). """ if not isinstance(default_value, int) or (default_value > 255 or default_value < 0): raise ValueError("default_value %s is not uint8/ubyte" % default_value) def shape_source(): """A generator that screens out non-geometric objects and does its best to make sure that no NULLs get through to GDALRasterizeGeometries.""" for index, item in enumerate(shapes): try: if isinstance(item, (tuple, list)): geom, value = item # TODO: relax this for other data types. if not isinstance(value, int) or value > 255 or value < 0: raise ValueError( "Shape number %i, value '%s' is not uint8/ubyte" % (index, value)) else: geom = item value = default_value geom = getattr(geom, '__geo_interface__', None) or geom if (not isinstance(geom, dict) or 'type' not in geom or 'coordinates' not in geom): raise ValueError( "Object %r at index %d is not a geometric object" % (geom, index)) yield geom, value except Exception: log.exception("Exception caught, skipping shape %d", index) if out_shape is not None: out = np.empty(out_shape, dtype=rasterio.ubyte) out.fill(fill) elif output is not None: if np.dtype(output.dtype) != np.dtype(rasterio.ubyte): raise ValueError("Output image must be dtype uint8/ubyte") out = output else: raise ValueError("An output image must be provided or specified") transform = guard_transform(transform) with rasterio.drivers(): _rasterize(shape_source(), out, transform.to_gdal(), all_touched) return out
gis = lakes['geo ' + ring_size].apply( lambda x: getattr(x, '__geo_interface__')) #takes 3 seconds lakes_results = lakes[['dowlknum']].copy() for new_col_names in new_col_names: lakes_results[new_col_names] = np.nan for i in lakes.index: if i % 1000 == 0: print(i) #using hidden rasterize function to skip validation an speed up the function up to 40% #modifies raster matrix, returns nothing raster.fill(0) _rasterize([(gis[i], 1)], raster, transform, all_touched, MergeAlg.replace) #extract the section of the land cover raster where this lake ring exists ring_lc = lc_arr[raster == 1] #extract the counts of each land cover type in the overlap ring_lc_dict = dict(zip(*np.unique(ring_lc, return_counts=True))) cell_ct = len(ring_lc) for lc_type_str, lc_type in land_cover_dict.items(): lakes_results.loc[i, lc_type_str + ' share'] = round( ring_lc_dict.get(lc_type, 0) / cell_ct, 4) print('vals inserted') lakes_results.to_csv('D/Land Cover/Land Cover Surrounding Lakes ' + ring_size + ' ' + year + '.csv',
def rasterize( shapes, out_shape=None, fill=0, out=None, transform=IDENTITY, all_touched=False, merge_alg=MergeAlg.replace, default_value=1, dtype=None): """Return an image array with input geometries burned in. Parameters ---------- shapes : iterable of (geometry, value) pairs or iterable over geometries. `geometry` can either be an object that implements the geo interface or GeoJSON-like object. out_shape : tuple or list with 2 integers Shape of output numpy ndarray. fill : int or float, optional Used as fill value for all areas not covered by input geometries. out : numpy ndarray, optional Array of same shape and data type as `source` in which to store results. transform : Affine transformation object, optional Transformation from pixel coordinates of `source` to the coordinate system of the input `shapes`. See the `transform` property of dataset objects. all_touched : boolean, optional If True, all pixels touched by geometries will be burned in. If false, only pixels whose center is within the polygon or that are selected by Bresenham's line algorithm will be burned in. merge_alg : MergeAlg, optional Merge algorithm to use. One of: MergeAlg.replace (default): the new value will overwrite the existing value. MergeAlg.add: the new value will be added to the existing raster. default_value : int or float, optional Used as value for all geometries, if not provided in `shapes`. dtype : rasterio or numpy data type, optional Used as data type for results, if `out` is not provided. Returns ------- out : numpy ndarray Results Notes ----- Valid data types for `fill`, `default_value`, `out`, `dtype` and shape values are rasterio.int16, rasterio.int32, rasterio.uint8, rasterio.uint16, rasterio.uint32, rasterio.float32, rasterio.float64. """ valid_dtypes = ( 'int16', 'int32', 'uint8', 'uint16', 'uint32', 'float32', 'float64' ) def format_invalid_dtype(param): return '{0} dtype must be one of: {1}'.format( param, ', '.join(valid_dtypes) ) def format_cast_error(param, dtype): return '{0} cannot be cast to specified dtype: {1}'.format(param, dtype) if fill != 0: fill_array = np.array([fill]) if not validate_dtype(fill_array, valid_dtypes): raise ValueError(format_invalid_dtype('fill')) if dtype is not None and not can_cast_dtype(fill_array, dtype): raise ValueError(format_cast_error('fill', dtype)) if default_value != 1: default_value_array = np.array([default_value]) if not validate_dtype(default_value_array, valid_dtypes): raise ValueError(format_invalid_dtype('default_value')) if dtype is not None and not can_cast_dtype(default_value_array, dtype): raise ValueError(format_cast_error('default_vaue', dtype)) if dtype is not None and np.dtype(dtype).name not in valid_dtypes: raise ValueError(format_invalid_dtype('dtype')) valid_shapes = [] shape_values = [] for index, item in enumerate(shapes): if isinstance(item, (tuple, list)): geom, value = item else: geom = item value = default_value geom = getattr(geom, '__geo_interface__', None) or geom # geom must be a valid GeoJSON geometry type and non-empty if not is_valid_geom(geom): raise ValueError( 'Invalid geometry object at index {0}'.format(index) ) if geom['type'] == 'GeometryCollection': # GeometryCollections need to be handled as individual parts to # avoid holes in output: # https://github.com/mapbox/rasterio/issues/1253. # Only 1-level deep since GeoJSON spec discourages nested # GeometryCollections for part in geom['geometries']: valid_shapes.append((part, value)) else: valid_shapes.append((geom, value)) shape_values.append(value) if not valid_shapes: raise ValueError('No valid geometry objects found for rasterize') shape_values = np.array(shape_values) if not validate_dtype(shape_values, valid_dtypes): raise ValueError(format_invalid_dtype('shape values')) if dtype is None: dtype = get_minimum_dtype(np.append(shape_values, fill)) elif not can_cast_dtype(shape_values, dtype): raise ValueError(format_cast_error('shape values', dtype)) if out is not None: if np.dtype(out.dtype).name not in valid_dtypes: raise ValueError(format_invalid_dtype('out')) if not can_cast_dtype(shape_values, out.dtype): raise ValueError(format_cast_error('shape values', out.dtype.name)) elif out_shape is not None: if len(out_shape) != 2: raise ValueError('Invalid out_shape, must be 2D') out = np.empty(out_shape, dtype=dtype) out.fill(fill) else: raise ValueError('Either an out_shape or image must be provided') if min(out.shape) == 0: raise ValueError("width and height must be > 0") transform = guard_transform(transform) _rasterize(valid_shapes, out, transform, all_touched, merge_alg) return out
def rasterize( shapes, out_shape=None, fill=0, output=None, transform=IDENTITY, all_touched=False, default_value=1, dtype=None): """Returns an image array with points, lines, or polygons burned in. A different value may be specified for each shape. The shapes may be georeferenced or may have image coordinates. An existing image array may be provided, or one may be created. By default, the center of image elements determines whether they are updated, but all touched elements may be optionally updated. Valid data types are: int16, int32, uint8, uint16, uint32, float32, float64 :param shapes: an iterator over Fiona style geometry objects (with a default value of default_value) or an iterator over (geometry, value) pairs. :param transform: GDAL style geotransform to be applied to the image. :param out_shape: shape of created image array :param fill: fill value for created image array :param output: alternatively, an existing image array :param all_touched: if True, will rasterize all pixels touched, otherwise will use GDAL default method. :param default_value: value burned in for shapes if not provided as part of shapes. """ valid_dtypes = ('int16', 'int32', 'uint8', 'uint16', 'uint32', 'float32', 'float64') def get_valid_dtype(values): values_dtype = values.dtype if values_dtype.kind == 'i': values_dtype = np.dtype(get_minimum_int_dtype(values)) if values_dtype.name in valid_dtypes: return values_dtype return None def can_cast_dtype(values, dtype): if values.dtype.name == np.dtype(dtype).name: return True elif values.dtype.kind == 'f': return np.allclose(values, values.astype(dtype)) else: return np.array_equal(values, values.astype(dtype)) if fill != 0: fill_array = np.array([fill]) if get_valid_dtype(fill_array) is None: raise ValueError('fill must be one of these types: %s' % (', '.join(valid_dtypes))) elif dtype is not None and not can_cast_dtype(fill_array, dtype): raise ValueError('fill value cannot be cast to specified dtype') if default_value != 1: default_value_array = np.array([default_value]) if get_valid_dtype(default_value_array) is None: raise ValueError('default_value must be one of these types: %s' % (', '.join(valid_dtypes))) elif dtype is not None and not can_cast_dtype(default_value_array, dtype): raise ValueError('default_value cannot be cast to specified dtype') valid_shapes = [] shape_values = [] for index, item in enumerate(shapes): try: if isinstance(item, (tuple, list)): geom, value = item else: geom = item value = default_value geom = getattr(geom, '__geo_interface__', None) or geom if (not isinstance(geom, dict) or 'type' not in geom or 'coordinates' not in geom): raise ValueError( 'Object %r at index %d is not a geometry object' % (geom, index)) valid_shapes.append((geom, value)) shape_values.append(value) except Exception: log.exception('Exception caught, skipping shape %d', index) if not valid_shapes: raise ValueError('No valid shapes found for rasterize. Shapes must be ' 'valid geometry objects') shape_values = np.array(shape_values) values_dtype = get_valid_dtype(shape_values) if values_dtype is None: raise ValueError('shape values must be one of these dtypes: %s' % (', '.join(valid_dtypes))) if dtype is None: dtype = values_dtype elif np.dtype(dtype).name not in valid_dtypes: raise ValueError('dtype must be one of: %s' % (', '.join(valid_dtypes))) elif not can_cast_dtype(shape_values, dtype): raise ValueError('shape values could not be cast to specified dtype') if output is not None: if np.dtype(output.dtype).name not in valid_dtypes: raise ValueError('Output image dtype must be one of: %s' % (', '.join(valid_dtypes))) if not can_cast_dtype(shape_values, output.dtype): raise ValueError('shape values cannot be cast to dtype of output ' 'image') elif out_shape is not None: output = np.empty(out_shape, dtype=dtype) output.fill(fill) else: raise ValueError('Either an output shape or image must be provided') transform = guard_transform(transform) with rasterio.drivers(): _rasterize(valid_shapes, output, transform.to_gdal(), all_touched) return output