test_raster.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. """
  2. gdalinfo tests/gis_tests/data/rasters/raster.tif:
  3. Driver: GTiff/GeoTIFF
  4. Files: tests/gis_tests/data/rasters/raster.tif
  5. Size is 163, 174
  6. Coordinate System is:
  7. PROJCS["NAD83 / Florida GDL Albers",
  8. GEOGCS["NAD83",
  9. DATUM["North_American_Datum_1983",
  10. SPHEROID["GRS 1980",6378137,298.2572221010002,
  11. AUTHORITY["EPSG","7019"]],
  12. TOWGS84[0,0,0,0,0,0,0],
  13. AUTHORITY["EPSG","6269"]],
  14. PRIMEM["Greenwich",0],
  15. UNIT["degree",0.0174532925199433],
  16. AUTHORITY["EPSG","4269"]],
  17. PROJECTION["Albers_Conic_Equal_Area"],
  18. PARAMETER["standard_parallel_1",24],
  19. PARAMETER["standard_parallel_2",31.5],
  20. PARAMETER["latitude_of_center",24],
  21. PARAMETER["longitude_of_center",-84],
  22. PARAMETER["false_easting",400000],
  23. PARAMETER["false_northing",0],
  24. UNIT["metre",1,
  25. AUTHORITY["EPSG","9001"]],
  26. AUTHORITY["EPSG","3086"]]
  27. Origin = (511700.468070655711927,435103.377123198588379)
  28. Pixel Size = (100.000000000000000,-100.000000000000000)
  29. Metadata:
  30. AREA_OR_POINT=Area
  31. Image Structure Metadata:
  32. INTERLEAVE=BAND
  33. Corner Coordinates:
  34. Upper Left ( 511700.468, 435103.377) ( 82d51'46.16"W, 27d55' 1.53"N)
  35. Lower Left ( 511700.468, 417703.377) ( 82d51'52.04"W, 27d45'37.50"N)
  36. Upper Right ( 528000.468, 435103.377) ( 82d41'48.81"W, 27d54'56.30"N)
  37. Lower Right ( 528000.468, 417703.377) ( 82d41'55.54"W, 27d45'32.28"N)
  38. Center ( 519850.468, 426403.377) ( 82d46'50.64"W, 27d50'16.99"N)
  39. Band 1 Block=163x50 Type=Byte, ColorInterp=Gray
  40. NoData Value=15
  41. """
  42. import os
  43. import struct
  44. import tempfile
  45. import unittest
  46. from django.contrib.gis.gdal import HAS_GDAL
  47. from django.contrib.gis.gdal.error import GDALException
  48. from django.contrib.gis.shortcuts import numpy
  49. from django.test import SimpleTestCase
  50. from ..data.rasters.textrasters import JSON_RASTER
  51. if HAS_GDAL:
  52. from django.contrib.gis.gdal import GDALRaster, GDAL_VERSION
  53. from django.contrib.gis.gdal.raster.band import GDALBand
  54. @unittest.skipUnless(HAS_GDAL, "GDAL is required")
  55. class GDALRasterTests(SimpleTestCase):
  56. """
  57. Test a GDALRaster instance created from a file (GeoTiff).
  58. """
  59. def setUp(self):
  60. self.rs_path = os.path.join(os.path.dirname(__file__), '../data/rasters/raster.tif')
  61. self.rs = GDALRaster(self.rs_path)
  62. def test_rs_name_repr(self):
  63. self.assertEqual(self.rs_path, self.rs.name)
  64. self.assertRegex(repr(self.rs), r"<Raster object at 0x\w+>")
  65. def test_rs_driver(self):
  66. self.assertEqual(self.rs.driver.name, 'GTiff')
  67. def test_rs_size(self):
  68. self.assertEqual(self.rs.width, 163)
  69. self.assertEqual(self.rs.height, 174)
  70. def test_rs_srs(self):
  71. self.assertEqual(self.rs.srs.srid, 3086)
  72. self.assertEqual(self.rs.srs.units, (1.0, 'metre'))
  73. def test_rs_srid(self):
  74. rast = GDALRaster({
  75. 'width': 16,
  76. 'height': 16,
  77. 'srid': 4326,
  78. })
  79. self.assertEqual(rast.srid, 4326)
  80. rast.srid = 3086
  81. self.assertEqual(rast.srid, 3086)
  82. def test_geotransform_and_friends(self):
  83. # Assert correct values for file based raster
  84. self.assertEqual(
  85. self.rs.geotransform,
  86. [511700.4680706557, 100.0, 0.0, 435103.3771231986, 0.0, -100.0]
  87. )
  88. self.assertEqual(self.rs.origin, [511700.4680706557, 435103.3771231986])
  89. self.assertEqual(self.rs.origin.x, 511700.4680706557)
  90. self.assertEqual(self.rs.origin.y, 435103.3771231986)
  91. self.assertEqual(self.rs.scale, [100.0, -100.0])
  92. self.assertEqual(self.rs.scale.x, 100.0)
  93. self.assertEqual(self.rs.scale.y, -100.0)
  94. self.assertEqual(self.rs.skew, [0, 0])
  95. self.assertEqual(self.rs.skew.x, 0)
  96. self.assertEqual(self.rs.skew.y, 0)
  97. # Create in-memory rasters and change gtvalues
  98. rsmem = GDALRaster(JSON_RASTER)
  99. rsmem.geotransform = range(6)
  100. self.assertEqual(rsmem.geotransform, [float(x) for x in range(6)])
  101. self.assertEqual(rsmem.origin, [0, 3])
  102. self.assertEqual(rsmem.origin.x, 0)
  103. self.assertEqual(rsmem.origin.y, 3)
  104. self.assertEqual(rsmem.scale, [1, 5])
  105. self.assertEqual(rsmem.scale.x, 1)
  106. self.assertEqual(rsmem.scale.y, 5)
  107. self.assertEqual(rsmem.skew, [2, 4])
  108. self.assertEqual(rsmem.skew.x, 2)
  109. self.assertEqual(rsmem.skew.y, 4)
  110. self.assertEqual(rsmem.width, 5)
  111. self.assertEqual(rsmem.height, 5)
  112. def test_rs_extent(self):
  113. self.assertEqual(
  114. self.rs.extent,
  115. (511700.4680706557, 417703.3771231986, 528000.4680706557, 435103.3771231986)
  116. )
  117. def test_rs_bands(self):
  118. self.assertEqual(len(self.rs.bands), 1)
  119. self.assertIsInstance(self.rs.bands[0], GDALBand)
  120. def test_memory_based_raster_creation(self):
  121. # Create uint8 raster with full pixel data range (0-255)
  122. rast = GDALRaster({
  123. 'datatype': 1,
  124. 'width': 16,
  125. 'height': 16,
  126. 'srid': 4326,
  127. 'bands': [{
  128. 'data': range(256),
  129. 'nodata_value': 255,
  130. }],
  131. })
  132. # Get array from raster
  133. result = rast.bands[0].data()
  134. if numpy:
  135. result = result.flatten().tolist()
  136. # Assert data is same as original input
  137. self.assertEqual(result, list(range(256)))
  138. def test_file_based_raster_creation(self):
  139. # Prepare tempfile
  140. rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
  141. # Create file-based raster from scratch
  142. GDALRaster({
  143. 'datatype': self.rs.bands[0].datatype(),
  144. 'driver': 'tif',
  145. 'name': rstfile.name,
  146. 'width': 163,
  147. 'height': 174,
  148. 'nr_of_bands': 1,
  149. 'srid': self.rs.srs.wkt,
  150. 'origin': (self.rs.origin.x, self.rs.origin.y),
  151. 'scale': (self.rs.scale.x, self.rs.scale.y),
  152. 'skew': (self.rs.skew.x, self.rs.skew.y),
  153. 'bands': [{
  154. 'data': self.rs.bands[0].data(),
  155. 'nodata_value': self.rs.bands[0].nodata_value,
  156. }],
  157. })
  158. # Reload newly created raster from file
  159. restored_raster = GDALRaster(rstfile.name)
  160. self.assertEqual(restored_raster.srs.wkt, self.rs.srs.wkt)
  161. self.assertEqual(restored_raster.geotransform, self.rs.geotransform)
  162. if numpy:
  163. numpy.testing.assert_equal(
  164. restored_raster.bands[0].data(),
  165. self.rs.bands[0].data()
  166. )
  167. else:
  168. self.assertEqual(restored_raster.bands[0].data(), self.rs.bands[0].data())
  169. def test_offset_size_and_shape_on_raster_creation(self):
  170. rast = GDALRaster({
  171. 'datatype': 1,
  172. 'width': 4,
  173. 'height': 4,
  174. 'srid': 4326,
  175. 'bands': [{
  176. 'data': (1,),
  177. 'offset': (1, 1),
  178. 'size': (2, 2),
  179. 'shape': (1, 1),
  180. 'nodata_value': 2,
  181. }],
  182. })
  183. # Get array from raster.
  184. result = rast.bands[0].data()
  185. if numpy:
  186. result = result.flatten().tolist()
  187. # Band data is equal to nodata value except on input block of ones.
  188. self.assertEqual(
  189. result,
  190. [2, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 2]
  191. )
  192. def test_set_nodata_value_on_raster_creation(self):
  193. # Create raster filled with nodata values.
  194. rast = GDALRaster({
  195. 'datatype': 1,
  196. 'width': 2,
  197. 'height': 2,
  198. 'srid': 4326,
  199. 'bands': [{'nodata_value': 23}],
  200. })
  201. # Get array from raster.
  202. result = rast.bands[0].data()
  203. if numpy:
  204. result = result.flatten().tolist()
  205. # All band data is equal to nodata value.
  206. self.assertEqual(result, [23, ] * 4)
  207. def test_set_nodata_none_on_raster_creation(self):
  208. if GDAL_VERSION < (2, 1):
  209. self.skipTest("GDAL >= 2.1 is required for this test.")
  210. # Create raster without data and without nodata value.
  211. rast = GDALRaster({
  212. 'datatype': 1,
  213. 'width': 2,
  214. 'height': 2,
  215. 'srid': 4326,
  216. 'bands': [{'nodata_value': None}],
  217. })
  218. # Get array from raster.
  219. result = rast.bands[0].data()
  220. if numpy:
  221. result = result.flatten().tolist()
  222. # Band data is equal to zero becaues no nodata value has been specified.
  223. self.assertEqual(result, [0] * 4)
  224. def test_raster_warp(self):
  225. # Create in memory raster
  226. source = GDALRaster({
  227. 'datatype': 1,
  228. 'driver': 'MEM',
  229. 'name': 'sourceraster',
  230. 'width': 4,
  231. 'height': 4,
  232. 'nr_of_bands': 1,
  233. 'srid': 3086,
  234. 'origin': (500000, 400000),
  235. 'scale': (100, -100),
  236. 'skew': (0, 0),
  237. 'bands': [{
  238. 'data': range(16),
  239. 'nodata_value': 255,
  240. }],
  241. })
  242. # Test altering the scale, width, and height of a raster
  243. data = {
  244. 'scale': [200, -200],
  245. 'width': 2,
  246. 'height': 2,
  247. }
  248. target = source.warp(data)
  249. self.assertEqual(target.width, data['width'])
  250. self.assertEqual(target.height, data['height'])
  251. self.assertEqual(target.scale, data['scale'])
  252. self.assertEqual(target.bands[0].datatype(), source.bands[0].datatype())
  253. self.assertEqual(target.name, 'sourceraster_copy.MEM')
  254. result = target.bands[0].data()
  255. if numpy:
  256. result = result.flatten().tolist()
  257. self.assertEqual(result, [5, 7, 13, 15])
  258. # Test altering the name and datatype (to float)
  259. data = {
  260. 'name': '/path/to/targetraster.tif',
  261. 'datatype': 6,
  262. }
  263. target = source.warp(data)
  264. self.assertEqual(target.bands[0].datatype(), 6)
  265. self.assertEqual(target.name, '/path/to/targetraster.tif')
  266. self.assertEqual(target.driver.name, 'MEM')
  267. result = target.bands[0].data()
  268. if numpy:
  269. result = result.flatten().tolist()
  270. self.assertEqual(
  271. result,
  272. [0.0, 1.0, 2.0, 3.0,
  273. 4.0, 5.0, 6.0, 7.0,
  274. 8.0, 9.0, 10.0, 11.0,
  275. 12.0, 13.0, 14.0, 15.0]
  276. )
  277. def test_raster_warp_nodata_zone(self):
  278. # Create in memory raster.
  279. source = GDALRaster({
  280. 'datatype': 1,
  281. 'driver': 'MEM',
  282. 'width': 4,
  283. 'height': 4,
  284. 'srid': 3086,
  285. 'origin': (500000, 400000),
  286. 'scale': (100, -100),
  287. 'skew': (0, 0),
  288. 'bands': [{
  289. 'data': range(16),
  290. 'nodata_value': 23,
  291. }],
  292. })
  293. # Warp raster onto a location that does not cover any pixels of the original.
  294. result = source.warp({'origin': (200000, 200000)}).bands[0].data()
  295. if numpy:
  296. result = result.flatten().tolist()
  297. # The result is an empty raster filled with the correct nodata value.
  298. self.assertEqual(result, [23] * 16)
  299. def test_raster_transform(self):
  300. # Prepare tempfile and nodata value
  301. rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
  302. ndv = 99
  303. # Create in file based raster
  304. source = GDALRaster({
  305. 'datatype': 1,
  306. 'driver': 'tif',
  307. 'name': rstfile.name,
  308. 'width': 5,
  309. 'height': 5,
  310. 'nr_of_bands': 1,
  311. 'srid': 4326,
  312. 'origin': (-5, 5),
  313. 'scale': (2, -2),
  314. 'skew': (0, 0),
  315. 'bands': [{
  316. 'data': range(25),
  317. 'nodata_value': ndv,
  318. }],
  319. })
  320. # Transform raster into srid 4326.
  321. target = source.transform(3086)
  322. # Reload data from disk
  323. target = GDALRaster(target.name)
  324. self.assertEqual(target.srs.srid, 3086)
  325. self.assertEqual(target.width, 7)
  326. self.assertEqual(target.height, 7)
  327. self.assertEqual(target.bands[0].datatype(), source.bands[0].datatype())
  328. self.assertAlmostEqual(target.origin[0], 9124842.791079799)
  329. self.assertAlmostEqual(target.origin[1], 1589911.6476407414)
  330. self.assertAlmostEqual(target.scale[0], 223824.82664250192)
  331. self.assertAlmostEqual(target.scale[1], -223824.82664250192)
  332. self.assertEqual(target.skew, [0, 0])
  333. result = target.bands[0].data()
  334. if numpy:
  335. result = result.flatten().tolist()
  336. # The reprojection of a raster that spans over a large area
  337. # skews the data matrix and might introduce nodata values.
  338. self.assertEqual(
  339. result,
  340. [
  341. ndv, ndv, ndv, ndv, 4, ndv, ndv,
  342. ndv, ndv, 2, 3, 9, ndv, ndv,
  343. ndv, 1, 2, 8, 13, 19, ndv,
  344. 0, 6, 6, 12, 18, 18, 24,
  345. ndv, 10, 11, 16, 22, 23, ndv,
  346. ndv, ndv, 15, 21, 22, ndv, ndv,
  347. ndv, ndv, 20, ndv, ndv, ndv, ndv,
  348. ]
  349. )
  350. @unittest.skipUnless(HAS_GDAL, "GDAL is required")
  351. class GDALBandTests(SimpleTestCase):
  352. def setUp(self):
  353. self.rs_path = os.path.join(os.path.dirname(__file__), '../data/rasters/raster.tif')
  354. rs = GDALRaster(self.rs_path)
  355. self.band = rs.bands[0]
  356. def test_band_data(self):
  357. pam_file = self.rs_path + '.aux.xml'
  358. self.assertEqual(self.band.width, 163)
  359. self.assertEqual(self.band.height, 174)
  360. self.assertEqual(self.band.description, '')
  361. self.assertEqual(self.band.datatype(), 1)
  362. self.assertEqual(self.band.datatype(as_string=True), 'GDT_Byte')
  363. self.assertEqual(self.band.nodata_value, 15)
  364. if numpy:
  365. data = self.band.data()
  366. assert_array = numpy.loadtxt(
  367. os.path.join(os.path.dirname(__file__), '../data/rasters/raster.numpy.txt')
  368. )
  369. numpy.testing.assert_equal(data, assert_array)
  370. self.assertEqual(data.shape, (self.band.height, self.band.width))
  371. try:
  372. smin, smax, smean, sstd = self.band.statistics(approximate=True)
  373. self.assertEqual(smin, 0)
  374. self.assertEqual(smax, 9)
  375. self.assertAlmostEqual(smean, 2.842331288343558)
  376. self.assertAlmostEqual(sstd, 2.3965567248965356)
  377. smin, smax, smean, sstd = self.band.statistics(approximate=False, refresh=True)
  378. self.assertEqual(smin, 0)
  379. self.assertEqual(smax, 9)
  380. self.assertAlmostEqual(smean, 2.828326634228898)
  381. self.assertAlmostEqual(sstd, 2.4260526986669095)
  382. self.assertEqual(self.band.min, 0)
  383. self.assertEqual(self.band.max, 9)
  384. self.assertAlmostEqual(self.band.mean, 2.828326634228898)
  385. self.assertAlmostEqual(self.band.std, 2.4260526986669095)
  386. # Statistics are persisted into PAM file on band close
  387. self.band = None
  388. self.assertTrue(os.path.isfile(pam_file))
  389. finally:
  390. # Close band and remove file if created
  391. self.band = None
  392. if os.path.isfile(pam_file):
  393. os.remove(pam_file)
  394. def test_read_mode_error(self):
  395. # Open raster in read mode
  396. rs = GDALRaster(self.rs_path, write=False)
  397. band = rs.bands[0]
  398. # Setting attributes in write mode raises exception in the _flush method
  399. with self.assertRaises(GDALException):
  400. setattr(band, 'nodata_value', 10)
  401. def test_band_data_setters(self):
  402. # Create in-memory raster and get band
  403. rsmem = GDALRaster({
  404. 'datatype': 1,
  405. 'driver': 'MEM',
  406. 'name': 'mem_rst',
  407. 'width': 10,
  408. 'height': 10,
  409. 'nr_of_bands': 1,
  410. 'srid': 4326,
  411. })
  412. bandmem = rsmem.bands[0]
  413. # Set nodata value
  414. bandmem.nodata_value = 99
  415. self.assertEqual(bandmem.nodata_value, 99)
  416. # Set data for entire dataset
  417. bandmem.data(range(100))
  418. if numpy:
  419. numpy.testing.assert_equal(bandmem.data(), numpy.arange(100).reshape(10, 10))
  420. else:
  421. self.assertEqual(bandmem.data(), list(range(100)))
  422. # Prepare data for setting values in subsequent tests
  423. block = list(range(100, 104))
  424. packed_block = struct.pack('<' + 'B B B B', *block)
  425. # Set data from list
  426. bandmem.data(block, (1, 1), (2, 2))
  427. result = bandmem.data(offset=(1, 1), size=(2, 2))
  428. if numpy:
  429. numpy.testing.assert_equal(result, numpy.array(block).reshape(2, 2))
  430. else:
  431. self.assertEqual(result, block)
  432. # Set data from packed block
  433. bandmem.data(packed_block, (1, 1), (2, 2))
  434. result = bandmem.data(offset=(1, 1), size=(2, 2))
  435. if numpy:
  436. numpy.testing.assert_equal(result, numpy.array(block).reshape(2, 2))
  437. else:
  438. self.assertEqual(result, block)
  439. # Set data from bytes
  440. bandmem.data(bytes(packed_block), (1, 1), (2, 2))
  441. result = bandmem.data(offset=(1, 1), size=(2, 2))
  442. if numpy:
  443. numpy.testing.assert_equal(result, numpy.array(block).reshape(2, 2))
  444. else:
  445. self.assertEqual(result, block)
  446. # Set data from bytearray
  447. bandmem.data(bytearray(packed_block), (1, 1), (2, 2))
  448. result = bandmem.data(offset=(1, 1), size=(2, 2))
  449. if numpy:
  450. numpy.testing.assert_equal(result, numpy.array(block).reshape(2, 2))
  451. else:
  452. self.assertEqual(result, block)
  453. # Set data from memoryview
  454. bandmem.data(memoryview(packed_block), (1, 1), (2, 2))
  455. result = bandmem.data(offset=(1, 1), size=(2, 2))
  456. if numpy:
  457. numpy.testing.assert_equal(result, numpy.array(block).reshape(2, 2))
  458. else:
  459. self.assertEqual(result, block)
  460. # Set data from numpy array
  461. if numpy:
  462. bandmem.data(numpy.array(block, dtype='int8').reshape(2, 2), (1, 1), (2, 2))
  463. numpy.testing.assert_equal(
  464. bandmem.data(offset=(1, 1), size=(2, 2)),
  465. numpy.array(block).reshape(2, 2)
  466. )
  467. # Test json input data
  468. rsmemjson = GDALRaster(JSON_RASTER)
  469. bandmemjson = rsmemjson.bands[0]
  470. if numpy:
  471. numpy.testing.assert_equal(
  472. bandmemjson.data(),
  473. numpy.array(range(25)).reshape(5, 5)
  474. )
  475. else:
  476. self.assertEqual(bandmemjson.data(), list(range(25)))
  477. def test_band_statistics_automatic_refresh(self):
  478. rsmem = GDALRaster({
  479. 'srid': 4326,
  480. 'width': 2,
  481. 'height': 2,
  482. 'bands': [{'data': [0] * 4, 'nodata_value': 99}],
  483. })
  484. band = rsmem.bands[0]
  485. # Populate statistics cache
  486. self.assertEqual(band.statistics(), (0, 0, 0, 0))
  487. # Change data
  488. band.data([1, 1, 0, 0])
  489. # Statistics are properly updated
  490. self.assertEqual(band.statistics(), (0.0, 1.0, 0.5, 0.5))
  491. # Change nodata_value
  492. band.nodata_value = 0
  493. # Statistics are properly updated
  494. self.assertEqual(band.statistics(), (1.0, 1.0, 1.0, 0.0))
  495. def test_band_statistics_empty_band(self):
  496. rsmem = GDALRaster({
  497. 'srid': 4326,
  498. 'width': 1,
  499. 'height': 1,
  500. 'bands': [{'data': [0], 'nodata_value': 0}],
  501. })
  502. self.assertEqual(rsmem.bands[0].statistics(), (None, None, None, None))
  503. def test_band_delete_nodata(self):
  504. rsmem = GDALRaster({
  505. 'srid': 4326,
  506. 'width': 1,
  507. 'height': 1,
  508. 'bands': [{'data': [0], 'nodata_value': 1}],
  509. })
  510. if GDAL_VERSION < (2, 1):
  511. msg = 'GDAL >= 2.1 required to delete nodata values.'
  512. with self.assertRaisesMessage(ValueError, msg):
  513. rsmem.bands[0].nodata_value = None
  514. else:
  515. rsmem.bands[0].nodata_value = None
  516. self.assertIsNone(rsmem.bands[0].nodata_value)
  517. def test_band_data_replication(self):
  518. band = GDALRaster({
  519. 'srid': 4326,
  520. 'width': 3,
  521. 'height': 3,
  522. 'bands': [{'data': range(10, 19), 'nodata_value': 0}],
  523. }).bands[0]
  524. # Variations for input (data, shape, expected result).
  525. combos = (
  526. ([1], (1, 1), [1] * 9),
  527. (range(3), (1, 3), [0, 0, 0, 1, 1, 1, 2, 2, 2]),
  528. (range(3), (3, 1), [0, 1, 2, 0, 1, 2, 0, 1, 2]),
  529. )
  530. for combo in combos:
  531. band.data(combo[0], shape=combo[1])
  532. if numpy:
  533. numpy.testing.assert_equal(band.data(), numpy.array(combo[2]).reshape(3, 3))
  534. else:
  535. self.assertEqual(band.data(), list(combo[2]))