Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skeleton #9

Closed
wants to merge 69 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
dd2f342
skeleton fixed
MichelDaab May 15, 2024
271836c
before pruning lines
MichelDaab May 21, 2024
75cc05a
works but too slow
MichelDaab May 27, 2024
59bd099
save before creation of the Branch class
MichelDaab May 31, 2024
4265cf0
Intermediary commit
MichelDaab Jun 21, 2024
1feaf72
acceptable result
MichelDaab Jun 21, 2024
e7a11c0
gap closed from mask
MichelDaab Jun 25, 2024
822403b
closing gaps by proximity to mask
MichelDaab Jun 25, 2024
25fe0c1
whole skeleton process works, no test yet
MichelDaab Jun 28, 2024
d64bb34
Clean version to create skeleton,
MichelDaab Jul 2, 2024
e69c9a5
forget to remove a line
MichelDaab Jul 2, 2024
bfc4969
Change to add DB credentials as GITHUB secrets
MichelDaab Jul 3, 2024
316a8c7
add dot_env for local variables (like passwords)
MichelDaab Jul 3, 2024
c7e24ca
unittesting for git action
MichelDaab Jul 3, 2024
f29eb49
change gitignore
MichelDaab Jul 3, 2024
26f16e5
fix typo for credentials in ci.yaml
MichelDaab Jul 3, 2024
9a77787
Some corrections following PR comments
MichelDaab Jul 3, 2024
d16339c
Refacto README, Dockerfile and test
mdupaysign Apr 26, 2024
275b5d1
Fix readme layout
leavauchier Apr 29, 2024
8208f0d
Update lidro/create_mask_hydro/rasters/create_mask_raster.py
mdupaysign Apr 29, 2024
8ec7df3
Update lidro/create_mask_hydro/rasters/create_mask_raster.py
mdupaysign Apr 29, 2024
6172944
Update create_mask_raster.py
mdupaysign Apr 29, 2024
126798a
Update lidro/create_mask_hydro/rasters/create_mask_raster.py
mdupaysign Apr 29, 2024
f2f67cf
update main_merge_mask.py
mdupaysign May 6, 2024
690461a
refacto with Lea
mdupaysign May 14, 2024
8e09393
manual correction for rebase
MichelDaab Jul 25, 2024
6c9ad27
move main_skeleton into lidro
MichelDaab Jul 26, 2024
7a523c0
merge skeleton lines at the end
MichelDaab Jul 26, 2024
e578b35
fix final merge lines
MichelDaab Jul 26, 2024
162992e
adding some tests
MichelDaab Jul 26, 2024
973e3be
remove launch.json
MichelDaab Jul 26, 2024
400e84d
better path (...maybe ???)
MichelDaab Jul 26, 2024
e9bc6a0
specify the WATER_MIN_SIZE parameter
MichelDaab Jul 29, 2024
f6f8aa1
more explanation for WATER_MIN_SIZE parameter
MichelDaab Jul 29, 2024
6a50fd5
To create skeleton lines, we only care
MichelDaab Jul 29, 2024
6cc70f6
fix to tests to match the changes of
MichelDaab Jul 29, 2024
4154e7d
small fix in case there is no bridge
MichelDaab Jul 30, 2024
8cf1c15
fix a rare case
MichelDaab Aug 1, 2024
fc9925f
change request to database to be sligthly faster
MichelDaab Aug 1, 2024
74e5627
add a test for the db query, only played
MichelDaab Aug 1, 2024
90dd93b
Merge branch 'dev' into skeleton
MichelDaab Aug 2, 2024
a2b2ca8
adding an example for create skeleton lines
MichelDaab Aug 2, 2024
5677001
removed a forgotten comment
MichelDaab Aug 2, 2024
5d7230f
changes according to Palvina's code review
MichelDaab Aug 5, 2024
5331b8a
removing files coming from God knows where
MichelDaab Aug 8, 2024
7c09772
removing .env
MichelDaab Aug 9, 2024
7c69a40
adding "null" to some config values to be consistent
MichelDaab Aug 12, 2024
2fe5a40
add null to config str to be consistent
MichelDaab Aug 12, 2024
ca9c0b9
a strange case of problem with git merge,
MichelDaab Aug 12, 2024
edc195b
moved the "make valid" at the beginning,
MichelDaab Aug 12, 2024
80f3c41
removed an unnecessary copy
MichelDaab Aug 12, 2024
76487b7
removed a typo and a log file that has no
MichelDaab Aug 12, 2024
eaeb81b
Set the UPPERCASE of configs to lowercase
MichelDaab Aug 13, 2024
8e9bda8
changes to code from dev that have been
MichelDaab Aug 13, 2024
77d99a0
Update of the readme.md for the location of
MichelDaab Aug 13, 2024
7e2c66d
get the right submodule data
MichelDaab Aug 13, 2024
d9b9f7d
removing "ci" directory, that has no business
MichelDaab Aug 14, 2024
58c64fc
changing test name to be more explicit
MichelDaab Aug 14, 2024
04521c3
correction of a modification on
MichelDaab Aug 14, 2024
34684de
add a test to branch
MichelDaab Aug 19, 2024
ac91fa1
revert some changes that a misuse of git created
MichelDaab Aug 19, 2024
89e7085
fix a typo
MichelDaab Aug 20, 2024
86e4050
fix a previous unwanted change
MichelDaab Aug 20, 2024
ef1aa3e
fix another unwanted change
MichelDaab Aug 20, 2024
f94c7ee
changes so all submodules can be run with
MichelDaab Aug 21, 2024
d977f10
moving input/ouptut files from skeleton.filepth to
MichelDaab Aug 21, 2024
a0870d0
Add the possibility to disable db connection
MichelDaab Aug 21, 2024
109f43f
Add another test to branch
MichelDaab Aug 21, 2024
1130aef
add small comment about db_using_db
MichelDaab Aug 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env_example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DB_UNI_USER='TO_BE_DEFINED'
DB_UNI_PASSWORD='TO_BE_DEFINED'
7 changes: 5 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,8 @@ jobs:
generate-run-shell: true
- name: Unit test
shell: micromamba-shell {0}
run: python -m pytest -s --log-cli-level DEBUG

run: |
leavauchier marked this conversation as resolved.
Show resolved Hide resolved
cp .env_example .env
sed -i "s/DB_UNI_USER='TO_BE_DEFINED'/DB_UNI_USER=${{ secrets.DB_UNI_USER }}/g" .env
sed -i "s/DB_UNI_PASSWORD='TO_BE_DEFINED'/DB_UNI_PASSWORD=${{ secrets.DB_UNI_PASSWORD }}/g" .env
python -m pytest -s --log-cli-level DEBUG
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
**/__pycache__
tmp
**.log
**.log

.env

outputs/
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pre-commit install
```

## Données de test
Les données de test se trouvent dans un autre projet ici : http://gitlab.forge-idi.ign.fr/Lidar/lidro-data
Les données de test se trouvent dans un autre projet ici : https://github.com/IGNF/lidro-data

Ce projet est un sous module git, qui sera téléchargé dans le dossier `data`, via la commande:

Expand Down Expand Up @@ -108,3 +108,29 @@ Pour lancer les tests :
```
python -m pytest -s
```
### paramètres pour créer les squelettes des cours d'eau
Pour fonctionner, la création de squelettes a besoin d'une série de paramètres, certains ayant une valeur par défaut, d'autres non. Les paramètres se trouvent dans le fichier configs/configs_lidro.yaml. On peut soit les y modifier, soit les modifer en ligne de commande lors de l'exécution du script avec :
```
python lidro/main_create_skeleton_lines.py [nom_paramètre_1]=[valeur_du_paramètre_1] [nom_paramètre_2]=[valeur_du_paramètre_2]
```
ces paramètres sont :
io.skeleton.mask_input_path : Le chemin d'entrée des masques des cours d'eau
io.skeleton.skeleton_lines_output_path : Le chemin de sortie des squelettes uniquement (pas de fichier de sortie si laissé à vide)
io.skeleton.gap_lines_output_path : Le chemin de sortie des lignes franchissant des ponts uniquement (pas de fichier de sortie si laissé à vide)
io.skeleton.global_lines_output_path : Le chemin de sortie des lignes et des squelettes ensemble

skeleton.max_gap_width : La distance maximale envisagée pour franchir des ponts
skeleton.max_bridges : Le nombre maximal de ponts entre deux bras séparés de cours d'eau
skeleton.gap_width_check_db : La distance à partir de laquelle on vérifie via la base de données s'il y a bien un pont
skeleton.ratio_gap : la proportion de la ligne franchissant un pont qui est comparé en base pour voir s'il y a bien un pont (trop grande et on pourrait trouver un pont qui ne correspond pas)

skeleton.db_uni.db_using_db : # Si à faux, la base de données ne sera pas utilisée (prévu pour être utilisé que s'il n'y pas d'accès à la base de données)
skeleton.db_uni.db_name : Le nom de la base de données
skeleton.db_uni.db_host : l'adresse de la base de données
skeleton.db_uni.db_user : L'utilisateur de la base de données
skeleton.db_uni.db_password : Le mot de passe de l'utilisateur
skeleton.db_uni.db_port : La port de connexion avec la base de données

skeleton.branch.voronoi_max_length : LA longuer maximum des lignes individuelles des squelettes
skeleton.branch.water_min_size : La longueur minimal à partir de laquelle une ligne de squelette sera automatiquement gardée (trop petite, et il y aura des sortes "d'aiguilles" qui apparaitront. Trop grande, et certains afluents ne seront pas détectés)
skeleton.branch.max_gap_candidates : Le nombre maximum de candidats pour envisager de franchir des ponts entre deux bras
27 changes: 27 additions & 0 deletions configs/configs_lidro.yaml
MichelDaab marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ io:
no_data_value: -9999
tile_size: 1000

skeleton:
mask_input_path: null
skeleton_lines_output_path: null # only branches' skeleton (if empty, no file is created)
gap_lines_output_path: null # only new lines to close gaps (if empty, no file is created)
global_lines_output_path: null # lines from both the skeletons and the gap lines

mask_generation:
raster:
# size for dilatation
Expand Down Expand Up @@ -47,6 +53,27 @@ virtual_point:
# The number of nearest neighbors to find with KNeighbors
k: 20

skeleton:
max_gap_width: 200 # distance max in meter of any gap between 2 branches we will try to close with a line
max_bridges: 1 # number max of bridges that can be created between 2 branches
gap_width_check_db: 20 # for a gap at least this wide, we check with db_uni if there is a bridge. Smaller than that, we assume a line automatically exists
ratio_gap: 0.25 # when checking if a candidate line to close a gap intersects a bridge in BD UNI, that's the ratio ]0.1] of the line to consider.
# we only check part of the line, because when the line is really long it can intersect with bridges not corresponding to that line,
# so we make the line smaller

db_uni:
db_using_db: True # if false, the DB won't be queried (expected to be used only in case you don't have access to the database)
db_name: bduni_france_consultation
db_host: bduni_consult.ign.fr
db_user: null
db_password: null
db_port: 5432

branch:
voronoi_max_length: 2 # max size of a voronoi line
water_min_size: 500 # min size of a skeleton line to be sure not to be removed (should be at least more than half the max river width)
max_gap_candidates: 3 # max number of candidates to close a gap between 2 branches

hydra:
output_subdir: null
run:
Expand Down
2 changes: 1 addition & 1 deletion data
Submodule data updated from c9398e to 19f969
2 changes: 2 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ dependencies:
- pdal>=2.6
- python-pdal>=3.2.1
- shapely>=2.0.3
- psycopg[binary]
- python-dotenv
# --------- hydra configs --------- #
- hydra-core
- hydra-colorlog
Expand Down
2 changes: 1 addition & 1 deletion lidro/create_mask_hydro/rasters/create_mask_raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,4 @@ def detect_hydro_by_tile(filename: str, tile_size: int, pixel_size: float, class
detected_water, structure=np.ones((dilation_size, dilation_size))
).astype(np.uint8)

return water_mask, pcd_origin
return water_mask, pcd_origin
3 changes: 3 additions & 0 deletions lidro/main_create_mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@

import logging
import os
import sys

import hydra
from omegaconf import DictConfig
from pyproj import CRS

sys.path.append('../lidro')

from lidro.create_mask_hydro.vectors.convert_to_vector import create_hydro_vector_mask


Expand Down
68 changes: 68 additions & 0 deletions lidro/main_create_skeleton_lines.py
leavauchier marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
""" Main script for creating skeleton lines inside masks
"""
import sys

import hydra
from omegaconf import DictConfig

import geopandas as gpd
import pandas as pd
from shapely.geometry import Point

sys.path.append('../lidro')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pourquoi rajouter cette ligne ?

Jusqu'ici on faisait sans, notamment en exécutant les fichiers main_*** de cette façon : python -m lidro.main_***
Pour la cohérence avec le reste, je préfèrerais qu'on garde le même fonctionnement partout

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

up

This comment was marked as resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

De mémoire c'est pour pytest, que je lance d'habitude avec "pytest" et non avec "python -m pytest".
Personnellement j'ai une nette tendance à préférer du code qui peut être lancé sans et avec le flag "-m" que d'avoir du code qui l'impose, d'autant que son utilité n'est pas limpide, j'ai dû chercher un bon moment sur google pour trouver des exemples de son utilité, et ça tourne autour de chemin d'install des librairies

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dans ce cas, estèce que tu peux le mettre partout où il y en a besoin ? (aussi dans le code de Malvina, pour que tout puisse se lancer de la même façon)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fait, il y a cependant 2 modules qui ne passent pas chez moi, que cela soit sans ou avec le flag (quand c'est avec, j'utilise l'exemple donné dans les batch)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lesquels ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Il y a juste "lidro.main_create_virtual_point" qui ne passe pas, les autres sont des exemples du même.
Cela me dit qu'il ne voit pas un fichier qui existe pourtant bien au chemin qu'il dit chercher


from lidro.skeleton.create_skeleton_lines import create_branches_list, create_branches_pair, select_candidates
from lidro.skeleton.branch import Branch, line_merge


@hydra.main(version_base="1.2", config_path="../configs/", config_name="configs_lidro.yaml")
def run(config: DictConfig):
"""
Get whole hydrographic skeleton lines, based on
a geojson file containing multiple river contours.
The result file will contain "skeleton" lines running in the middle of
those contours to describe the flow of the rivers, and lines crossing the contours
to join with the skeleton lines, as bridge and other elements may "break" river contours
args:
- config (DictConfig): the config dict from hydra
"""

gdf_hydro_global_mask = gpd.read_file(config.io.skeleton.mask_input_path)
crs = gdf_hydro_global_mask.crs # Load a crs from input

branches_list = create_branches_list(config, gdf_hydro_global_mask, crs)
branches_pair_list = create_branches_pair(config, branches_list)
validated_candidates = select_candidates(config, branches_pair_list)

# create the gap lines from the selected candidates
gap_lines_list = [validated_candidate.line for validated_candidate in validated_candidates]
gdf_gap_lines = gpd.GeoDataFrame(geometry=gap_lines_list).set_crs(crs, allow_override=True)
if config.io.skeleton.gap_lines_output_path and validated_candidates:
gdf_gap_lines.to_file(config.io.skeleton.gap_lines_output_path, driver='GeoJSON')

# add the extremities used on each branch to close a gap to the list of gap_point of that branch,
# to create a new line toward that extremity and know not to remove it during the "simplify"
for candidate in validated_candidates:
candidate.branch_1.gap_points.append(Point(candidate.extremity_1))
candidate.branch_2.gap_points.append(Point(candidate.extremity_2))

# get skeletons for all branches
for branch in branches_list:
branch: Branch
branch.create_skeleton()
branch.simplify()

# putting all skeleton lines together, and save them if there is a path
branch_lines_list = [branch.gdf_skeleton_lines for branch in branches_list]
gdf_branch_lines = gpd.GeoDataFrame(pd.concat(branch_lines_list, ignore_index=True))
if config.io.skeleton.skeleton_lines_output_path:
gdf_branch_lines.to_file(config.io.skeleton.skeleton_lines_output_path, driver='GeoJSON')

# saving all lines
gdf_global_lines = gpd.GeoDataFrame(pd.concat([gdf_branch_lines, gdf_gap_lines], ignore_index=True))
gdf_global_lines = line_merge(gdf_global_lines, crs) # merge lines into polylines
gdf_global_lines.to_file(config.io.skeleton.global_lines_output_path, driver='GeoJSON')


if __name__ == "__main__":
run()
3 changes: 3 additions & 0 deletions lidro/main_create_virtual_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@

import logging
import os
import sys

import geopandas as gpd
import hydra
import pandas as pd
from omegaconf import DictConfig
from pyproj import CRS

sys.path.append('../lidro')

from lidro.create_virtual_point.vectors.extract_points_around_skeleton import (
extract_points_around_skeleton_points_one_tile,
)
Expand Down
3 changes: 3 additions & 0 deletions lidro/main_merge_mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@

import logging
import os
import sys

import hydra
from omegaconf import DictConfig
from pyproj import CRS

sys.path.append('../lidro')

from lidro.merge_mask_hydro.vectors.merge_vector import merge_geom


Expand Down
2 changes: 1 addition & 1 deletion lidro/merge_mask_hydro/vectors/close_holes.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ def close_holes(polygon: Polygon, min_hole_area)-> Polygon:
shell=polygon.exterior, holes=interior_holes_filter)


return final_polygon
return final_polygon
Empty file added lidro/skeleton/__init__.py
Empty file.
Loading