Exemple #1
0
def clip_with_aoi(src):
    dst = os.path.join(MVI_RESULTS_DIR, os.path.basename(src))
    logger.info("Clip %s with AOI to %s", src, dst)

    os.makedirs(MVI_RESULTS_DIR, exist_ok=True)
    if not os.path.exists(dst):
        run_command(
            "{gdal_bin_path}/gdalwarp -co COMPRESS=DEFLATE -co TILED=YES -of GTiff -cutline {aoi} -crop_to_cutline {src} {dst}".format(
                gdal_bin_path=settings.GDAL_BIN_PATH, aoi=AOI_PATH, src=src, dst=dst
            )
        )
Exemple #2
0
def clip_srtm_to_extent():
    logger.info("Clip SRTM to extent")
    srtm_clipped_path = os.path.join(MODIS_VI_TASKS_DATA_DIR, "srtm_dem_clipped.tif")
    if not os.path.exists(srtm_clipped_path):
        run_command(
            "{gdal_bin_path}/gdalwarp -of GTiff -cutline {aoi} -crop_to_cutline {src} {dst}".format(
                gdal_bin_path=settings.GDAL_BIN_PATH,
                aoi=EXTENT_PATH,
                src=SRTM_DEM_PATH,
                dst=srtm_clipped_path,
            )
        )
    return srtm_clipped_path
Exemple #3
0
def extract_subdatasets_as_gtiffs(files, tif_dir):
    logger.info("Extract subdatasets as GeoTIFFs")
    for src in files:
        name, _ = os.path.splitext(os.path.basename(src))
        dst = os.path.join(tif_dir, name)
        if not os.path.exists(f"{dst}_ndvi.tif"):
            run_command(
                f"gdal_translate "
                f'HDF4_EOS:EOS_GRID:{src}:MODIS_Grid_16DAY_250m_500m_VI:"250m 16 days NDVI" '
                f"{dst}_ndvi.tif")
        if not os.path.exists(f"{dst}_pixelrel.tif"):
            run_command(
                f"gdal_translate "
                f'HDF4_EOS:EOS_GRID:{src}:MODIS_Grid_16DAY_250m_500m_VI:"250m 16 days pixel reliability" '
                f"{dst}_pixelrel.tif")
Exemple #4
0
def create_raster_tiles(raster, *, levels):
    gdal2tiles = settings.GDAL2TILES_BIN_PATH
    n_jobs = settings.GDAL2TILES_NUM_JOBS
    media_dir = settings.MEDIA_ROOT
    rasters_dir = os.path.join(media_dir, "rasters")
    tiles_dir = os.path.join(media_dir, "tiles")

    src = raster.file.path
    dst = os.path.join(tiles_dir, raster.path())
    zoom_range = f"{levels[0]}-{levels[1]}"

    cmd = f"{gdal2tiles} --processes {n_jobs} -w none -n -z {zoom_range} {src} {dst}"

    # Make sure output directory does not exist
    if os.path.exists(dst):
        shutil.rmtree(dst)

    run_command(cmd)
Exemple #5
0
def create_masks(date_from, date_to):
    period_s = f'{date_from.strftime("%Y%m")}-{date_to.strftime("%Y%m")}'

    logger.info("Polygonize mask")
    src_path = os.path.join(
        MVI_RESULTS_DIR, "{}_vegetation_cloud_mask.tif".format(period_s)
    )
    dst_path = os.path.join(
        MVI_RESULTS_DIR, "{}_vegetation_cloud_mask.geojson".format(period_s)
    )
    run_command(
        '{gdal_bin_path}/gdal_polygonize.py {src} {dst} -b 1 -f "GeoJSON" DN'.format(
            gdal_bin_path=settings.GDAL_BIN_PATH, src=src_path, dst=dst_path
        )
    )

    logging.info("Reproject to epsg:4326")
    data = gpd.read_file(dst_path)
    data_proj = data.copy()
    data_proj["geometry"] = data_proj["geometry"].to_crs(epsg=4326)
    data_proj.to_file(dst_path)

    logger.info("Load vegetation mask to DB")
    create_vegetation_masks(dst_path, date_to)
Exemple #6
0
def download_and_process(date_from, date_to):
    os.makedirs(MVI_RAW_DIR, exist_ok=True)
    os.makedirs(MVI_TIF_DIR, exist_ok=True)

    modis_filenames = download_modis_vi_images(
        date_from=date_from,
        date_to=date_to,
        output_dir=MVI_RAW_DIR,
        username=settings.MODIS_USER,
        password=settings.MODIS_PASS,
    )

    if not modis_filenames:
        logger.error("No MODIS files for this period!")
        return

    extract_subdatasets_as_gtiffs(modis_filenames, MVI_TIF_DIR)

    srtm_clipped_path = clip_srtm_to_extent()
    lomas_mask = calculate_srtm_mask(srtm_clipped_path)

    logger.info("Clip NDVI to extent")
    os.makedirs(MVI_CLIP_DIR, exist_ok=True)
    name, _ = os.path.splitext(os.path.basename(modis_filenames[0]))
    ndvi_path = glob(os.path.join(MVI_TIF_DIR, f"{name}_ndvi.tif"))[0]
    ndvi_clipped_path = os.path.join(MVI_CLIP_DIR, os.path.basename(ndvi_path))
    if os.path.exists(ndvi_clipped_path):
        os.unlink(ndvi_clipped_path)
    run_command(
        "{gdal_bin_path}/gdalwarp -of GTiff -cutline {extent} -crop_to_cutline {src} {dst}".format(
            gdal_bin_path=settings.GDAL_BIN_PATH,
            extent=EXTENT_PATH,
            src=ndvi_path,
            dst=ndvi_clipped_path,
        )
    )

    logger.info("Superimpose clipped SRTM and NDVI rasters to align them")
    run_command(
        "{otb_bin_path}/otbcli_Superimpose -inr {inr} -inm {inm} -out {out}".format(
            otb_bin_path=settings.OTB_BIN_PATH,
            inr=srtm_clipped_path,
            inm=ndvi_clipped_path,
            out=ndvi_clipped_path,
        )
    )

    with rasterio.open(ndvi_clipped_path) as src:
        modis_ndvi = src.read(1)
        modis_meta = src.profile.copy()

    modis_meta["nodata"] = 0
    modis_meta["dtype"] = np.uint8

    logger.info("Build final vegetation mask")
    vegetacion_mask = modis_ndvi > THRESHOLD
    verde_mask = vegetacion_mask & lomas_mask
    verde = np.copy(modis_ndvi)
    verde[~verde_mask] = 0

    logger.info("Build scaled NDVI mask")
    verde_rango = np.copy(verde)
    verde_rango[(verde >= (0.2 / FACTOR_ESCALA)) & (verde < (0.4 / FACTOR_ESCALA))] = 1
    verde_rango[(verde >= (0.4 / FACTOR_ESCALA)) & (verde < (0.6 / FACTOR_ESCALA))] = 2
    verde_rango[(verde >= (0.6 / FACTOR_ESCALA)) & (verde < (0.8 / FACTOR_ESCALA))] = 3
    verde_rango[verde >= (0.8 / FACTOR_ESCALA)] = 4
    verde_rango[verde < 0] = 0
    verde_rango = verde_rango.astype(dtype=np.uint8)

    period_s = f'{date_from.strftime("%Y%m")}-{date_to.strftime("%Y%m")}'

    logger.info("Write masked NDVI raster")
    os.makedirs(MVI_MASK_DIR, exist_ok=True)
    ndvi_path = os.path.join(MVI_MASK_DIR, "{}_ndvi.tif".format(period_s))
    meta = modis_meta.copy()
    meta.update(dtype=verde.dtype)
    with rasterio.open(ndvi_path, "w", **meta) as dst:
        dst.write(verde, 1)

    verde[verde_mask] = 1
    verde = verde.astype(dtype=np.uint8)

    logger.info("Write vegetation mask raster")
    os.makedirs(MVI_MASK_DIR, exist_ok=True)
    vegetation_mask_path = os.path.join(
        MVI_MASK_DIR, "{}_vegetation_mask.tif".format(period_s)
    )
    with rasterio.open(vegetation_mask_path, "w", **modis_meta) as dst:
        dst.write(verde, 1)

    # Cloud mask
    logger.info("Clip pixel reliability raster to extent")
    name, _ = os.path.splitext(os.path.basename(modis_filenames[0]))
    pixelrel_path = glob(os.path.join(MVI_TIF_DIR, f"{name}_pixelrel.tif"))[0]
    pixelrel_clipped_path = os.path.join(MVI_CLIP_DIR, os.path.basename(pixelrel_path))
    if os.path.exists(pixelrel_clipped_path):
        os.unlink(pixelrel_clipped_path)
    run_command(
        "{gdal_bin_path}/gdalwarp -of GTiff -cutline {extent} -crop_to_cutline {src} {dst}".format(
            gdal_bin_path=settings.GDAL_BIN_PATH,
            extent=EXTENT_PATH,
            src=pixelrel_path,
            dst=pixelrel_clipped_path,
        )
    )

    logger.info("Superimpose pixel rel raster to SRTM raster")
    run_command(
        "{otb_bin_path}/otbcli_Superimpose -inr {inr} -inm {inm} -out {out}".format(
            otb_bin_path=settings.OTB_BIN_PATH,
            inr=srtm_clipped_path,
            inm=pixelrel_clipped_path,
            out=pixelrel_clipped_path,
        )
    )

    logger.info("Build cloud mask from pixel reliability raster")
    with rasterio.open(pixelrel_clipped_path) as cloud_src:
        clouds = cloud_src.read(1)

    # In clouds 2 is snow/ice and 3 are clouds, and -1 is not processed data
    cloud_mask = np.copy(clouds)
    cloud_mask[(clouds == 2) | (clouds == 3) | (clouds == -1)] = 1
    cloud_mask[(clouds != 2) & (clouds != 3)] = 0
    cloud_mask = cloud_mask.astype(np.uint8)

    logger.info("Write cloud mask raster")
    cloud_mask_path = os.path.join(MVI_MASK_DIR, "{}_cloud_mask.tif".format(period_s))
    with rasterio.open(cloud_mask_path, "w", **modis_meta) as dst:
        dst.write(cloud_mask, 1)

    # vegetation_range_path = os.path.join(
    #     MVI_MASK_DIR, "{}_vegetation_range.tif".format(period_s)
    # )
    # with rasterio.open(vegetation_range_path, "w", **modis_meta) as dst:
    #     dst.write(verde_rango, 1)

    logger.info("Create a mask with both vegetation and clouds")
    verde[cloud_mask == 1] = 2
    veg_cloud_mask_path = os.path.join(
        MVI_MASK_DIR, "{}_vegetation_cloud_mask.tif".format(period_s)
    )
    with rasterio.open(veg_cloud_mask_path, "w", **modis_meta) as dst:
        dst.write(verde, 1)

    # Clip to AOI all rasters into RESULTS_DIR
    clip_with_aoi(ndvi_path)
    clip_with_aoi(vegetation_mask_path)
    clip_with_aoi(cloud_mask_path)
    clip_with_aoi(veg_cloud_mask_path)

    return True