mirror of
https://github.com/django/django.git
synced 2025-08-04 19:08:28 +00:00
Added write support for GDALRaster
- Instantiation of GDALRaster instances from dict or json data. - Retrieve and write pixel values in GDALBand objects. - Support for the GDALFlushCache in gdal C prototypes - Added private flush method to GDALRaster to make sure all data is written to files when file-based rasters are changed. - Replaced ``ptr`` with ``_ptr`` for internal ptr variable Refs #23804. Thanks Claude Paroz and Tim Graham for the reviews.
This commit is contained in:
parent
8758a63ddb
commit
f269c1d6f6
11 changed files with 600 additions and 57 deletions
|
@ -13,13 +13,13 @@ formats.
|
|||
|
||||
GeoDjango provides a high-level Python interface for some of the
|
||||
capabilities of OGR, including the reading and coordinate transformation
|
||||
of vector spatial data.
|
||||
of vector spatial data and minimal support for GDAL's features with respect
|
||||
to raster (image) data.
|
||||
|
||||
.. note::
|
||||
|
||||
Although the module is named ``gdal``, GeoDjango only supports
|
||||
some of the capabilities of OGR. Thus, GDAL's features with respect to
|
||||
raster (image) data are minimally supported (read-only) at this time.
|
||||
some of the capabilities of OGR and GDAL's raster features at this time.
|
||||
|
||||
__ http://www.gdal.org/
|
||||
__ http://www.gdal.org/ogr/
|
||||
|
@ -27,6 +27,8 @@ __ http://www.gdal.org/ogr/
|
|||
Overview
|
||||
========
|
||||
|
||||
.. _gdal_sample_data:
|
||||
|
||||
Sample Data
|
||||
-----------
|
||||
|
||||
|
@ -37,6 +39,7 @@ have any data of your own to use, GeoDjango tests contain a number of
|
|||
simple data sets that you can use for testing. You can download them here::
|
||||
|
||||
$ wget https://raw.githubusercontent.com/django/django/master/tests/gis_tests/data/cities/cities.{shp,prj,shx,dbf}
|
||||
$ wget https://raw.githubusercontent.com/django/django/master/tests/gis_tests/data/rasters/raster.tif
|
||||
|
||||
Vector Data Source Objects
|
||||
==========================
|
||||
|
@ -1101,35 +1104,106 @@ one or more layers of data named bands. Each band, represented by a
|
|||
image is represented as three bands: one for red, one for green, and one for
|
||||
blue.
|
||||
|
||||
.. class:: GDALRaster(ds_input)
|
||||
.. note::
|
||||
|
||||
The constructor for ``GDALRaster`` accepts a single parameter: the path of
|
||||
the file you want to read.
|
||||
For raster data there is no difference between a raster instance and its
|
||||
data source. Unlike for the Geometry objects, :class:`GDALRaster` objects are
|
||||
always a data source. Temporary rasters can be instantiated in memory
|
||||
using the corresponding driver, but they will be of the same class as file-based
|
||||
raster sources.
|
||||
|
||||
.. class:: GDALRaster(ds_input, write=False)
|
||||
|
||||
The constructor for ``GDALRaster`` accepts two parameters. The first parameter
|
||||
defines the raster source, it is either a path to a file or spatial data with
|
||||
values defining the properties of a new raster (such as size and name). If the
|
||||
input is a file path, the second parameter specifies if the raster should
|
||||
be opened with write access. The following example shows how rasters can be
|
||||
created from different input sources (using the sample data from the GeoDjango
|
||||
tests, see the :ref:`gdal_sample_data` section)::
|
||||
|
||||
>>> from django.contrib.gis.gdal.raster.source import GDALRaster
|
||||
>>> rst = GDALRaster('/path/to/your/raster.tif', write=False)
|
||||
>>> rst.name
|
||||
'/path/to/your/raster.tif'
|
||||
>>> rst.width, rst.height # This file has 163 x 174 pixels
|
||||
(163, 174)
|
||||
>>> rst = GDALRaster({'srid': 4326, 'width': 1, 'height': 2, 'datatype': 1
|
||||
... 'bands': [{'data': [0, 1]}]}) # Creates in-memory raster
|
||||
>>> rst.srs.srid
|
||||
4326
|
||||
>>> rst.width, rst.height
|
||||
(1, 2)
|
||||
>>> rst.bands[0].data()
|
||||
array([[0, 1]], dtype=int8)
|
||||
|
||||
.. versionchanged:: 1.9
|
||||
|
||||
``GDALRaster`` objects can now be instantiated directly from raw data.
|
||||
Setters have been added for the following properties: ``srs``,
|
||||
``geotransform``, ``origin``, ``scale``, and ``skew``.
|
||||
|
||||
.. attribute:: name
|
||||
|
||||
The name of the source which is equivalent to the input file path.
|
||||
The name of the source which is equivalent to the input file path or the name
|
||||
provided upon instantiation.
|
||||
|
||||
>>> GDALRaster({'width': 10, 'height': 10, 'name': 'myraster'}).name
|
||||
'myraster'
|
||||
|
||||
.. attribute:: driver
|
||||
|
||||
The name of the GDAL driver used to handle the input file. For example,
|
||||
``GTiff`` for a ``GeoTiff`` file. See also the `GDAL Raster Formats`__
|
||||
list.
|
||||
The name of the GDAL driver used to handle the input file. For ``GDALRaster``\s created
|
||||
from a file, the driver type is detected automatically. The creation of rasters from
|
||||
scratch is a in-memory raster by default (``'MEM'``), but can be altered as
|
||||
needed. For instance, use ``GTiff`` for a ``GeoTiff`` file. For a list of file types,
|
||||
see also the `GDAL Raster Formats`__ list.
|
||||
|
||||
__ http://www.gdal.org/formats_list.html
|
||||
|
||||
An in-memory raster is created through the following example:
|
||||
|
||||
>>> GDALRaster({'width': 10, 'height': 10}).driver.name
|
||||
'MEM'
|
||||
|
||||
A file based GeoTiff raster is created through the following example:
|
||||
|
||||
>>> import tempfile
|
||||
>>> rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
|
||||
>>> rst = GDALRaster({'driver': 'GTiff', 'name': rstfile.name,
|
||||
... 'width': 255, 'height': 255, 'nr_of_bands': 1})
|
||||
>>> rst.name
|
||||
'/tmp/tmp7x9H4J.tif' # The exact filename will be different on your computer
|
||||
>>> rst.driver.name
|
||||
'GTiff'
|
||||
|
||||
.. attribute:: width
|
||||
|
||||
The width of the source in pixels (X-axis).
|
||||
The width of the source in pixels (X-axis).
|
||||
|
||||
>>> GDALRaster({'width': 10, 'height': 20}).width
|
||||
10
|
||||
|
||||
.. attribute:: height
|
||||
|
||||
The height of the source in pixels (Y-axis).
|
||||
|
||||
>>> GDALRaster({'width': 10, 'height': 20}).height
|
||||
20
|
||||
|
||||
.. attribute:: srs
|
||||
|
||||
The spatial reference system of the source, as a
|
||||
:class:`SpatialReference` instance.
|
||||
The spatial reference system of the raster, as a
|
||||
:class:`SpatialReference` instance. The SRS can be changed by
|
||||
setting it to an other :class:`SpatialReference` or providing any input
|
||||
that is accepted by the :class:`SpatialReference` constructor.
|
||||
|
||||
>>> rst = GDALRaster({'width': 10, 'height': 20})
|
||||
>>> rst.srs
|
||||
None
|
||||
>>> rst.srs = 4326
|
||||
>>> rst.srs.srid
|
||||
4326
|
||||
|
||||
.. attribute:: geotransform
|
||||
|
||||
|
@ -1144,34 +1218,75 @@ blue.
|
|||
(indices 0 and 3), :attr:`scale` (indices 1 and 5) and :attr:`skew`
|
||||
(indices 2 and 4) properties.
|
||||
|
||||
The default is ``[0.0, 1.0, 0.0, 0.0, 0.0, -1.0]``.
|
||||
|
||||
>>> rst = GDALRaster({'width': 10, 'height': 20})
|
||||
>>> rst.geotransform
|
||||
[0.0, 1.0, 0.0, 0.0, 0.0, -1.0]
|
||||
|
||||
.. attribute:: origin
|
||||
|
||||
Coordinates of the top left origin of the raster in the spatial
|
||||
reference system of the source, as a point object with ``x`` and ``y``
|
||||
members.
|
||||
|
||||
>>> rst = GDALRaster({'width': 10, 'height': 20})
|
||||
>>> rst.origin
|
||||
[0.0, 0.0]
|
||||
>>> rst.origin.x = 1
|
||||
>>> rst.origin
|
||||
[1.0, 0.0]
|
||||
|
||||
.. attribute:: scale
|
||||
|
||||
Pixel width and height used for georeferencing the raster, as a as a
|
||||
point object with ``x`` and ``y`` members. See :attr:`geotransform`
|
||||
for more information.
|
||||
|
||||
>>> rst = GDALRaster({'width': 10, 'height': 20})
|
||||
>>> rst.scale
|
||||
[1.0, -1.0]
|
||||
>>> rst.scale.x = 2
|
||||
>>> rst.scale
|
||||
[2.0, -1.0]
|
||||
|
||||
.. attribute:: skew
|
||||
|
||||
Skew coefficients used to georeference the raster, as a point object
|
||||
with ``x`` and ``y`` members. In case of north up images, these
|
||||
coefficients are both ``0``.
|
||||
|
||||
>>> rst = GDALRaster({'width': 10, 'height': 20})
|
||||
>>> rst.skew
|
||||
[0.0, 0.0]
|
||||
>>> rst.skew.x = 3
|
||||
>>> rst.skew
|
||||
[3.0, 0.0]
|
||||
|
||||
.. attribute:: extent
|
||||
|
||||
Extent (boundary values) of the raster source, as a 4-tuple
|
||||
``(xmin, ymin, xmax, ymax)`` in the spatial reference system of the
|
||||
source.
|
||||
|
||||
>>> rst = GDALRaster({'width': 10, 'height': 20})
|
||||
>>> rst.extent
|
||||
(0.0, -20.0, 10.0, 0.0)
|
||||
>>> rst.origin.x = 100
|
||||
>>> rst.extent
|
||||
(100.0, -20.0, 110.0, 0.0)
|
||||
|
||||
.. attribute:: bands
|
||||
|
||||
List of all bands of the source, as :class:`GDALBand` instances.
|
||||
|
||||
>>> rst = GDALRaster({"width": 1, "height": 2, "bands": [{"data": [0, 1]},
|
||||
... {"data": [2, 3]}]})
|
||||
>>> len(rst.bands)
|
||||
2
|
||||
>>> rst.bands[1].data()
|
||||
array([[ 2., 3.]], dtype=float32)
|
||||
|
||||
``GDALBand``
|
||||
------------
|
||||
|
||||
|
@ -1179,7 +1294,7 @@ blue.
|
|||
|
||||
``GDALBand`` instances are not created explicitly, but rather obtained
|
||||
from a :class:`GDALRaster` object, through its :attr:`~GDALRaster.bands`
|
||||
attribute.
|
||||
attribute. The GDALBands contain the actual pixel values of the raster.
|
||||
|
||||
.. attribute:: description
|
||||
|
||||
|
@ -1193,6 +1308,12 @@ blue.
|
|||
|
||||
The height of the band in pixels (Y-axis).
|
||||
|
||||
.. attribute:: pixel_count
|
||||
|
||||
.. versionadded:: 1.9
|
||||
|
||||
The total number of pixels in this band. Is equal to ``width * height``.
|
||||
|
||||
.. attribute:: min
|
||||
|
||||
The minimum pixel value of the band (excluding the "no data" value).
|
||||
|
@ -1207,6 +1328,10 @@ blue.
|
|||
to mark pixels that are not valid data. Such pixels should generally not
|
||||
be displayed, nor contribute to analysis operations.
|
||||
|
||||
.. versionchanged:: 1.9
|
||||
|
||||
This property can now be set as well.
|
||||
|
||||
.. method:: datatype([as_string=False])
|
||||
|
||||
The data type contained in the band, as an integer constant between 0
|
||||
|
@ -1216,6 +1341,50 @@ blue.
|
|||
``GDT_UInt32``, ``GDT_Int32``, ``GDT_Float32``, ``GDT_Float64``,
|
||||
``GDT_CInt16``, ``GDT_CInt32``, ``GDT_CFloat32``, and ``GDT_CFloat64``.
|
||||
|
||||
.. method:: data(data=None, offset=None, size=None)
|
||||
|
||||
.. versionadded:: 1.9
|
||||
|
||||
The accessor to the pixel values of the ``GDALBand``. Returns the complete
|
||||
data array if no parameters are provided. A subset of the pixel array can
|
||||
be requested by specifying an offset and block size as tuples.
|
||||
|
||||
If NumPy is available, the data is returned as NumPy array. For performance
|
||||
reasons, it is highly recommended to use NumPy.
|
||||
|
||||
Data is written to the ``GDALBand`` if the ``data`` parameter is provided.
|
||||
The input can be of one of the following types - packed string, buffer, list,
|
||||
array, and NumPy array. The number of items in the input must correspond to the
|
||||
total number of pixels in the band, or to the number of pixels for a specific
|
||||
block of pixel values if the ``offset`` and ``size`` parameters are provided.
|
||||
|
||||
For example:
|
||||
|
||||
>>> rst = GDALRaster({'width': 4, 'height': 4, 'datatype': 1, 'nr_of_bands': 1})
|
||||
>>> bnd = rst.bands[0]
|
||||
>>> bnd.data(range(16))
|
||||
>>> bnd.data()
|
||||
array([[ 0, 1, 2, 3],
|
||||
[ 4, 5, 6, 7],
|
||||
[ 8, 9, 10, 11],
|
||||
[12, 13, 14, 15]], dtype=int8)
|
||||
>>> bnd.data(offset=(1,1), size=(2,2))
|
||||
array([[ 5, 6],
|
||||
[ 9, 10]], dtype=int8)
|
||||
>>> bnd.data(data=[-1, -2, -3, -4], offset=(1,1), size=(2,2))
|
||||
>>> bnd.data()
|
||||
array([[ 0, 1, 2, 3],
|
||||
[ 4, -1, -2, 7],
|
||||
[ 8, -3, -4, 11],
|
||||
[12, 13, 14, 15]], dtype=int8)
|
||||
>>> bnd.data(data='\x9d\xa8\xb3\xbe', offset=(1,1), size=(2,2))
|
||||
>>> bnd.data()
|
||||
array([[ 0, 1, 2, 3],
|
||||
[ 4, -99, -88, 7],
|
||||
[ 8, -77, -66, 11],
|
||||
[ 12, 13, 14, 15]], dtype=int8)
|
||||
|
||||
|
||||
Settings
|
||||
========
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue