wolfhece 2.2.42__py3-none-any.whl → 2.2.44__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/pywalous.py CHANGED
@@ -22,6 +22,8 @@ import wx.grid
22
22
 
23
23
  from .PyTranslate import _
24
24
  from .PyPalette import wolfpalette
25
+ from .wolf_array import WolfArray, header_wolf
26
+
25
27
 
26
28
  """
27
29
  Hydrology classification for Land Use in Wallonia:
@@ -339,8 +341,8 @@ class Walous_data():
339
341
 
340
342
  """
341
343
 
342
- self._dir = dir_data # directory of the data
343
- self._fn = fn # filename without extension
344
+ self._dir = str(dir_data) # directory of the data
345
+ self._fn = str(fn) # filename without extension
344
346
  self._extension = extension # extension of the file
345
347
  self._gdf = None # geopandas dataframe
346
348
 
@@ -402,6 +404,8 @@ class Walous_data():
402
404
 
403
405
  chdir(detsdir)
404
406
 
407
+ fnout = str((Path(fnout)).with_suffix(self._extension))
408
+
405
409
  self._gdf.to_file(basename(fnout))
406
410
 
407
411
  chdir(curdir)
@@ -753,3 +757,143 @@ class Walous_OCS_Legend(wx.Dialog):
753
757
 
754
758
  def close(self):
755
759
  self.Destroy()
760
+
761
+
762
+ def get_array_WALOUS_OCS(fname:Path, spatial_res:float, bounds:Union[list[float, float, float, float],list[list[float, float], list[float, float]]]) -> Union[WolfArray, None]:
763
+ """ Get WALOUS OCS as WolfArray
764
+
765
+ :param fname: path to the WALOUS OCS file
766
+ :param spatial_res: desired spatial resolution (in m)
767
+ :param bounds: [xmin, ymin, xmax, ymax] or [[xmin, xmax], [ymin, ymax]]
768
+ :return: WolfArray or None if error
769
+ """
770
+
771
+ if not fname.exists():
772
+ logging.error(_('WALOUS OCS file not found: {}').format(fname))
773
+ return None
774
+
775
+ # Convert bounds to [[xmin, xmax], [ymin, ymax]] if needed
776
+ if len(bounds)==4:
777
+ bounds = [[bounds[0], bounds[2]], [bounds[1], bounds[3]]]
778
+
779
+ # Convert bvounds to list to be able to modify it
780
+ bounds = [list(bounds[0]), list(bounds[1])]
781
+
782
+ bounds_copy = [list(bounds[0]), list(bounds[1])]
783
+
784
+ header_OCS = header_wolf.read_header(fname)
785
+ if header_OCS.dx != spatial_res:
786
+ # Adapt bounds to ensure that the rebin will be correct.
787
+ # If spatial_res is a multiple of header_OCS.dx, no need to change bounds.
788
+ # If not, change the bounds to ensure that the crop will include data in all footprints.
789
+
790
+ if (bounds[0][0] - header_OCS.origx) % header_OCS.dx != 0:
791
+ bounds[0][0] = header_OCS.origx + ((bounds[0][0] - header_OCS.origx) // header_OCS.dx) * header_OCS.dx
792
+ if (bounds[0][1] - bounds[0][0]) % header_OCS.dx != 0:
793
+ bounds[0][1] = bounds[0][0] + ((bounds[0][1] - bounds[0][0]) // header_OCS.dx + 1) * header_OCS.dx
794
+ if (bounds[1][0] - header_OCS.origy) % header_OCS.dy != 0:
795
+ bounds[1][0] = header_OCS.origy + ((bounds[1][0] - header_OCS.origy) // header_OCS.dy) * header_OCS.dy
796
+ if (bounds[1][1] - bounds[1][0]) % header_OCS.dy != 0:
797
+ bounds[1][1] = bounds[1][0] + ((bounds[1][1] - bounds[1][0]) // header_OCS.dy + 1) * header_OCS.dy
798
+
799
+ locwalous = WolfArray(fname=fname, crop = [bounds[0][0], bounds[0][1], bounds[1][0], bounds[1][1]])
800
+
801
+ if locwalous.dx != spatial_res:
802
+ locwalous.rebin(spatial_res / locwalous.dx, operation='min')
803
+ logging.info(_('Rebin to {} m because original data are {} m').format(spatial_res, locwalous.dx))
804
+ locwalous = WolfArray(mold=locwalous, crop = bounds_copy)
805
+
806
+ return locwalous
807
+
808
+ def get_array_WALOUS_OCS_2023_10m(spatial_res:float, bounds:Union[list[float, float, float, float],list[list[float, float], list[float, float]]]) -> Union[WolfArray, None]:
809
+ """ Get WALOUS OCS 2023 as WolfArray
810
+
811
+ :param spatial_res: desired spatial resolution (in m)
812
+ :param bounds: [xmin, ymin, xmax, ymax] or [[xmin, xmax], [ymin, ymax]]
813
+ :return: WolfArray or None if error
814
+ """
815
+
816
+ from wolfhece.pydownloader import toys_dataset
817
+
818
+ fname = toys_dataset(dir='Walous_OCS', file='WALOUS_2023_lbt72_10m.tif')
819
+
820
+ return get_array_WALOUS_OCS(fname, spatial_res, bounds)
821
+
822
+ def get_array_WALOUS_OCS_2023_4m(spatial_res:float, bounds:Union[list[float, float, float, float],list[list[float, float], list[float, float]]]) -> Union[WolfArray, None]:
823
+ """ Get WALOUS OCS 2023 as WolfArray
824
+
825
+ :param spatial_res: desired spatial resolution (in m)
826
+ :param bounds: [xmin, ymin, xmax, ymax] or [[xmin, xmax], [ymin, ymax]]
827
+ :return: WolfArray or None if error
828
+ """
829
+
830
+ from wolfhece.pydownloader import toys_dataset
831
+
832
+ fname = toys_dataset(dir='Walous_OCS', file='WALOUS_2023_lbt72_4m.tif')
833
+
834
+ return get_array_WALOUS_OCS(fname, spatial_res, bounds)
835
+
836
+ def get_array_WALOUS_OCS_2020_10m(spatial_res:float, bounds:Union[list[float, float, float, float],list[list[float, float], list[float, float]]]) -> Union[WolfArray, None]:
837
+ """ Get WALOUS OCS 2020 as WolfArray
838
+
839
+ :param spatial_res: desired spatial resolution (in m)
840
+ :param bounds: [xmin, ymin, xmax, ymax] or [[xmin, xmax], [ymin, ymax]]
841
+ :return: WolfArray or None if error
842
+ """
843
+
844
+ from wolfhece.pydownloader import toys_dataset
845
+
846
+ fname = toys_dataset(dir='Walous_OCS', file='WALOUS_2020_lbt72_10m.tif')
847
+
848
+ return get_array_WALOUS_OCS(fname, spatial_res, bounds)
849
+
850
+ def get_array_WALOUS_OCS_2020_4m(spatial_res:float, bounds:Union[list[float, float, float, float],list[list[float, float], list[float, float]]]) -> Union[WolfArray, None]:
851
+ """ Get WALOUS OCS 2020 as WolfArray
852
+
853
+ :param spatial_res: desired spatial resolution (in m)
854
+ :param bounds: [xmin, ymin, xmax, ymax] or [[xmin, xmax], [ymin, ymax]]
855
+ :return: WolfArray or None if error
856
+ """
857
+
858
+ from wolfhece.pydownloader import toys_dataset
859
+
860
+ fname = toys_dataset(dir='Walous_OCS', file='WALOUS_2020_lbt72_4m.tif')
861
+
862
+ return get_array_WALOUS_OCS(fname, spatial_res, bounds)
863
+
864
+ def get_array_WALOUS_UTS(fname:Path, fnout:Path, spatial_res:float, bounds:Union[list[float, float, float, float],list[list[float, float], list[float, float]]], which:Literal['UTS_MAJ_NIV1', 'UTS_MAJ_NIV2'] = 'UTS_MAJ_NIV1') -> Union[WolfArray, None]:
865
+ """ Get WALOUS UTS as WolfArray
866
+
867
+ :param fname: path to the WALOUS UTS file
868
+ :param spatial_res: desired spatial resolution (in m)
869
+ :param bounds: [xmin, ymin, xmax, ymax] or [[xmin, xmax], [ymin, ymax]]
870
+ :param which: which level to use ('UTS_MAJ_NIV1' or 'UTS_MAJ_NIV2')
871
+ :return: WolfArray or None if error
872
+ """
873
+
874
+ fname = Path(fname)
875
+ fnout = Path(fnout)
876
+
877
+ if not fname.exists():
878
+ logging.error(_('WALOUS UTS file not found: {}').format(fname))
879
+ return None
880
+
881
+ # Convert bounds to [[xmin, xmax], [ymin, ymax]] if needed
882
+ if len(bounds)==4:
883
+ bounds = [[bounds[0], bounds[2]], [bounds[1], bounds[3]]]
884
+
885
+ # Convert bvounds to list to be able to modify it
886
+ bounds = [list(bounds[0]), list(bounds[1])]
887
+
888
+ bounds_copy = [list(bounds[0]), list(bounds[1])]
889
+
890
+ locwalous = Walous_data(fname.parent, fname.name, extension=fname.suffix, bounds=bounds)
891
+ ret = locwalous.rasterize(bounds=bounds, layer= which, fn_out=fnout.with_suffix('.tif'), pixel_size=spatial_res)
892
+
893
+ ret = Path(ret)
894
+
895
+ if ret.exists():
896
+ locwalous_array = WolfArray(fname=ret)
897
+ return locwalous_array
898
+ else:
899
+ return None
wolfhece/wolf_array.py CHANGED
@@ -515,6 +515,15 @@ class header_wolf():
515
515
  return ([self.origx, self.origx + float(self.nbx) * self.dx],
516
516
  [self.origy, self.origy + float(self.nby) * self.dy])
517
517
 
518
+ def get_scale_yoverx(self):
519
+ """
520
+ Return the scale of the array (height over width)
521
+ """
522
+ if self.dx == 0 or self.dy == 0 or self.nbx == 0 or self.nby == 0:
523
+ return 1.
524
+
525
+ return float((self.nby * self.dy) / (self.nbx * self.dx))
526
+
518
527
  def get_bounds_ij(self, abs=False):
519
528
  """
520
529
  Return bounds in indices
@@ -596,6 +605,9 @@ class header_wolf():
596
605
  else:
597
606
  locij = np.zeros(locxy.shape, dtype=np.int32)
598
607
 
608
+ if locxy.size == 0:
609
+ return locij
610
+
599
611
  locxy[:,0] -= self.origx
600
612
  locxy[:,1] -= self.origy
601
613
 
@@ -7693,6 +7705,10 @@ class WolfArray(Element_To_Draw, header_wolf):
7693
7705
  depuis les vertices 3D du polygone
7694
7706
  """
7695
7707
 
7708
+ if vector.area == 0.:
7709
+ logging.error(_('The polygon has no area'))
7710
+ return
7711
+
7696
7712
  if keep not in ['all', 'below', 'above']:
7697
7713
  logging.error(_('keep must be "all", "below" or "above"'))
7698
7714
  raise ValueError
@@ -7702,7 +7718,7 @@ class WolfArray(Element_To_Draw, header_wolf):
7702
7718
  raise ValueError
7703
7719
 
7704
7720
  if self.mngselection is None:
7705
- destxy = self.get_xy_inside_polygon(working_vector)
7721
+ destxy = self.get_xy_inside_polygon(working_vector, method = 'shapely_strict')
7706
7722
  if len(destxy)==0:
7707
7723
  logging.debug(_('No points to interpolate'))
7708
7724
  return
@@ -7720,16 +7736,16 @@ class WolfArray(Element_To_Draw, header_wolf):
7720
7736
  destxy = self.ij2xy_np(destij)
7721
7737
  else:
7722
7738
  if self.SelectionData.nb == 0:
7723
- destxy = self.get_xy_inside_polygon(working_vector)
7739
+ destxy = self.get_xy_inside_polygon(working_vector, method= 'shapely_strict')
7740
+ if destxy.shape[0] == 0:
7741
+ logging.debug(_('No points to interpolate'))
7742
+ return
7724
7743
  else:
7725
7744
  destxy = self.SelectionData.myselection
7726
7745
 
7727
- # if isinstance(destxy, list):
7728
- # destxy = np.asarray(destxy)
7729
-
7730
- if len(destxy)==0:
7731
- logging.debug(_('No points to interpolate'))
7732
- return
7746
+ if len(destxy)==0:
7747
+ logging.debug(_('No points to interpolate'))
7748
+ return
7733
7749
 
7734
7750
  destij = self.xy2ij_np(destxy)
7735
7751
 
@@ -7813,6 +7829,56 @@ class WolfArray(Element_To_Draw, header_wolf):
7813
7829
  for curvec in working_zone.myvectors:
7814
7830
  self.interpolate_on_polygon(curvec, method, keep)
7815
7831
 
7832
+ def interpolate_strictly_on_polyline(self, working_vector:vector, usemask=True, keep:Literal['all', 'below', 'above'] = 'all'):
7833
+ """
7834
+ Interpolation des mailles strictement sous une polyligne.
7835
+
7836
+ On utilise ensuite "interpolate" de shapely pour interpoler les altitudes des mailles
7837
+ depuis les vertices 3D de la polyligne
7838
+ """
7839
+
7840
+ vecls = working_vector.linestring
7841
+ xy = self.get_xy_strictly_on_borders(working_vector, usemask=usemask)
7842
+ if xy.shape[0] == 0:
7843
+ logging.debug(_('No points to interpolate'))
7844
+ return
7845
+ ij = np.asarray([self.get_ij_from_xy(x, y) for x, y in xy])
7846
+ newz = np.asarray([vecls.interpolate(vecls.project(Point(x, y))).z for x, y in xy])
7847
+
7848
+ if keep == 'all':
7849
+ self.array.data[ij[:, 0], ij[:, 1]] = newz
7850
+ elif keep == 'below':
7851
+ locmask = np.where((newz != -99999.) & (newz < self.array.data[ij[:, 0], ij[:, 1]]))
7852
+ self.array.data[ij[locmask][:, 0], ij[locmask][:, 1]] = newz[locmask]
7853
+ elif keep == 'above':
7854
+ locmask = np.where((newz != -99999.) & (newz > self.array.data[ij[:, 0], ij[:, 1]]))
7855
+ self.array.data[ij[locmask][:, 0], ij[locmask][:, 1]] = newz[locmask]
7856
+
7857
+ def interpolate_strictly_on_vertices(self, working_vector:vector, usemask=True, keep:Literal['all', 'below', 'above'] = 'all'):
7858
+ """
7859
+ Interpolation des mailles strictement sous une polyligne.
7860
+
7861
+ On utilise ensuite "interpolate" de shapely pour interpoler les altitudes des mailles
7862
+ depuis les vertices 3D de la polyligne
7863
+ """
7864
+
7865
+ vecls = working_vector.linestring
7866
+ xy = self.get_xy_strictly_on_vertices(working_vector, usemask=usemask)
7867
+ if xy.shape[0] == 0:
7868
+ logging.debug(_('No points to interpolate'))
7869
+ return
7870
+ ij = np.asarray([self.get_ij_from_xy(x, y) for x, y in xy])
7871
+ newz = np.asarray([vecls.interpolate(vecls.project(Point(x, y))).z for x, y in xy])
7872
+
7873
+ if keep == 'all':
7874
+ self.array.data[ij[:, 0], ij[:, 1]] = newz
7875
+ elif keep == 'below':
7876
+ locmask = np.where((newz != -99999.) & (newz < self.array.data[ij[:, 0], ij[:, 1]]))
7877
+ self.array.data[ij[locmask][:, 0], ij[locmask][:, 1]] = newz[locmask]
7878
+ elif keep == 'above':
7879
+ locmask = np.where((newz != -99999.) & (newz > self.array.data[ij[:, 0], ij[:, 1]]))
7880
+ self.array.data[ij[locmask][:, 0], ij[locmask][:, 1]] = newz[locmask]
7881
+
7816
7882
  def interpolate_on_polyline(self, working_vector:vector, usemask=True):
7817
7883
  """
7818
7884
  Interpolation sous une polyligne
@@ -7889,8 +7955,9 @@ class WolfArray(Element_To_Draw, header_wolf):
7889
7955
  def interpolate_on_triangulation(self, coords, triangles,
7890
7956
  grid_x=None, grid_y = None,
7891
7957
  mask_tri=None,
7892
- interp_method:Literal['matplotlib','scipy'] = 'matplotlib',
7893
- keep:Literal['all', 'below', 'above'] = 'all'):
7958
+ interp_method:Literal['matplotlib','scipy'] = 'scipy',
7959
+ keep:Literal['all', 'below', 'above'] = 'all',
7960
+ points_along_edges:bool = True):
7894
7961
  """
7895
7962
  Interpolation sur une triangulation.
7896
7963
 
@@ -7898,7 +7965,7 @@ class WolfArray(Element_To_Draw, header_wolf):
7898
7965
  - uniquement dans les mailles sélectionnées si elles existent
7899
7966
  - dans les mailles contenues dans la triangulation sinon
7900
7967
 
7901
- Matplotlib is used by default, but Scipy(griddata) can be used as well. If Matplotlib crashes, try with Scipy.
7968
+ Scipy(griddata) is used by default (more robust), but Matplotlib can be used as well (more strict). If Matplotlib crashes, try with Scipy.
7902
7969
 
7903
7970
  **Matplotlib is more strict on the quality of the triangulation.**
7904
7971
 
@@ -8205,6 +8272,7 @@ class WolfArray(Element_To_Draw, header_wolf):
8205
8272
  #on force les valeurs masquées à nullvalue afin que l'interpolation n'applique pas ses effets dans cette zone
8206
8273
  self.array.data[self.array.mask]= self.nullvalue
8207
8274
  except:
8275
+ logging.error(_('Bad triangulation - We will try with Scipy'))
8208
8276
  use_scipy=True
8209
8277
 
8210
8278
  if interp_method != 'matplotlib' or use_scipy:
@@ -8216,8 +8284,15 @@ class WolfArray(Element_To_Draw, header_wolf):
8216
8284
  curvec.add_vertex(wolfvertex(coords[curpt,0], coords[curpt,1], coords[curpt,2]))
8217
8285
  curvec.close_force()
8218
8286
 
8287
+ # if bool(np.isnan(curvec.x).any() or np.isnan(curvec.y).any()):
8288
+ # continue
8219
8289
  self.interpolate_on_polygon(curvec, "linear", keep)
8220
8290
 
8291
+ if points_along_edges:
8292
+ # Test points along edges
8293
+ self.interpolate_strictly_on_polyline(curvec, usemask=True, keep=keep)
8294
+ # self.interpolate_strictly_on_vertices(curvec, usemask=True, keep=keep)
8295
+
8221
8296
  self.reset_plot()
8222
8297
  return
8223
8298
 
@@ -9003,7 +9078,7 @@ class WolfArray(Element_To_Draw, header_wolf):
9003
9078
  self.mask_reset()
9004
9079
 
9005
9080
  def interpolation2D(self, key:str='1'):
9006
- """ Interpolation 2D basde on selected points in key 1 """
9081
+ """ Interpolation 2D based on selected points in key 1 """
9007
9082
 
9008
9083
  #FIXME : auhtorize interpolation on other keys
9009
9084
 
@@ -9576,6 +9651,113 @@ class WolfArray(Element_To_Draw, header_wolf):
9576
9651
  elif method == 'rasterio':
9577
9652
  return self.get_xy_inside_polygon_rasterio(myvect, usemask)
9578
9653
 
9654
+ def get_xy_strictly_on_borders(self, myvect: vector | Polygon | LineString, usemask:bool=True,
9655
+ method:Literal['shapely']='shapely'):
9656
+ """
9657
+ Return the coordinates strictly on the borders of a polygon.
9658
+
9659
+ ATTENTION : Tests are performed numerically, so the results may not be exact
9660
+ in the sense of pure geometry.
9661
+
9662
+ Do not confuse with "get_xy_under_polyline" which
9663
+ "rasterize" the polyline to find useful coordinates.
9664
+
9665
+ :param myvect: target vector
9666
+ :param usemask: limit potential nodes to unmaksed nodes
9667
+ :param method: method to use ('shapely' for now)
9668
+ """
9669
+
9670
+ # As we will use Shapely(contains) to test if points are on the border,
9671
+ # we need to use a Linestring or a Polygon.boundary.
9672
+ if isinstance(myvect, vector):
9673
+ myvect.find_minmax()
9674
+ boundary = myvect.linestring
9675
+ elif isinstance(myvect, Polygon):
9676
+ boundary = myvect.boundary
9677
+ elif isinstance(myvect, LineString):
9678
+ boundary = myvect
9679
+
9680
+ if not is_prepared(boundary):
9681
+ prepare(boundary) # Prepare the polygon for **faster** contains check -- VERY IMPORTANT
9682
+ to_destroy = True
9683
+ else:
9684
+ to_destroy = False
9685
+ mypointsxy, mypointsij = self.get_xy_infootprint_vect(myvect)
9686
+
9687
+ points= np.array([Point(x,y) for x,y in mypointsxy])
9688
+ on_border = list(map(lambda point: boundary.contains(point), points))
9689
+
9690
+ if to_destroy:
9691
+ destroy_prepared(boundary) # Destroy the prepared polygon
9692
+
9693
+ to_keep = np.where(on_border)
9694
+ mypointsxy = mypointsxy[to_keep]
9695
+
9696
+ if mypointsxy.shape[0] == 0:
9697
+ return mypointsxy
9698
+
9699
+ if usemask:
9700
+ mypointsij = mypointsij[to_keep]
9701
+ mymask = np.logical_not(self.array.mask[mypointsij[:, 0], mypointsij[:, 1]])
9702
+ mypointsxy = mypointsxy[np.where(mymask)]
9703
+
9704
+ return mypointsxy
9705
+
9706
+ def get_xy_strictly_on_vertices(self, myvect: vector | Polygon | LineString, usemask:bool=True,
9707
+ method:Literal['shapely']='shapely', eps:float = 1.e-4):
9708
+ """
9709
+ Return the coordinates strictly on the vertices of a polygon, Linestring or vector.
9710
+
9711
+ ATTENTION : Tests are performed numerically, so the results may not be exact
9712
+ in the sense of pure geometry.
9713
+
9714
+ :param myvect: target vector
9715
+ :param usemask: limit potential nodes to unmaksed nodes
9716
+ :param method: method to use ('shapely' for now)
9717
+ """
9718
+
9719
+ # As we will use Shapely(contains) to test if points are on the border,
9720
+ # we need to use a Linestring or a Polygon.boundary.
9721
+ if isinstance(myvect, vector):
9722
+ myvect.find_minmax()
9723
+ boundary = myvect.linestring
9724
+ elif isinstance(myvect, Polygon):
9725
+ boundary = myvect.boundary
9726
+ elif isinstance(myvect, LineString):
9727
+ boundary = myvect
9728
+
9729
+ if not is_prepared(boundary):
9730
+ prepare(boundary) # Prepare the polygon for **faster** contains check -- VERY IMPORTANT
9731
+ to_destroy = True
9732
+ else:
9733
+ to_destroy = False
9734
+
9735
+ mypointsxy, mypointsij = self.get_xy_infootprint_vect(myvect)
9736
+
9737
+ # Calculate distances to the vertices
9738
+ # We use the vertices of the polygon or linestring to check if points are on the
9739
+ # vertices.
9740
+
9741
+ points = np.array([Point(x,y) for x,y in mypointsxy])
9742
+ vertices = [Point(pt[0], pt[1], pt[2]) for pt in boundary.coords]
9743
+ on_vertices = list(map(lambda point: any(vert.distance(point) < eps for vert in vertices), points))
9744
+
9745
+ if to_destroy:
9746
+ destroy_prepared(boundary) # Destroy the prepared polygon
9747
+
9748
+ to_keep = np.where(on_vertices)
9749
+ mypointsxy = mypointsxy[to_keep]
9750
+
9751
+ if mypointsxy.shape[0] == 0:
9752
+ return mypointsxy
9753
+
9754
+ if usemask:
9755
+ mypointsij = mypointsij[to_keep]
9756
+ mymask = np.logical_not(self.array.mask[mypointsij[:, 0], mypointsij[:, 1]])
9757
+ mypointsxy = mypointsxy[np.where(mymask)]
9758
+
9759
+ return mypointsxy
9760
+
9579
9761
  def get_xy_inside_polygon_mpl(self, myvect: vector | Polygon, usemask:bool=True):
9580
9762
  """
9581
9763
  Return the coordinates inside a polygon
@@ -9641,10 +9823,14 @@ class WolfArray(Element_To_Draw, header_wolf):
9641
9823
  if to_destroy:
9642
9824
  destroy_prepared(polygon) # Destroy the prepared polygon
9643
9825
 
9644
- mypointsxy = mypointsxy[np.where(inside)]
9826
+ to_keep = np.where(inside)
9827
+ mypointsxy = mypointsxy[to_keep]
9828
+
9829
+ if mypointsxy.shape[0] == 0:
9830
+ return mypointsxy
9645
9831
 
9646
9832
  if usemask:
9647
- mypointsij = mypointsij[np.where(inside)]
9833
+ mypointsij = mypointsij[to_keep]
9648
9834
  mymask = np.logical_not(self.array.mask[mypointsij[:, 0], mypointsij[:, 1]])
9649
9835
  mypointsxy = mypointsxy[np.where(mymask)]
9650
9836
 
@@ -9710,6 +9896,33 @@ class WolfArray(Element_To_Draw, header_wolf):
9710
9896
  elif method == 'rasterio':
9711
9897
  return self._get_ij_inside_polygon_rasterio(myvect, usemask, eps)
9712
9898
 
9899
+
9900
+ def get_ij_inside_listofpolygons(self, myvects: list[vector | Polygon],
9901
+ usemask:bool=True, eps:float = 0.,
9902
+ method:Literal['mpl', 'shapely_strict', 'shapely_wboundary', 'rasterio']='shapely_strict'):
9903
+ """
9904
+ Return the indices inside a list of polygons
9905
+ :param myvects: target vector
9906
+ :param usemask: limit potential nodes to unmaksed nodes
9907
+ :param eps: epsilon for the intersection
9908
+ """
9909
+ if isinstance(myvects, zone):
9910
+ myvects = myvects.myvectors
9911
+
9912
+ alls = list(map(lambda vec: self.get_ij_inside_polygon(vec, usemask, method=method), myvects))
9913
+ #remove empty arrays
9914
+ alls = [cur for cur in alls if cur.shape[0] > 0]
9915
+ if len(alls) == 0:
9916
+ return np.empty((0, 2), dtype=int)
9917
+ # Concatenate all arrays
9918
+ mypointsij = np.concatenate(alls, axis=0)
9919
+ # Remove duplicates
9920
+ mypointsij = np.unique(mypointsij, axis=0)
9921
+ if mypointsij.shape[0] == 0:
9922
+ return np.empty((0, 2), dtype=int)
9923
+ return mypointsij
9924
+
9925
+
9713
9926
  def get_ij_inside_polygon_mpl(self, myvect: vector | Polygon, usemask:bool=True, eps:float = 0.):
9714
9927
  """
9715
9928
  Return the indices inside a polygon
@@ -11683,16 +11896,16 @@ class WolfArray(Element_To_Draw, header_wolf):
11683
11896
  try:
11684
11897
  bounds = self.get_bounds()
11685
11898
 
11686
- scale_xovery = (bounds[0][1] - bounds[0][0]) / (bounds[1][1] - bounds[1][0])
11899
+ scale_covery = (bounds[0][1] - bounds[0][0]) / (bounds[1][1] - bounds[1][0])
11687
11900
 
11688
- if scale_xovery > 1.:
11901
+ if scale_covery > 1.:
11689
11902
  # x is larger than y
11690
11903
  w = 2000
11691
- h = int(2000 / scale_xovery)
11904
+ h = int(2000 / scale_covery)
11692
11905
  else:
11693
11906
  # y is larger than x
11694
11907
  h = 2000
11695
- w = int(2000 * scale_xovery)
11908
+ w = int(2000 * scale_covery)
11696
11909
 
11697
11910
  IO_image = getWalonmap(cat, bounds[0][0], bounds[1][0],
11698
11911
  bounds[0][1], bounds[1][1],
@@ -11716,15 +11929,15 @@ class WolfArray(Element_To_Draw, header_wolf):
11716
11929
  else:
11717
11930
  try:
11718
11931
  bounds = self.get_bounds()
11719
- scale_xovery = (bounds[0][1] - bounds[0][0]) / (bounds[1][1] - bounds[1][0])
11720
- if scale_xovery > 1.:
11932
+ scale_covery = (bounds[0][1] - bounds[0][0]) / (bounds[1][1] - bounds[1][0])
11933
+ if scale_covery > 1.:
11721
11934
  # x is larger than y
11722
11935
  w = 2000
11723
- h = int(2000 / scale_xovery)
11936
+ h = int(2000 / scale_covery)
11724
11937
  else:
11725
11938
  # y is larger than x
11726
11939
  h = 2000
11727
- w = int(2000 * scale_xovery)
11940
+ w = int(2000 * scale_covery)
11728
11941
  IO_image = getNGI(cat, bounds[0][0], bounds[1][0],
11729
11942
  bounds[0][1], bounds[1][1],
11730
11943
  w=w, h=h, tofile=False) # w=self.nbx, h=self.nby
@@ -11744,15 +11957,15 @@ class WolfArray(Element_To_Draw, header_wolf):
11744
11957
  else:
11745
11958
  try:
11746
11959
  bounds = self.get_bounds()
11747
- scale_xovery = (bounds[0][1] - bounds[0][0]) / (bounds[1][1] - bounds[1][0])
11748
- if scale_xovery > 1.:
11960
+ scale_covery = (bounds[0][1] - bounds[0][0]) / (bounds[1][1] - bounds[1][0])
11961
+ if scale_covery > 1.:
11749
11962
  # x is larger than y
11750
11963
  w = 2000
11751
- h = int(2000 / scale_xovery)
11964
+ h = int(2000 / scale_covery)
11752
11965
  else:
11753
11966
  # y is larger than x
11754
11967
  h = 2000
11755
- w = int(2000 * scale_xovery)
11968
+ w = int(2000 * scale_covery)
11756
11969
  IO_image = getCartoweb(cat, bounds[0][0], bounds[1][0],
11757
11970
  bounds[0][1], bounds[1][1],
11758
11971
  w=w, h=h, tofile=False) # w=self.nbx, h=self.nby
@@ -11779,8 +11992,8 @@ class WolfArray(Element_To_Draw, header_wolf):
11779
11992
  self.origx + self.dx * self.nbx,
11780
11993
  self.origy,
11781
11994
  self.origy + self.dy * self.nby),
11782
- alpha=np.select([self.array.mask.T, ~self.array.mask.T],
11783
- [np.zeros(self.shape).T, np.ones(self.shape).T]))
11995
+ alpha=np.select([self.array.mask.T, ~self.array.mask.T],
11996
+ [np.zeros(self.shape).T, np.ones(self.shape).T * self.alpha]))
11784
11997
 
11785
11998
  if with_legend:
11786
11999
  # add a legend in a new axis
@@ -11809,7 +12022,7 @@ class WolfArray(Element_To_Draw, header_wolf):
11809
12022
  self.origy + self.dy * self.nby),
11810
12023
  vmin=vmin, vmax=vmax,
11811
12024
  alpha=np.select([self.array.mask.T, ~self.array.mask.T],
11812
- [np.zeros(self.shape).T, np.ones(self.shape).T]) )
12025
+ [np.zeros(self.shape).T, np.ones(self.shape).T * self.alpha]))
11813
12026
 
11814
12027
 
11815
12028
  if with_legend:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wolfhece
3
- Version: 2.2.42
3
+ Version: 2.2.44
4
4
  Author-email: Pierre Archambeau <pierre.archambeau@uliege.be>
5
5
  Project-URL: Homepage, https://uee.uliege.be/hece
6
6
  Project-URL: Issues, https://uee.uliege.be/hece
@@ -73,7 +73,7 @@ Requires-Dist: tabulate
73
73
  Requires-Dist: ipympl
74
74
  Requires-Dist: contextily
75
75
  Requires-Dist: pefile
76
- Requires-Dist: wolfpydike
76
+ Requires-Dist: wolfpydike==0.1.3
77
77
  Requires-Dist: PyMuPDF
78
78
  Requires-Dist: eccodes
79
79
  Requires-Dist: dataframe_image