def extract(src_vector: str,
            burn_attribute: str,
            src_raster: list,
            dst_names: list,
            dst_dir: str,
            src_raster_template: str = None,
            gdal_dtype: int = 4,
            n_jobs: int = 1):
    """Extract values from list of single band raster for pixels overlapping with a vector data.

    The extracted data will be stored in the ``dst_dir`` by using the ``dst_names`` for the
    filename. If a file with a given name already exists the raster will be skipped.

    Arguments:
        src_vector {str} -- Filename of the vector dataset. Currently it must have the same CRS as
            the raster.
        burn_attribute {str} -- Name of the attribute column in the ``src_vector`` dataset to be
            stored with the extracted data. This should usually be a unique ID for the features
            (points, lines, polygons) in the vector dataset.
        src_raster {list} -- List of filenames of the single band raster files from which to
            extract.
        dst_names {list} -- List corresponding to ``src_raster`` names used to store and later
            identify the extracted to.
        dst_dir {str} -- Directory to store the data to.

    Keyword Arguments:
        src_raster_template {str} -- A template raster to be used for rasterizing the vectorfile.
            Usually the first element of ``src_raster``. (default: {None})
        gdal_dtype {int} -- Numeric GDAL data type, defaults to 4 which is UInt32.
            See https://github.com/mapbox/rasterio/blob/master/rasterio/dtypes.py for useful look-up
            tables.

    Returns:
        [int] -- If successful, 0 is returned as exit code.
    """
    if src_raster_template is None:
        src_raster_template = src_raster[0]
    path_rasterized = os.path.join(dst_dir, f"burn_attribute_rasterized_{burn_attribute}.tif")
    paths_extracted_aux = {ele: os.path.join(dst_dir, f"{ele}.npy") \
                           for ele in [f"aux_vector_{burn_attribute}",
                                       "aux_coord_x",
                                       "aux_coord_y"]}
    paths_extracted_raster = {}
    for path, name in zip(src_raster, dst_names):
        dst = f"{os.path.join(dst_dir, name)}.npy"
        if not os.path.exists(dst):
            paths_extracted_raster[path] = dst

    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
    # if it does not already exist, here we first create the rasterized data
    if not os.path.exists(path_rasterized):
        if src_raster_template is None:
            src_raster_template = src_raster[0]
        # print("Rasterizing vector attribute.")
        rasterize(src_vector=src_vector,
                  burn_attribute=burn_attribute,
                  src_raster_template=src_raster_template,
                  dst_rasterized=path_rasterized,
                  gdal_dtype=gdal_dtype)

    # if any of the destination files do not exist we need the locations of the pixels to be
    # extracted in form of a numpy array bool (mask_arr) that fits the rasters from which we will
    # extract below
    if not (all([os.path.exists(path) for path in paths_extracted_aux.values()]) and \
            all([os.path.exists(path) for path in paths_extracted_raster.values()])):
        # print("Creating mask array for pixels to be extracted.")
        mask_arr = _get_mask_array(path_rasterized, paths_extracted_aux, burn_attribute)
    else:
        return 0

    # create the pixel coordinates if they do not exist
    if not all([os.path.exists(paths_extracted_aux["aux_coord_x"]),
                os.path.exists(paths_extracted_aux["aux_coord_y"])]):
        _create_and_save_coords(path_rasterized, paths_extracted_aux, mask_arr)

    # lets extract the raster values in case of sequential processing
    # or remove existing raster layers to prepare parallel processing
    if n_jobs == 1:
        for path_src, path_dst in tqdm(paths_extracted_raster.items(),
                                       total=len(paths_extracted_raster)):
            _extract_and_save_one_layer(path_src, path_dst, mask_arr)
    else:
        import multiprocessing as mp
        if n_jobs == -1:
            n_jobs = mp.cpu_count()
        pool = mp.Pool(processes=n_jobs)
        _ = [pool.apply_async(_extract_and_save_one_layer,
                              args=(src, dst, mask_arr)) for \
                                  src, dst in paths_extracted_raster.items()]
        pool.close()
        pool.join()
    return 0
Extract values from list of single band raster for pixels overlapping with a vector data.

    The extracted data will be stored in the ``dst_dir`` by using the ``dst_names`` for the
    filename. If a file with a given name already exists the raster will be skipped.

    Arguments:
        src_vector {str} -- Filename of the vector dataset. Currently it must have the same CRS as
            the raster.
        burn_attribute {str} -- Name of the attribute column in the ``src_vector`` dataset to be
            stored with the extracted data. This should usually be a unique ID for the features
            (points, lines, polygons) in the vector dataset.
        src_raster {list} -- List of filenames of the single band raster files from which to
            extract.
        dst_names {list} -- List corresponding to ``src_raster`` names used to store and later
            identify the extracted to.
        dst_dir {str} -- Directory to store the data to.

    Keyword Arguments:
        src_raster_template {str} -- A template raster to be used for rasterizing the vectorfile.
            Usually the first element of ``src_raster``. (default: {None})
        gdal_dtype {int} -- Numeric GDAL data type, defaults to 4 which is UInt32.
            See https://github.com/mapbox/rasterio/blob/master/rasterio/dtypes.py for useful look-up
            tables.

    Returns:
        [int] -- If successful, 0 is returned as exit code.