diff --git a/.travis.yml b/.travis.yml index 8f0b3a2..9871dee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: python python: - - "2.7" - "3.5" - "3.6" before_install: diff --git a/hrds/__init__.py b/hrds/__init__.py index bde9b4f..2551db0 100644 --- a/hrds/__init__.py +++ b/hrds/__init__.py @@ -24,7 +24,7 @@ """ -__version__ = "0.1.0" +__version__ = "0.1.1" from .raster import RasterInterpolator # NOQA from .raster_buffer import CreateBuffer # NOQA diff --git a/hrds/hrds.py b/hrds/hrds.py index 2255fa0..e5add87 100644 --- a/hrds/hrds.py +++ b/hrds/hrds.py @@ -2,6 +2,8 @@ from .raster import RasterInterpolator from .raster_buffer import CreateBuffer import os +from shutil import copyfile +import tempfile try: from itertools import izip as zip except ImportError: # will be 3.x series @@ -33,7 +35,8 @@ class HRDSError(Exception): class HRDS(object): - """The main HRDS class. Create a raster stack and initialise: + """ + The main HRDS class. Create a raster stack and initialise: bathy = HRDS("gebco_uk.tif", rasters=("emod_utm.tif", @@ -59,7 +62,8 @@ class HRDS(object): which would set a maximum depth of -5m on the gebco data (-ve = below sea level, +ve above), maximum of -3m on the emod data and no limits on the marine_digimap data. You must supply the same number of min-max - pairs are there are total rasters. + pairs are there are total rasters. Temporary buffer files will be created + and deleted at clean up If is possible to supply the buffer rasters directly (e.g. if you want to use different distances on each edge of your raster, or some other @@ -77,11 +81,11 @@ class HRDS(object): Once set up, you can ask for data at any point: bathy.get_val(100,100) - - """ + """ def __init__(self, baseRaster, rasters=None, distances=None, - buffers=None, minmax=None): - """ baseRaster is the low res raster filename across whole domain. + buffers=None, minmax=None, saveBuffers=False): + """ + baseRaster is the low res raster filename across whole domain. rasters is a list of filenames of the other rasters in priority order. distances is the distance to create a buffer (in same units as corresponding raster) for each. @@ -118,15 +122,27 @@ def __init__(self, baseRaster, rasters=None, distances=None, else: self.raster_stack.append(RasterInterpolator(r, minmax[i+1])) self.buffer_stack = [] + # the user is asking us to create the buffer files if buffers is None: - for r, d in zip(rasters, distances): - # create buffer file name, based on raster filename - buf_file = os.path.splitext(r)[0]+"_buffer.tif" - # create buffer - rbuff = CreateBuffer(r, d) - rbuff.make_buffer(buf_file) - # add to stack - self.buffer_stack.append(RasterInterpolator(buf_file)) + # we create the files in a temp dir and if the user wants + # them afterwards we copy to a sensible name + with tempfile.TemporaryDirectory() as tmpdirname: + for r, d in zip(rasters, distances): + # create buffer file name, based on raster filename + keep_buf_file = os.path.splitext(r)[0]+"_buffer.tif" + temp_buf_file = os.path.join(tmpdirname, + os.path.splitext( + os.path.basename(r))[0] + + "_buffer.tif") + # create buffer + rbuff = CreateBuffer(r, d) + rbuff.make_buffer(temp_buf_file) + # add to stack and store in memory + self.buffer_stack.append(RasterInterpolator(temp_buf_file)) + # does the user also want the file saving? + if saveBuffers: + copyfile(temp_buf_file, keep_buf_file) + else: # create buffer stack from filenames for r in buffers: @@ -156,7 +172,8 @@ def set_bands(self, bands=None): counter += 1 def get_val(self, point): - """Performs bilinear interpolation of your raster stack + """ + Performs bilinear interpolation of your raster stack to give a value at the requested point. """ # determine if we're in any of the rasters in the list, diff --git a/hrds/raster.py b/hrds/raster.py index 0e950f3..72c3a6d 100644 --- a/hrds/raster.py +++ b/hrds/raster.py @@ -219,6 +219,6 @@ def point_in(self, point): urc = np.amax(self.extent, axis=0)-(self.dx[1]/2) if ((point[0] <= urc[0] and point[0] >= llc[0]) and (point[1] <= urc[1] and point[1] >= llc[1])): - return True + return True else: - return False + return False diff --git a/hrds/raster_buffer.py b/hrds/raster_buffer.py index 8a62fdf..cea1db6 100644 --- a/hrds/raster_buffer.py +++ b/hrds/raster_buffer.py @@ -24,7 +24,8 @@ class CreateBuffer(object): - """Implements the creation of a distance buffer from the edge of + """ + Implements the creation of a distance buffer from the edge of a raster to the centre: rbuff = CreateBuffer('myRaster.tif',10000.0) diff --git a/requirements.txt b/requirements.txt index 0c1b0e4..a41d56f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ numpy>=1.11.0 scipy>=0.17 pygdal>=1.1 +pytest diff --git a/setup.py b/setup.py index c8904bd..99f3823 100644 --- a/setup.py +++ b/setup.py @@ -35,6 +35,6 @@ def get_version(): 'Development Status :: 4 - Beta', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)', - 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.6', 'Topic :: Scientific/Engineering'], ) diff --git a/tests/test_hrds.py b/tests/test_hrds.py index cef02e2..605263e 100644 --- a/tests/test_hrds.py +++ b/tests/test_hrds.py @@ -47,7 +47,8 @@ def test_simple_rasters(self): We ask for points around all layers and in the buffer and check against those expected. """ - bathy = HRDS(base_raster, rasters=(layer1, layer2), distances=(7, 5)) + + bathy = HRDS(base_raster, rasters=(layer1, layer2), distances=(7, 5), saveBuffers=True) bathy.set_bands() points = ([5, 5], # 1 [40, 50], # 3 @@ -58,10 +59,10 @@ def test_simple_rasters(self): expected = [1.0, 3.0, 2.0, 1.5, 2.5] for p, e in zip(points, expected): self.assertAlmostEqual(bathy.get_val(p), e, delta=0.1) + # check that the buffer files exists + self.assertTrue(os.path.exists(os.path.join(test_dir, "layer1_buffer.tif"))) + self.assertTrue(os.path.exists(os.path.join(test_dir, "layer2_buffer.tif"))) - -@unittest.skipUnless(os.path.isfile("real_data/gebco_uk.tif"), - "Skipping as proprietary data missing.") class RealDataTest(unittest.TestCase): def test_real_world(self): @@ -69,9 +70,9 @@ def test_real_world(self): Norfolk coast. Projected to UTM 30, so everything in m. """ - bathy = HRDS("real_data/gebco_uk.tif", - rasters=("real_data/emod_utm.tif", - "real_data/inspire_data.tif"), + bathy = HRDS(os.path.join(test_dir,"real_data/gebco_uk.tif"), + rasters=(os.path.join(test_dir,"real_data/emod_utm.tif"), + os.path.join(test_dir,"real_data/inspire_data.tif")), distances=(700, 200)) bathy.set_bands() """ @@ -98,7 +99,7 @@ def test_real_world(self): [822634., 5848528.], [822447., 5848684.], ) - expected = [-25.0, # -21.318 - limited! + expected = [-21.318, # -25.289, -28.6, # in the buffer, so mostly gebco -5.884, @@ -112,20 +113,16 @@ def test_real_world(self): self.assertAlmostEqual(bathy.get_val(p), e, delta=0.75) -# ############### -# FIXME: same name for test!!!!! -@unittest.skipUnless(os.path.isfile("real_data/gebco_uk.tif"), - "Skipping as proprietary data missing.") -class RealDataTest(unittest.TestCase): +class RealDataTest_limited(unittest.TestCase): def test_real_world_limit(self): """ Mix of GEBCO, EMODnet and UK Gov data just off the Norfolk coast. Projected to UTM 30, so everything in m. """ - bathy = HRDS("real_data/gebco_uk.tif", - rasters=("real_data/emod_utm.tif", - "real_data/inspire_data.tif"), + bathy = HRDS(os.path.join(test_dir,"real_data/gebco_uk.tif"), + rasters=(os.path.join(test_dir,"real_data/emod_utm.tif"), + os.path.join(test_dir,"real_data/inspire_data.tif")), distances=(700, 200), minmax=[[None,-25],[None,-10],[None,None]]) bathy.set_bands()