Loading django/contrib/gis/gdal/raster/band.py +7 −4 Original line number Diff line number Diff line Loading @@ -170,7 +170,7 @@ class GDALBand(GDALBase): dtype = GDAL_PIXEL_TYPES[dtype] return dtype def data(self, data=None, offset=None, size=None, as_memoryview=False): def data(self, data=None, offset=None, size=None, shape=None, as_memoryview=False): """ Reads or writes pixel values for this band. Blocks of data can be accessed by specifying the width, height and offset of the Loading @@ -185,6 +185,9 @@ class GDALBand(GDALBase): if not size: size = (self.width - offset[0], self.height - offset[1]) if not shape: shape = size if any(x <= 0 for x in size): raise ValueError('Offset too big for this raster.') Loading @@ -192,7 +195,7 @@ class GDALBand(GDALBase): raise ValueError('Size is larger than raster.') # Create ctypes type array generator ctypes_array = GDAL_TO_CTYPES[self.datatype()] * (size[0] * size[1]) ctypes_array = GDAL_TO_CTYPES[self.datatype()] * (shape[0] * shape[1]) if data is None: # Set read mode Loading @@ -211,8 +214,8 @@ class GDALBand(GDALBase): # Access band capi.band_io(self._ptr, access_flag, offset[0], offset[1], size[0], size[1], byref(data_array), size[0], size[1], self.datatype(), 0, 0) size[0], size[1], byref(data_array), shape[0], shape[1], self.datatype(), 0, 0) # Return data as numpy array if possible, otherwise as list if data is None: Loading docs/ref/contrib/gis/gdal.txt +28 −4 Original line number Diff line number Diff line Loading @@ -1477,7 +1477,7 @@ 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) .. method:: data(data=None, offset=None, size=None, shape=None) .. versionadded:: 1.9 Loading @@ -1490,9 +1490,17 @@ blue. 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. array, and NumPy array. The number of items in the input should normally 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. If the number of items in the input is different from the target pixel block, the ``shape`` parameter must be specified. The shape is a tuple that specifies the width and height of the input data in pixels. The data is then replicated to update the pixel values of the selected block. This is useful to fill an entire band with a single value, for instance. For example: Loading @@ -1519,6 +1527,22 @@ blue. [ 4, -99, -88, 7], [ 8, -77, -66, 11], [ 12, 13, 14, 15]], dtype=int8) >>> bnd.data([1], shape=(1, 1)) >>> bnd.data() array([[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]], dtype=uint8) >>> bnd.data(range(4), shape=(1, 4)) array([[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]], dtype=uint8) .. versionchanged:: 1.10 The ``shape`` parameter and the ability to replicate data input when setting ``GDALBand`` data was added. Settings ======== Loading docs/releases/1.10.txt +4 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,10 @@ Minor features primary key of objects in the ``properties`` dictionary if specific fields aren't specified. * The ability to replicate input data on the :meth:`GDALBand.data() <django.contrib.gis.gdal.GDALBand.data>` method was added. Band data can now be updated with repeated values efficiently. :mod:`django.contrib.messages` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Loading tests/gis_tests/gdal_tests/test_raster.py +21 −0 Original line number Diff line number Diff line Loading @@ -483,3 +483,24 @@ class GDALBandTests(SimpleTestCase): else: rsmem.bands[0].nodata_value = None self.assertIsNone(rsmem.bands[0].nodata_value) def test_band_data_replication(self): band = GDALRaster({ 'srid': 4326, 'width': 3, 'height': 3, 'bands': [{'data': range(10, 19), 'nodata_value': 0}], }).bands[0] # Variations for input (data, shape, expected result). combos = ( ([1], (1, 1), [1] * 9), (range(3), (1, 3), [0, 0, 0, 1, 1, 1, 2, 2, 2]), (range(3), (3, 1), [0, 1, 2, 0, 1, 2, 0, 1, 2]), ) for combo in combos: band.data(combo[0], shape=combo[1]) if numpy: numpy.testing.assert_equal(band.data(), numpy.array(combo[2]).reshape(3, 3)) else: self.assertEqual(band.data(), list(combo[2])) Loading
django/contrib/gis/gdal/raster/band.py +7 −4 Original line number Diff line number Diff line Loading @@ -170,7 +170,7 @@ class GDALBand(GDALBase): dtype = GDAL_PIXEL_TYPES[dtype] return dtype def data(self, data=None, offset=None, size=None, as_memoryview=False): def data(self, data=None, offset=None, size=None, shape=None, as_memoryview=False): """ Reads or writes pixel values for this band. Blocks of data can be accessed by specifying the width, height and offset of the Loading @@ -185,6 +185,9 @@ class GDALBand(GDALBase): if not size: size = (self.width - offset[0], self.height - offset[1]) if not shape: shape = size if any(x <= 0 for x in size): raise ValueError('Offset too big for this raster.') Loading @@ -192,7 +195,7 @@ class GDALBand(GDALBase): raise ValueError('Size is larger than raster.') # Create ctypes type array generator ctypes_array = GDAL_TO_CTYPES[self.datatype()] * (size[0] * size[1]) ctypes_array = GDAL_TO_CTYPES[self.datatype()] * (shape[0] * shape[1]) if data is None: # Set read mode Loading @@ -211,8 +214,8 @@ class GDALBand(GDALBase): # Access band capi.band_io(self._ptr, access_flag, offset[0], offset[1], size[0], size[1], byref(data_array), size[0], size[1], self.datatype(), 0, 0) size[0], size[1], byref(data_array), shape[0], shape[1], self.datatype(), 0, 0) # Return data as numpy array if possible, otherwise as list if data is None: Loading
docs/ref/contrib/gis/gdal.txt +28 −4 Original line number Diff line number Diff line Loading @@ -1477,7 +1477,7 @@ 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) .. method:: data(data=None, offset=None, size=None, shape=None) .. versionadded:: 1.9 Loading @@ -1490,9 +1490,17 @@ blue. 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. array, and NumPy array. The number of items in the input should normally 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. If the number of items in the input is different from the target pixel block, the ``shape`` parameter must be specified. The shape is a tuple that specifies the width and height of the input data in pixels. The data is then replicated to update the pixel values of the selected block. This is useful to fill an entire band with a single value, for instance. For example: Loading @@ -1519,6 +1527,22 @@ blue. [ 4, -99, -88, 7], [ 8, -77, -66, 11], [ 12, 13, 14, 15]], dtype=int8) >>> bnd.data([1], shape=(1, 1)) >>> bnd.data() array([[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]], dtype=uint8) >>> bnd.data(range(4), shape=(1, 4)) array([[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]], dtype=uint8) .. versionchanged:: 1.10 The ``shape`` parameter and the ability to replicate data input when setting ``GDALBand`` data was added. Settings ======== Loading
docs/releases/1.10.txt +4 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,10 @@ Minor features primary key of objects in the ``properties`` dictionary if specific fields aren't specified. * The ability to replicate input data on the :meth:`GDALBand.data() <django.contrib.gis.gdal.GDALBand.data>` method was added. Band data can now be updated with repeated values efficiently. :mod:`django.contrib.messages` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Loading
tests/gis_tests/gdal_tests/test_raster.py +21 −0 Original line number Diff line number Diff line Loading @@ -483,3 +483,24 @@ class GDALBandTests(SimpleTestCase): else: rsmem.bands[0].nodata_value = None self.assertIsNone(rsmem.bands[0].nodata_value) def test_band_data_replication(self): band = GDALRaster({ 'srid': 4326, 'width': 3, 'height': 3, 'bands': [{'data': range(10, 19), 'nodata_value': 0}], }).bands[0] # Variations for input (data, shape, expected result). combos = ( ([1], (1, 1), [1] * 9), (range(3), (1, 3), [0, 0, 0, 1, 1, 1, 2, 2, 2]), (range(3), (3, 1), [0, 1, 2, 0, 1, 2, 0, 1, 2]), ) for combo in combos: band.data(combo[0], shape=combo[1]) if numpy: numpy.testing.assert_equal(band.data(), numpy.array(combo[2]).reshape(3, 3)) else: self.assertEqual(band.data(), list(combo[2]))