def prepare(self, process_area=None, **kwargs): bounds = snap_bounds( bounds=Bounds(*process_area.intersection( box(*self.output_params["delimiters"] ["effective_bounds"])).bounds), pyramid=self.pyramid, zoom=self.zoom) if process_area else self.output_params[ "delimiters"]["effective_bounds"] height = math.ceil((bounds.top - bounds.bottom) / self.pyramid.pixel_x_size(self.zoom)) width = math.ceil((bounds.right - bounds.left) / self.pyramid.pixel_x_size(self.zoom)) logger.debug("output raster bounds: %s", bounds) logger.debug("output raster shape: %s, %s", height, width) self._profile = dict( GTIFF_DEFAULT_PROFILE, driver="GTiff", transform=Affine(self.pyramid.pixel_x_size(self.zoom), 0, bounds.left, 0, -self.pyramid.pixel_y_size(self.zoom), bounds.top), height=height, width=width, count=self.output_params["bands"], crs=self.pyramid.crs, **{ k: self.output_params.get(k, GTIFF_DEFAULT_PROFILE[k]) for k in GTIFF_DEFAULT_PROFILE.keys() }, bigtiff=self.output_params.get("bigtiff", "NO")) logger.debug("single GTiff profile: %s", self._profile) self.in_memory = (self.in_memory if self.in_memory is False else height * width < IN_MEMORY_THRESHOLD) # set up rasterio if path_exists(self.path): if self.output_params["mode"] != "overwrite": raise MapcheteConfigError( "single GTiff file already exists, use overwrite mode to replace" ) else: logger.debug("remove existing file: %s", self.path) os.remove(self.path) # create output directory if necessary makedirs(os.path.dirname(self.path)) logger.debug("open output file: %s", self.path) self._ctx = ExitStack() # (1) use memfile if output is remote or COG if self.cog or path_is_remote(self.path): if self.in_memory: self._memfile = self._ctx.enter_context(MemoryFile()) self.dst = self._ctx.enter_context( self._memfile.open(**self._profile)) else: # in case output raster is too big, use tempfile on disk self._tempfile = self._ctx.enter_context(NamedTemporaryFile()) self.dst = self._ctx.enter_context( rasterio.open(self._tempfile.name, "w+", **self._profile)) else: self.dst = self._ctx.enter_context( rasterio.open(self.path, "w+", **self._profile))
def test_effective_bounds(files_bounds, baselevels): config = MapcheteConfig(files_bounds.dict) assert config.effective_bounds == snap_bounds( bounds=config.bounds, pyramid=config.process_pyramid, zoom=min(config.zoom_levels)) config = MapcheteConfig(baselevels.dict, zoom=[5, 7], bounds=(0, 1, 2, 3)) assert config.effective_bounds != config.init_bounds assert config.effective_bounds == snap_bounds( bounds=config.init_bounds, pyramid=config.process_pyramid, zoom=5) with pytest.raises(MapcheteConfigError): MapcheteConfig( dict(baselevels.dict, zoom_levels=dict(min=7, max=7), baselevels=dict(lower="cubic", max=7)))
def prepare(self, process_area=None, **kwargs): bounds = snap_bounds( bounds=Bounds(*process_area.intersection( box(*self.output_params["delimiters"] ["effective_bounds"])).bounds), pyramid=self.pyramid, zoom=self.zoom) if process_area else self.output_params[ "delimiters"]["effective_bounds"] height = math.ceil((bounds.top - bounds.bottom) / self.pyramid.pixel_x_size(self.zoom)) width = math.ceil((bounds.right - bounds.left) / self.pyramid.pixel_x_size(self.zoom)) logger.debug("output raster bounds: %s", bounds) logger.debug("output raster shape: %s, %s", height, width) self._profile = dict( GTIFF_DEFAULT_PROFILE, driver="GTiff", transform=Affine(self.pyramid.pixel_x_size(self.zoom), 0, bounds.left, 0, -self.pyramid.pixel_y_size(self.zoom), bounds.top), height=height, width=width, count=self.output_params["bands"], crs=self.pyramid.crs, **{ k: self.output_params.get(k, GTIFF_DEFAULT_PROFILE[k]) for k in GTIFF_DEFAULT_PROFILE.keys() }) logger.debug("single GTiff profile: %s", self._profile) if height * width > 20000 * 20000: raise ValueError("output GeoTIFF too big") # set up rasterio if path_exists(self.path): if self.output_params["mode"] != "overwrite": raise MapcheteConfigError( "single GTiff file already exists, use overwrite mode to replace" ) else: logger.debug("remove existing file: %s", self.path) os.remove(self.path) logger.debug("open output file: %s", self.path) self.rio_file = rasterio.open(self.path, "w+", **self._profile)