def execute(self, process_tile, raise_nodata=False): """ Run Mapchete process on a tile. Execute, write and return data. Parameters ---------- process_tile : Tile or tile index tuple Member of the process tile pyramid (not necessarily the output pyramid, if output has a different metatiling setting) Returns ------- data : NumPy array or features process output """ process_tile = validate_tile(process_tile, self.config.process_pyramid) try: return self.config.output.streamline_output( TileProcess(tile=process_tile, config=self.config).execute()) except MapcheteNodataTile: if raise_nodata: # pragma: no cover raise else: return self.config.output.empty(process_tile)
def write(self, process_tile, data): """ Write data into output format. Parameters ---------- process_tile : BufferedTile or tile index tuple process tile data : NumPy array or features data to be written """ process_tile = validate_tile(process_tile, self.config.process_pyramid) if self.config.mode not in ["continue", "overwrite"]: raise ValueError("cannot write output in current process mode") if self.config.mode == "continue" and ( self.config.output.tiles_exist(process_tile)): message = "output exists, not overwritten" logger.debug((process_tile.id, message)) return ProcessInfo(tile=process_tile, processed=False, process_msg=None, written=False, write_msg=message) elif data is None: message = "output empty, nothing written" logger.debug((process_tile.id, message)) return ProcessInfo(tile=process_tile, processed=False, process_msg=None, written=False, write_msg=message) else: with Timer() as t: self.config.output.write(process_tile=process_tile, data=data) message = "output written in %s" % t logger.debug((process_tile.id, message)) return ProcessInfo(tile=process_tile, processed=False, process_msg=None, written=True, write_msg=message)
def read(self, output_tile): """ Read from written process output. Parameters ---------- output_tile : BufferedTile or tile index tuple Member of the output tile pyramid (not necessarily the process pyramid, if output has a different metatiling setting) Returns ------- data : NumPy array or features process output """ output_tile = validate_tile(output_tile, self.config.output_pyramid) if self.config.mode not in ["readonly", "continue", "overwrite"]: raise ValueError( "process mode must be readonly, continue or overwrite") return self.config.output.read(output_tile)
def get_raw_output(self, tile, _baselevel_readonly=False): """ Get output raw data. This function won't work with multiprocessing, as it uses the ``threading.Lock()`` class. Parameters ---------- tile : tuple, Tile or BufferedTile If a tile index is given, a tile from the output pyramid will be assumed. Tile cannot be bigger than process tile! Returns ------- data : NumPy array or features process output """ tile = validate_tile(tile, self.config.output_pyramid) tile = (self.config.baselevels["tile_pyramid"].tile( *tile.id) if _baselevel_readonly else tile) # Return empty data if zoom level is outside of process zoom levels. if tile.zoom not in self.config.zoom_levels: return self.config.output.empty(tile) # TODO implement reprojection if tile.crs != self.config.process_pyramid.crs: raise NotImplementedError( "reprojection between processes not yet implemented") if self.config.mode == "memory": # Determine affected process Tile and check whether it is already # cached. process_tile = self.config.process_pyramid.intersecting(tile)[0] return self._extract( in_tile=process_tile, in_data=self._execute_using_cache(process_tile), out_tile=tile) # TODO: cases where tile intersects with multiple process tiles process_tile = self.config.process_pyramid.intersecting(tile)[0] # get output_tiles that intersect with current tile if tile.pixelbuffer > self.config.output.pixelbuffer: output_tiles = list( self.config.output_pyramid.tiles_from_bounds( tile.bounds, tile.zoom)) else: output_tiles = self.config.output_pyramid.intersecting(tile) if self.config.mode == "readonly" or _baselevel_readonly: if self.config.output.tiles_exist(process_tile): return self._read_existing_output(tile, output_tiles) else: return self.config.output.empty(tile) elif self.config.mode == "continue" and not _baselevel_readonly: if self.config.output.tiles_exist(process_tile): return self._read_existing_output(tile, output_tiles) else: return self._process_and_overwrite_output(tile, process_tile) elif self.config.mode == "overwrite" and not _baselevel_readonly: return self._process_and_overwrite_output(tile, process_tile)