Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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
Пример #6
0
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
Пример #7
0
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
Пример #8
0
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
Пример #9
0
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
Пример #10
0
        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',
Пример #11
0
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
Пример #12
0
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