Skip to content

Commit

Permalink
fix #2804 - make checking the analysis environment more efficient by …
Browse files Browse the repository at this point in the history
…not reading the full raster each time you pan or zoom (#3102)

* fix #2804 - make checking the analysis environment more efficient by not reading the full raster each time you pan or zoom

* Fix failing test for #2804
  • Loading branch information
timlinux committed Aug 3, 2016
1 parent afbcc34 commit 965bcfc
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 34 deletions.
2 changes: 1 addition & 1 deletion safe/storage/layer.py
Expand Up @@ -47,7 +47,7 @@ def __init__(self, name=None, projection=None,
# Defaults
self.sublayer = sublayer
self.filename = None
self.data = None
self._data = None # class private

def __ne__(self, other):
"""Override '!=' to allow comparison with other projection objecs
Expand Down
84 changes: 55 additions & 29 deletions safe/storage/raster.py
Expand Up @@ -94,6 +94,7 @@ class docstring.
projection=projection,
keywords=keywords,
style_info=style_info)
self.band = None

# Input checks
if data is None:
Expand All @@ -111,7 +112,7 @@ class docstring.
# Assume that data is provided as a numpy array
# with extra keyword arguments supplying metadata

self.data = numpy.array(data, dtype='d', copy=False)
self._data = numpy.array(data, dtype='d', copy=False)

proj4 = self.get_projection(proj4=True)
if 'longlat' in proj4 and 'WGS84' in proj4:
Expand All @@ -122,7 +123,6 @@ class docstring.

self.rows = data.shape[0]
self.columns = data.shape[1]

self.number_of_bands = 1

def __str__(self):
Expand Down Expand Up @@ -173,6 +173,53 @@ def __eq__(self, other, rtol=1.0e-5, atol=1.0e-8):
# Raster layers are identical up to the specified tolerance
return True

@property
def data(self):
"""Property for the data of this layer.
The setter does a lazy read so that the data matrix is only
initialised if is is actually wanted.
:returns: A matrix containing the layer data or None if the layer
has no band.
:rtype: numpy.array
"""
if self._data is None:
if self.band is None:
return None
# Read from raster file
data = self.band.ReadAsArray()

# Convert to double precision (issue #75)
data = numpy.array(data, dtype=numpy.float64)

# Self check
M, N = data.shape
msg = (
'Dimensions of raster array do not match those of '
'raster file %s' % self.filename)
verify(M == self.rows, msg)
verify(N == self.columns, msg)
nodata = self.band.GetNoDataValue()
if nodata is None:
nodata = -9999

if nodata is not numpy.nan:
NaN = numpy.ones((M, N), numpy.float64) * numpy.nan
data = numpy.where(data == nodata, NaN, data)

self._data = data

return self._data

@data.setter
def data(self, data):
"""Setter for the data of this layer.
:param data: A matrix containing the layer data.
"""
self._data = data

def read_from_file(self, filename):
"""Read and unpack raster data
"""
Expand All @@ -186,9 +233,10 @@ def read_from_file(self, filename):
if not os.path.exists(filename):
msg = 'Could not find file %s' % filename
else:
msg = ('File %s exists, but could not be read. '
'Please check if the file can be opened with '
'e.g. qgis or gdalinfo' % filename)
msg = (
'File %s exists, but could not be read. '
'Please check if the file can be opened with '
'e.g. qgis or gdalinfo' % filename)
raise ReadLayerError(msg)

# Record raster metadata from file
Expand Down Expand Up @@ -248,29 +296,6 @@ def read_from_file(self, filename):
# Force garbage collection to free up any memory we can (TS)
gc.collect()

# Read from raster file
data = band.ReadAsArray()

# Convert to double precision (issue #75)
data = numpy.array(data, dtype=numpy.float64)

# Self check
M, N = data.shape
msg = (
'Dimensions of raster array do not match those of '
'raster file %s' % self.filename)
verify(M == self.rows, msg)
verify(N == self.columns, msg)
nodata = self.band.GetNoDataValue()
if nodata is None:
nodata = -9999

if nodata is not numpy.nan:
NaN = numpy.ones((M, N), numpy.float64) * numpy.nan
data = numpy.where(data == nodata, NaN, data)

self.data = data

def write_to_file(self, filename):
"""Save raster data to file
Expand Down Expand Up @@ -307,13 +332,14 @@ def write_to_file(self, filename):

self.filename = filename

# Write metada
# Write metadata
fid.SetProjection(str(self.projection))
fid.SetGeoTransform(self.geotransform)

# Write data
fid.GetRasterBand(1).WriteArray(A)
fid.GetRasterBand(1).SetNoDataValue(self.get_nodata_value())
# noinspection PyUnusedLocal
fid = None # Close

# Write keywords if any
Expand Down
7 changes: 3 additions & 4 deletions safe/storage/test/test_io.py
Expand Up @@ -1748,10 +1748,9 @@ def test_layer_API(self):

assert same_API(V, R, exclude=exclude)

for filename in [os.path.join(TESTDATA,
'test_buildings.shp'),
os.path.join(HAZDATA,
'Lembang_Earthquake_Scenario.asc')]:
for filename in [
os.path.join(TESTDATA, 'test_buildings.shp'),
os.path.join(HAZDATA, 'Lembang_Earthquake_Scenario.asc')]:

L = read_layer(filename)

Expand Down

0 comments on commit 965bcfc

Please sign in to comment.