diff --git a/src/equi7grid/equi7grid.py b/src/equi7grid/equi7grid.py index b05fce7..8de783f 100644 --- a/src/equi7grid/equi7grid.py +++ b/src/equi7grid/equi7grid.py @@ -99,11 +99,11 @@ class Equi7Grid(TiledProjectionSystem): _static_tilecodes = ["T6", "T3", "T1"] # supported grid spacing ( = the pixel sampling) _static_sampling = [ - 1000, 800, 750, 600, 500, 400, 300, 250, 200, 150, 125, 100, 96, 80, + 6000, 3000, 1000, 800, 750, 600, 500, 400, 300, 250, 200, 150, 125, 100, 96, 80, 75, 64, 60, 50, 48, 40, 32, 30, 25, 24, 20, 16, 10, 8, 5, 4, 2, 1 ] - def __init__(self, sampling): + def __init__(self, sampling, tile_names_in_m=False): """ Initialises an Equi7Grid class for a specified sampling. @@ -111,8 +111,13 @@ def __init__(self, sampling): ---------- sampling : int the grid sampling = size of pixels; in metres. + tile_names_in_m : bool, optional + controls whether the tile names are in metres or in km when > 1000m """ + + self._tile_names_in_m = tile_names_in_m + # check if the equi7grid.data have been loaded successfully if Equi7Grid._static_data is None: raise ValueError("cannot load Equi7Grid ancillary data!") @@ -123,9 +128,10 @@ def __init__(self, sampling): # initializing super(Equi7Grid, self).__init__(sampling, tag='Equi7') self.core.projection = 'multiple' + self.core.tile_names_in_m = tile_names_in_m @staticmethod - def encode_sampling(sampling): + def encode_sampling(sampling, tile_names_in_m=False): """ provides a string representing the sampling (e.g. for the tilenames) @@ -138,15 +144,20 @@ def encode_sampling(sampling): ------- sampling_str : str string representing the sampling + tile_names_in_m : bool, optional + controls whether the tile names are in metres or in km when > 1000m """ - if sampling <= 999: + if tile_names_in_m: sampling_str = str(sampling).rjust(3, '0') - if sampling >= 1000: - sampling_str = "".join((str(sampling / 1000.0)[0], 'K', str(sampling / 1000.0)[2])) + else: + if sampling <= 999: + sampling_str = str(sampling).rjust(3, '0') + if sampling >= 1000: + sampling_str = "".join((str(sampling / 1000.0)[0], 'K', str(sampling / 1000.0)[2])) return sampling_str @staticmethod - def decode_sampling(sampling_str): + def decode_sampling(sampling_str, tile_names_in_m=False): """ converts the string representing the sampling (e.g. from the tilenames) to an integer value in metres @@ -155,18 +166,23 @@ def decode_sampling(sampling_str): ---------- sampling_str : str string representing the sampling + tile_names_in_m : bool, optional + controls whether the tile names are in metres or in km when > 1000m Returns ------- sampling : int the grid sampling = size of pixels; in metres. """ - if len(sampling_str) != 3: - raise ValueError('Resolution is badly defined!') - if sampling_str[1] == 'K': - sampling = int(sampling_str[0]) * 1000 + int(sampling_str[2]) * 100 - else: + if tile_names_in_m: sampling = int(sampling_str) + else: + if len(sampling_str) != 3: + raise ValueError('Resolution is badly defined!') + if sampling_str[1] == 'K': + sampling = int(sampling_str[0]) * 1000 + int(sampling_str[2]) * 100 + else: + sampling = int(sampling_str) return sampling def define_subgrids(self): @@ -178,6 +194,11 @@ def define_subgrids(self): subgrids : dict of Equi7Subgrid dict of all subgrids of the grid """ + # Set the tile names in metres or in km + # Reinforce copying into self.core, as it's initialized in TiledProjectionSystem not in Equi7Grid so can't + # take this custom property at init time. This is a bit of a hack but its needed in Equi7Subgrid() + self.core.tile_names_in_m = self._tile_names_in_m + subgrids = dict() for sg in self._static_subgrid_ids: subgrids[sg] = Equi7Subgrid(self.core, sg) @@ -204,9 +225,9 @@ def get_tiletype(self, sampling=None): sampling = int(sampling) - # allowing sampling of [1000, 800, 750, 600, 500, 400, 300, 250, 200, + # allowing sampling of [6000, 3000, 1000, 800, 750, 600, 500, 400, 300, 250, 200, # 150, 125, 100, 96, 80, 75, 64] metres - if ((sampling in range(64, 1001)) and (600000 % sampling == 0)): + if ((sampling in range(64, 6001)) and (600000 % sampling == 0)): tilecode = "T6" # allowing sampling of [60, 50, 48, 40, 32, 30, 25, 24, 20] metres elif ((sampling in range(20, 61)) and (300000 % sampling == 0)): @@ -370,7 +391,7 @@ def __init__(self, core, continent): self.core = _core # holds name of the subgrid - self.name = ''.join(('EQUI7_', continent, Equi7Grid.encode_sampling(core.sampling), 'M')) + self.name = ''.join(('EQUI7_', continent, Equi7Grid.encode_sampling(core.sampling, core.tile_names_in_m), 'M')) # holds the extent of the subgrid in the lonlat-space self.polygon_geog = create_geometry_from_wkt(data['zone_extent'], epsg=4326) @@ -546,7 +567,7 @@ def encode_tilename(self, llx, lly, sampling, tilecode, shortform=False): # gives long-form of tilename (e.g. "EU500M_E012N018T6") tilename = "{}{}M_E{:03d}N{:03d}{}".format( self.core.tag, - Equi7Grid.encode_sampling(sampling), + Equi7Grid.encode_sampling(sampling, self.core.tile_names_in_m), int(llx) // 100000, int(lly) // 100000, tilecode) @@ -688,29 +709,29 @@ def decode_tilename(self, tilename): sampling = self.core.sampling # allow long-form of tilename (e.g. "EU500M_E012N018T6") - elif len(tilename) == 17: + # tile_names_in_m True or False + else: subgrid_id = tilename[0:2] if subgrid_id != self.core.tag: raise ValueError(self.msg1) - sampling = Equi7Grid.decode_sampling(tilename[2:5]) + tilename_sampling = tilename[2:].split('M') + sampling = Equi7Grid.decode_sampling(tilename_sampling[0], self.core.tile_names_in_m) + tilename_remaining = tilename.split('_')[1] if sampling != self.core.sampling: raise ValueError(self.msg1) - tile_size_m = int(tilename[-1]) * 100000 + tile_size_m = int(tilename_remaining[-1]) * 100000 if tile_size_m != self.core.tile_xsize_m: raise ValueError(self.msg1) - llx = int(tilename[8:11]) + llx = int(tilename_remaining[1:4]) if llx % tf: raise ValueError(self.msg2) - lly = int(tilename[12:15]) + lly = int(tilename_remaining[5:8]) if lly % tf: raise ValueError(self.msg2) - tilecode = tilename[-2:] + tilecode = tilename_remaining[-2:] if tilecode != self.core.tiletype: raise ValueError(self.msg1) - # wrong length - else: - raise ValueError(self.msg1) return subgrid_id, sampling, tile_size_m, llx * 100000, lly * 100000, tilecode diff --git a/tests/test_equi7grid.py b/tests/test_equi7grid.py index d82d4d9..9a95aec 100644 --- a/tests/test_equi7grid.py +++ b/tests/test_equi7grid.py @@ -222,6 +222,29 @@ def test_lonlat2ij_in_tile(self): nptest.assert_equal(j, row_should) nptest.assert_equal(tilename, tile_should) + def test_lonlat2ij_in_tile(self): + """ + Tests the tile name with option tile_names_in_m as True or False + + """ + e7 = Equi7Grid(3000, tile_names_in_m=True) + column_should = 199 + row_should = 0 + tile_should = 'EU3000M_E048N012T6' + tilename, i, j = e7.lonlat2ij_in_tile(18.507, 44.571, lowerleft=True) + nptest.assert_equal(i, column_should) + nptest.assert_equal(j, row_should) + nptest.assert_equal(tilename, tile_should) + + e7 = Equi7Grid(3000, tile_names_in_m=False) + column_should = 199 + row_should = 0 + tile_should = 'EU3K0M_E048N012T6' + tilename, i, j = e7.lonlat2ij_in_tile(18.507, 44.571, lowerleft=True) + nptest.assert_equal(i, column_should) + nptest.assert_equal(j, row_should) + nptest.assert_equal(tilename, tile_should) + def test_proj4_reprojection_accuracy(self): """ Tests the proj4 reproject accuracy by forward and backward reprojection.