-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add search radius plugin fix environment test ci fix compil windows radius_search : remove dimRange and use special attributes fix cmakelist * Add possibility to restrict the cylinder with 2D serach * fix test * why this break ?!! * fix find cell * change name of attribute * add pdal pipeline examples * update test * update DockerFile * add pip to environment.yml Co-authored-by: leavauchier <[email protected]> * Update macro/ex_filtering_points.py update parser help Co-authored-by: leavauchier <[email protected]> * Update src/filter_radius_search/radius_searchFilter.cpp Co-authored-by: leavauchier <[email protected]> * update exemple * no more shapely + fix test * add pre-commit * update test : 3 tests indeed one * update test_radius_search * add test to grid_decimation * Update doc/grid_radius_search.md Co-authored-by: leavauchier <[email protected]> * filter search => assign * update name attribute * update class name * update name attribute * fix equality * fix : name, orthograph, ... * update nom attributes * floor => ceil * update macro * deprectated grid_decimation * fix test * fix doc * update readme * fix readme * add comment to example + try to recode example * V.0 script example * update macro orthogaph * fix script orthograph * maj nom attributs * fix doc code * fix test * fix test * Update doc/radius_assign.md Co-authored-by: leavauchier <[email protected]> * fix doc + rename file * gridDecimation : modification du type de sortie * update example * example - fix write gdal * grid_decimation to deprecated * attribut => dimension * update docker --------- Co-authored-by: leavauchier <[email protected]>
- Loading branch information
1 parent
02d974f
commit 139a137
Showing
22 changed files
with
725 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
xcode | ||
install | ||
__pycache__ | ||
test/__pycache__ | ||
test/__pycache_ | ||
test/.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
repos: | ||
- repo: https://github.com/ambv/black | ||
rev: 23.12.0 | ||
hooks: | ||
- id: black | ||
language_version: python3.11 | ||
- repo: https://github.com/pycqa/flake8 | ||
rev: 6.1.0 | ||
hooks: | ||
- id: flake8 | ||
- repo: https://github.com/pycqa/isort | ||
rev: 5.13.2 | ||
hooks: | ||
- id: isort | ||
name: isort (python) | ||
args: ["--profile", "black"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# filter radius assign | ||
|
||
Purpose | ||
--------------------------------------------------------------------------------------------------------- | ||
|
||
The **radius assign filter** overwrites the output_dimension_ dimension with boolean values: | ||
* 1 if the point has any neighbor with a distance lower than radius_ that belongs to the domain reference_domain_ | ||
* 0 otherwise. | ||
|
||
|
||
Example | ||
--------------------------------------------------------------------------------------------------------- | ||
|
||
This pipeline updates the Keypoint dimension of all points with classification 1 to 2 (unclassified and ground) that are closer than 1 meter from a point with classification 6 (building) | ||
|
||
|
||
``` | ||
[ | ||
"file-input.las", | ||
{ | ||
"type" : "filters.radius_assign", | ||
"src_domain" : "Classification[1:2]", | ||
"reference_domain" : "Classification[6:6]", | ||
"radius" : 1, | ||
"output_dimension": "radius", | ||
"is3d": True | ||
}, | ||
"output.las" | ||
] | ||
``` | ||
|
||
Options | ||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ||
|
||
**src_domain** : | ||
A :ref:`range <ranges>` which selects points to be processed by the filter. Can be specified multiple times. Points satisfying any range will be processed | ||
|
||
**reference_domain** : | ||
A :ref:`range <ranges>` which selects points that can are considered as potential neighbors. Can be specified multiple times. | ||
|
||
**radius** : | ||
An positive float which specifies the radius for the neighbors search. | ||
|
||
**output_dimension**: The name of the new dimension'. [Default: radius] | ||
|
||
**is3d**: Search in 3d (as a ball). [Default: false] | ||
|
||
**max2d_above**: If search in 2d : upward maximum distance in Z for potential neighbors (corresponds to a search in a cylinder with a height = max2d_above above the source point). Default (0) = infinite height [Default: 0.] | ||
|
||
**max2d_below**: If search in 2d : upward maximum distance in Z for potential neighbors (corresponds to a search in a cylinder with a height = max2d_below below the source point). Default (0) = infinite height [Default: 0.] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,19 @@ | ||
name: pdal_ign_plugin | ||
channels: | ||
- conda-forge | ||
- anaconda | ||
dependencies: | ||
- pdal | ||
- python-pdal | ||
- gdal | ||
# --------- dev dep --------- # | ||
- cmake | ||
- pre-commit # hooks for applying linters on commit | ||
- black # code formatting | ||
- isort # import sorting | ||
- flake8 # code analysis | ||
- pytest | ||
- black | ||
- isort | ||
- shapely | ||
# --------- pip & pip librairies --------- # | ||
- pip | ||
- pip: | ||
- ign-pdal-tools | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,13 @@ | ||
name: pdal_ign_plugin | ||
channels: | ||
- conda-forge | ||
- anaconda | ||
dependencies: | ||
- pdal | ||
- python-pdal | ||
- gdal | ||
# --------- pip & pip librairies --------- # | ||
- pip | ||
- pip: | ||
- ign-pdal-tools | ||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import argparse | ||
import pdal | ||
import macro | ||
|
||
""" | ||
This tool shows how to use functions of macro in a pdal pipeline | ||
""" | ||
|
||
def parse_args(): | ||
parser = argparse.ArgumentParser("Tool to apply pdal pipelines for DSM and DTM calculation") | ||
parser.add_argument("--input", "-i", type=str, required=True, help="Input las file") | ||
parser.add_argument("--output_las", "-o", type=str, required=True, help="Output cloud las file") | ||
parser.add_argument("--output_dsm", "-s", type=str, required=True, help="Output dsm tiff file") | ||
parser.add_argument("--output_dtm", "-t", type=str, required=True, help="Output dtm tiff file") | ||
return parser.parse_args() | ||
|
||
|
||
if __name__ == "__main__": | ||
args = parse_args() | ||
|
||
pipeline = pdal.Reader.las(args.input) | ||
|
||
## 1 - recherche des points max de végétation (4,5) sur une grille régulière, avec prise en compte des points sol (2) et basse | ||
## vegetation (3) proche de la végétation : on les affecte en 100 | ||
|
||
# bouche trou : assigne les points sol en 102 à l'intérieur de la veget (4,5) | ||
pipeline = macro.add_radius_assign(pipeline, 1, False, condition_src="Classification==2", condition_ref=macro.build_condition("Classification", [4,5]), condition_out="Classification=102") | ||
pipeline = macro.add_radius_assign(pipeline, 1, False, condition_src="Classification==102", condition_ref="Classification==2", condition_out="Classification=2") | ||
|
||
# selection des points de veget basse proche de la veget haute : assigne 103 | ||
pipeline = macro.add_radius_assign(pipeline, 1, False, condition_src="Classification==3", condition_ref="Classification==5", condition_out="Classification=103") | ||
|
||
# max des points de veget (et surement veget - 102,103) sur une grille régulière : assigne 100 | ||
pipeline |= pdal.Filter.gridDecimation(resolution=0.75, value="Classification=100", output_type="max", where=macro.build_condition("Classification", [4,5,102,103])) | ||
|
||
# remise à zero des codes 102 et 103 | ||
pipeline |= pdal.Filter.assign(value="Classification=2", where="Classification==102") | ||
pipeline |= pdal.Filter.assign(value="Classification=3", where="Classification==103") | ||
|
||
## 2 - sélection des points pour DTM et DSM | ||
|
||
# selection de points sol (max) sur une grille régulière | ||
pipeline |= pdal.Filter.gridDecimation(resolution=0.5, value="Classification=102", output_type="max", where="Classification==2") | ||
|
||
# selection de points DSM (max) sur une grille régulière | ||
pipeline |= pdal.Filter.gridDecimation(resolution=0.5, value="Classification=200", output_type="max", where=macro.build_condition("Classification", [2,3,4,5,6,9,17,64,100])) | ||
|
||
# assigne des points sol sélectionnés (102) en 100 : les points proches de la végaétation, des ponts, de l'eau et 64 | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="Classification==102", | ||
condition_ref=macro.build_condition("Classification", [4,5,6,9,17,64,100]), condition_out="Classification=100") | ||
|
||
# remise à zero du code 102 | ||
pipeline |= pdal.Filter.assign(value="Classification=2", where="Classification==102") | ||
|
||
## 3 - gestion des ponts | ||
|
||
|
||
|
||
# bouche trou : on élimine les points sol (2) au milieu du pont en les mettant à 102 | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="Classification==2", condition_ref="Classification==17", condition_out="Classification=102") | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="Classification==102", | ||
condition_ref=macro.build_condition("Classification", [2,3,4,5]), condition_out="Classification=2") | ||
|
||
# bouche trou : on élimine les points basse végétation (3) au milieu du pont en les mettant à 103 | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="Classification==3", condition_ref="Classification==17", condition_out="Classification=103") | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="Classification==103", | ||
condition_ref=macro.build_condition("Classification", [2,3,4,5]), condition_out="Classification=3") | ||
|
||
# bouche trou : on élimine les points moyenne végétation (4) au milieu du pont en les mettant à 104 | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="Classification==4", condition_ref="Classification==17", condition_out="Classification=104") | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="Classification==104", | ||
condition_ref=macro.build_condition("Classification", [2,3,4,5]), condition_out="Classification=4") | ||
|
||
# bouche trou : on élimine les points haute végétation (5) au milieu du pont en les mettant à 105 | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="Classification==5", condition_ref="Classification==17", condition_out="Classification=105") | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="Classification==105", | ||
condition_ref=macro.build_condition("Classification", [2,3,4,5]), condition_out="Classification=5") | ||
|
||
# bouche trou : on élimine les points eau (9) au milieu du pont en les mettant à 109 | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="Classification==9", condition_ref="Classification==17", condition_out="Classification=109") | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="Classification==109", | ||
condition_ref="Classification==9", condition_out="Classification=9") | ||
|
||
# step 15 et supression des points ?? | ||
|
||
# 4 - export du nuage | ||
pipeline |= pdal.Writer.las(extra_dims="all",forward="all",filename=args.output_las) | ||
|
||
# export des DSM/DTM | ||
pipeline |= pdal.Writer.gdal(gdaldriver="GTiff", output_type="max", resolution=2.0, filename=args.output_dtm, where=macro.build_condition("Classification", [2,66])) | ||
pipeline |= pdal.Writer.gdal(gdaldriver="GTiff", output_type="max", resolution=2.0, filename=args.output_dsm, where=macro.build_condition("Classification", [2,3,4,5,17,64])) | ||
|
||
pipeline.execute() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import argparse | ||
import pdal | ||
import macro | ||
|
||
""" | ||
This tool shows how to use functions of macro in a pdal pipeline | ||
""" | ||
|
||
def parse_args(): | ||
parser = argparse.ArgumentParser("Tool to apply pdal pipelines for DSM and DTM calculation (with add dimensions for the concerned points)") | ||
parser.add_argument("--input", "-i", type=str, required=True, help="Input las file") | ||
parser.add_argument("--output_las", "-o", type=str, required=True, help="Output cloud las file") | ||
parser.add_argument("--output_dsm", "-s", type=str, required=True, help="Output dsm tiff file") | ||
parser.add_argument("--output_dtm", "-t", type=str, required=True, help="Output dtm tiff file") | ||
return parser.parse_args() | ||
|
||
|
||
if __name__ == "__main__": | ||
args = parse_args() | ||
|
||
pipeline = pdal.Reader.las(args.input) | ||
|
||
# 0 - ajout de dimensions temporaires | ||
pipeline |= pdal.Filter.ferry(dimensions=f"=>PT_GRID_DSM, =>PT_VEG_DSM, =>PT_GRID_DTM, =>PT_ON_BRIDGE") | ||
|
||
|
||
## 1 - recherche des points max de végétation (4,5) sur une grille régulière, avec prise en compte des points sol (2) et basse | ||
## vegetation (3) proche de la végétation | ||
## pour le calcul du DSM | ||
|
||
pipeline |= pdal.Filter.assign(value=["PT_VEG_DSM = 1 WHERE " + macro.build_condition("Classification", [4,5])]) | ||
|
||
# bouche trou : assigne les points sol à l'intérieur de la veget (4,5) | ||
pipeline = macro.add_radius_assign(pipeline, 1, False, condition_src="Classification==2", condition_ref=macro.build_condition("Classification", [4,5]), condition_out="PT_VEG_DSM=1") | ||
pipeline = macro.add_radius_assign(pipeline, 1, False, condition_src="PT_VEG_DSM==1 && Classification==2", condition_ref="Classification==2", condition_out="PT_VEG_DSM=0") | ||
|
||
# selection des points de veget basse proche de la veget haute | ||
pipeline = macro.add_radius_assign(pipeline, 1, False, condition_src="Classification==3", condition_ref="Classification==5", condition_out="PT_VEG_DSM=1") | ||
|
||
# max des points de veget (PT_VEG_DSM==1) sur une grille régulière : | ||
pipeline |= pdal.Filter.gridDecimation(resolution=0.75, value="PT_GRID_DSM=1", output_type="max", where="PT_VEG_DSM==1") | ||
|
||
|
||
## 2 - sélection des points pour DTM et DSM | ||
|
||
# selection de points DTM (max) sur une grille régulière | ||
pipeline |= pdal.Filter.gridDecimation(resolution=0.5, value="PT_GRID_DTM=1", output_type="max", where="Classification==2") | ||
|
||
# selection de points DSM (max) sur une grille régulière | ||
pipeline |= pdal.Filter.gridDecimation(resolution=0.5, value="PT_GRID_DSM=1", output_type="max", | ||
where="(" + macro.build_condition("Classification", [6,9,17,64]) + ") || PT_GRID_DSM==1") | ||
|
||
# assigne des points sol sélectionnés : les points proches de la végétation, des ponts, de l'eau, 64 | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="PT_GRID_DTM==1", | ||
condition_ref=macro.build_condition("Classification", [4,5,6,9,17,64]), | ||
condition_out="PT_GRID_DSM=1") | ||
|
||
|
||
## 3 - gestion des ponts | ||
# bouche trou : on filtre les points (2,3,4,5,9) au milieu du pont en les mettant à PT_ON_BRIDGE=1 | ||
|
||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src=macro.build_condition("Classification", [2,3,4,5,9]), condition_ref="Classification==17", condition_out="PT_ON_BRIDGE=1") | ||
pipeline = macro.add_radius_assign(pipeline, 1.5, False, condition_src="PT_ON_BRIDGE==1", | ||
condition_ref=macro.build_condition("Classification", [2,3,4,5]), condition_out="PT_ON_BRIDGE=0") | ||
pipeline |= pdal.Filter.assign(value=["PT_GRID_DSM=0 WHERE PT_ON_BRIDGE==1"]) | ||
|
||
|
||
## 4 - point pour DTM servent au DSM également | ||
pipeline |= pdal.Filter.assign(value=["PT_GRID_DSM=1 WHERE PT_GRID_DTM==1"]) | ||
|
||
## 5 - export du nuage et des DSM | ||
|
||
pipeline |= pdal.Writer.las(extra_dims="all", forward="all", filename=args.output_las) | ||
pipeline |= pdal.Writer.gdal(gdaldriver="GTiff", output_type="max", resolution=2.0, filename=args.output_dtm, where="PT_GRID_DTM==1") | ||
pipeline |= pdal.Writer.gdal(gdaldriver="GTiff", output_type="max", resolution=2.0, filename=args.output_dsm, where="PT_GRID_DSM==1") | ||
|
||
pipeline.execute() | ||
|
Oops, something went wrong.