From 4fe6588da372cdcc14f3e981d4bb960cf905dc74 Mon Sep 17 00:00:00 2001 From: Niall Dalton Date: Mon, 18 Sep 2017 20:39:36 -0400 Subject: [PATCH] Fixed #28576 -- Added color interpretation method to GDALBand. --- AUTHORS | 1 + django/contrib/gis/gdal/prototypes/raster.py | 1 + django/contrib/gis/gdal/raster/band.py | 11 +++++++++- django/contrib/gis/gdal/raster/const.py | 21 ++++++++++++++++++++ docs/ref/contrib/gis/gdal.txt | 16 +++++++++++++++ docs/releases/2.0.txt | 4 ++++ tests/gis_tests/gdal_tests/test_raster.py | 2 ++ 7 files changed, 55 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 65d1af71052..e877db3fda1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -591,6 +591,7 @@ answer newbie questions, and generally made Django that much better: Nebojša Dorđević Ned Batchelder Nena Kojadin + Niall Dalton Niall Kelly Nick Efford Nick Lane diff --git a/django/contrib/gis/gdal/prototypes/raster.py b/django/contrib/gis/gdal/prototypes/raster.py index 72702ab178b..14cb5122455 100644 --- a/django/contrib/gis/gdal/prototypes/raster.py +++ b/django/contrib/gis/gdal/prototypes/raster.py @@ -75,6 +75,7 @@ get_band_index = int_output(std_call('GDALGetBandNumber'), [c_void_p]) get_band_description = const_string_output(std_call('GDALGetDescription'), [c_void_p]) get_band_ds = voidptr_output(std_call('GDALGetBandDataset'), [c_void_p]) get_band_datatype = int_output(std_call('GDALGetRasterDataType'), [c_void_p]) +get_band_color_interp = int_output(std_call('GDALGetRasterColorInterpretation'), [c_void_p]) get_band_nodata_value = double_output(std_call('GDALGetRasterNoDataValue'), [c_void_p, POINTER(c_int)]) set_band_nodata_value = void_output(std_call('GDALSetRasterNoDataValue'), [c_void_p, c_double]) if GDAL_VERSION >= (2, 1): diff --git a/django/contrib/gis/gdal/raster/band.py b/django/contrib/gis/gdal/raster/band.py index 19d8ef41cf5..d78fd2213e7 100644 --- a/django/contrib/gis/gdal/raster/band.py +++ b/django/contrib/gis/gdal/raster/band.py @@ -6,7 +6,9 @@ from django.contrib.gis.gdal.raster.base import GDALRasterBase from django.contrib.gis.shortcuts import numpy from django.utils.encoding import force_text -from .const import GDAL_INTEGER_TYPES, GDAL_PIXEL_TYPES, GDAL_TO_CTYPES +from .const import ( + GDAL_COLOR_TYPES, GDAL_INTEGER_TYPES, GDAL_PIXEL_TYPES, GDAL_TO_CTYPES, +) class GDALBand(GDALRasterBase): @@ -168,6 +170,13 @@ class GDALBand(GDALRasterBase): dtype = GDAL_PIXEL_TYPES[dtype] return dtype + def color_interp(self, as_string=False): + """Return the GDAL color interpretation for this band.""" + color = capi.get_band_color_interp(self._ptr) + if as_string: + color = GDAL_COLOR_TYPES[color] + return color + def data(self, data=None, offset=None, size=None, shape=None, as_memoryview=False): """ Read or writes pixel values for this band. Blocks of data can diff --git a/django/contrib/gis/gdal/raster/const.py b/django/contrib/gis/gdal/raster/const.py index 8b2656d33f7..3c87499b876 100644 --- a/django/contrib/gis/gdal/raster/const.py +++ b/django/contrib/gis/gdal/raster/const.py @@ -44,6 +44,27 @@ GDAL_RESAMPLE_ALGORITHMS = { 'Mode': 6, } +# See http://www.gdal.org/gdal_8h.html#ace76452d94514561fffa8ea1d2a5968c +GDAL_COLOR_TYPES = { + 0: 'GCI_Undefined', # Undefined, default value, i.e. not known + 1: 'GCI_GrayIndex', # Greyscale + 2: 'GCI_PaletteIndex', # Paletted + 3: 'GCI_RedBand', # Red band of RGBA image + 4: 'GCI_GreenBand', # Green band of RGBA image + 5: 'GCI_BlueBand', # Blue band of RGBA image + 6: 'GCI_AlphaBand', # Alpha (0=transparent, 255=opaque) + 7: 'GCI_HueBand', # Hue band of HLS image + 8: 'GCI_SaturationBand', # Saturation band of HLS image + 9: 'GCI_LightnessBand', # Lightness band of HLS image + 10: 'GCI_CyanBand', # Cyan band of CMYK image + 11: 'GCI_MagentaBand', # Magenta band of CMYK image + 12: 'GCI_YellowBand', # Yellow band of CMYK image + 13: 'GCI_BlackBand', # Black band of CMLY image + 14: 'GCI_YCbCr_YBand', # Y Luminance + 15: 'GCI_YCbCr_CbBand', # Cb Chroma + 16: 'GCI_YCbCr_CrBand', # Cr Chroma, also GCI_Max +} + # Fixed base path for buffer-based GDAL in-memory files. VSI_FILESYSTEM_BASE_PATH = '/vsimem/' diff --git a/docs/ref/contrib/gis/gdal.txt b/docs/ref/contrib/gis/gdal.txt index 832d91977c8..68aca347cc7 100644 --- a/docs/ref/contrib/gis/gdal.txt +++ b/docs/ref/contrib/gis/gdal.txt @@ -1551,6 +1551,22 @@ blue. ``GDT_UInt32``, ``GDT_Int32``, ``GDT_Float32``, ``GDT_Float64``, ``GDT_CInt16``, ``GDT_CInt32``, ``GDT_CFloat32``, and ``GDT_CFloat64``. + .. method:: color_interp(as_string=False) + + .. versionadded:: 2.0 + + The color interpretation for the band, as an integer between 0and 16. + If ``as_string`` is ``True``, the data type is returned as a string + with the following possible values: + ``GCI_Undefined``, ``GCI_GrayIndex``, ``GCI_PaletteIndex``, + ``GCI_RedBand``, ``GCI_GreenBand``, ``GCI_BlueBand``, ``GCI_AlphaBand``, + ``GCI_HueBand``, ``GCI_SaturationBand``, ``GCI_LightnessBand``, + ``GCI_CyanBand``, ``GCI_MagentaBand``, ``GCI_YellowBand``, + ``GCI_BlackBand``, ``GCI_YCbCr_YBand``, ``GCI_YCbCr_CbBand``, and + ``GCI_YCbCr_CrBand``. ``GCI_YCbCr_CrBand`` also represents ``GCI_Max`` + because both correspond to the integer 16, but only ``GCI_YCbCr_CrBand`` + is returned as a string. + .. method:: data(data=None, offset=None, size=None, shape=None) The accessor to the pixel values of the ``GDALBand``. Returns the complete diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 457e69ea9e5..71d41b664ce 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -144,6 +144,10 @@ Minor features GDAL's internal virtual filesystem. Rasters can now be :ref:`created from and converted to binary data ` in-memory. +* The new :meth:`GDALBand.color_interp() + ` method returns the color + interpretation for the band. + :mod:`django.contrib.messages` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/gis_tests/gdal_tests/test_raster.py b/tests/gis_tests/gdal_tests/test_raster.py index 9534681d446..219600fb6a8 100644 --- a/tests/gis_tests/gdal_tests/test_raster.py +++ b/tests/gis_tests/gdal_tests/test_raster.py @@ -562,6 +562,8 @@ class GDALBandTests(SimpleTestCase): self.assertEqual(self.band.description, '') self.assertEqual(self.band.datatype(), 1) self.assertEqual(self.band.datatype(as_string=True), 'GDT_Byte') + self.assertEqual(self.band.color_interp(), 1) + self.assertEqual(self.band.color_interp(as_string=True), 'GCI_GrayIndex') self.assertEqual(self.band.nodata_value, 15) if numpy: data = self.band.data()