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 23 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: 0 additions & 2 deletions .env
Copy link
Collaborator

Choose a reason for hiding this comment

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

Effectivement sur Github les codes ne doivent pas être rendu publique ! Il va falloir en discuter, l'idée serait peut-être de fournir un shapefile ou geojson des données vectorielles que tu as besoin afin que quelqu'un en externe puisse également lancer le code. a discuter

Copy link
Contributor Author

Choose a reason for hiding this comment

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

J'interroge la présence de pont sur des endroits où je soupçonne qu'on peut prolonger l'eau. Ce n'est pas possible de préparer les données à l'avance, à moins de vouloir faire à chaque fois un shapefile avec tous les ponts du bloc traité

Copy link
Collaborator

Choose a reason for hiding this comment

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

Est-ce que c'est envisageable (dans une autre MR) de rendre ça plus indépendant de la base de donnée, pour que les externes puissent utiliser la BDTOPO ?

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.

Si la base de données a la même structure, c'est déjà possible de changer d'adresse de base de données dans le fichier config.

Si la base de données a une structure différente, cela veut dire que la requête est différente. Au mieux on peut peut-être rendre la requête configurable, mais cela demanderait des acrobaties étrange car il faudrait mettre dans la config des strings qui peuvent être parsées pour y injecter les valeurs utilse pour l'interrogation de la nouvelle base.

Cela me semble être un casse-tête qui ne se justifie pas car on ne va pas avoir une nouvelle base avec une nouvelle structure tous les quatre matins, c'est sans doute plus facile d'écrire les requêtes en amont pour chaque base qu'on envisage, et de rajouter un switch dans la config

Copy link
Collaborator

Choose a reason for hiding this comment

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

Et mettre la requête dans un fichier sql à part (en rendant le chemin vers le fichier paramétrable) pour que quelqu'un qui veut changer la requête puisse le faire facilement ? A quel point c'est faisable / facile ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

La difficulté principale c'est qu'il faut injecter dans la requête les coordonnées d'une ligne pour savoir si cette ligne croise un pont existant. Donc il faut en quelque sorte trouver un moyen pour rendre la requête dynamique, sans savoir par avance quelle tête elle aura.

Par exemple, voilà une partie d'une des deux requête sql qui existent :
"AND ST_Intersects(ST_Force2D(geometrie), ST_GeomFromText('[AJOUTER LIGNE ICI]'))"

On peut envisager de faire une substitution d'une chaine particulière décidée à l'avnace, par exemple [LINE ICI].
Et il faut le faire deux fois, une fois pour les ponts linéaires, une fois pour les ponts surfaciques. Donc en plus on se rajoute l'éventualité d'un nombre quelconque de requête, peut-être juste une, peut-être trois...

Et à côté de cela il faut pouvoir expliquer à l'utilisateur ce mécanisme interne pour qu'il puisse modifier sa requête en fonction des modalités de notre "dynamiqueur" pour qu'elle puisse être lu, puisque c'est lui qui au final écrira sa requête.

Dans l'exemple au-dessus, il faut que l'utilisateur ait bien compris où mettre [LINE ICI], que c'est à l'intérieur d'une parenthèse de la fonction "ST_GeomFromText" qu'il aura ajouté, et ainsi de suite.

Pour moi cela m'a tout l'air d'être une usine à gaz, et que si on veut d'autres BD il sera plus simple d'écrire nous-même une requête idoine pour chaque

Copy link
Collaborator

Choose a reason for hiding this comment

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

Effectivement... ça a pas l'air si facile finalement (j'avais pas pensé à la partie interactive). Tant pis

Copy link
Collaborator

Choose a reason for hiding this comment

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

@mdupaysign C'est bon pour toi pour la question initiale ? Normalement les codes ne sont plus là

This file was deleted.

41 changes: 21 additions & 20 deletions 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 @@ -114,22 +114,23 @@ Pour fonctionner, la création de squelettes a besoin d'une série de paramètre
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 :
SKELETON.FILE_PATH.MASK_INPUT_PATH : Le chemin d'entrée des masques des cours d'eau
SKELETON.FILE_PATH.SKELETON_LINES_OUTPUT_PATH : Le chemin de sortie des squelettes uniquement (pas de fichier de sortie si laissé à vide)
SKELETON.FILE_PATH.GAP_LINES_OUTPUT_PATH : Le chemin de sortie des lignes franchissant des ponts uniquement (pas de fichier de sortie si laissé à vide)
SKELETON.FILE_PATH.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_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
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
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
1 change: 0 additions & 1 deletion ci/test.sh

This file was deleted.

43 changes: 22 additions & 21 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,31 +53,26 @@ virtual_point:
# The number of nearest neighbors to find with KNeighbors
k: 20

SKELETON:
FILE_PATH:
MASK_INPUT_PATH:
SKELETON_LINES_OUTPUT_PATH: # only branches' skeleton (if empty, no file is created)
GAP_LINES_OUTPUT_PATH: # only new lines to close gaps (if empty, no file is created)
GLOBAL_LINES_OUTPUT_PATH: # lines from both the skeletons and the gap lines

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.
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_NAME: bduni_france_consultation
DB_HOST: bduni_consult.ign.fr
DB_USER:
DB_PASSWORD:
DB_PORT: 5432
db_uni:
db_using_db: True # if false, the DB won't be queried
leavauchier marked this conversation as resolved.
Show resolved Hide resolved
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
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
Expand Down
2 changes: 1 addition & 1 deletion data
Submodule data updated from c9398e to 19f969
33 changes: 18 additions & 15 deletions lidro/create_mask_hydro/rasters/create_mask_raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,21 @@ def create_occupancy_map(points: np.array, tile_size: int, pixel_size: float, or

def detect_hydro_by_tile(filename: str, tile_size: int, pixel_size: float, classes: List[int], dilation_size: int):
""" "Detect hydrographic surfaces in a tile from the classified points of the input pointcloud
An hydrographic surface is define as a surface where there is no points from any class different from water
The output hydrographic surface mask is dilated to make sure that the masks are continuous when merged with their neighbours
Args:
filename (str): input pointcloud
tile_size (int): size of the raster grid (in meters)
pixel_size (float): distance between each node of the raster grid (in meters)
classes (List[int]): List of classes to use for the binarisation (points with other
classification values are ignored)
dilation_size (int): size for dilatation raster
An hydrographic surface is defined as a surface where there is no points from any class different from water
The output hydrographic surface mask is dilated to make sure that the masks are continuous when merged with their
neighbours
Args:
filename (str): input pointcloud
tile_size (int): size of the raster grid (in meters)
pixel_size (float): distance between each node of the raster grid (in meters)
classes (List[int]): List of classes to use for the binarisation (points with other
classification values are ignored)
dilation_size (int): size of the structuring element for dilation

Returns:
smoothed_water (np.array): 2D binary array (x, y) of the water presence from the point cloud
pcd_origin (list): top left corner of the tile containing the point cloud
(infered from pointcloud bounding box and input tile size)
Returns:
smoothed_water (np.array): 2D binary array (x, y) of the water presence from the point cloud
pcd_origin (list): top left corner of the tile containing the point cloud
(infered from pointcloud bounding box and input tile size)
"""
# Read pointcloud, and extract coordinates (X, Y, Z, and classification) of all points
array, crs = read_pointcloud(filename)
Expand All @@ -68,6 +69,8 @@ def detect_hydro_by_tile(filename: str, tile_size: int, pixel_size: float, class
# Apply a mathematical morphology operations: DILATION
# / ! \ NOT "CLOSING", due to the reduction in the size of hydro masks (tile borders)
# / ! \ WITH "CLOSING" => Masks Hydro are no longer continuous, when they are merged
water_mask = scipy.ndimage.binary_dilation(detected_water, structure=np.ones((dilation_size, dilation_size))).astype(np.uint8)
water_mask = scipy.ndimage.binary_dilation(
detected_water, structure=np.ones((dilation_size, dilation_size))
).astype(np.uint8)

return water_mask, pcd_origin
return water_mask, pcd_origin
4 changes: 3 additions & 1 deletion lidro/create_mask_hydro/vectors/convert_to_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
from lidro.create_mask_hydro.rasters.create_mask_raster import detect_hydro_by_tile


def create_hydro_vector_mask(filename: str, output: str, pixel_size: float, tile_size: int, classes: list, crs: str, dilatation_size: int):
def create_hydro_vector_mask(
filename: str, output: str, pixel_size: float, tile_size: int, classes: list, crs: str, dilatation_size: int
):
"""Create a vector mask of hydro surfaces in a tile from the points classification of the input LAS/LAZ file,
and save it as a GeoJSON file.

Expand Down
6 changes: 5 additions & 1 deletion 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 Expand Up @@ -58,7 +61,7 @@ def main_on_one_tile(filename):
input_file = os.path.join(input_dir, filename) # path to the LAS file
output_file = os.path.join(output_dir, f"MaskHydro_{tilename}.GeoJSON") # path to the Mask Hydro file
logging.info(f"\nCreate Mask Hydro 1 for tile : {tilename}")
create_hydro_vector_mask(input_file, output_file, pixel_size, tile_size, classe, crs, dilatation_size)
create_hydro_vector_mask(input_file, output_file, pixel_size, tile_size, classe, crs, dilation_size)

if initial_las_filename:
# Lauch creating mask by one tile:
Expand All @@ -69,5 +72,6 @@ def main_on_one_tile(filename):
for file in os.listdir(input_dir):
main_on_one_tile(file)


if __name__ == "__main__":
main()
12 changes: 6 additions & 6 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
Expand Up @@ -27,7 +27,7 @@ def run(config: DictConfig):
- config (DictConfig): the config dict from hydra
"""

gdf_hydro_global_mask = gpd.read_file(config.SKELETON.FILE_PATH.MASK_INPUT_PATH)
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)
Expand All @@ -37,8 +37,8 @@ def run(config: DictConfig):
# 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.SKELETON.FILE_PATH.GAP_LINES_OUTPUT_PATH and validated_candidates:
gdf_gap_lines.to_file(config.SKELETON.FILE_PATH.GAP_LINES_OUTPUT_PATH, driver='GeoJSON')
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"
Expand All @@ -55,13 +55,13 @@ def run(config: DictConfig):
# 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.SKELETON.FILE_PATH.GAP_LINES_OUTPUT_PATH:
gdf_branch_lines.to_file(config.SKELETON.FILE_PATH.SKELETON_LINES_OUTPUT_PATH, driver='GeoJSON')
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.SKELETON.FILE_PATH.GLOBAL_LINES_OUTPUT_PATH, driver='GeoJSON')
gdf_global_lines.to_file(config.io.skeleton.global_lines_output_path, driver='GeoJSON')


if __name__ == "__main__":
Expand Down
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
4 changes: 2 additions & 2 deletions lidro/merge_mask_hydro/vectors/close_holes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from shapely.ops import unary_union


def close_holes(polygon: Polygon, min_hole_area):
def close_holes(polygon: Polygon, min_hole_area)-> Polygon:
"""Remove small holes (surface < 100 m²)

Args:
Expand All @@ -26,4 +26,4 @@ def close_holes(polygon: Polygon, min_hole_area):
shell=polygon.exterior, holes=interior_holes_filter)


return final_polygon
return final_polygon
Loading