diff --git a/requirements/fct.txt b/requirements/fct.txt index d1c5ce3..f5ce7c6 100644 --- a/requirements/fct.txt +++ b/requirements/fct.txt @@ -14,4 +14,5 @@ duecredit==0.9.2 python-dotenv==0.21.1 matplotlib==3.6.3 rastachimp==0.3 -shapelysmooth==0.2.0 \ No newline at end of file +shapelysmooth==0.2.0 +opencv-python==4.10.0.84 \ No newline at end of file diff --git a/tutorials/01-drainage_plan/01-drainage.py b/tutorials/01-drainage_plan/01-drainage.py index 33aa6b3..7246ab9 100644 --- a/tutorials/01-drainage_plan/01-drainage.py +++ b/tutorials/01-drainage_plan/01-drainage.py @@ -1,80 +1,96 @@ -# coding: utf-8 - -''' -Goals of step 01-drainage : - - Get a clean Flow Accumulation raster in km2 - - -''' +import os +from fct.config import config +from multiprocessing import cpu_count +p = cpu_count()/2 # Create your tileset - from fct.cli import Tiles -Tiles.CreateTileset('dem', 10000.0, - tileset1 = '/data/sdunesme/fct/tests_1m/fct_workdir/10k_tileset.gpkg', - tileset2 = '/data/sdunesme/fct/tests_1m/fct_workdir/10kbis_tileset.gpkg') +Tiles.CreateTileset('dem5m', 30000.0, + tileset1 = os.path.join(config.workdir, 'default_tileset.gpkg'), + tileset2 = os.path.join(config.workdir, 'aux_tileset.gpkg')) -# Prepare the DEM tiles and VRT +# ATTENTION : Bien vérifier que les tilesets couvrent bien tout le DEM avant de continuer + +# Copy the Hydrographic Reference to outputs/GLOBAL/REFHYDRO +if not os.path.isdir(os.path.join(config.workdir, 'GLOBAL/REFHYDRO/')): + os.makedirs(os.path.join(config.workdir, 'GLOBAL/REFHYDRO/')) +# COPY input REFHYDRO to /local/sdunesme/run_rmc_5m/GLOBAL/REFHYDRO/REFERENTIEL_HYDRO.shp + +# Prepare the DEM tiles and VRT from fct.cli import Tiles -Tiles.DatasourceToTiles('dem', '10k', 'dem', processes=32) -Tiles.DatasourceToTiles('dem', '10kbis', 'dem', processes=32) +Tiles.DatasourceToTiles('dem5m', 'default', 'dem', processes=p) # Environ 120G pour 32*20km +Tiles.DatasourceToTiles('dem5m', 'aux', 'dem', processes=p) from fct.tileio import buildvrt -buildvrt('10k', 'dem') -buildvrt('10kbis', 'dem') +buildvrt('default', 'dem') +buildvrt('aux', 'dem') -# If you have two different scales DEM, you can fill the precise one with the less precise # First step when you have only one DEM : Smoothing from fct.drainage import PrepareDEM params = PrepareDEM.SmoothingParameters() -params.window=15 +#params.window=15 # Uncomment for 1m resolution DEM -PrepareDEM.MeanFilter(params, overwrite=True, processes=32, tileset='10k') -PrepareDEM.MeanFilter(params, overwrite=True, processes=32, tileset='10kbis') +PrepareDEM.MeanFilter(params, overwrite=True, processes=p, tileset='default') +PrepareDEM.MeanFilter(params, overwrite=True, processes=p, tileset='aux') + +from fct.tileio import buildvrt +buildvrt('default', 'smoothed') +buildvrt('aux', 'smoothed') + +# Drape hydrography network +from fct.drainage import Drape +params = Drape.Parameters() +#params.elevations = 'smoothed' +params.stream_network = 'network-cartography-ready' +params.draped = 'stream-network-draped' +Drape.DrapeNetworkAndAdjustElevations(params) +Drape.SplitStreamNetworkIntoTiles(params, tileset='default') +Drape.SplitStreamNetworkIntoTiles(params, tileset='aux') # Fill sinks from fct.drainage import DepressionFill params = DepressionFill.Parameters() -params.elevations = 'smoothed' -params.offset = -1.0 # burn offset in meters +#params.elevations = 'smoothed' +params.offset = 1.0 # burn offset in meters params.exterior_data = 9000.0 # exterior value -DepressionFill.LabelWatersheds(params, overwrite=True, processes=32) -DepressionFill.LabelWatersheds(params, overwrite=True, processes=32, tileset='10kbis') +DepressionFill.LabelWatersheds(params, overwrite=True, processes=p) +DepressionFill.LabelWatersheds(params, overwrite=True, processes=p, tileset='aux') from fct.tileio import buildvrt -buildvrt('10k', 'dem-watershed-labels') -buildvrt('10kbis', 'dem-watershed-labels') +buildvrt('default', 'dem-watershed-labels') +buildvrt('aux', 'dem-watershed-labels') DepressionFill.ResolveWatershedSpillover(params, overwrite=True) -DepressionFill.ResolveWatershedSpillover(params, overwrite=True, tileset='10kbis') +DepressionFill.ResolveWatershedSpillover(params, overwrite=True, tileset='aux') -DepressionFill.DispatchWatershedMinimumZ(params, overwrite=True, processes=32) -DepressionFill.DispatchWatershedMinimumZ(params, overwrite=True, processes=32, tileset='10kbis') +DepressionFill.DispatchWatershedMinimumZ(params, overwrite=True, processes=p) +DepressionFill.DispatchWatershedMinimumZ(params, overwrite=True, processes=p, tileset='aux') from fct.tileio import buildvrt -buildvrt('10k', 'dem-filled-resolved') -buildvrt('10kbis', 'dem-filled-resolved') +buildvrt('default', 'dem-filled-resolved') +buildvrt('aux', 'dem-filled-resolved') # Resolve flats from fct.drainage import BorderFlats params = BorderFlats.Parameters() -BorderFlats.LabelBorderFlats(params=params, processes=32) -BorderFlats.LabelBorderFlats(params=params, processes=32, tileset='10kbis') +BorderFlats.LabelBorderFlats(params=params, processes=p) +BorderFlats.LabelBorderFlats(params=params, processes=p, tileset='aux') from fct.tileio import buildvrt -buildvrt('10k', 'dem-flat-labels') -buildvrt('10kbis', 'dem-flat-labels') +buildvrt('default', 'dem-flat-labels') +buildvrt('aux', 'dem-flat-labels') BorderFlats.ResolveFlatSpillover(params=params) -BorderFlats.ResolveFlatSpillover(params=params, tileset='10kbis') +BorderFlats.ResolveFlatSpillover(params=params, tileset='aux') -BorderFlats.DispatchFlatMinimumZ(params=params, overwrite=True, processes=32) -BorderFlats.DispatchFlatMinimumZ(params=params, overwrite=True, processes=32, tileset='10kbis') +BorderFlats.DispatchFlatMinimumZ(params=params, overwrite=True, processes=p) +BorderFlats.DispatchFlatMinimumZ(params=params, overwrite=True, processes=p, tileset='aux') from fct.tileio import buildvrt -buildvrt('10k', 'dem-drainage-resolved') -buildvrt('10kbis', 'dem-drainage-resolved') +buildvrt('default', 'dem-drainage-resolved') +buildvrt('aux', 'dem-drainage-resolved') # FlatMap.DepressionDepthMap is useful if you want to check which flat areas have been resolved @@ -82,47 +98,47 @@ from fct.drainage import FlowDirection params = FlowDirection.Parameters() params.exterior = 'off' -FlowDirection.FlowDirection(params=params, overwrite=True, processes=32) -FlowDirection.FlowDirection(params=params, overwrite=True, processes=32, tileset='10kbis') +FlowDirection.FlowDirection(params=params, overwrite=True, processes=p) +FlowDirection.FlowDirection(params=params, overwrite=True, processes=p, tileset='aux') from fct.tileio import buildvrt -buildvrt('10k', 'flow') -buildvrt('10kbis', 'flow') +buildvrt('default', 'flow') +buildvrt('aux', 'flow') # Flow tiles inlets/outlets graph from fct.drainage import Accumulate params = Accumulate.Parameters() params.elevations = 'dem-drainage-resolved' -Accumulate.Outlets(params=params, processes=32) -Accumulate.Outlets(params=params, processes=32, tileset='10kbis') +Accumulate.Outlets(params=params, processes=p) +Accumulate.Outlets(params=params, processes=p, tileset='aux') Accumulate.AggregateOutlets(params) -Accumulate.AggregateOutlets(params, tileset='10kbis') +Accumulate.AggregateOutlets(params, tileset='aux') # Resolve inlets/outlets graph Accumulate.InletAreas(params=params) -Accumulate.InletAreas(params=params, tileset='10kbis') +Accumulate.InletAreas(params=params, tileset='aux') # Flow accumulation -Accumulate.FlowAccumulation(params=params, overwrite=True, processes=32) -Accumulate.FlowAccumulation(params=params, overwrite=True, processes=32, tileset='10kbis') +Accumulate.FlowAccumulation(params=params, overwrite=True, processes=p) +Accumulate.FlowAccumulation(params=params, overwrite=True, processes=p, tileset='aux') from fct.tileio import buildvrt -buildvrt('10k', 'acc') -buildvrt('10kbis', 'acc') +buildvrt('default', 'acc') +buildvrt('aux', 'acc') # Stream Network from sources from fct.drainage import StreamSources StreamSources.InletSources(params) -StreamSources.InletSources(params, tileset='10kbis') +StreamSources.InletSources(params, tileset='aux') -StreamSources.StreamToFeatureFromSources(min_drainage=500, processes=32) -StreamSources.StreamToFeatureFromSources(min_drainage=500, processes=32, tileset='10kbis') +StreamSources.StreamToFeatureFromSources(min_drainage=500, processes=p) +StreamSources.StreamToFeatureFromSources(min_drainage=500, processes=p, tileset='aux') StreamSources.AggregateStreamsFromSources() -StreamSources.AggregateStreamsFromSources(tileset='10kbis') +StreamSources.AggregateStreamsFromSources(tileset='aux') # Find NoFlow pixels from RHTS from fct.drainage import FixNoFlow @@ -131,53 +147,61 @@ params.noflow = 'noflow' params.fixed = 'noflow-targets' -FixNoFlow.DrainageRaster(params=params, processes=32) -FixNoFlow.DrainageRaster(params=params, processes=32, tileset='10kbis') +FixNoFlow.DrainageRaster(params=params, processes=p) +FixNoFlow.DrainageRaster(params=params, processes=p, tileset='aux') from fct.tileio import buildvrt -buildvrt('10k', 'drainage-raster-from-sources') -buildvrt('10kbis', 'drainage-raster-from-sources') +buildvrt('default', 'drainage-raster-from-sources') +buildvrt('aux', 'drainage-raster-from-sources') -FixNoFlow.NoFlowPixels(params=params, processes=32) -FixNoFlow.NoFlowPixels(params=params, processes=32, tileset='10kbis') +FixNoFlow.NoFlowPixels(params=params, processes=p) +FixNoFlow.NoFlowPixels(params=params, processes=p, tileset='aux') FixNoFlow.AggregateNoFlowPixels(params) -FixNoFlow.AggregateNoFlowPixels(params, tileset='10kbis') +FixNoFlow.AggregateNoFlowPixels(params, tileset='aux') # Fix NoFlow (create TARGETS shapefile and fix Flow Direction data) -FixNoFlow.FixNoFlow(params, tileset1='10k', tileset2='10kbis', fix=True) +FixNoFlow.FixNoFlow(params, tileset1='default', tileset2='aux', fix=True) +FixNoFlow.FixNoFlow(params, tileset1='aux', tileset2='default', fix=True) # Remake FlowAccumulation with NoFlow pixels fixed +# Il est possible de déplacer un peu les sources à la main et relancer à partir d'ici pour recalculer le RHTS from fct.drainage import Accumulate params = Accumulate.Parameters() params.elevations = 'dem-drainage-resolved' +# params.exterior_flow = 'exterior-inlet' # Uncomment this if you have exterior EXTERIOR INLET points -Accumulate.Outlets(params=params, processes=32) -Accumulate.AggregateOutlets(params) -Accumulate.InletAreas(params=params) -Accumulate.FlowAccumulation(params=params, overwrite=True, processes=32) +Accumulate.Outlets(params=params, processes=p, tileset='default') +Accumulate.AggregateOutlets(params, tileset='default') +Accumulate.InletAreas(params=params, tileset='default') +Accumulate.FlowAccumulation(params=params, overwrite=True, processes=p, tileset='default') # Remake stream Network from sources with NoFlow pixels fixed +from fct.drainage import Accumulate +params = Accumulate.Parameters() +params.elevations = 'dem-drainage-resolved' +# params.exterior_flow = 'exterior-inlet' # Uncomment this if you have exterior EXTERIOR INLET points from fct.drainage import StreamSources -StreamSources.InletSources(params) -StreamSources.StreamToFeatureFromSources(min_drainage=500, processes=32) -StreamSources.AggregateStreamsFromSources() +StreamSources.InletSources(params, tileset='default') +StreamSources.StreamToFeatureFromSources(min_drainage=500, processes=p, tileset='default') +StreamSources.AggregateStreamsFromSources(tileset='default') + +# IF NETWORK IS DISCONNECTED, TRY TO RESTART THE WORKFLOW FROM "Remake flow accumulation" WITH THE OTHER TILESET # Identify network nodes from fct.drainage import IdentifyNetworkNodes params = IdentifyNetworkNodes.Parameters() -IdentifyNetworkNodes.IdentifyNetworkNodes(params) -IdentifyNetworkNodes.JoinSourcesAttributes(params) - -# Sur le réseau hydro => rang de Hack => Créer champ AXIS = 16 derniers caractères de liens_vers_coursd_eau => extraction des sources +IdentifyNetworkNodes.IdentifyNetworkNodes(params, tileset='default') +IdentifyNetworkNodes.JoinSourcesAttributes(params, tileset='default') +# Join network attributes and aggregate by axis import os -if not os.path.isdir('/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/MEASURE'): - os.mkdir('/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/MEASURE') +if not os.path.isdir(f'{config.workdir}/GLOBAL/MEASURE'): + os.mkdir(f'{config.workdir}/GLOBAL/MEASURE') from fct.drainage import JoinNetworkAttributes -JoinNetworkAttributes.JoinNetworkAttributes('/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/DEM/SOURCES_IDENTIFIED_10K.shp', '/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/DEM/NETWORK_IDENTIFIED_10K.shp', '/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/DEM/RHTS.shp') -# JoinNetworkAttributes.UpdateLengthOrder('/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/DEM/RHTS.shp', '/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/DEM/RHTS.shp') -JoinNetworkAttributes.AggregateByAxis('/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/DEM/RHTS.shp', '/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/MEASURE/REFAXIS.shp') +JoinNetworkAttributes.JoinNetworkAttributes(f'{config.workdir}/GLOBAL/DEM/SOURCES_IDENTIFIED_DEFAULT.shp', f'{config.workdir}/GLOBAL/DEM/NETWORK_IDENTIFIED_DEFAULT.shp', f'{config.workdir}/GLOBAL/DEM/RHTS.shp') +# JoinNetworkAttributes.UpdateLengthOrder(f'{config.workdir}/GLOBAL/DEM/RHTS.shp', f'{config.workdir}/GLOBAL/DEM/RHTS.shp') +JoinNetworkAttributes.AggregateByAxis(f'{config.workdir}/GLOBAL/DEM/RHTS.shp', f'{config.workdir}/GLOBAL/MEASURE/REFAXIS.shp') diff --git a/tutorials/01-drainage_plan/01-drainage_workflow.ipynb b/tutorials/01-drainage_plan/01-drainage_workflow.ipynb deleted file mode 100644 index 5872050..0000000 --- a/tutorials/01-drainage_plan/01-drainage_workflow.ipynb +++ /dev/null @@ -1,894 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "4fbb418a-29f2-4908-b4f2-3232d1a8a35e", - "metadata": {}, - "source": [ - "# Fluvial corridor workflow" - ] - }, - { - "cell_type": "markdown", - "id": "a6e57800-53a6-45dd-bc2f-654e1dd914dd", - "metadata": {}, - "source": [ - "## Install GDAL\n", - "For Windows 10, install GDAL with OSGEO4W\n", - "\n", - "[link to installer](https://trac.osgeo.org/osgeo4w/wiki/OSGeo4W_fr)\n", - "\n", - "Choose *Express Install* then GDAL.\n", - "\n", - "In your user environement variables add C:\\OSGeo4W\\bin to PATH." - ] - }, - { - "cell_type": "markdown", - "id": "5978cbcb-e7c8-42ad-a16f-393b362954c2", - "metadata": {}, - "source": [ - "## Set input parameters\n", - "Create a config.ini file following the example below.\n", - "\n", - "```\n", - "[workspace]\n", - "\n", - " workdir=./path/to/outputs\n", - " srs=EPSG:2154\n", - "\n", - "[DataSources] ; each datasource are referenced with parameters below\n", - "\n", - " bdalti = BDALTI ; DEM with bigger resolution used to fill no data in finer resolution DEM, tif extent\n", - " rgealti = RGEALTI ; reference DEM\n", - " sources = SOURCES_BDTOPO ; hydrographic network sources\n", - "\n", - "[Tilesets] ; Two overlapping grids are required to tile the calculations. The overlay allows to correct the errors between the junctions of the tiles.\n", - " default = 10K_TILESET ; if tileset is define as default the first grid is selected\n", - " 10k = 10K_TILESET ; first grid\n", - " 10kbis = 10KBIS_TILESET ; second overlapping grids\n", - "\n", - "; \n", - "; Describe Datasources below wich are reference above in [DataSources] and [Tilesets]\n", - "; \n", - "\n", - "[BDALTI]\n", - "\n", - " type=datasource\n", - " data=elevation\n", - " filename=./tutorials/dem_to_dgo/inputs/DEM.tif ; relative path to file\n", - " resolution=25.0 ; DEM resolution\n", - "\n", - "[RGEALTI]\n", - "\n", - " type=datasource\n", - " data=elevation\n", - " filename=./tutorials/dem_to_dgo/inputs/DEM_5M.tif ; relative path to file\n", - " resolution=5.0 ; DEM resolution\n", - "\n", - "[SOURCES_BDTOPO]\n", - "\n", - " type = datasource\n", - " data = hydrography\n", - " filename = ./tutorials/dem_to_dgo/inputs/sources.gpkg ; relative path to file\n", - "\n", - "[10K_TILESET]\n", - "\n", - " type=tileset\n", - " index=./tutorials/dem_to_dgo/inputs/10k_tileset.gpkg ; relative path to file\n", - " height=2000\n", - " width=2000\n", - " tiledir=10K\n", - " resolution=10000.0\n", - "\n", - "[10KBIS_TILESET]\n", - "\n", - " type=tileset\n", - " index=./tutorials/dem_to_dgo/inputs/10kbis_tileset.gpkg ; relative path to file\n", - " height=2000\n", - " width=2000\n", - " tiledir=10KBIS\n", - " resolution=10000.0\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "6782ec31-ac5b-4c6e-a08d-23d07f9f7f10", - "metadata": {}, - "source": [ - "Create a .env text file near to this notebook with\n", - "```FCT_CONFIG=/path/to/config.ini```\n", - "\n", - "The outputs folder and name are generated automatically.\n", - "They are defined in yml files in the config/datasets folder or by tiledir attributes in config.ini section.\n", - "Activate the virtual environement in shell from the python-fct folder." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "15c52440-29c2-4751-88d4-a6f61fbd8359", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Set number of your computer core for processing parallelization\n", - "import os\n", - "core = os.cpu_count()\n", - "# core = 8" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0b27b483-3444-48e0-9db0-bd7f8b6c43f3", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Prepare the DEM tiles and VRT\n", - "\n", - "from fct.cli import Tiles\n", - "Tiles.DatasourceToTiles('rgealti', '10k', 'dem', processes=core, overwrite=True)\n", - "Tiles.DatasourceToTiles('rgealti', '10kbis', 'dem', processes=core, overwrite=True)" - ] - }, - { - "cell_type": "markdown", - "id": "09bb08dd-1c45-49c9-9a5d-5b6c24a2fd64", - "metadata": {}, - "source": [ - "Arguments :\n", - "- bdalti or rgealti = input define in config.ini\n", - "- 10k = input tile grid define in config.ini\n", - "- dem = output file define in config/datasets/drainage.yml\n", - "- processes=core depends on the number of cores in your computer" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "361eebb2-01ab-4468-86d7-a4ccfb6b2d12", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from fct.tileio import buildvrt\n", - "buildvrt('10k', 'dem', overwrite=True)\n", - "buildvrt('10kbis', 'dem', overwrite=True)" - ] - }, - { - "cell_type": "markdown", - "id": "c8839739-f2e2-404b-8e6f-26b30f03c019", - "metadata": {}, - "source": [ - "Arguments :\n", - "- 10k = input tile grid define in config.ini\n", - "- dem = output file define in config/datasets/drainage.yml" - ] - }, - { - "cell_type": "markdown", - "id": "51e18449-53eb-4566-8642-1257cda35a4a", - "metadata": {}, - "source": [ - "If you have two different scales DEM, you can fill the precise one with the less precise\n", - "A faire en amont du lissage?" - ] - }, - { - "cell_type": "markdown", - "id": "179fbb82-33af-4a97-a0d6-044e9c22a637", - "metadata": {}, - "source": [ - "## Create a drainage networks\n", - "### DEM preparation" - ] - }, - { - "cell_type": "markdown", - "id": "0d1269b8-4478-4a8d-9cbd-2b5644cb6754", - "metadata": {}, - "source": [ - "#### DEM smoothing" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5d864289-906f-4c67-b6a1-7025bc48d551", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from fct.drainage import PrepareDEM\n", - "# Prepare the smoothing parameter\n", - "params = PrepareDEM.SmoothingParameters()" - ] - }, - { - "cell_type": "markdown", - "id": "48456de2-668e-4362-85b9-9ed43b06114b", - "metadata": {}, - "source": [ - "smoothing parameters : \n", - "- elevations = input\n", - "- output = output smoothed dem\n", - "- window = smoothing window" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d212bf86-b110-4bb2-a002-e65348c4c175", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# change window size (defaut = 5)\n", - "params.window=5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "53f3fefd-6dc4-42a0-918f-81ab41e7d364", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# uncomment below to print other parameters\n", - "# help(params)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f6ce6671-2282-4474-8a1f-a6fd2207881a", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Mean filter for each tile of the tileset\n", - "PrepareDEM.MeanFilter(params, overwrite=True, processes=core, tileset='10k')\n", - "PrepareDEM.MeanFilter(params, overwrite=True, processes=core, tileset='10kbis')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "764ab41e-ed90-4b36-bb80-663a2c296cdd", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# uncomment below to see an example of the the output tile path\n", - "# params.output.tilename(row=1, col=1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0bd6960c-35a1-491c-8441-6ee40c136ebb", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Create virtual rasters for tiles\n", - "from fct.tileio import buildvrt\n", - "buildvrt('10k', 'smoothed', overwrite=True)\n", - "buildvrt('10kbis', 'smoothed', overwrite=True)" - ] - }, - { - "cell_type": "markdown", - "id": "8a3ad78a-a6a3-43d9-aad7-4d5dc19c99db", - "metadata": {}, - "source": [ - "#### Fill sink\n", - "Create a depressionless DEM form each tile before get flow direction" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b8173c83-55b2-44cd-a2c5-1bd7e4c9879b", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# import module\n", - "from fct.drainage import DepressionFill\n", - "# set parameters\n", - "params = DepressionFill.Parameters()" - ] - }, - { - "cell_type": "markdown", - "id": "a0d48525-fe5b-484d-aed7-0a498573c1c9", - "metadata": {}, - "source": [ - "DepressionFill parameters :\n", - "\n", - "- _elevations = input\n", - "- _hydrography = Stream network derived from cartography draped on DEM **a quoi ça sert?? c'est dans la fonction BurnTile pour creuser le MNT (avec le paramètre offset) avec un réseau hydrographique si cette couche est disponible (sauf que l'emplacement du fichier shp à fournir dans le yml est dans les outputs et non dans les input). J'ai l'impression que ce n'est plus utilisé...**\n", - "- _filled = output filled DEM tiles define in yml. DEM tiles, depression filling procedure, first pass: individual tile processing\n", - "- _labels = output watershed label raster tiles define in yml. Watershed labels (depression filling procedure)\n", - "- _graph = output watershed graph define in yml. Cross-tile watershed connection graph (depression filling procedure)\n", - "- _spillover = output watershed spillover define in yml. Tile spillovers, z resolution of dem-watershed-graph (depression filling procedure)\n", - "- _resolved = output final filled DEM tiles define in yml. DEM tiles, depression filling procedure, second pass: cross-tile resolution based on spillover graph\n", - "- _offset = ? **Est utiliser par la fonction BurnTile pour modifier les donnes du MNT avec le réseau hydrographique, par défault la valeur est de -1, cependant si elle est égale à -1 le réseau est surélevé et non creusé...**\n", - "- _exterior_data = DEM edge value. Default 9000 to create wall to avoid flow to get out." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e262f06-6dbc-4aca-949b-817a131babde", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# uncomment below to show default parameters\n", - "# help(params)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "af80ae40-38a6-46b2-9f61-50ebe7f924ab", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# change default parameters\n", - "params.elevations = 'smoothed'\n", - "# params.exterior_data = 0.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "da4eba37-2e34-411c-bbe6-f06517ed8b4a", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Identifies and numbers the watersheds and continuous areas of the same elevation, with filling in the holes\n", - "DepressionFill.LabelWatersheds(params, overwrite=True, processes=core, tileset='10k')\n", - "DepressionFill.LabelWatersheds(params, overwrite=True, processes=core, tileset='10kbis')\n", - "\n", - "# Calculates the overflow graph between the different tiles\n", - "DepressionFill.ResolveWatershedSpillover(params, overwrite=True, tileset='10k')\n", - "DepressionFill.ResolveWatershedSpillover(params, overwrite=True, tileset='10kbis')\n", - "\n", - "# Adjusts the elevation of tile edge depressions, (altitude differential with the overflow point)\n", - "DepressionFill.DispatchWatershedMinimumZ(params, overwrite=True, processes=core, tileset='10k')\n", - "DepressionFill.DispatchWatershedMinimumZ(params, overwrite=True, processes=core, tileset='10kbis')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "da3800c2-b092-4e01-9ef6-32bf225a3bf0", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Create virtual rasters for tiles\n", - "from fct.tileio import buildvrt\n", - "buildvrt('10k', 'dem-watershed-labels', overwrite=True)\n", - "buildvrt('10kbis', 'dem-watershed-labels', overwrite=True)\n", - "\n", - "buildvrt('10k', 'dem-filled', overwrite=True)\n", - "buildvrt('10kbis', 'dem-filled', overwrite=True)\n", - "\n", - "buildvrt('10k', 'dem-filled-resolved', overwrite=True)\n", - "buildvrt('10kbis', 'dem-filled-resolved', overwrite=True)" - ] - }, - { - "cell_type": "markdown", - "id": "079f127d-6f47-4506-84d3-6a9411326645", - "metadata": { - "tags": [] - }, - "source": [ - "#### Resolve flats\n", - "Resolve flat areas between filled DEM tiles" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a09a470a-4d40-4e3e-adaf-000f23f55e33", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# import module\n", - "from fct.drainage import BorderFlats\n", - "# set parameters\n", - "params = BorderFlats.Parameters()" - ] - }, - { - "cell_type": "markdown", - "id": "4dab245a-4c9a-4bc9-9652-4caed7c673c3", - "metadata": {}, - "source": [ - "BorderFlats parameters :\n", - "\n", - "- _labels = watersheds with labels create in fill sinks step.\n", - "- _resolved = filled DEM tiles create in fill sinks, depression filling procedure, second pass: cross-tile resolution based on spillover graph\n", - "- _flat_labels = Flat labels output raster (depression filling procedure)\n", - "- _flat_graph = Cross-tile flat output connection graph (depression filling procedure)\n", - "- _flat_spillover = Tile spillovers output, z resolution of dem-flat-graph (depression filling procedure)\n", - "- _output = BorderFlats output. Filled DEM tiles, depression filling procedure, second pass: cross-tile resolution based on spillover graph" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "51a8da82-776c-4e4f-b10c-648b7e60855a", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# uncomment below to show default parameters\n", - "# help(params)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1dab5d57-5d3b-4174-886b-2ec67874ae77", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Identify flat area in previous filled DEM tiles and fix flat border\n", - "BorderFlats.LabelBorderFlats(params=params, processes=core, tileset='10k') \n", - "BorderFlats.LabelBorderFlats(params=params, processes=core, tileset='10kbis')\n", - "\n", - "BorderFlats.ResolveFlatSpillover(params=params, tileset='10k')\n", - "BorderFlats.ResolveFlatSpillover(params=params, tileset='10kbis')\n", - "\n", - "# Adjusts the elevation of tile edge depressions, and calculates the depression map (altitude differential with the overflow point)\n", - "BorderFlats.DispatchFlatMinimumZ(params=params, overwrite=True, processes=core, tileset='10k')\n", - "BorderFlats.DispatchFlatMinimumZ(params=params, overwrite=True, processes=core, tileset='10kbis')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "812d5a3a-46a4-4b53-9077-7efcb229865a", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Create virtual rasters for tiles\n", - "from fct.tileio import buildvrt\n", - "buildvrt('10k', 'dem-flat-labels', overwrite=True)\n", - "buildvrt('10kbis', 'dem-flat-labels', overwrite=True)\n", - "\n", - "buildvrt('10k', 'dem-drainage-resolved', overwrite=True)\n", - "buildvrt('10kbis', 'dem-drainage-resolved', overwrite=True)" - ] - }, - { - "cell_type": "markdown", - "id": "5d59efee-94e6-4f57-9f4f-b2af1946802e", - "metadata": {}, - "source": [ - "### Flow direction" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8ae4eee4-513d-4990-8822-1225b24ead66", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# import module\n", - "from fct.drainage import FlowDirection\n", - "# set parameters\n", - "params = FlowDirection.Parameters()" - ] - }, - { - "cell_type": "markdown", - "id": "827649c2-e3ad-41df-97b5-2a1dbed8e56d", - "metadata": {}, - "source": [ - "FlowDirection parameters :\n", - "- _exterior = exterior domain. not found in yml input, should be a shape file to indentify the area out of the DEM and avoid flow to go out of this mask (flow = -1). **utilisé?**\n", - "- _elevations = filled DEM tiles raster input from Resolve flats step.\n", - "- _flow = D8 Flow Direction output raster, derived from DEM" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "82289df0-e758-49d8-993b-dae9a506fd41", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# uncomment below to show default parameters\n", - "# help(params)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "419d16c5-6a3d-495a-a0d5-90f191a65d3e", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# change default parameters\n", - "# deactivate this parameter, exterior shapefile not define\n", - "params.exterior = 'off'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6ecf5259-f5cc-4add-918f-7aa0505d21f3", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Calculate flow direction\n", - "# Resolve flats drainage direction and calculate D8 flow direction from adjusted elevations.\n", - "FlowDirection.FlowDirection(params=params, overwrite=True, processes=core, tileset='10k')\n", - "FlowDirection.FlowDirection(params=params, overwrite=True, processes=core, tileset='10kbis')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "74508c52-a031-4306-8095-dddf9ffa9b1a", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Create virtual rasters for tiles\n", - "from fct.tileio import buildvrt\n", - "buildvrt('10k', 'flow', overwrite=True)\n", - "buildvrt('10kbis', 'flow', overwrite=True)" - ] - }, - { - "cell_type": "markdown", - "id": "4a94bacc-4258-4f00-9639-6ecb6773df0d", - "metadata": {}, - "source": [ - "### Flow accumulation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f349e21f-839c-42b5-a55f-583e9d13ac10", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# import module\n", - "from fct.drainage import Accumulate\n", - "# set parameters\n", - "params = Accumulate.Parameters()" - ] - }, - { - "cell_type": "markdown", - "id": "5935d56b-6add-46e9-8417-b301be895950", - "metadata": {}, - "source": [ - "Flow accumulation parameters :\n", - "- _exterior_flow = shapefile to connect outlets flow. **Pas dans le yml ni dans config.ini...**\n", - "- _elevations = initial raster DEM input\n", - "- _flow = Flow Direction input raster from flow direction step\n", - "- _outlets = " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ea7cc1f3-0356-4338-a7f7-e62e61c80041", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# uncomment below to show default parameters\n", - "# help(params)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "651fd74d-6337-414d-9cf3-721da82ee2f1", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# change default parameters\n", - "params.elevations = 'dem-drainage-resolved'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "34906c93-ff80-40c6-b4f8-db2248a7db1a", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Find tile outlets,ie. pixels connecting to anoter tile according to flow direction.\n", - "Accumulate.Outlets(params=params, processes=core, tileset='10k')\n", - "Accumulate.Outlets(params=params, processes=core, tileset='10kbis')\n", - "\n", - "# Aggregate ROW_COL_INLETS_ORIGIN.geojson files into one ROW_COL_INLETS.shp shapefile\n", - "Accumulate.AggregateOutlets(params, tileset='10k')\n", - "Accumulate.AggregateOutlets(params, tileset='10kbis')\n", - "\n", - "# Accumulate areas across tiles and output per tile inlet shapefiles with contributing area flowing into tile.\n", - "Accumulate.InletAreas(params=params, tileset='10k')\n", - "Accumulate.InletAreas(params=params, tileset='10kbis')\n", - "\n", - "# Calculate D8 flow direction tile\n", - "Accumulate.FlowAccumulation(params=params, overwrite=True, processes=core, tileset='10k') \n", - "Accumulate.FlowAccumulation(params=params, overwrite=True, processes=core, tileset='10kbis')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f976a1bf-a29e-4175-bc62-562e9a31d3f8", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Create virtual rasters for tiles\n", - "from fct.tileio import buildvrt\n", - "buildvrt('10k', 'acc', overwrite=True)\n", - "buildvrt('10kbis', 'acc', overwrite=True)" - ] - }, - { - "cell_type": "markdown", - "id": "9a4b8ec6-913e-4444-a47a-21f3cc59cf13", - "metadata": {}, - "source": [ - "### Stream network from source" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b98d98c0-77ac-4c21-813f-222384c25ace", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# import module\n", - "from fct.drainage import StreamSources\n", - "# same parameters as flow accumulation" - ] - }, - { - "cell_type": "markdown", - "id": "c16b558a-8cba-4699-bf02-4e4fdaee45d2", - "metadata": {}, - "source": [ - "**Add parameters for StreamSources**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6edbe103-8468-4921-b26b-421caf8eacb0", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "StreamSources.InletSources(params, tileset='10k')\n", - "StreamSources.InletSources(params, tileset='10kbis')\n", - "\n", - "StreamSources.StreamToFeatureFromSources(min_drainage=500, processes=core, tileset='10k')\n", - "StreamSources.StreamToFeatureFromSources(min_drainage=500, processes=core, tileset='10kbis')\n", - "\n", - "StreamSources.AggregateStreamsFromSources(tileset='10k')\n", - "StreamSources.AggregateStreamsFromSources(tileset='10kbis')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e85645d5-3bde-4b5b-b402-c699b1492b6f", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Create virtual rasters for tiles\n", - "from fct.tileio import buildvrt\n", - "buildvrt('10k', 'drainage-raster-from-sources')\n", - "buildvrt('10kbis', 'drainage-raster-from-sources')" - ] - }, - { - "cell_type": "markdown", - "id": "94f0d8d9-2477-4b8c-a9b4-a309a039c141", - "metadata": {}, - "source": [ - "#### Fix no flow" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "627bc9ba-33ce-47a4-b40a-eccb71bad783", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Find NoFlow pixels from RHTS\n", - "from fct.drainage import FixNoFlow\n", - "params = FixNoFlow.Parameters()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2cd1de67-5515-47ca-a5f0-6ae7c1a99727", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# uncomment below to show default parameters\n", - "help(params)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7047ac86-6d31-401d-9b8a-da3004566afb", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# change default parameters\n", - "params.noflow = 'noflow'\n", - "params.fixed = 'noflow-targets'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bba73815-10b7-468f-af8b-79a823a8a425", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "FixNoFlow.DrainageRaster(params=params, processes=core, tileset='10k')\n", - "FixNoFlow.DrainageRaster(params=params, processes=core, tileset='10kbis')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fd98a294-daf8-4bf8-8090-61988f8783d9", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Create virtual rasters for tiles\n", - "from fct.tileio import buildvrt\n", - "buildvrt('10k', 'drainage-raster-from-sources')\n", - "buildvrt('10kbis', 'drainage-raster-from-sources')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "014be940-2584-433e-bf83-6267b1d92add", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "FixNoFlow.NoFlowPixels(params=params, processes=core, tileset='10k')\n", - "FixNoFlow.NoFlowPixels(params=params, processes=core, tileset='10kbis')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2a68c298-cdb1-45e6-b004-550f992baf58", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "FixNoFlow.AggregateNoFlowPixels(params, tileset='10k')\n", - "FixNoFlow.AggregateNoFlowPixels(params, tileset='10kbis')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a44ed189-76f2-4726-ac5e-4b026edd69ca", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Fix NoFlow (create TARGETS shapefile and fix Flow Direction data)\n", - "FixNoFlow.FixNoFlow(params, tileset1='10k', tileset2='10kbis', fix=True)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/tutorials/02-swaths/02-swaths.py b/tutorials/02-swaths/02-swaths.py index 2776518..1fefe0d 100644 --- a/tutorials/02-swaths/02-swaths.py +++ b/tutorials/02-swaths/02-swaths.py @@ -1,122 +1,164 @@ -import glob, shutil, os +import shutil, os +from fct.config import config +from multiprocessing import cpu_count +p = cpu_count()/2 # Copy the Hydrographic Reference to outputs/GLOBAL/REFHYDRO -if not os.path.isdir('/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/REFHYDRO/'): - os.mkdir('/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/REFHYDRO/') +if not os.path.isdir(f'{config.workdir}/GLOBAL/REFHYDRO/'): + os.mkdir(f'{config.workdir}/GLOBAL/REFHYDRO/') -for f in glob.glob('./data/sdunesme/fct/tests_1m/inputs/REFERENTIEL_HYDRO.*'): - shutil.copy(f, '/data/sdunesme/fct/tests_1m/fct_workdir/GLOBAL/REFHYDRO/') +# COPY input REFHYDRO to {config.workdir}/GLOBAL/REFHYDRO/REFERENTIEL_HYDRO.shp # Shortest path exploration from fct.height import ShortestHeight params = ShortestHeight.Parameters() -params.scale_distance = 1.0 # scale distance output with given scale factor, corresponding to pixel resolution +params.dem = 'dem-drainage-resolved' # elevation raster (DEM) +#params.reference = 'network-cartography-ready' +params.mask = 'off' # 'nearest_height' height raster defining domain mask +params.scale_distance = 5.0 # scale distance output with given scale factor, corresponding to pixel resolution params.mask_height_max = 100.0 # maximum height defining domain mask params.height_max = 100.0 # stop at maximum height above reference -params.distance_min = 20.0 # minimum distance before applying stop criteria, expressed in pixels) -params.distance_max = 2000.0 # stop at maximum distance, expressed in pixels +params.distance_min = 4.0 # minimum distance before applying stop criteria, expressed in pixels) +params.distance_max = 800.0 # stop at maximum distance, expressed in pixels params.jitter = 0.4 # apply jitter on performing shortest path exploration -shutil.rmtree('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/HEIGHT/10K/SHORTEST_HEIGHT/') -ShortestHeight.ShortestHeight(params, processes=32) +if os.path.isdir(f'{config.workdir}/NETWORK/HEIGHT/DEFAULT/SHORTEST_HEIGHT/'): + shutil.rmtree(f'{config.workdir}/NETWORK/HEIGHT/DEFAULT/SHORTEST_HEIGHT/') +ShortestHeight.ShortestHeight(params, processes=p) from fct.tileio import buildvrt -buildvrt('10k', 'shortest_height') -buildvrt('10k', 'shortest_distance') -buildvrt('10k', 'shortest_state') +buildvrt('default', 'shortest_height') +buildvrt('default', 'shortest_distance') +buildvrt('default', 'shortest_state') # Height above nearest drainage from fct.height import HeightAboveNearestDrainage params = HeightAboveNearestDrainage.Parameters() +params.dem = 'dem-drainage-resolved' +params.tiles = 'shortest_tiles' +params.drainage = 'network-cartography-ready' +# params.drainage = 'refaxis' +params.mask = 'shortest_height' +params.height = 'nearest_height' +params.distance = 'nearest_distance' +params.nearest = 'nearest_drainage_axis' params.mask_height_max = 100.0 # maximum height defining domain mask params.buffer_width = 2000 # enlarge domain mask by buffer width expressed in real distance unit (eg. meters) -params.resolution = 1.0 # raster resolution, ie. pixel size, in real distance unit (eg. meters) +params.resolution = 5.0 # raster resolution, ie. pixel size, in real distance unit (eg. meters) -shutil.rmtree('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/HEIGHT/10K/NEAREST_HEIGHT/') -HeightAboveNearestDrainage.HeightAboveNearestDrainage(params, processes=20) # FATRAM NEEDED +if os.path.isdir(f'{config.workdir}/NETWORK/HEIGHT/DEFAULT/NEAREST_HEIGHT/'): + shutil.rmtree(f'{config.workdir}/NETWORK/HEIGHT/DEFAULT/NEAREST_HEIGHT/') +HeightAboveNearestDrainage.HeightAboveNearestDrainage(params, processes=p) from fct.tileio import buildvrt -buildvrt('10k', 'nearest_height') -buildvrt('10k', 'nearest_distance') -buildvrt('10k', 'nearest_drainage_axis') +buildvrt('default', 'nearest_height') +buildvrt('default', 'nearest_distance') +buildvrt('default', 'nearest_drainage_axis') # Disaggregate along refaxis from fct.measure import SwathMeasurement params = SwathMeasurement.Parameters() +# params.reference = 'network-cartography-ready' +params.reference = 'refaxis' params.mdelta = 200.0 -swaths = SwathMeasurement.DisaggregateIntoSwaths(params, processes=20) # FATRAM NEEDED +swaths = SwathMeasurement.DisaggregateIntoSwaths(params, processes=p) swaths_bounds = SwathMeasurement.WriteSwathsBounds(params, attrs=swaths) from fct.tileio import buildvrt -buildvrt('10k', 'axis_measure') -buildvrt('10k', 'axis_nearest') -buildvrt('10k', 'axis_distance') -buildvrt('10k', 'swaths_refaxis') +buildvrt('default', 'axis_measure') +buildvrt('default', 'axis_nearest') +buildvrt('default', 'axis_distance') +buildvrt('default', 'swaths_refaxis') # Swath drainage from fct.corridor import SwathDrainage params = SwathDrainage.Parameters() +params.axis = 'axis_nearest' -swath_drainage = SwathDrainage.SwathDrainage(params, processes=16) +swath_drainage = SwathDrainage.SwathDrainage(params, processes=p) SwathDrainage.WriteDrainageToDisk(swath_drainage, params) +swath_drainage = SwathDrainage.ReadDrainageFromDisk(params.output.filename()) # Valley bottom features from fct.corridor import ValleyBottomFeatures params = ValleyBottomFeatures.Parameters() +params.dem = 'dem-drainage-resolved' +params.axis = 'axis_nearest' +params.distance = 'axis_distance' +params.measure = 'axis_measure' params.height_max = 20.0 params.swath_length = 200.0 params.patch_min_pixels = 100 params.thresholds = [ # drainage area km², distance min, distance max, max height (depth), max slope (%) - ValleyBottomFeatures.ValleyBottomThreshold(0, 1.0, 50.0, 0.5, 12.0), + ValleyBottomFeatures.ValleyBottomThreshold(0, 5.0, 50.0, 0.5, 12.0), + ValleyBottomFeatures.ValleyBottomThreshold(1, 5.0, 60.0, 0.7, 11.8), + ValleyBottomFeatures.ValleyBottomThreshold(2, 5.0, 70.0, 0.9, 11.6), + ValleyBottomFeatures.ValleyBottomThreshold(3, 5.0, 80.0, 1.1, 11.4), + ValleyBottomFeatures.ValleyBottomThreshold(4, 5.0, 90.0, 1.3, 11.2), + ValleyBottomFeatures.ValleyBottomThreshold(5, 5.0, 100.0, 1.5, 11.0), + ValleyBottomFeatures.ValleyBottomThreshold(6, 5.0, 110.0, 1.7, 10.8), + ValleyBottomFeatures.ValleyBottomThreshold(7, 5.0, 120.0, 1.9, 10.6), + ValleyBottomFeatures.ValleyBottomThreshold(8, 5.0, 130.0, 2.1, 10.4), + ValleyBottomFeatures.ValleyBottomThreshold(9, 5.0, 140.0, 2.4, 10.2), + ValleyBottomFeatures.ValleyBottomThreshold(10, 10.0, 150.0, 2.6, 10.0), + ValleyBottomFeatures.ValleyBottomThreshold(11, 11.0, 160.0, 2.8, 9.8), + ValleyBottomFeatures.ValleyBottomThreshold(12, 12.0, 170.0, 3.0, 9.6), + ValleyBottomFeatures.ValleyBottomThreshold(13, 13.0, 180.0, 3.0, 9.4), + ValleyBottomFeatures.ValleyBottomThreshold(14, 14.0, 190.0, 3.0, 9.2), ValleyBottomFeatures.ValleyBottomThreshold(15, 15.0, 200.0, 3.0, 9.0), ValleyBottomFeatures.ValleyBottomThreshold(30, 20.0, 400.0, 4.0, 7.0), ValleyBottomFeatures.ValleyBottomThreshold(250, 20.0, 1500.0, 5.0, 5.0), - ValleyBottomFeatures.ValleyBottomThreshold(1000, 20.0, 2000.0, 6.0, 3.5), - ValleyBottomFeatures.ValleyBottomThreshold(5000, 20.0, 2500.0, 6.5, 3.0), - ValleyBottomFeatures.ValleyBottomThreshold(11500, 20.0, 4000.0, 7.5, 2.5), - ValleyBottomFeatures.ValleyBottomThreshold(13000, 20.0, 4000.0, 8.5, 2.5), - ValleyBottomFeatures.ValleyBottomThreshold(45000, 20.0, 7500.0, 10.5, 2.0) + ValleyBottomFeatures.ValleyBottomThreshold(1000, 20.0, 2000.0, 6.5, 3.5), + ValleyBottomFeatures.ValleyBottomThreshold(3000, 20.0, 2000.0, 7.0, 3.5), + ValleyBottomFeatures.ValleyBottomThreshold(5000, 20.0, 2500.0, 8.0, 3.0), + ValleyBottomFeatures.ValleyBottomThreshold(11500, 20.0, 4000.0, 8.5, 2.5), + ValleyBottomFeatures.ValleyBottomThreshold(13000, 20.0, 4000.0, 9.0, 2.5), + ValleyBottomFeatures.ValleyBottomThreshold(45000, 20.0, 7500.0, 14, 2.0) ] -shutil.rmtree('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/TEMP/10K/VALLEY_BOTTOM_FEATURES/') -ValleyBottomFeatures.ClassifyValleyBottomFeatures(params, swath_drainage, processes=16) + +if os.path.isdir(f'{config.workdir}/NETWORK/TEMP/DEFAULT/VALLEY_BOTTOM_FEATURES/'): + shutil.rmtree(f'{config.workdir}/NETWORK/TEMP/DEFAULT/VALLEY_BOTTOM_FEATURES/') + +ValleyBottomFeatures.ClassifyValleyBottomFeatures(params, swath_drainage, processes=p) from fct.tileio import buildvrt -buildvrt('10k', 'valley_bottom_features') -buildvrt('10k', 'slope') +buildvrt('default', 'valley_bottom_features') +buildvrt('default', 'slope') # Connected Valley bottom from fct.corridor import ValleyBottomFinal params = ValleyBottomFinal.Parameters() -params.distance_max = 2000 -params.jitter = 0.9 +params.distance = 'axis_distance' +# params.distance_max = 2000 +params.jitter = 0.4 -shutil.rmtree('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/TEMP/10K/VALLEY_BOTTOM_CONNECTED/') -shutil.rmtree('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/TEMP/10K/VALLEY_BOTTOM_DISTANCE_CONNECTED/') -ValleyBottomFinal.ConnectedValleyBottom(params, processes=16) +if os.path.isdir(f'{config.workdir}/NETWORK/TEMP/DEFAULT/VALLEY_BOTTOM_CONNECTED/'): + shutil.rmtree(f'{config.workdir}/NETWORK/TEMP/DEFAULT/VALLEY_BOTTOM_CONNECTED/') +if os.path.isdir(f'{config.workdir}/NETWORK/TEMP/DEFAULT/VALLEY_BOTTOM_DISTANCE_CONNECTED/'): + shutil.rmtree(f'{config.workdir}/NETWORK/TEMP/DEFAULT/VALLEY_BOTTOM_DISTANCE_CONNECTED/') +ValleyBottomFinal.ConnectedValleyBottom(params, processes=p) -shutil.rmtree('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/HEIGHT/10K/VALLEY_BOTTOM/') -ValleyBottomFinal.TrueValleyBottom(params, processes=16) +if os.path.isdir(f'{config.workdir}/NETWORK/HEIGHT/DEFAULT/VALLEY_BOTTOM/'): + shutil.rmtree(f'{config.workdir}/NETWORK/HEIGHT/DEFAULT/VALLEY_BOTTOM/') +ValleyBottomFinal.TrueValleyBottom(params, processes=p) from fct.tileio import buildvrt -buildvrt('10k', 'valley_bottom_final') - -# Vectorize Refaxis Swaths -from fct.measure import SwathPolygons -params = SwathPolygons.Parameters() - -swaths = SwathPolygons.Swaths(params, processes=16) -SwathPolygons.VectorizeSwaths(swaths, swath_drainage, params, processes=16) +buildvrt('default', 'valley_bottom_final') # Calculate medial axes from fct.corridor import MedialAxis2 params = MedialAxis2.Parameters() +params.swath_length = 100.0 +params.nearest = 'axis_nearest' +params.distance = 'axis_distance' medial_axis = MedialAxis2.MedialAxis(params) MedialAxis2.SimplifyMedialAxis(params, medial_axis) +medial_axis.to_dataframe(name='vbw').to_csv(f'{config.workdir}/VBW_TEMP.csv') # Disaggregate along medial axes from fct.measure import SwathMeasurement @@ -130,34 +172,43 @@ params.output_swaths_bounds = 'swaths_medialaxis_bounds' params.mdelta = 200.0 -swaths = SwathMeasurement.DisaggregateIntoSwaths(params, processes=20, tileset='default') +swaths = SwathMeasurement.DisaggregateIntoSwaths(params, processes=p, tileset='default') swaths_bounds = SwathMeasurement.WriteSwathsBounds(params, attrs=swaths) from fct.tileio import buildvrt -buildvrt('10k', 'swaths_medialaxis') +buildvrt('default', 'medialaxis_measure') +buildvrt('default', 'medialaxis_nearest') +buildvrt('default', 'medialaxis_distance') +buildvrt('default', 'swaths_medialaxis') # Swath drainage from fct.corridor import SwathDrainage params = SwathDrainage.Parameters() +params.drainage = 'acc' +params.axis = 'medialaxis_nearest' params.measure = 'medialaxis_measure' params.swath_length = 200.0 -swath_drainage = SwathDrainage.SwathDrainage(params, processes=16) +swath_drainage = SwathDrainage.SwathDrainage(params, processes=p) SwathDrainage.WriteDrainageToDisk(swath_drainage, params) +swath_drainage = SwathDrainage.ReadDrainageFromDisk(params.output.filename(tileset='default')) # Vectorize Medialaxis Swaths from fct.measure import SwathPolygons params = SwathPolygons.Parameters() +#params.nearest = 'nearest_drainage_axis' +params.nearest = 'medialaxis_nearest' +params.distance = 'medialaxis_distance' params.swaths = 'swaths_medialaxis' params.polygons = 'swaths_medialaxis_polygons' params.measure = 'medialaxis_measure' params.swath_length = 200.0 -swaths = SwathPolygons.Swaths(params, processes=16) -SwathPolygons.VectorizeSwaths(swaths, swath_drainage, params, processes=16) +swaths = SwathPolygons.Swaths(params, processes=p) +SwathPolygons.VectorizeSwaths(swaths, swath_drainage, params, processes=p) -# SimplifySwathsPolygons to get a clean vectorial output +# SimplifySwathsPolygons to get a clean vectorial outputq from fct.measure import SimplifySwathPolygons2 params = SimplifySwathPolygons2.Parameters() -SimplifySwathPolygons2.SimplifySwathPolygons(params) \ No newline at end of file +SimplifySwathPolygons2.SimplifySwathPolygons(params) diff --git a/tutorials/03-metrics/03-metrics.py b/tutorials/03-metrics/03-metrics.py index da6cb4a..e9d1bbf 100644 --- a/tutorials/03-metrics/03-metrics.py +++ b/tutorials/03-metrics/03-metrics.py @@ -1,12 +1,16 @@ +from fct.config import config +from multiprocessing import cpu_count +p = cpu_count()/2 + ###### # Random Poisson Samples from fct.measure import RandomPoissonSamples params = RandomPoissonSamples.Parameters() -RandomPoissonSamples.RandomPoissonSamples(params, processes=16) +RandomPoissonSamples.RandomPoissonSamples(params, processes=p) from fct.tileio import buildvrt -buildvrt('10k', 'poisson_samples') +buildvrt('default', 'poisson_samples') ###### # Reload swath bounds dataset @@ -18,23 +22,29 @@ # Swath Elevation Profile from fct.profiles import SwathProfile params = SwathProfile.Parameters() +params.values = 'dem-drainage-resolved' +params.nearest = 'medialaxis_nearest' +params.axis_distance = 'medialaxis_distance' params.swaths = 'swaths_medialaxis' -params.values = 'dem' params.is_continuous = True params.polygons = 'swaths_medialaxis_polygons' -swath_profiles = SwathProfile.SwathProfile(params, processes=16) -swath_profiles.to_netcdf('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/METRICS/SWATHS_ELEVATION.nc') -swath_profiles.to_dataframe().to_csv('/data/sdunesme/fct/tests_1m/fct_workdir/SWATH_ELEVATION_PROFILES.csv') +swath_profiles = SwathProfile.SwathProfile(params, processes=p) +swath_profiles.to_netcdf(f'{config.workdir}/NETWORK/METRICS/SWATHS_ELEVATION.nc') +swath_profiles.to_dataframe().to_csv(f'{config.workdir}/SWATH_ELEVATION_PROFILES.csv') + +# Reload swath_profiles if needed +import xarray as xr +swath_profiles = xr.load_dataset(f'{config.workdir}/NETWORK/METRICS/SWATHS_ELEVATION.nc') ###### # ValleyBottomWidth from fct.metrics import ValleyBottomWidth2 params = ValleyBottomWidth2.Parameters() -vbw = ValleyBottomWidth2.ValleyBottomWidth(swath_profiles.set_index(sample=('axis', 'measure', 'distance')), params, processes=16) -vbw.to_netcdf('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/METRICS/WIDTH_VALLEY_BOTTOM.nc') -vbw.to_dataframe().to_csv('/data/sdunesme/fct/tests_1m/fct_workdir/WIDTH_VALLEY_BOTTOM.csv') +vbw = ValleyBottomWidth2.ValleyBottomWidth(swath_profiles.set_index(sample=('axis', 'measure', 'distance')), params, processes=p) +vbw.to_netcdf(f'{config.workdir}/NETWORK/METRICS/WIDTH_VALLEY_BOTTOM.nc') +vbw.to_dataframe().to_csv(f'{config.workdir}/WIDTH_VALLEY_BOTTOM.csv') ###### # Valley Bottom Height @@ -47,9 +57,9 @@ params.talweg = dict(key='metrics_refaxis_points', tiled=False, subdir='NETWORK/METRICS') params.measure = 'medialaxis_measure' -river_profile = ValleyBottomHeight.ValleyBottomHeight(swath_bounds=swath_bounds, params=params, processes=16) -river_profile.to_netcdf('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/METRICS/HEIGHT_FLOODPLAIN.nc') -river_profile.to_dataframe().to_csv('/data/sdunesme/fct/tests_1m/fct_workdir/HEIGHT_FLOODPLAIN.csv') +river_profile = ValleyBottomHeight.ValleyBottomHeight(swath_bounds=swath_bounds, params=params, processes=p) +river_profile.to_netcdf(f'{config.workdir}/NETWORK/METRICS/HEIGHT_FLOODPLAIN.nc') +river_profile.to_dataframe().to_csv(f'{config.workdir}/HEIGHT_FLOODPLAIN.csv') ###### # Talweg metrics @@ -62,15 +72,15 @@ params.nearest = 'medialaxis_nearest' params.sample_distance = 10.0 -talweg_points = TalwegElevationProfile.TalwegElevation(params, processes=16) -talweg_points.to_netcdf('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/METRICS/REFAXIS_POINTS.nc') +talweg_points = TalwegElevationProfile.TalwegElevation(params, processes=p) +talweg_points.to_netcdf(f'{config.workdir}/NETWORK/METRICS/REFAXIS_POINTS.nc') swath_profiles = TalwegElevationProfile.TalwegElevationProfile(data=talweg_points, swath_bounds=swath_bounds, params=params, - processes=16) -swath_profiles.to_netcdf('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/METRICS/TALWEG_METRICS.nc') -swath_profiles.to_dataframe().to_csv('/data/sdunesme/fct/tests_1m/fct_workdir/TALWEG_METRICS.csv') + processes=p) +swath_profiles.to_netcdf(f'{config.workdir}/NETWORK/METRICS/TALWEG_METRICS.nc') +swath_profiles.to_dataframe().to_csv(f'{config.workdir}/TALWEG_METRICS.csv') ###### # LANDCOVER AND CONTINUITY ANALYSIS @@ -79,10 +89,10 @@ # Prepare the tiles and VRT from fct.cli import Tiles -Tiles.DatasourceToTiles('landcover', '10k', 'landcover-default', processes=64) +Tiles.DatasourceToTiles('landcover5m', 'default', 'landcover-default', processes=p, overwrite=True) from fct.tileio import buildvrt -buildvrt('10k', 'landcover-default') +buildvrt('default', 'landcover-default') # Extract ValleyBottom Landcover from fct.corridor import ValleyBottomLandcover @@ -90,32 +100,26 @@ params.landcover = 'landcover-default' -ValleyBottomLandcover.ValleyBottomLandcover(params, processes=64) +ValleyBottomLandcover.ValleyBottomLandcover(params, processes=p) from fct.tileio import buildvrt -buildvrt('10k', 'landcover_valley_bottom') - -# # Continuity analysis -# from fct.corridor import ContinuityAnalysisWeighted -# params = ContinuityAnalysisWeighted.Parameters() - -# ContinuityAnalysisWeighted.ContinuityAnalysisWeighted(params, processes=16) +buildvrt('default', 'landcover_valley_bottom') # Continuity analysis from fct.corridor import ContinuityAnalysisMax params = ContinuityAnalysisMax.Parameters() -ContinuityAnalysisMax.ContinuityAnalysisMax(params, processes=16) +ContinuityAnalysisMax.ContinuityAnalysisMax(params, processes=p) # Continuity remapping from fct.corridor import ContinuityAnalysisRemap params = ContinuityAnalysisRemap.Parameters() params.output = 'continuity' -ContinuityAnalysisRemap.RemapContinuityRaster(params, processes=16, tag='MAX') +ContinuityAnalysisRemap.RemapContinuityRaster(params, processes=p, tag='MAX') from fct.tileio import buildvrt -buildvrt('10k', 'continuity') +buildvrt('default', 'continuity') ### # LANDCOVER METRICS @@ -123,29 +127,47 @@ # Swath Landcover Profile from fct.profiles import SwathProfile params = SwathProfile.Parameters() -params.swaths = 'swaths_medialaxis' + params.values = 'landcover_valley_bottom' -params.is_continuous = False +params.nearest = 'medialaxis_nearest' +params.axis_distance = 'medialaxis_distance' +params.talweg_distance = 'nearest_distance' +params.swaths = 'swaths_medialaxis' params.polygons = 'swaths_medialaxis_polygons' -params.labels = {0: 'Water Channel', 1: 'Gravel Bars', 2: 'Natural Open', 3: 'Forest', 4: 'Grassland', 5: 'Crops', 6: 'Diffuse Urban', 7: 'Dense Urban', 8: 'Infrastructures'} - -swath_profiles = SwathProfile.SwathProfile(params, processes=16) -swath_profiles.to_netcdf('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/METRICS/SWATHS_LANDCOVER.nc') - -# Landcover width (TODO: Update CorridorWidth2.py) +params.output = 'swath_landcover' +params.is_continuous = False +params.swath_length = 200.0 +params.distance_delta = 10.0 +params.percentiles = None +params.labels = { + 0: 'Water Channel', + 1: 'Gravel Bars', + 2: 'Natural Open', + 3: 'Forest', + 4: 'Grassland', + 5: 'Crops', + 6: 'Diffuse Urban', + 7: 'Dense Urban', + 8: 'Infrastructures' + } + +swath_profiles = SwathProfile.SwathProfile(params, processes=p) +swath_profiles.to_netcdf(f'{config.workdir}/NETWORK/METRICS/SWATHS_LANDCOVER.nc') + +# Landcover width import xarray as xr from fct.metrics import DiscreteClassesWidth from pathlib import Path data = ( - xr.open_dataset('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/METRICS/SWATHS_LANDCOVER.nc') + xr.open_dataset(f'{config.workdir}/NETWORK/METRICS/SWATHS_LANDCOVER.nc') .set_index(sample=('axis', 'measure', 'distance')) .load() ) params = DiscreteClassesWidth.Parameters() params.resolution = 1.0 -width_landcover = DiscreteClassesWidth.DiscreteClassesWidth(data, params, processes=16) +width_landcover = DiscreteClassesWidth.DiscreteClassesWidth(data, params, processes=p) width_sum = width_landcover.sum(['label', 'side']) width_landcover['width_landcover'] = ( @@ -155,10 +177,10 @@ # width1 = area / swath_length # width2 = np.sum(data.profile / density_ref, axis=0) * distance_delta -width_landcover.to_netcdf('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/METRICS/WIDTH_LANDCOVER.nc') +width_landcover.to_netcdf(f'{config.workdir}/NETWORK/METRICS/WIDTH_LANDCOVER.nc') # Export metrics to csv -width_landcover.to_dataframe().to_csv('/data/sdunesme/fct/tests_1m/fct_workdir/WIDTH_LANDCOVER.csv') +width_landcover.to_dataframe().to_csv(f'{config.workdir}/WIDTH_LANDCOVER.csv') ### # CONTINUITY METRICS @@ -166,58 +188,51 @@ # Swath Continuity Profile from fct.profiles import SwathProfile params = SwathProfile.Parameters() -params.swaths = 'swaths_medialaxis' + params.values = 'continuity' -params.is_continuous = False +params.nearest = 'medialaxis_nearest' +params.axis_distance = 'medialaxis_distance' +params.talweg_distance = 'nearest_distance' +params.swaths = 'swaths_medialaxis' params.polygons = 'swaths_medialaxis_polygons' -params.labels = {0: 'Water Channel', 1: 'Active Channel', 10: 'Riparian Buffer', 20: 'Connected Meadows', 30: 'Connected Cultivated', 40: 'Disconnected', 50: 'Built', 255: 'No Data'} - -swath_profiles = SwathProfile.SwathProfile(params, processes=16, tag='MAX') -swath_profiles.to_netcdf('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/METRICS/SWATHS_CONTINUITY.nc') - -# Continuity width (TODO: Update CorridorWidth2.py) +params.output = 'swath_continuity' +params.is_continuous = False +params.swath_length = 200.0 +params.distance_delta = 10.0 +params.percentiles = None +params.labels = { + 0: 'Water Channel', + 1: 'Active Channel', + 10: 'Riparian Buffer', + 20: 'Connected Meadows', + 30: 'Connected Cultivated', + 40: 'Disconnected', + 50: 'Built', + 255: 'No Data'} + +swath_profiles = SwathProfile.SwathProfile(params, processes=p, tag='MAX') +swath_profiles.to_netcdf(f'{config.workdir}/NETWORK/METRICS/SWATHS_CONTINUITY.nc') + +# Continuity width import xarray as xr from fct.metrics import DiscreteClassesWidth -from pathlib import Path data = ( - xr.open_dataset('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/METRICS/SWATHS_CONTINUITY.nc') + xr.open_dataset(f'{config.workdir}/NETWORK/METRICS/SWATHS_CONTINUITY.nc') .set_index(sample=('axis', 'measure', 'distance')) .load() ) params = DiscreteClassesWidth.Parameters() params.resolution = 1.0 -width_continuity = DiscreteClassesWidth.DiscreteClassesWidth(data, params, processes=16) +width_continuity = DiscreteClassesWidth.DiscreteClassesWidth(data, params, processes=p) width_sum = width_continuity.sum(['label', 'side']) width_continuity['width_continuity'] = ( width_continuity.width2 / width_sum.width2 * width_sum.width1 ) -# width1 = area / swath_length -# width2 = np.sum(data.profile / density_ref, axis=0) * distance_delta -width_continuity.to_netcdf('/data/sdunesme/fct/tests_1m/fct_workdir/NETWORK/METRICS/WIDTH_CONTINUITY.nc') +width_continuity.to_netcdf(f'{config.workdir}/NETWORK/METRICS/WIDTH_CONTINUITY.nc') # Export metrics to csv -width_continuity.to_dataframe().to_csv('/data/sdunesme/fct/tests_1m/fct_workdir/WIDTH_CONTINUITY.csv') - -### -# PLANFORM METRICS - -from fct.planform import PlanformAxis -params = PlanformAxis.Parameters() -params.planform = 'network-cartography-ready' -params.inflection_points = 'planform_inflection_points' -params.segments = 'planform_segments' -params.amplitude_stems = 'amplitude_stems' -params.planform_axis_segments = 'planform_axis_segments' -params.planform_axis = 'planform_axis' - -params.amplitude_min = 20.0 -params.distance_max = 1000.0 -params.simplify_distance = 45.0 -params.smooth_iterations = 3 - -PlanformAxis.PlanformAxis(params) - +width_continuity.to_dataframe().to_csv(f'{config.workdir}/WIDTH_CONTINUITY.csv')