Commit c485e672 authored by Hoek, Steven's avatar Hoek, Steven
Browse files

Initialisation and tiling

In the classes from the formats folder better initialisation was implemented. The Tile manager in module tilelib was improved too.
parent b1434a19
......@@ -37,7 +37,8 @@ class AsciiGrid(Raster, GridEnvelope2D):
self.name = "dummy." + self._const.FILEXT;
# Initialise further
super(AsciiGrid, self).__init__(filepath)
Raster.__init__(self, filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
# Retrieve the name from the filepath and assign - incl. extension
self.name = os.path.basename(filepath);
......
......@@ -28,6 +28,8 @@ class BandRaster(Raster, GridEnvelope2D):
# Initialise
Raster.__init__(self, filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
# Retrieve the name from the filepath and assign - incl. extension
self.name = os.path.basename(filepath);
# Also derive the folder
......
......@@ -31,7 +31,7 @@ class BaseTiffRaster(Raster):
print('File path cannot be an empty string (method __init__).')
# Initialise
super(BaseTiffRaster, self).__init__(filepath)
Raster.__init__(self, filepath)
# Module wide constants
self._const = Const()
......
......@@ -64,7 +64,10 @@ class BitmapRaster(Raster, GridEnvelope2D):
# Module wide constants
self._const = Const()
self._const.FILEXT = "bmp"
super(BitmapRaster, self).__init__(filepath)
# Initialise further
Raster.__init__(self, filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
# Retrieve the name from the filepath and assign - incl. extension; idem folder
self.name = os.path.basename(filepath);
......
......@@ -197,7 +197,10 @@ class CsfRaster(Raster, GridEnvelope2D):
# Module wide constants
self._const = Const()
self._const.FILEXT = "map"
super(CsfRaster, self).__init__(filepath)
# Initialise further
Raster.__init__(self, filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
# Retrieve the name from the filepath and assign - incl. extension; idem folder
self.name = os.path.basename(filepath);
......
......@@ -32,6 +32,7 @@ class FloatingPointRaster(Raster, GridEnvelope2D):
# Initialise
Raster.__init__(self, filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
self._const = Const()
# Class and subclass wide constants
......
......@@ -41,6 +41,10 @@ class GeotiffRaster(Raster, GridEnvelope2D):
__memmap = None;
def __init__(self, filepath, *datatype):
# Initialise
Raster.__init__(self, filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
# Retrieve the name from the filepath and assign - incl. extension
self.name = os.path.basename(filepath);
# Also derive the folder
......
......@@ -39,8 +39,10 @@ class Hdf5Raster(Raster, GridEnvelope2D):
currow = 0;
def __init__(self, filepath):
# Initialise super class instance
# Initialise
Raster.__init__(self, filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
# Retrieve the name from the filepath and assign - incl. extension
self.name = os.path.basename(filepath);
# Also derive the folder
......
......@@ -18,7 +18,10 @@ class InMemoryRaster(Raster, GridEnvelope2D):
dataformat = 'f'
def __init__(self, filepath, data=None, *datatype):
# Initialise
Raster.__init__(self, filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
if not data is None:
self.data = data
if len(datatype) > 0:
......
......@@ -11,7 +11,7 @@ except ImportError:
__author__ = "Steven B. Hoek"
class Netcdf4Raster(Netcdf4Envelope2D):
class Netcdf4Raster(Netcdf4Envelope2D):
# Constants
DATAFILEXT = 'nc4';
_original_name = "Band1" # TODO: set it when a template file is opened for appending
......@@ -28,6 +28,9 @@ class Netcdf4Raster(Netcdf4Envelope2D):
__Y = ""
def __init__(self, filepath):
# Initialise
Netcdf4Envelope2D.__init__(None)
# Retrieve the name from the filepath and assign - incl. extension
self.name = os.path.basename(filepath);
# Also derive the folder
......
......@@ -24,6 +24,8 @@ class NumpyRaster(Raster, GridEnvelope2D):
def __init__(self, filepath, *datatype):
# Initialise
Raster.__init__(self, filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
# Retrieve the name from the filepath and assign - incl. extension
self.name = os.path.basename(filepath)
# Also derive the folder
......
......@@ -46,7 +46,8 @@ class RowTiffRaster(BaseTiffRaster, GridEnvelope2D):
print('File path cannot be an empty string (method __init__).')
# Initialise
super(RowTiffRaster, self).__init__(filepath)
BaseTiffRaster.__init__(self, filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
if self._const == None:
raise AttributeError("TIFF raster not properly initialised!")
......
......@@ -42,7 +42,9 @@ class StripTiffRaster(BaseTiffRaster, GridEnvelope2D):
def __init__(self, filepath, *datatype):
# Initialise
super(StripTiffRaster, self).__init__(filepath)
BaseTiffRaster.__init__(filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
# Retrieve the name from the filepath and assign - incl. extension
self.name = os.path.basename(filepath);
# Also derive the folder
......
......@@ -41,7 +41,9 @@ class TileTiffRaster(BaseTiffRaster, GridEnvelope2D):
def __init__(self, filepath, *datatype):
# Initialise
super(TileTiffRaster, self).__init__(filepath)
BaseTiffRaster.__init__(filepath)
GridEnvelope2D.__init__(self, 1, 1, 0.0, 0.0, 0.1, 0.1)
if self._const == None:
raise AttributeError("TIFF raster not properly initialised!")
......
from lmgeo.formats.rioraster import RioRaster
from .test_baseraster import TestBaseRaster
import unittest
__author__ = "Steven B. Hoek"
class TestRioRaster(TestBaseRaster):
# Load data from a pickle file and metadata from a header file
# Write the data to an AsciiGrid. Close and open teh file again for reading and check
test_class = RioRaster
int_extension = 'tif'
def suite():
""" This defines all the tests of a module"""
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestRioRaster))
return suite
from lmgeo.formats.rowtiffraster import RowTiffRaster
from .test_baseraster import TestBaseRaster
import unittest
__author__ = "Steven B. Hoek"
class TestRowTifRaster(TestBaseRaster):
# Load data from a pickle file and metadata from a header file
# Write the data to an AsciiGrid. Close and open teh file again for reading and check
test_class = RowTiffRaster
int_extension = 'tif'
flt_extension = 'tif'
def suite():
""" This defines all the tests of a module"""
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestRowTifRaster))
return suite
\ No newline at end of file
......@@ -6,9 +6,19 @@ from ..formats.raster import Raster
from ..formats.inmemoryraster import InMemoryRaster
from ..toolbox.striplib import StripManager
from ..formats.const import constants as const
from math import ceil
import numpy as np
__author__ = "Steven B. Hoek"
class Tile(InMemoryRaster):
rowidx = 0
colidx = 0
def __init__(self, filepath, data=None, *datatype):
# Initialise
InMemoryRaster.__init__(self, filepath, data, datatype)
class TileManager():
'''
Class that retrieves enough rows of data from a given raster grid to obtain a strip
......@@ -19,14 +29,23 @@ class TileManager():
__depth = 1
__width = 1
__curcol = 0
__rowidx = -1 # actually strip index
__colidx = -1
__curstrip = None
__stripmanager = None
__rowoffset = 0 # row offset
__coloffset = 0 # column offset
__rowoverlap = 0
__coloverlap = 0
__add_edges = True
def __init__(self, rg, tilewidth, tileheight, coloverlap=0, rowoverlap=0):
def __init__(self, rg, tilewidth, tileheight, coloverlap=0, rowoverlap=0, addedges=False):
'''
Initialisation of the tile manager with tile width and tile height. In addition, it can be
indicated whether there should be column and row overlap should be and if so how many pixels.
In addition, it can be indicated whether edges with nodata should be added - or not - to the
tiles in order to make sures all delivered tiles are of the same width and height.
'''
# Check the inputs
if not isinstance(rg, Raster):
raise TypeError("Input is not a raster!")
......@@ -40,13 +59,13 @@ class TileManager():
self.__ncols = rg.ncols
self.__nrows = rg.nrows
self.__datatype = rg.datatype
self.__curcol = 0
self.__stripmanager = StripManager(rg, tileheight)
self.__stripmanager.stripheight = tileheight
self.__depth = tileheight
self.__width = tilewidth
self.__rowoverlap = rowoverlap
self.__coloverlap = coloverlap
self.__addedges = addedges
# Get the first strip ready
self.nextstrip()
......@@ -58,20 +77,48 @@ class TileManager():
'''Returns a tile with number of rows and columns'''
# TODO: implement the option to have row and column offsets
result = None
if self.__curcol + self.__width > self.__ncols:
width = self.__ncols - self.__curcol
else:
maxrowno = self.__nrows // self.__depth # zero-based
colsleft = self.__ncols - self.__curcol
if colsleft > self.__width:
# More tiles to be written
width = self.__width
if (width > 0) and (not self.__curstrip is None):
else:
# Last tile of this strip
width = colsleft
if (colsleft > 0) and (not self.__curstrip is None):
# In case buffer contains rows, prepare to add them at the beginning of the output raster
width += self.__coloverlap
xll = self.__xll + (self.__curcol * self.__rg.dx)
data = self.__curstrip.data[:, self.__curcol:self.__curcol+width]
imr = InMemoryRaster("dummy_file.ext", data, self.__datatype)
width = min(width, len(data[0]))
if self.__curcol + width + self.__coloverlap <= self.__ncols:
width += self.__coloverlap
data = self.__curstrip.data[:, self.__curcol:self.__curcol + width]
# Check whether extra columns have to be added
if (data.shape[1] < self.__width + self.__coloverlap) and self.__addedges:
extradata = np.empty((data.shape[0], self.__width + self.__coloverlap - data.shape[1]), dtype=data.dtype)
extradata.fill(self.__rg.nodatavalue)
data = np.append(data, extradata, 1)
# Establish width, height and the coordinates of the lower left point
width = data.shape[1]
height = self.__curstrip.nrows
imr.open('w', width, height, xll, self.__yll, self.__rg.dy, self.__rg.nodatavalue)
xll = self.__xll + (self.__curcol * self.__rg.dx)
yll = self.__curstrip.yll
# Check whether extra rows have to be added
if (self.__rowidx == maxrowno) and (height < self.__depth) and self.__addedges:
extradata = np.empty((self.__depth - height + self.__rowoverlap, data.shape[1]), dtype=data.dtype)
extradata.fill(self.__rg.nodatavalue)
data = np.append(data, extradata, 0)
yll = yll - (self.__depth - height + self.__rowoverlap) * self.__rg.dy
height = self.__depth + self.__rowoverlap
# Now that we have retrieved enough particulars, prepare the result
imr = Tile("dummy_file.ext", data, self.__datatype)
imr.open('w', width, height, xll, yll, self.__rg.dy, self.__rg.nodatavalue)
self.__curcol += self.__width
self.__colidx += 1
imr.rowidx = self.__rowidx
imr.colidx = self.__colidx
result = imr
return result
......@@ -85,6 +132,8 @@ class TileManager():
rowbuf = self.__curstrip.data[-1 * self.__rowoverlap:, :]
self.__curstrip = self.__stripmanager.next(rowbuf, self.__rowoverlap)
self.__curcol = 0
self.__colidx = -1
self.__rowidx += 1
result = True
except:
raise StopIteration
......@@ -154,7 +203,7 @@ class TileIterator:
curcol = self.__tilemanager.curcol
width = self.__tilemanager.tilewidth
ncols = self.__tilemanager.ncols
tilesleft = (ncols - curcol) // width
tilesleft = ceil((ncols - curcol) / width)
if tilesleft > 0:
result = self.__tilemanager.next()
else:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment