Package osgeo :: Module gdal_array |
[hide private]
[frames] | no frames]

# Source Code for Module osgeo.gdal_array

      1  # This file was automatically generated by SWIG (http://www.swig.org).
      2  # Version 4.0.1
      3  #
      4  # Do not make changes to this file unless you know what you are doing--modify
      5  # the SWIG interface file instead.
      6
      7  from sys import version_info as _swig_python_version_info
      8  if _swig_python_version_info < (2, 7, 0):
      9      raise RuntimeError("Python 2.7 or later required")
     10
     11  # Import the low-level C/C++ module
     12  if __package__ or "." in __name__:
     13      from . import _gdal_array
     14  else:
     15      import _gdal_array
     16
     17  try:
     18      import builtins as __builtin__
     19  except ImportError:
     20      import __builtin__
     21
     22 -def _swig_repr(self):
     23      try:
     24          strthis = "proxy of " + self.this.__repr__()
     25      except __builtin__.Exception:
     26          strthis = ""
     27      return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
     28
     29
     30 -def _swig_setattr_nondynamic_instance_variable(set):
     31      def set_instance_attr(self, name, value):
     32          if name == "thisown":
     33              self.this.own(value)
     34          elif name == "this":
     35              set(self, name, value)
     36          elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
     37              set(self, name, value)
     38          else:
     39              raise AttributeError("You cannot add instance attributes to %s" % self)
     40      return set_instance_attr
     41
     42
     43 -def _swig_setattr_nondynamic_class_variable(set):
     44      def set_class_attr(cls, name, value):
     45          if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
     46              set(cls, name, value)
     47          else:
     48              raise AttributeError("You cannot add class attributes to %s" % cls)
     49      return set_class_attr
     50
     51
     52 -def _swig_add_metaclass(metaclass):
     53      """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
     54      def wrapper(cls):
     55          return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
     56      return wrapper
     57
     58
     59 -class _SwigNonDynamicMeta(type):
     60      """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
     61      __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)
     62
     63
     64  from . import gdal
     65 -class VirtualMem(object):
     66      r"""Proxy of C++ CPLVirtualMemShadow class."""
     67
     68      thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
     69
     70 -    def __init__(self, *args, **kwargs):
     71          raise AttributeError("No constructor defined")
     72      __repr__ = _swig_repr
     73      __swig_destroy__ = _gdal_array.delete_VirtualMem
     74
     75 -    def GetAddr(self):
     76          r"""GetAddr(VirtualMem self)"""
     77          return _gdal_array.VirtualMem_GetAddr(self)
     78
     79 -    def Pin(self, start_offset=0, nsize=0, bWriteOp=0):
     80          r"""Pin(VirtualMem self, size_t start_offset=0, size_t nsize=0, int bWriteOp=0)"""
     81          return _gdal_array.VirtualMem_Pin(self, start_offset, nsize, bWriteOp)
     82
     83  # Register VirtualMem in _gdal_array:
     84  _gdal_array.VirtualMem_swigregister(VirtualMem)
     85
     86
     87 -def _StoreLastException():
     88      r"""_StoreLastException()"""
     89      return _gdal_array._StoreLastException()
     90
     91 -def TermProgress_nocb(dfProgress, pszMessage=None, pData=None):
     92      r"""TermProgress_nocb(double dfProgress, char const * pszMessage=None, void * pData=None) -> int"""
     93      return _gdal_array.TermProgress_nocb(dfProgress, pszMessage, pData)
     94  TermProgress = _gdal_array.TermProgress
     95
     96
     97 -def OpenNumPyArray(psArray, binterleave):
     98      r"""OpenNumPyArray(PyArrayObject * psArray, bool binterleave) -> Dataset"""
     99      return _gdal_array.OpenNumPyArray(psArray, binterleave)
    100
    101 -def OpenMultiDimensionalNumPyArray(psArray):
    102      r"""OpenMultiDimensionalNumPyArray(PyArrayObject * psArray) -> Dataset"""
    103      return _gdal_array.OpenMultiDimensionalNumPyArray(psArray)
    104
    105 -def GetArrayFilename(psArray):
    106      r"""GetArrayFilename(PyArrayObject * psArray) -> retStringAndCPLFree *"""
    107      return _gdal_array.GetArrayFilename(psArray)
    108
    109 -def BandRasterIONumPy(band, bWrite, xoff, yoff, xsize, ysize, psArray, buf_type, resample_alg, callback=0, callback_data=None):
    110      r"""BandRasterIONumPy(Band band, int bWrite, double xoff, double yoff, double xsize, double ysize, PyArrayObject * psArray, GDALDataType buf_type, GDALRIOResampleAlg resample_alg, GDALProgressFunc callback=0, void * callback_data=None) -> CPLErr"""
    111      return _gdal_array.BandRasterIONumPy(band, bWrite, xoff, yoff, xsize, ysize, psArray, buf_type, resample_alg, callback, callback_data)
    112
    113 -def DatasetIONumPy(ds, bWrite, xoff, yoff, xsize, ysize, psArray, buf_type, resample_alg, callback=0, callback_data=None, binterleave=True, band_list=0):
    114      r"""DatasetIONumPy(Dataset ds, int bWrite, double xoff, double yoff, double xsize, double ysize, PyArrayObject * psArray, GDALDataType buf_type, GDALRIOResampleAlg resample_alg, GDALProgressFunc callback=0, void * callback_data=None, bool binterleave=True, int band_list=0) -> CPLErr"""
    115      return _gdal_array.DatasetIONumPy(ds, bWrite, xoff, yoff, xsize, ysize, psArray, buf_type, resample_alg, callback, callback_data, binterleave, band_list)
    116
    117 -def MDArrayIONumPy(bWrite, mdarray, psArray, nDims1, nDims3, buffer_datatype):
    118      r"""MDArrayIONumPy(bool bWrite, GDALMDArrayHS * mdarray, PyArrayObject * psArray, int nDims1, int nDims3, GDALExtendedDataTypeHS * buffer_datatype) -> CPLErr"""
    119      return _gdal_array.MDArrayIONumPy(bWrite, mdarray, psArray, nDims1, nDims3, buffer_datatype)
    120
    121 -def VirtualMemGetArray(virtualmem):
    122      r"""VirtualMemGetArray(VirtualMem virtualmem)"""
    123      return _gdal_array.VirtualMemGetArray(virtualmem)
    124
    125 -def RATValuesIONumPyWrite(poRAT, nField, nStart, psArray):
    126      r"""RATValuesIONumPyWrite(RasterAttributeTable poRAT, int nField, int nStart, PyArrayObject * psArray) -> CPLErr"""
    127      return _gdal_array.RATValuesIONumPyWrite(poRAT, nField, nStart, psArray)
    128
    129 -def RATValuesIONumPyRead(poRAT, nField, nStart, nLength):
    130      r"""RATValuesIONumPyRead(RasterAttributeTable poRAT, int nField, int nStart, int nLength) -> PyObject *"""
    131      return _gdal_array.RATValuesIONumPyRead(poRAT, nField, nStart, nLength)
    132
    133  import numpy
    134
    135  from osgeo import gdalconst
    136  from osgeo import gdal
    137  gdal.AllRegister()
    138
    139  codes = {gdalconst.GDT_Byte: numpy.uint8,
    140           gdalconst.GDT_UInt16: numpy.uint16,
    141           gdalconst.GDT_Int16: numpy.int16,
    142           gdalconst.GDT_UInt32: numpy.uint32,
    143           gdalconst.GDT_Int32: numpy.int32,
    144           gdalconst.GDT_Float32: numpy.float32,
    145           gdalconst.GDT_Float64: numpy.float64,
    146           gdalconst.GDT_CInt16: numpy.complex64,
    147           gdalconst.GDT_CInt32: numpy.complex64,
    148           gdalconst.GDT_CFloat32:  numpy.complex64,
    149           gdalconst.GDT_CFloat64: numpy.complex128}
    150
    151
    152 -def OpenArray(array, prototype_ds=None, interleave='band'):
    153
    154      interleave = interleave.lower()
    155      if interleave == 'band':
    156          interleave = True
    157      elif interleave == 'pixel':
    158          interleave = False
    159      else:
    160          raise ValueError('Interleave should be band or pixel')
    161
    162      ds = OpenNumPyArray(array, interleave)
    163
    164      if ds is not None and prototype_ds is not None:
    165          if type(prototype_ds).__name__ == 'str':
    166              prototype_ds = gdal.Open(prototype_ds)
    167          if prototype_ds is not None:
    168              CopyDatasetInfo(prototype_ds, ds)
    169
    170      return ds
    171
    172
    173 -def flip_code(code):
    174      if isinstance(code, (numpy.dtype, type)):
    175  # since several things map to complex64 we must carefully select
    176  # the opposite that is an exact match (ticket 1518)
    177          if code == numpy.int8:
    178              return gdalconst.GDT_Byte
    179          if code == numpy.complex64:
    180              return gdalconst.GDT_CFloat32
    181
    182          for key, value in codes.items():
    183              if value == code:
    184                  return key
    185          return None
    186      else:
    187          try:
    188              return codes[code]
    189          except KeyError:
    190              return None
    191
    192 -def NumericTypeCodeToGDALTypeCode(numeric_type):
    193      if not isinstance(numeric_type, (numpy.dtype, type)):
    194          raise TypeError("Input must be a type")
    195      return flip_code(numeric_type)
    196
    197 -def GDALTypeCodeToNumericTypeCode(gdal_code):
    198      return flip_code(gdal_code)
    199
    200 -def _RaiseException():
    201      if gdal.GetUseExceptions():
    202          _StoreLastException()
    203          raise RuntimeError(gdal.GetLastErrorMsg())
    204
    205 -def LoadFile(filename, xoff=0, yoff=0, xsize=None, ysize=None,
    206               buf_xsize=None, buf_ysize=None, buf_type=None,
    207               resample_alg=gdal.GRIORA_NearestNeighbour,
    208               callback=None, callback_data=None, interleave='band',
    209               band_list=None):
    210      ds = gdal.Open(filename)
    211      if ds is None:
    212          raise ValueError("Can't open "+filename+"\n\n"+gdal.GetLastErrorMsg())
    213
    214      return DatasetReadAsArray(ds, xoff, yoff, xsize, ysize,
    215                                buf_xsize=buf_xsize, buf_ysize=buf_ysize, buf_type=buf_type,
    216                                resample_alg=resample_alg,
    217                                callback=callback, callback_data=callback_data,
    218                                interleave=interleave,
    219                                band_list=band_list)
    220
    221 -def SaveArray(src_array, filename, format="GTiff", prototype=None, interleave='band'):
    222      driver = gdal.GetDriverByName(format)
    223      if driver is None:
    224          raise ValueError("Can't find driver "+format)
    225
    226      return driver.CreateCopy(filename, OpenArray(src_array, prototype, interleave))
    227
    228
    229 -def DatasetReadAsArray(ds, xoff=0, yoff=0, win_xsize=None, win_ysize=None, buf_obj=None,
    230                         buf_xsize=None, buf_ysize=None, buf_type=None,
    231                         resample_alg=gdal.GRIORA_NearestNeighbour,
    232                         callback=None, callback_data=None, interleave='band',
    233                         band_list=None):
    234      """Pure python implementation of reading a chunk of a GDAL file
    235      into a numpy array.  Used by the gdal.Dataset.ReadAsArray method."""
    236
    237      if win_xsize is None:
    238          win_xsize = ds.RasterXSize
    239      if win_ysize is None:
    240          win_ysize = ds.RasterYSize
    241
    242      if band_list is None:
    243          band_list = list(range(1, ds.RasterCount + 1))
    244
    245      interleave = interleave.lower()
    246      if interleave == 'band':
    247          interleave = True
    248          xdim = 2
    249          ydim = 1
    250          banddim = 0
    251      elif interleave == 'pixel':
    252          interleave = False
    253          xdim = 1
    254          ydim = 0
    255          banddim = 2
    256      else:
    257          raise ValueError('Interleave should be band or pixel')
    258
    259      nbands = len(band_list)
    260      if nbands == 0:
    261          return None
    262
    263      if nbands == 1:
    264          return BandReadAsArray(ds.GetRasterBand(band_list[0]), xoff, yoff, win_xsize, win_ysize,
    265                                 buf_xsize=buf_xsize, buf_ysize=buf_ysize, buf_type=buf_type,
    266                                 buf_obj=buf_obj,
    267                                 resample_alg=resample_alg,
    268                                 callback=callback,
    269                                 callback_data=callback_data)
    270
    271      if buf_obj is None:
    272          if buf_xsize is None:
    273              buf_xsize = win_xsize
    274          if buf_ysize is None:
    275              buf_ysize = win_ysize
    276          if buf_type is None:
    277              buf_type = ds.GetRasterBand(band_list[0]).DataType
    278              for idx in range(1, nbands):
    279                  band_index = band_list[idx]
    280                  if buf_type != ds.GetRasterBand(band_index).DataType:
    281                      buf_type = gdalconst.GDT_Float32
    282
    283          typecode = GDALTypeCodeToNumericTypeCode(buf_type)
    284          if typecode is None:
    285              buf_type = gdalconst.GDT_Float32
    286              typecode = numpy.float32
    287          else:
    288              buf_type = NumericTypeCodeToGDALTypeCode(typecode)
    289
    290          if buf_type == gdalconst.GDT_Byte and ds.GetRasterBand(1).GetMetadataItem('PIXELTYPE', 'IMAGE_STRUCTURE') == 'SIGNEDBYTE':
    291              typecode = numpy.int8
    292          buf_shape = (nbands, buf_ysize, buf_xsize) if interleave else (buf_ysize, buf_xsize, nbands)
    293          buf_obj = numpy.empty(buf_shape, dtype=typecode)
    294
    295      else:
    296          if len(buf_obj.shape) != 3:
    297              raise ValueError('Array should have 3 dimensions')
    298
    299          shape_buf_xsize = buf_obj.shape[xdim]
    300          shape_buf_ysize = buf_obj.shape[ydim]
    301          if buf_xsize is not None and buf_xsize != shape_buf_xsize:
    302              raise ValueError('Specified buf_xsize not consistent with array shape')
    303          if buf_ysize is not None and buf_ysize != shape_buf_ysize:
    304              raise ValueError('Specified buf_ysize not consistent with array shape')
    305          if buf_obj.shape[banddim] != nbands:
    306              raise ValueError('Dimension %d of array should have size %d to store bands)' % (banddim, nbands))
    307
    308          datatype = NumericTypeCodeToGDALTypeCode(buf_obj.dtype.type)
    309          if not datatype:
    310              raise ValueError("array does not have corresponding GDAL data type")
    311          if buf_type is not None and buf_type != datatype:
    312              raise ValueError("Specified buf_type not consistent with array type")
    313          buf_type = datatype
    314
    315      if DatasetIONumPy(ds, 0, xoff, yoff, win_xsize, win_ysize,
    316                        buf_obj, buf_type, resample_alg, callback, callback_data,
    317                        interleave, band_list) != 0:
    318          _RaiseException()
    319          return None
    320
    321      return buf_obj
    322
    323
    324 -def DatasetWriteArray(ds, array, xoff=0, yoff=0,
    325                        band_list=None,
    326                        interleave='band',
    327                        resample_alg=gdal.GRIORA_NearestNeighbour,
    328                        callback=None, callback_data=None):
    329      """Pure python implementation of writing a chunk of a GDAL file
    330      from a numpy array.  Used by the gdal.Dataset.WriteArray method."""
    331
    332      if band_list is None:
    333          band_list = list(range(1, ds.RasterCount + 1))
    334
    335      interleave = interleave.lower()
    336      if interleave == 'band':
    337          interleave = True
    338          xdim = 2
    339          ydim = 1
    340          banddim = 0
    341      elif interleave == 'pixel':
    342          interleave = False
    343          xdim = 1
    344          ydim = 0
    345          banddim = 2
    346      else:
    347          raise ValueError('Interleave should be band or pixel')
    348
    349      if len(band_list) == 1:
    350          if array is None or (len(array.shape) != 2 and len(array.shape) != 3):
    351              raise ValueError("expected array of dim 2 or 3")
    352          if len(array.shape) == 3:
    353              if array.shape[banddim] != 1:
    354                  raise ValueError("expected size of dimension %d should be 1" % banddim)
    355              array = array[banddim]
    356
    357          return BandWriteArray(ds.GetRasterBand(band_list[0]),
    358                                array,
    359                                xoff=xoff, yoff=yoff, resample_alg=resample_alg,
    360                                callback=callback, callback_data=callback_data)
    361
    362      if array is None or len(array.shape) != 3:
    363          raise ValueError("expected array of dim 3")
    364
    365      xsize = array.shape[xdim]
    366      ysize = array.shape[ydim]
    367
    368      if xsize + xoff > ds.RasterXSize or ysize + yoff > ds.RasterYSize:
    369          raise ValueError("array larger than output file, or offset off edge")
    370      if array.shape[banddim] != len(band_list):
    371          raise ValueError('Dimension %d of array should have size %d to store bands)' % (banddim, len(band_list)))
    372
    373      datatype = NumericTypeCodeToGDALTypeCode(array.dtype.type)
    374
    375  # if we receive some odd type, like int64, try casting to a very
    376  # generic type we do support (#2285)
    377      if not datatype:
    378          gdal.Debug('gdal_array', 'force array to float64')
    379          array = array.astype(numpy.float64)
    380          datatype = NumericTypeCodeToGDALTypeCode(array.dtype.type)
    381
    382      if not datatype:
    383          raise ValueError("array does not have corresponding GDAL data type")
    384
    385      ret = DatasetIONumPy(ds, 1, xoff, yoff, xsize, ysize,
    386                           array, datatype, resample_alg, callback, callback_data,
    387                           interleave, band_list)
    388      if ret != 0:
    389          _RaiseException()
    390      return ret
    391
    392
    393 -def BandReadAsArray(band, xoff=0, yoff=0, win_xsize=None, win_ysize=None,
    394                      buf_xsize=None, buf_ysize=None, buf_type=None, buf_obj=None,
    395                      resample_alg=gdal.GRIORA_NearestNeighbour,
    396                      callback=None, callback_data=None):
    397      """Pure python implementation of reading a chunk of a GDAL file
    398      into a numpy array.  Used by the gdal.Band.ReadAsArray method."""
    399
    400      if win_xsize is None:
    401          win_xsize = band.XSize
    402      if win_ysize is None:
    403          win_ysize = band.YSize
    404
    405      if buf_obj is None:
    406          if buf_xsize is None:
    407              buf_xsize = win_xsize
    408          if buf_ysize is None:
    409              buf_ysize = win_ysize
    410          if buf_type is None:
    411              buf_type = band.DataType
    412
    413          typecode = GDALTypeCodeToNumericTypeCode(buf_type)
    414          if typecode is None:
    415              buf_type = gdalconst.GDT_Float32
    416              typecode = numpy.float32
    417          else:
    418              buf_type = NumericTypeCodeToGDALTypeCode(typecode)
    419
    420          if buf_type == gdalconst.GDT_Byte and band.GetMetadataItem('PIXELTYPE', 'IMAGE_STRUCTURE') == 'SIGNEDBYTE':
    421              typecode = numpy.int8
    422          buf_obj = numpy.empty([buf_ysize, buf_xsize], dtype=typecode)
    423
    424      else:
    425          if len(buf_obj.shape) not in (2, 3):
    426              raise ValueError("expected array of dimension 2 or 3")
    427
    428          if len(buf_obj.shape) == 2:
    429              shape_buf_xsize = buf_obj.shape[1]
    430              shape_buf_ysize = buf_obj.shape[0]
    431          else:
    432              if buf_obj.shape[0] != 1:
    433                  raise ValueError("expected size of first dimension should be 0")
    434              shape_buf_xsize = buf_obj.shape[2]
    435              shape_buf_ysize = buf_obj.shape[1]
    436          if buf_xsize is not None and buf_xsize != shape_buf_xsize:
    437              raise ValueError('Specified buf_xsize not consistent with array shape')
    438          if buf_ysize is not None and buf_ysize != shape_buf_ysize:
    439              raise ValueError('Specified buf_ysize not consistent with array shape')
    440
    441          datatype = NumericTypeCodeToGDALTypeCode(buf_obj.dtype.type)
    442          if not datatype:
    443              raise ValueError("array does not have corresponding GDAL data type")
    444          if buf_type is not None and buf_type != datatype:
    445              raise ValueError("Specified buf_type not consistent with array type")
    446          buf_type = datatype
    447
    448      if BandRasterIONumPy(band, 0, xoff, yoff, win_xsize, win_ysize,
    449                           buf_obj, buf_type, resample_alg, callback, callback_data) != 0:
    450          _RaiseException()
    451          return None
    452
    453      return buf_obj
    454
    455 -def BandWriteArray(band, array, xoff=0, yoff=0,
    456                     resample_alg=gdal.GRIORA_NearestNeighbour,
    457                     callback=None, callback_data=None):
    458      """Pure python implementation of writing a chunk of a GDAL file
    459      from a numpy array.  Used by the gdal.Band.WriteArray method."""
    460
    461      if array is None or len(array.shape) != 2:
    462          raise ValueError("expected array of dim 2")
    463
    464      xsize = array.shape[1]
    465      ysize = array.shape[0]
    466
    467      if xsize + xoff > band.XSize or ysize + yoff > band.YSize:
    468          raise ValueError("array larger than output file, or offset off edge")
    469
    470      datatype = NumericTypeCodeToGDALTypeCode(array.dtype.type)
    471
    472  # if we receive some odd type, like int64, try casting to a very
    473  # generic type we do support (#2285)
    474      if not datatype:
    475          gdal.Debug('gdal_array', 'force array to float64')
    476          array = array.astype(numpy.float64)
    477          datatype = NumericTypeCodeToGDALTypeCode(array.dtype.type)
    478
    479      if not datatype:
    480          raise ValueError("array does not have corresponding GDAL data type")
    481
    482      ret = BandRasterIONumPy(band, 1, xoff, yoff, xsize, ysize,
    483                               array, datatype, resample_alg, callback, callback_data)
    484      if ret != 0:
    485          _RaiseException()
    486      return ret
    487
    488 -def ExtendedDataTypeToNumPyDataType(dt):
    489      klass = dt.GetClass()
    490
    491      if klass == gdal.GEDTC_STRING:
    492          return numpy.bytes_
    493
    494      if klass == gdal.GEDTC_NUMERIC:
    495          buf_type = dt.GetNumericDataType()
    496          typecode = GDALTypeCodeToNumericTypeCode(buf_type)
    497          if typecode is None:
    498              typecode = numpy.float32
    499          return typecode
    500
    501      assert klass == gdal.GEDTC_COMPOUND
    502      names = []
    503      formats = []
    504      offsets = []
    505      for comp in dt.GetComponents():
    506          names.append(comp.GetName())
    507          formats.append(ExtendedDataTypeToNumPyDataType(comp.GetType()))
    508          offsets.append(comp.GetOffset())
    509
    510      return numpy.dtype({'names': names,
    511                          'formats': formats,
    512                          'offsets': offsets,
    513                          'itemsize': dt.GetSize()})
    514
    515 -def MDArrayReadAsArray(mdarray,
    516                          array_start_idx = None,
    517                          count = None,
    518                          array_step = None,
    519                          buffer_datatype = None,
    520                          buf_obj = None):
    521      if not array_start_idx:
    522          array_start_idx = [0] * mdarray.GetDimensionCount()
    523      if not count:
    524          count = [ dim.GetSize() for dim in mdarray.GetDimensions() ]
    525      if not array_step:
    526          array_step = [1] * mdarray.GetDimensionCount()
    527      if not buffer_datatype:
    528          buffer_datatype = mdarray.GetDataType()
    529
    530      if buf_obj is None:
    531          typecode = ExtendedDataTypeToNumPyDataType(buffer_datatype)
    532          buf_obj = numpy.empty(count, dtype=typecode)
    533
    534      ret = MDArrayIONumPy(False, mdarray, buf_obj, array_start_idx, array_step, buffer_datatype)
    535      if ret != 0:
    536          _RaiseException()
    537      return buf_obj
    538
    539 -def MDArrayWriteArray(mdarray, array,
    540                          array_start_idx = None,
    541                          array_step = None):
    542      if not array_start_idx:
    543          array_start_idx = [0] * mdarray.GetDimensionCount()
    544      if not array_step:
    545          array_step = [1] * mdarray.GetDimensionCount()
    546
    547      buffer_datatype = mdarray.GetDataType()
    548      if array.dtype != ExtendedDataTypeToNumPyDataType(buffer_datatype):
    549          datatype = NumericTypeCodeToGDALTypeCode(array.dtype.type)
    550
    551  # if we receive some odd type, like int64, try casting to a very
    552  # generic type we do support (#2285)
    553          if not datatype:
    554              gdal.Debug('gdal_array', 'force array to float64')
    555              array = array.astype(numpy.float64)
    556              datatype = NumericTypeCodeToGDALTypeCode(array.dtype.type)
    557
    558          if not datatype:
    559              raise ValueError("array does not have corresponding GDAL data type")
    560
    561          buffer_datatype = gdal.ExtendedDataType.Create(datatype)
    562
    563      ret = MDArrayIONumPy(True, mdarray, array, array_start_idx, array_step, buffer_datatype)
    564      if ret != 0:
    565          _RaiseException()
    566      return ret
    567
    568 -def RATWriteArray(rat, array, field, start=0):
    569      """
    570      Pure Python implementation of writing a chunk of the RAT
    571      from a numpy array. Type of array is coerced to one of the types
    572      (int, double, string) supported. Called from RasterAttributeTable.WriteArray
    573      """
    574      if array is None:
    575          raise ValueError("Expected array of dim 1")
    576
    577  # if not the array type convert it to handle lists etc
    578      if not isinstance(array, numpy.ndarray):
    579          array = numpy.array(array)
    580
    581      if array.ndim != 1:
    582          raise ValueError("Expected array of dim 1")
    583
    584      if (start + array.size) > rat.GetRowCount():
    585          raise ValueError("Array too big to fit into RAT from start position")
    586
    587      if numpy.issubdtype(array.dtype, numpy.integer):
    588  # is some type of integer - coerce to standard int
    589  # TODO: must check this is fine on all platforms
    590  # confusingly numpy.int 64 bit even if native type 32 bit
    591          array = array.astype(numpy.int32)
    592      elif numpy.issubdtype(array.dtype, numpy.floating):
    593  # is some type of floating point - coerce to double
    594          array = array.astype(numpy.double)
    595      elif numpy.issubdtype(array.dtype, numpy.character):
    596  # cast away any kind of Unicode etc
    597          array = array.astype(bytes)
    598      else:
    599          raise ValueError("Array not of a supported type (integer, double or string)")
    600
    601      ret = RATValuesIONumPyWrite(rat, field, start, array)
    602      if ret != 0:
    603          _RaiseException()
    604      return ret
    605
    606 -def RATReadArray(rat, field, start=0, length=None):
    607      """
    608      Pure Python implementation of reading a chunk of the RAT
    609      into a numpy array. Called from RasterAttributeTable.ReadAsArray
    610      """
    611      if length is None:
    612          length = rat.GetRowCount() - start
    613
    614      ret = RATValuesIONumPyRead(rat, field, start, length)
    615      if ret is None:
    616          _RaiseException()
    617      return ret
    618
    619 -def CopyDatasetInfo(src, dst, xoff=0, yoff=0):
    620      """
    621      Copy georeferencing information and metadata from one dataset to another.
    622      src: input dataset
    623      dst: output dataset - It can be a ROI -
    624      xoff, yoff:  dst's offset with respect to src in pixel/line.
    625
    626      Notes: Destination dataset must have update access.  Certain formats
    627             do not support creation of geotransforms and/or gcps.
    628
    629      """
    630
    631      dst.SetMetadata(src.GetMetadata())
    632
    633
    634
    635  #Check for geo transform
    636      gt = src.GetGeoTransform()
    637      if gt != (0, 1, 0, 0, 0, 1):
    638          dst.SetProjection(src.GetProjectionRef())
    639
    640          if xoff == 0 and yoff == 0:
    641              dst.SetGeoTransform(gt)
    642          else:
    643              ngt = [gt[0], gt[1], gt[2], gt[3], gt[4], gt[5]]
    644              ngt[0] = gt[0] + xoff*gt[1] + yoff*gt[2]
    645              ngt[3] = gt[3] + xoff*gt[4] + yoff*gt[5]
    646              dst.SetGeoTransform((ngt[0], ngt[1], ngt[2], ngt[3], ngt[4], ngt[5]))
    647
    648  #Check for GCPs
    649      elif src.GetGCPCount() > 0:
    650
    651          if (xoff == 0) and (yoff == 0):
    652              dst.SetGCPs(src.GetGCPs(), src.GetGCPProjection())
    653          else:
    654              gcps = src.GetGCPs()
    655  #Shift gcps
    656              new_gcps = []
    657              for gcp in gcps:
    658                  ngcp = gdal.GCP()
    659                  ngcp.GCPX = gcp.GCPX
    660                  ngcp.GCPY = gcp.GCPY
    661                  ngcp.GCPZ = gcp.GCPZ
    662                  ngcp.GCPPixel = gcp.GCPPixel - xoff
    663                  ngcp.GCPLine = gcp.GCPLine - yoff
    664                  ngcp.Info = gcp.Info
    665                  ngcp.Id = gcp.Id
    666                  new_gcps.append(ngcp)
    667
    668              try:
    669                  dst.SetGCPs(new_gcps, src.GetGCPProjection())
    670              except:
    671                  print("Failed to set GCPs")
    672                  return
    673
    674      return
    675