def _calculate_cost(gene: TileGeneration, layer_name: str, options: Namespace) -> Tuple[float, timedelta, float, int]: nb_metatiles = {} nb_tiles = {} config = gene.get_config(options.config) layer = config.config["layers"][layer_name] meta = layer["meta"] if options.cost_algo == "area": tile_size = config.config["grids"][layer["grid"]]["tile_size"] for zoom, resolution in enumerate( config.config["grids"][layer["grid"]]["resolutions"]): if "min_resolution_seed" in layer and resolution < layer[ "min_resolution_seed"]: continue print(f"Calculate zoom {zoom}.") px_buffer = layer["px_buffer"] + layer["meta_buffer"] if meta else 0 m_buffer = px_buffer * resolution if meta: size = tile_size * layer["meta_size"] * resolution meta_buffer = size * 0.7 + m_buffer meta_geom = gene.get_geoms(config, layer_name)[zoom].buffer( meta_buffer, 1) nb_metatiles[zoom] = int(round(meta_geom.area / size**2)) size = tile_size * resolution tile_buffer = size * 0.7 + m_buffer geom = gene.get_geoms(config, layer_name)[zoom].buffer(tile_buffer, 1) nb_tiles[zoom] = int(round(geom.area / size**2)) elif options.cost_algo == "count": gene.init_tilecoords(config, layer_name) gene.add_geom_filter() if meta: def count_metatile(tile: Tile) -> Tile: if tile: if tile.tilecoord.z in nb_metatiles: nb_metatiles[tile.tilecoord.z] += 1 else: nb_metatiles[tile.tilecoord.z] = 1 return tile gene.imap(count_metatile) class MetaTileSplitter(TileStore): """Convert the metatile flow to tile flow.""" @staticmethod def get(tiles: Iterable[Tile]) -> Iterator[Tile]: for metatile in tiles: for tilecoord in metatile.tilecoord: yield Tile(tilecoord) gene.add_metatile_splitter(MetaTileSplitter()) # Only keep tiles that intersect geometry gene.add_geom_filter() def count_tile(tile: Tile) -> Tile: if tile: if tile.tilecoord.z in nb_tiles: nb_tiles[tile.tilecoord.z] += 1 else: print(f"Calculate zoom {tile.tilecoord.z}.") nb_tiles[tile.tilecoord.z] = 1 return tile gene.imap(count_tile) run = Run(gene, gene.functions_metatiles) assert gene.tilestream for tile in gene.tilestream: tile.metadata["layer"] = layer_name run(tile) times = {} print() for z, nb_metatile in nb_metatiles.items(): print(f"{nb_metatile} meta tiles in zoom {z}.") times[z] = layer["cost"]["metatile_generation_time"] * nb_metatile price: float = 0 all_size: float = 0 all_time: float = 0 all_tiles = 0 for z, nb_tile in nb_tiles.items(): print() print(f"{nb_tile} tiles in zoom {z}.") all_tiles += nb_tile if meta: time = times[z] + layer["cost"]["tile_generation_time"] * nb_tile else: time = layer["cost"]["tileonly_generation_time"] * nb_tile size = layer["cost"]["tile_size"] * nb_tile all_size += size all_time += time td = timedelta(milliseconds=time) print(f"Time to generate: {duration_format(td)} [d h:mm:ss]") c = gene.get_main_config( ).config["cost"]["s3"]["put"] * nb_tile / 1000.0 price += c print(f"S3 PUT: {c:0.2f} [$]") if "sqs" in gene.get_main_config().config: if meta: nb_sqs = nb_metatiles[z] * 3 else: nb_sqs = nb_tile * 3 c = nb_sqs * gene.get_main_config( ).config["cost"]["sqs"]["request"] / 1000000.0 price += c print(f"SQS usage: {c:0.2f} [$]") print() td = timedelta(milliseconds=all_time) print(f"Number of tiles: {all_tiles}") print(f"Generation time: {duration_format(td)} [d h:mm:ss]") print(f"Generation cost: {price:0.2f} [$]") return all_size, td, price, all_tiles