wolfhece 2.1.125__py3-none-any.whl → 2.1.127__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wolfhece/PyConfig.py +77 -4
- wolfhece/PyDraw.py +717 -11
- wolfhece/PyVertexvectors.py +33 -1
- wolfhece/apps/version.py +1 -1
- wolfhece/eikonal.py +495 -0
- wolfhece/lazviewer/laz_viewer.py +133 -23
- wolfhece/math_parser/calculator.py +1 -1
- wolfhece/scenario/config_manager.py +12 -12
- wolfhece/wolf_array.py +274 -8
- {wolfhece-2.1.125.dist-info → wolfhece-2.1.127.dist-info}/METADATA +1 -1
- {wolfhece-2.1.125.dist-info → wolfhece-2.1.127.dist-info}/RECORD +14 -13
- {wolfhece-2.1.125.dist-info → wolfhece-2.1.127.dist-info}/WHEEL +0 -0
- {wolfhece-2.1.125.dist-info → wolfhece-2.1.127.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.125.dist-info → wolfhece-2.1.127.dist-info}/top_level.txt +0 -0
wolfhece/lazviewer/laz_viewer.py
CHANGED
@@ -17,6 +17,7 @@ from matplotlib.figure import Figure
|
|
17
17
|
from shapely.geometry import LineString, Point, CAP_STYLE, Polygon
|
18
18
|
from shapely.ops import prep
|
19
19
|
import wx
|
20
|
+
from tqdm import tqdm
|
20
21
|
|
21
22
|
from . import viewer
|
22
23
|
from ..PyWMS import getWalonmap
|
@@ -41,6 +42,7 @@ class Colors_Lazviewer(Enum):
|
|
41
42
|
ORTHO_2006_2007 = 2006
|
42
43
|
CODE_2013 = 0
|
43
44
|
CODE_2023 = 2
|
45
|
+
CODE_2021_2022 = 3
|
44
46
|
FROM_FILE = 1
|
45
47
|
|
46
48
|
class Classification_LAZ():
|
@@ -68,6 +70,18 @@ class Classification_LAZ():
|
|
68
70
|
9 : ['Eau', 'Eau',Colors.rgb_withalpha_float('aqua',1.)],
|
69
71
|
10 : ['Ponts', 'Ponts',Colors.rgb_withalpha_float('lightyellow1',1.)]}
|
70
72
|
|
73
|
+
def init_2021_2022(self):
|
74
|
+
|
75
|
+
self.class_name = 'SPW 2021-2022'
|
76
|
+
self.classification={
|
77
|
+
0 : ['0', 'Pas de classification', Colors.rgb_withalpha_float('black',.2),],
|
78
|
+
1 : ['Hors-sol', 'building, toits et autres', Colors.rgb_withalpha_float('white',.2),],
|
79
|
+
2 : ['Sol', 'y compris talus et digues', Colors.rgb_withalpha_float('brown',1.)],
|
80
|
+
4 : ['Végétation', 'y compris la végétation linéaire', Colors.rgb_withalpha_float('forestgreen',1.)],
|
81
|
+
9 : ['Eau', 'Eau',Colors.rgb_withalpha_float('aqua',1.)],
|
82
|
+
10 : ['Ponts', 'Ponts',Colors.rgb_withalpha_float('lightyellow1',1.)],
|
83
|
+
15 : ['Ligne hautes-tension', 'Ligne hautes-tension',Colors.rgb_withalpha_float('lightcyan1',0.25)]}
|
84
|
+
|
71
85
|
def init_2023(self):
|
72
86
|
|
73
87
|
self.class_name = 'SPW-Geofit 2023'
|
@@ -155,8 +169,8 @@ class xyz_laz():
|
|
155
169
|
parts = last_part.split('_')
|
156
170
|
|
157
171
|
# L'origine est codée dans le nom de fichier
|
158
|
-
self.origx = float(parts[
|
159
|
-
self.origy = float(parts[
|
172
|
+
self.origx = float(parts[-3])
|
173
|
+
self.origy = float(parts[-2])
|
160
174
|
|
161
175
|
dx = 2500.
|
162
176
|
dy = 3500.
|
@@ -557,6 +571,9 @@ class xyz_laz_grids():
|
|
557
571
|
return ret
|
558
572
|
|
559
573
|
def find_files_in_bounds(self, bounds:Union[tuple[tuple[float,float],tuple[float,float]], list[list[float, float],list[float, float]]]):
|
574
|
+
""" Find all files in bounds
|
575
|
+
|
576
|
+
:param bounds: [[xmin,xmax], [ymin,ymax]]"""
|
560
577
|
|
561
578
|
ret = [(cur.mydir, cur.find_files_in_bounds(bounds)) for cur in self.grids]
|
562
579
|
ret = [cur for cur in ret if len(cur[1])>0]
|
@@ -569,6 +586,11 @@ class xyz_laz_grids():
|
|
569
586
|
return ret
|
570
587
|
|
571
588
|
def copy_files_in_bounds(self, bounds:Union[tuple[tuple[float,float],tuple[float,float]], list[list[float, float],list[float, float]]], dirout:str):
|
589
|
+
""" Copy files in bounds to directory
|
590
|
+
|
591
|
+
:param bounds: [[xmin,xmax], [ymin,ymax]]
|
592
|
+
:param dirout: output directory
|
593
|
+
"""
|
572
594
|
|
573
595
|
import shutil
|
574
596
|
|
@@ -587,10 +609,28 @@ class xyz_laz_grids():
|
|
587
609
|
shutil.copy(join(curdir,'gridinfo.txt'), locdir / 'gridinfo.txt')
|
588
610
|
|
589
611
|
def read_dir(self, dir_grids):
|
612
|
+
""" Read all grids in directory and subdirectories """
|
613
|
+
|
614
|
+
import asyncio
|
615
|
+
|
590
616
|
dirs = listdir(dir_grids)
|
591
617
|
|
592
|
-
|
593
|
-
|
618
|
+
logging.info(_('Reading grids information -- {} grids'.format(len(dirs))))
|
619
|
+
|
620
|
+
def init_grid(curdir):
|
621
|
+
if (Path(dir_grids) / Path(curdir)).is_dir():
|
622
|
+
return xyz_laz_grid(join(dir_grids, curdir))
|
623
|
+
|
624
|
+
return None
|
625
|
+
|
626
|
+
async def init_grid_async(curdir):
|
627
|
+
return init_grid(curdir)
|
628
|
+
|
629
|
+
loop = asyncio.get_event_loop()
|
630
|
+
tasks = [init_grid_async(curdir) for curdir in dirs]
|
631
|
+
self.grids = list(filter(None, loop.run_until_complete(asyncio.gather(*tasks))))
|
632
|
+
|
633
|
+
logging.info(_('Grids initialized'))
|
594
634
|
|
595
635
|
def scan_around(self, xy:Union[LineString,list[list[float], list[float]]], length_buffer=5.):
|
596
636
|
"""
|
@@ -707,42 +747,82 @@ class xyz_laz_grids():
|
|
707
747
|
|
708
748
|
return figmpl
|
709
749
|
|
710
|
-
def create_from_laz(self, dir_laz:str, shape:str, ds:float = 50, force_format = np.float64):
|
750
|
+
def create_from_laz(self, dir_laz:str, shape:str=None, ds:float = 50, force_format = np.float64):
|
711
751
|
|
712
752
|
try:
|
713
753
|
from ..PyVertexvectors import Zones
|
714
754
|
except:
|
715
755
|
from wolfhece.PyVertexvectors import Zones
|
716
|
-
vecs = Zones(shape)
|
717
756
|
|
718
|
-
|
757
|
+
vecs = None
|
758
|
+
if shape is not None:
|
759
|
+
vecs = Zones(shape)
|
760
|
+
|
761
|
+
dir_laz = Path(dir_laz)
|
762
|
+
|
763
|
+
for entry in tqdm(dir_laz.glob('**/*.laz')):
|
719
764
|
if entry.is_file():
|
720
|
-
if entry.name.endswith('.laz'):
|
721
765
|
|
722
|
-
|
723
|
-
|
766
|
+
file_wo_suf = entry.stem
|
767
|
+
dirname = join(self.dir, file_wo_suf)
|
724
768
|
|
725
|
-
|
726
|
-
|
769
|
+
if not exists(dirname):
|
770
|
+
makedirs(dirname, exist_ok=True)
|
727
771
|
|
728
|
-
|
772
|
+
newlaz = xyz_laz_grid(mydir=dirname)
|
729
773
|
|
774
|
+
if vecs is not None:
|
730
775
|
vec = vecs.get_zone(file_wo_suf)
|
731
776
|
bounds = vec.myvectors[0].get_bounds()
|
777
|
+
else:
|
778
|
+
lazdata = laspy.read(entry)
|
779
|
+
bounds = [[lazdata.x.min(), lazdata.y.min()],
|
780
|
+
[lazdata.x.max(), lazdata.y.max()]]
|
781
|
+
|
782
|
+
bounds = [[math.floor(bounds[0][0]/ds)*ds, math.floor(bounds[0][1]/ds)*ds],
|
783
|
+
[math.ceil(bounds[1][0]/ds)*ds, math.ceil(bounds[1][1]/ds)*ds]]
|
784
|
+
|
785
|
+
dx = bounds[1][0] -bounds[0][0]
|
786
|
+
dy = bounds[1][1] -bounds[0][1]
|
787
|
+
nb = max(int(dx/ds), int(dy/ds))
|
788
|
+
|
789
|
+
self.grids.append(newlaz._sort_grid_np(entry,
|
790
|
+
join(dirname, file_wo_suf),
|
791
|
+
bounds=[[bounds[0][0], bounds[1][0]], [bounds[0][1], bounds[1][1]]],
|
792
|
+
gridsize=[max(int(dx/ds),1), max(int(dy/ds),1)],
|
793
|
+
force_format=force_format))
|
794
|
+
|
795
|
+
def create_bounds_shape(self, dir_laz:str, out_shape:str):
|
796
|
+
""" Create shape from laz files """
|
797
|
+
try:
|
798
|
+
from ..PyVertexvectors import Zones
|
799
|
+
except:
|
800
|
+
from wolfhece.PyVertexvectors import Zones
|
801
|
+
|
802
|
+
dir_laz = Path(dir_laz)
|
803
|
+
out_shape = Path(out_shape)
|
804
|
+
|
805
|
+
vecs = Zones()
|
732
806
|
|
733
|
-
|
734
|
-
|
807
|
+
for entry in tqdm(dir_laz.glob('**/*.laz')):
|
808
|
+
if entry.is_file():
|
809
|
+
lazdata = laspy.read(entry)
|
810
|
+
|
811
|
+
bounds = [[lazdata.x.min(), lazdata.y.min()],
|
812
|
+
[lazdata.x.max(), lazdata.y.max()]]
|
813
|
+
loczone = zone(name=entry.stem)
|
814
|
+
locvec = vector(name=entry.stem)
|
735
815
|
|
736
|
-
|
737
|
-
|
738
|
-
|
816
|
+
locvec.add_vertex(wolfvertex(bounds[0][0], bounds[0][1]))
|
817
|
+
locvec.add_vertex(wolfvertex(bounds[1][0], bounds[0][1]))
|
818
|
+
locvec.add_vertex(wolfvertex(bounds[1][0], bounds[1][1]))
|
819
|
+
locvec.add_vertex(wolfvertex(bounds[0][0], bounds[1][1]))
|
820
|
+
locvec.close_force()
|
739
821
|
|
740
|
-
|
741
|
-
|
742
|
-
bounds=[[bounds[0][0], bounds[1][0]], [bounds[0][1], bounds[1][1]]],
|
743
|
-
gridsize=[max(int(dx/ds),1), max(int(dy/ds),1)],
|
744
|
-
force_format=force_format))
|
822
|
+
loczone.add_vector(locvec, forceparent=True)
|
823
|
+
vecs.add_zone(loczone, forceparent=True)
|
745
824
|
|
825
|
+
vecs.saveas(Path(self.dir) / out_shape)
|
746
826
|
|
747
827
|
class Wolf_LAZ_Data(Element_To_Draw):
|
748
828
|
""" Base class for LAZ data which can be imported in Pydraw.Mapviewer.
|
@@ -1145,6 +1225,8 @@ class Wolf_LAZ_Data(Element_To_Draw):
|
|
1145
1225
|
logging.warning(_('No classification chosen - Abort !'))
|
1146
1226
|
elif classification == 'SPW 2013-2014':
|
1147
1227
|
self.classification.init_2013()
|
1228
|
+
elif classification == 'SPW 2021-2022':
|
1229
|
+
self.classification.init_2021_2022()
|
1148
1230
|
else:
|
1149
1231
|
self.classification.init_2023()
|
1150
1232
|
|
@@ -1900,6 +1982,34 @@ def get_colors(las:laspy.LasData, which_colors:Colors_Lazviewer, imsize=2000, fn
|
|
1900
1982
|
name, comment, color = value
|
1901
1983
|
colors[myclass==int(key)] = color
|
1902
1984
|
|
1985
|
+
elif which_colors==Colors_Lazviewer.CODE_2021_2022.value:
|
1986
|
+
"""
|
1987
|
+
- Rebus/non classés - Code 0;
|
1988
|
+
- Hors-sol (building, toits et autres) - Code 1;
|
1989
|
+
- Sol (y compris talus et digues) - Code 2;
|
1990
|
+
- Végétation haute (y compris la végétation linéaire) - Code 4;
|
1991
|
+
- Eau - Code 9;
|
1992
|
+
- Pont – Code 10;
|
1993
|
+
- Ligne hautes-tension - Code 15.
|
1994
|
+
"""
|
1995
|
+
if type(las) is laspy.LasData:
|
1996
|
+
myclass = las.classification
|
1997
|
+
elif type(las) is list:
|
1998
|
+
myclass=[]
|
1999
|
+
for curlas in las:
|
2000
|
+
myclass.append(curlas.classification)
|
2001
|
+
myclass = np.concatenate(myclass)
|
2002
|
+
else:
|
2003
|
+
myclass = np.int8(las[:,3])
|
2004
|
+
|
2005
|
+
if palette_classif is None:
|
2006
|
+
palette_classif = Classification_LAZ()
|
2007
|
+
palette_classif.init_2021_2022()
|
2008
|
+
|
2009
|
+
for key, value in palette_classif.classification.items():
|
2010
|
+
name, comment, color = value
|
2011
|
+
colors[myclass==int(key)] = color
|
2012
|
+
|
1903
2013
|
elif which_colors==Colors_Lazviewer.CODE_2023.value:
|
1904
2014
|
|
1905
2015
|
if palette_classif is None:
|
@@ -116,7 +116,7 @@ class Calculator(wx.Frame):
|
|
116
116
|
from ..PyDraw import draw_type
|
117
117
|
ids = self._mapviewer.get_list_keys(drawing_type=draw_type.ARRAYS, checked_state=None)
|
118
118
|
for id in ids:
|
119
|
-
self.memory_txt
|
119
|
+
self.memory_txt = id
|
120
120
|
|
121
121
|
def memory_clear_event(self, e):
|
122
122
|
self.memory_clear()
|
@@ -472,13 +472,13 @@ class Config_Manager_2D_GPU:
|
|
472
472
|
|
473
473
|
logging.info(_('Number of tif files : {}'.format(len(list_tif))))
|
474
474
|
|
475
|
-
standard_files = ['bathymetry.tif',
|
476
|
-
'manning.tif',
|
477
|
-
'infiltration.tif',
|
478
|
-
'h.tif',
|
479
|
-
'qx.tif',
|
480
|
-
'qy.tif',
|
481
|
-
'roof.tif',
|
475
|
+
standard_files = ['bathymetry.tif',
|
476
|
+
'manning.tif',
|
477
|
+
'infiltration.tif',
|
478
|
+
'h.tif',
|
479
|
+
'qx.tif',
|
480
|
+
'qy.tif',
|
481
|
+
'roof.tif',
|
482
482
|
'deck.tif']
|
483
483
|
|
484
484
|
log = ''
|
@@ -1217,7 +1217,7 @@ class Config_Manager_2D_GPU:
|
|
1217
1217
|
logging.error(_("No 'bathymetry.tif' file found in the root directory !"))
|
1218
1218
|
|
1219
1219
|
|
1220
|
-
def combine_bath_roof_deck(self, bathymetry:WolfArray,
|
1220
|
+
def combine_bath_roof_deck(self, bathymetry:WolfArray,
|
1221
1221
|
bridge_roof:WolfArray, bridge_deck:WolfArray,
|
1222
1222
|
threshold:float = .05) -> str:
|
1223
1223
|
""" Verify bathymetry, roof and deck """
|
@@ -1231,7 +1231,7 @@ class Config_Manager_2D_GPU:
|
|
1231
1231
|
if ret != '':
|
1232
1232
|
logging.error(ret)
|
1233
1233
|
return ret
|
1234
|
-
|
1234
|
+
|
1235
1235
|
# si la matrice de toit de pont est plus basse que la bathymétrie, on met à 99999
|
1236
1236
|
# la bathymétrie et le toit de pont.
|
1237
1237
|
# Ainsi, ces maille seront infranchissables.
|
@@ -1257,7 +1257,7 @@ class Config_Manager_2D_GPU:
|
|
1257
1257
|
ret += _(' -- Bathymetry values will be set to max(bath, deck)\n')
|
1258
1258
|
ret += _(' -- These cells will remain impassable until the water level rises above them\n')
|
1259
1259
|
bridge_roof.array.data[mask] = 99999.
|
1260
|
-
bathymetry.array.data[mask] = np.maximum(bridge_deck.array.data[mask], bathymetry.array.data[mask])
|
1260
|
+
bathymetry.array.data[mask] = np.maximum(bridge_deck.array.data[mask], bathymetry.array.data[mask])
|
1261
1261
|
|
1262
1262
|
mask = np.where(bridge_roof.array.data - bathymetry.array.data < threshold)
|
1263
1263
|
if mask[0].shape[0] > 0:
|
@@ -1273,7 +1273,7 @@ class Config_Manager_2D_GPU:
|
|
1273
1273
|
logging.warning(ret)
|
1274
1274
|
|
1275
1275
|
return ret
|
1276
|
-
|
1276
|
+
|
1277
1277
|
def create_simulation(self,
|
1278
1278
|
dir:Path,
|
1279
1279
|
idx_hydros:list[int] = [-1],
|
@@ -1576,7 +1576,7 @@ class Config_Manager_2D_GPU:
|
|
1576
1576
|
for cursim in allsims:
|
1577
1577
|
cursim:Path
|
1578
1578
|
batch += 'cd {}\n'.format(str(cursim.parent))
|
1579
|
-
batch += str(cursim.name) + '\n'
|
1579
|
+
batch += 'call ' + str(cursim.name) + '\n'
|
1580
1580
|
|
1581
1581
|
with open(path, 'w', encoding='utf-8') as f:
|
1582
1582
|
f.write(batch)
|