def zoom_index_gen(<EOL>mp=None,<EOL>out_dir=None,<EOL>zoom=None,<EOL>geojson=False,<EOL>gpkg=False,<EOL>shapefile=False,<EOL>txt=False,<EOL>vrt=False,<EOL>fieldname="<STR_LIT:location>",<EOL>basepath=None,<EOL>for_gdal=True,<EOL>threading=False,<EOL>):
for zoom in get_zoom_levels(process_zoom_levels=zoom):<EOL><INDENT>with ExitStack() as es:<EOL><INDENT>index_writers = []<EOL>if geojson:<EOL><INDENT>index_writers.append(<EOL>es.enter_context(<EOL>VectorFileWriter(<EOL>driver="<STR_LIT>",<EOL>out_path=_index_file_path(out_dir, zoom, "<STR_LIT>"),<EOL>crs=mp.config.output_pyramid.crs,<EOL>fieldname=fieldname<EOL>)<EOL>)<EOL>)<EOL><DEDENT>if gpkg:<EOL><INDENT>index_writers.append(<EOL>es.enter_context(<EOL>VectorFileWriter(<EOL>driver="<STR_LIT>",<EOL>out_path=_index_file_path(out_dir, zoom, "<STR_LIT>"),<EOL>crs=mp.config.output_pyramid.crs,<EOL>fieldname=fieldname<EOL>)<EOL>)<EOL>)<EOL><DEDENT>if shapefile:<EOL><INDENT>index_writers.append(<EOL>es.enter_context(<EOL>VectorFileWriter(<EOL>driver="<STR_LIT>",<EOL>out_path=_index_file_path(out_dir, zoom, "<STR_LIT>"),<EOL>crs=mp.config.output_pyramid.crs,<EOL>fieldname=fieldname<EOL>)<EOL>)<EOL>)<EOL><DEDENT>if txt:<EOL><INDENT>index_writers.append(<EOL>es.enter_context(<EOL>TextFileWriter(out_path=_index_file_path(out_dir, zoom, "<STR_LIT>"))<EOL>)<EOL>)<EOL><DEDENT>if vrt:<EOL><INDENT>index_writers.append(<EOL>es.enter_context(<EOL>VRTFileWriter(<EOL>out_path=_index_file_path(out_dir, zoom, "<STR_LIT>"),<EOL>output=mp.config.output,<EOL>out_pyramid=mp.config.output_pyramid<EOL>)<EOL>)<EOL>)<EOL><DEDENT>logger.debug("<STR_LIT>", index_writers)<EOL>def _worker(tile):<EOL><INDENT>tile_path = _tile_path(<EOL>orig_path=mp.config.output.get_path(tile),<EOL>basepath=basepath,<EOL>for_gdal=for_gdal<EOL>)<EOL>indexes = [<EOL>i for i in index_writers<EOL>if not i.entry_exists(tile=tile, path=tile_path)<EOL>]<EOL>if indexes:<EOL><INDENT>output_exists = mp.config.output.tiles_exist(output_tile=tile)<EOL><DEDENT>else:<EOL><INDENT>output_exists = None<EOL><DEDENT>return tile, tile_path, indexes, output_exists<EOL><DEDENT>with concurrent.futures.ThreadPoolExecutor() as executor:<EOL><INDENT>for task in concurrent.futures.as_completed(<EOL>(<EOL>executor.submit(_worker, i)<EOL>for i in mp.config.output_pyramid.tiles_from_geom(<EOL>mp.config.area_at_zoom(zoom), zoom<EOL>)<EOL>)<EOL>):<EOL><INDENT>tile, tile_path, indexes, output_exists = task.result()<EOL>if indexes and output_exists:<EOL><INDENT>logger.debug("<STR_LIT>", tile_path)<EOL>logger.debug("<STR_LIT>" % len(indexes))<EOL>for index in indexes:<EOL><INDENT>index.write(tile, tile_path)<EOL><DEDENT><DEDENT>yield tile<EOL><DEDENT><DEDENT><DEDENT><DEDENT>
Generate indexes for given zoom level.

Parameters
----------
mp : Mapchete object
    process output to be indexed
out_dir : path
    optionally override process output directory
zoom : int
    zoom level to be processed
geojson : bool
    generate GeoJSON index (default: False)
gpkg : bool
    generate GeoPackage index (default: False)
shapefile : bool
    generate Shapefile index (default: False)
txt : bool
    generate tile path list textfile (default: False)
vrt : bool
    GDAL-style VRT file (default: False)
fieldname : str
    field name which contains paths of tiles (default: "location")
basepath : str
    if set, use custom base path instead of output path
for_gdal : bool
    use GDAL compatible remote paths, i.e. add "/vsicurl/" before path
    (default: True)