You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

base.py 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. from django.contrib.gis.gdal.base import GDALBase
  2. from django.contrib.gis.gdal.prototypes import raster as capi
  3. class GDALRasterBase(GDALBase):
  4. """
  5. Attributes that exist on both GDALRaster and GDALBand.
  6. """
  7. @property
  8. def metadata(self):
  9. """
  10. Return the metadata for this raster or band. The return value is a
  11. nested dictionary, where the first-level key is the metadata domain and
  12. the second-level is the metadata item names and values for that domain.
  13. """
  14. # The initial metadata domain list contains the default domain.
  15. # The default is returned if domain name is None.
  16. domain_list = ['DEFAULT']
  17. # Get additional metadata domains from the raster.
  18. meta_list = capi.get_ds_metadata_domain_list(self._ptr)
  19. if meta_list:
  20. # The number of domains is unknown, so retrieve data until there
  21. # are no more values in the ctypes array.
  22. counter = 0
  23. domain = meta_list[counter]
  24. while domain:
  25. domain_list.append(domain.decode())
  26. counter += 1
  27. domain = meta_list[counter]
  28. # Free domain list array.
  29. capi.free_dsl(meta_list)
  30. # Retrieve metadata values for each domain.
  31. result = {}
  32. for domain in domain_list:
  33. # Get metadata for this domain.
  34. data = capi.get_ds_metadata(
  35. self._ptr,
  36. (None if domain == 'DEFAULT' else domain.encode()),
  37. )
  38. if not data:
  39. continue
  40. # The number of metadata items is unknown, so retrieve data until
  41. # there are no more values in the ctypes array.
  42. domain_meta = {}
  43. counter = 0
  44. item = data[counter]
  45. while item:
  46. key, val = item.decode().split('=')
  47. domain_meta[key] = val
  48. counter += 1
  49. item = data[counter]
  50. # The default domain values are returned if domain is None.
  51. result[domain or 'DEFAULT'] = domain_meta
  52. return result
  53. @metadata.setter
  54. def metadata(self, value):
  55. """
  56. Set the metadata. Update only the domains that are contained in the
  57. value dictionary.
  58. """
  59. # Loop through domains.
  60. for domain, metadata in value.items():
  61. # Set the domain to None for the default, otherwise encode.
  62. domain = None if domain == 'DEFAULT' else domain.encode()
  63. # Set each metadata entry separately.
  64. for meta_name, meta_value in metadata.items():
  65. capi.set_ds_metadata_item(
  66. self._ptr, meta_name.encode(),
  67. meta_value.encode() if meta_value else None,
  68. domain,
  69. )