mirror of https://github.com/django/django.git
Fixed #31766 -- Made GDALRaster.transform() return a clone for the same SRID and driver.
Thanks Daniel Wiesmann for the review.
This commit is contained in:
parent
5362e08624
commit
12d6cae7c0
1
AUTHORS
1
AUTHORS
|
@ -110,6 +110,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
Baptiste Mispelon <bmispelon@gmail.com>
|
Baptiste Mispelon <bmispelon@gmail.com>
|
||||||
Barry Pederson <bp@barryp.org>
|
Barry Pederson <bp@barryp.org>
|
||||||
Bartolome Sanchez Salado <i42sasab@uco.es>
|
Bartolome Sanchez Salado <i42sasab@uco.es>
|
||||||
|
Barton Ip <notbartonip@gmail.com>
|
||||||
Bartosz Grabski <bartosz.grabski@gmail.com>
|
Bartosz Grabski <bartosz.grabski@gmail.com>
|
||||||
Bashar Al-Abdulhadi
|
Bashar Al-Abdulhadi
|
||||||
Bastian Kleineidam <calvin@debian.org>
|
Bastian Kleineidam <calvin@debian.org>
|
||||||
|
|
|
@ -425,6 +425,27 @@ class GDALRaster(GDALRasterBase):
|
||||||
|
|
||||||
return target
|
return target
|
||||||
|
|
||||||
|
def clone(self, name=None):
|
||||||
|
"""Return a clone of this GDALRaster."""
|
||||||
|
if name:
|
||||||
|
clone_name = name
|
||||||
|
elif self.driver.name != 'MEM':
|
||||||
|
clone_name = self.name + '_copy.' + self.driver.name
|
||||||
|
else:
|
||||||
|
clone_name = os.path.join(VSI_FILESYSTEM_BASE_PATH, str(uuid.uuid4()))
|
||||||
|
return GDALRaster(
|
||||||
|
capi.copy_ds(
|
||||||
|
self.driver._ptr,
|
||||||
|
force_bytes(clone_name),
|
||||||
|
self._ptr,
|
||||||
|
c_int(),
|
||||||
|
c_char_p(),
|
||||||
|
c_void_p(),
|
||||||
|
c_void_p(),
|
||||||
|
),
|
||||||
|
write=self._write,
|
||||||
|
)
|
||||||
|
|
||||||
def transform(self, srs, driver=None, name=None, resampling='NearestNeighbour',
|
def transform(self, srs, driver=None, name=None, resampling='NearestNeighbour',
|
||||||
max_error=0.0):
|
max_error=0.0):
|
||||||
"""
|
"""
|
||||||
|
@ -443,6 +464,9 @@ class GDALRaster(GDALRasterBase):
|
||||||
'Transform only accepts SpatialReference, string, and integer '
|
'Transform only accepts SpatialReference, string, and integer '
|
||||||
'objects.'
|
'objects.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if target_srs.srid == self.srid and (not driver or driver == self.driver.name):
|
||||||
|
return self.clone(name)
|
||||||
# Create warped virtual dataset in the target reference system
|
# Create warped virtual dataset in the target reference system
|
||||||
target = capi.auto_create_warped_vrt(
|
target = capi.auto_create_warped_vrt(
|
||||||
self._ptr, self.srs.wkt.encode(), target_srs.wkt.encode(),
|
self._ptr, self.srs.wkt.encode(), target_srs.wkt.encode(),
|
||||||
|
|
|
@ -2,6 +2,7 @@ import os
|
||||||
import shutil
|
import shutil
|
||||||
import struct
|
import struct
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
from django.contrib.gis.gdal import GDAL_VERSION, GDALRaster, SpatialReference
|
from django.contrib.gis.gdal import GDAL_VERSION, GDALRaster, SpatialReference
|
||||||
from django.contrib.gis.gdal.error import GDALException
|
from django.contrib.gis.gdal.error import GDALException
|
||||||
|
@ -470,6 +471,40 @@ class GDALRasterTests(SimpleTestCase):
|
||||||
# The result is an empty raster filled with the correct nodata value.
|
# The result is an empty raster filled with the correct nodata value.
|
||||||
self.assertEqual(result, [23] * 16)
|
self.assertEqual(result, [23] * 16)
|
||||||
|
|
||||||
|
def test_raster_clone(self):
|
||||||
|
rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
|
||||||
|
tests = [
|
||||||
|
('MEM', '', 23), # In memory raster.
|
||||||
|
('tif', rstfile.name, 99), # In file based raster.
|
||||||
|
]
|
||||||
|
for driver, name, nodata_value in tests:
|
||||||
|
with self.subTest(driver=driver):
|
||||||
|
source = GDALRaster({
|
||||||
|
'datatype': 1,
|
||||||
|
'driver': driver,
|
||||||
|
'name': name,
|
||||||
|
'width': 4,
|
||||||
|
'height': 4,
|
||||||
|
'srid': 3086,
|
||||||
|
'origin': (500000, 400000),
|
||||||
|
'scale': (100, -100),
|
||||||
|
'skew': (0, 0),
|
||||||
|
'bands': [{
|
||||||
|
'data': range(16),
|
||||||
|
'nodata_value': nodata_value,
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
clone = source.clone()
|
||||||
|
self.assertNotEqual(clone.name, source.name)
|
||||||
|
self.assertEqual(clone._write, source._write)
|
||||||
|
self.assertEqual(clone.srs.srid, source.srs.srid)
|
||||||
|
self.assertEqual(clone.width, source.width)
|
||||||
|
self.assertEqual(clone.height, source.height)
|
||||||
|
self.assertEqual(clone.origin, source.origin)
|
||||||
|
self.assertEqual(clone.scale, source.scale)
|
||||||
|
self.assertEqual(clone.skew, source.skew)
|
||||||
|
self.assertIsNot(clone, source)
|
||||||
|
|
||||||
def test_raster_transform(self):
|
def test_raster_transform(self):
|
||||||
tests = [
|
tests = [
|
||||||
3086,
|
3086,
|
||||||
|
@ -531,6 +566,54 @@ class GDALRasterTests(SimpleTestCase):
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_raster_transform_clone(self):
|
||||||
|
with mock.patch.object(GDALRaster, 'clone') as mocked_clone:
|
||||||
|
# Create in file based raster.
|
||||||
|
rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
|
||||||
|
source = GDALRaster({
|
||||||
|
'datatype': 1,
|
||||||
|
'driver': 'tif',
|
||||||
|
'name': rstfile.name,
|
||||||
|
'width': 5,
|
||||||
|
'height': 5,
|
||||||
|
'nr_of_bands': 1,
|
||||||
|
'srid': 4326,
|
||||||
|
'origin': (-5, 5),
|
||||||
|
'scale': (2, -2),
|
||||||
|
'skew': (0, 0),
|
||||||
|
'bands': [{
|
||||||
|
'data': range(25),
|
||||||
|
'nodata_value': 99,
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
# transform() returns a clone because it is the same SRID and
|
||||||
|
# driver.
|
||||||
|
source.transform(4326)
|
||||||
|
self.assertEqual(mocked_clone.call_count, 1)
|
||||||
|
|
||||||
|
def test_raster_transform_clone_name(self):
|
||||||
|
# Create in file based raster.
|
||||||
|
rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
|
||||||
|
source = GDALRaster({
|
||||||
|
'datatype': 1,
|
||||||
|
'driver': 'tif',
|
||||||
|
'name': rstfile.name,
|
||||||
|
'width': 5,
|
||||||
|
'height': 5,
|
||||||
|
'nr_of_bands': 1,
|
||||||
|
'srid': 4326,
|
||||||
|
'origin': (-5, 5),
|
||||||
|
'scale': (2, -2),
|
||||||
|
'skew': (0, 0),
|
||||||
|
'bands': [{
|
||||||
|
'data': range(25),
|
||||||
|
'nodata_value': 99,
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
clone_name = rstfile.name + '_respect_name.GTiff'
|
||||||
|
target = source.transform(4326, name=clone_name)
|
||||||
|
self.assertEqual(target.name, clone_name)
|
||||||
|
|
||||||
|
|
||||||
class GDALBandTests(SimpleTestCase):
|
class GDALBandTests(SimpleTestCase):
|
||||||
rs_path = os.path.join(os.path.dirname(__file__), '../data/rasters/raster.tif')
|
rs_path = os.path.join(os.path.dirname(__file__), '../data/rasters/raster.tif')
|
||||||
|
|
Loading…
Reference in New Issue