wolfhece 2.1.16__py3-none-any.whl → 2.1.18__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/PyDraw.py +104 -3
- wolfhece/PyGuiHydrology.py +210 -31
- wolfhece/PyParams.py +4 -1
- wolfhece/PyVertexvectors.py +4 -0
- wolfhece/PyWMS.py +12 -11
- wolfhece/RatingCurve.py +18 -6
- wolfhece/Results2DGPU.py +78 -8
- wolfhece/apps/version.py +1 -1
- wolfhece/hydrology/PyWatershed.py +171 -6
- wolfhece/wolf_array.py +175 -15
- wolfhece/wolfresults_2D.py +158 -29
- {wolfhece-2.1.16.dist-info → wolfhece-2.1.18.dist-info}/METADATA +1 -1
- {wolfhece-2.1.16.dist-info → wolfhece-2.1.18.dist-info}/RECORD +16 -16
- {wolfhece-2.1.16.dist-info → wolfhece-2.1.18.dist-info}/WHEEL +0 -0
- {wolfhece-2.1.16.dist-info → wolfhece-2.1.18.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.16.dist-info → wolfhece-2.1.18.dist-info}/top_level.txt +0 -0
@@ -130,6 +130,33 @@ class Node_Watershed:
|
|
130
130
|
|
131
131
|
return np.sqrt(pow(self.x-x,2)+pow(self.y-y,2))
|
132
132
|
|
133
|
+
def get_up_nodes(self, excluded_node:list["Node_Watershed"]=[]):
|
134
|
+
"""
|
135
|
+
Get all upstream nodes
|
136
|
+
"""
|
137
|
+
|
138
|
+
all_up = [self]
|
139
|
+
all_rivers = [self] if self.river else []
|
140
|
+
all_runoff = [] if self.river else [self]
|
141
|
+
|
142
|
+
for curup in self.up:
|
143
|
+
|
144
|
+
if curup in excluded_node:
|
145
|
+
continue
|
146
|
+
|
147
|
+
all_up.append(curup)
|
148
|
+
if curup.river:
|
149
|
+
all_rivers.append(curup)
|
150
|
+
else:
|
151
|
+
all_runoff.append(curup)
|
152
|
+
|
153
|
+
up, river, runoff = curup.get_up_nodes(excluded_node)
|
154
|
+
all_up.extend(up)
|
155
|
+
all_rivers.extend(river)
|
156
|
+
all_runoff.extend(runoff)
|
157
|
+
|
158
|
+
return all_up, all_rivers, all_runoff
|
159
|
+
|
133
160
|
def get_up_nodes_same_sub(self, excluded_node:list["Node_Watershed"]=[]):
|
134
161
|
"""
|
135
162
|
Get all upstream nodes in the same sub-basin
|
@@ -162,30 +189,50 @@ class Node_Watershed:
|
|
162
189
|
|
163
190
|
return all_up, all_rivers, all_runoff
|
164
191
|
|
192
|
+
def get_up_runoff_nodes(self):
|
193
|
+
"""
|
194
|
+
Get all upstream runoff nodes
|
195
|
+
"""
|
196
|
+
|
197
|
+
all_up = [self]
|
198
|
+
for curup in self.up:
|
199
|
+
if not curup.river:
|
200
|
+
all_up += curup.get_up_runoff_nodes()
|
201
|
+
|
202
|
+
return all_up
|
203
|
+
|
165
204
|
def get_up_runoff_nodes_same_sub(self):
|
166
205
|
"""
|
167
206
|
Get all upstream runoff nodes in the same sub-basin
|
168
207
|
"""
|
169
208
|
|
170
|
-
all_up = []
|
209
|
+
all_up = [self]
|
171
210
|
for curup in self.up:
|
172
211
|
if curup.sub == self.sub and not curup.river:
|
173
|
-
all_up.append(curup)
|
174
|
-
|
175
212
|
all_up += curup.get_up_runoff_nodes_same_sub()
|
176
213
|
|
177
214
|
return all_up
|
178
215
|
|
216
|
+
|
217
|
+
def get_up_rivernodes(self):
|
218
|
+
"""
|
219
|
+
Get all upstream river nodes
|
220
|
+
"""
|
221
|
+
|
222
|
+
all_up = [self]
|
223
|
+
for curup in self.upriver:
|
224
|
+
all_up += curup.get_up_rivernodes()
|
225
|
+
|
226
|
+
return all_up
|
227
|
+
|
179
228
|
def get_up_rivernodes_same_sub(self):
|
180
229
|
"""
|
181
230
|
Get all upstream river nodes in the same sub-basin
|
182
231
|
"""
|
183
232
|
|
184
|
-
all_up = []
|
233
|
+
all_up = [self]
|
185
234
|
for curup in self.upriver:
|
186
235
|
if curup.sub == self.sub:
|
187
|
-
all_up.append(curup)
|
188
|
-
|
189
236
|
all_up += curup.get_up_rivernodes_same_sub()
|
190
237
|
|
191
238
|
return all_up
|
@@ -214,6 +261,28 @@ class Node_Watershed:
|
|
214
261
|
|
215
262
|
return np.unique(all_down).tolist()
|
216
263
|
|
264
|
+
def get_down_nodes(self):
|
265
|
+
"""
|
266
|
+
Get all downstream nodes
|
267
|
+
"""
|
268
|
+
|
269
|
+
all_down = [self]
|
270
|
+
if self.down is not None:
|
271
|
+
all_down += self.down.get_down_nodes()
|
272
|
+
|
273
|
+
return all_down
|
274
|
+
|
275
|
+
def get_down_nodes_same_sub(self):
|
276
|
+
"""
|
277
|
+
Get all downstream nodes in the same sub-basin
|
278
|
+
"""
|
279
|
+
|
280
|
+
all_down = [self]
|
281
|
+
if self.down is not None:
|
282
|
+
if self.down.sub == self.sub:
|
283
|
+
all_down += self.down.get_down_nodes_same_sub()
|
284
|
+
|
285
|
+
return all_down
|
217
286
|
|
218
287
|
class RiverSystem:
|
219
288
|
"""
|
@@ -1716,6 +1785,102 @@ class Watershed:
|
|
1716
1785
|
|
1717
1786
|
return newsub
|
1718
1787
|
|
1788
|
+
def get_xy_downstream_node(self,
|
1789
|
+
starting_node:Node_Watershed,
|
1790
|
+
limit_to_sub:bool = False):
|
1791
|
+
"""
|
1792
|
+
Récupération des coordonnées du noeud aval
|
1793
|
+
"""
|
1794
|
+
|
1795
|
+
if limit_to_sub:
|
1796
|
+
down = starting_node.get_down_nodes_same_sub()
|
1797
|
+
else:
|
1798
|
+
down = starting_node.get_down_nodes()
|
1799
|
+
|
1800
|
+
return [[cur.x, cur.y] for cur in down]
|
1801
|
+
|
1802
|
+
def get_xy_upstream_node(self,
|
1803
|
+
starting_node:Node_Watershed,
|
1804
|
+
limit_to_sub:bool = False,
|
1805
|
+
limit_to_river:bool = False,
|
1806
|
+
limit_to_runoff:bool = False) -> list[list[float]]:
|
1807
|
+
"""
|
1808
|
+
Récupération des coordonnées des noeuds amont
|
1809
|
+
"""
|
1810
|
+
|
1811
|
+
if limit_to_sub:
|
1812
|
+
|
1813
|
+
if limit_to_river:
|
1814
|
+
up = starting_node.get_up_rivernodes_same_sub()
|
1815
|
+
elif limit_to_runoff:
|
1816
|
+
up = starting_node.get_up_runoff_nodes_same_sub()
|
1817
|
+
else:
|
1818
|
+
up, all_river, all_runoff = starting_node.get_up_nodes_same_sub()
|
1819
|
+
|
1820
|
+
else:
|
1821
|
+
if limit_to_river:
|
1822
|
+
up = starting_node.get_up_rivernodes()
|
1823
|
+
elif limit_to_runoff:
|
1824
|
+
up = starting_node.get_up_runoff_nodes()
|
1825
|
+
else:
|
1826
|
+
up, all_river, all_runoff = starting_node.get_up_nodes()
|
1827
|
+
|
1828
|
+
return [[cur.x, cur.y] for cur in up]
|
1829
|
+
|
1830
|
+
def get_array_from_upstream_node(self,
|
1831
|
+
starting_node:Node_Watershed,
|
1832
|
+
limit_to_sub:bool = False):
|
1833
|
+
"""
|
1834
|
+
Récupération de l'array à partir d'un noeud amont
|
1835
|
+
"""
|
1836
|
+
|
1837
|
+
up = self.get_xy_upstream_node(starting_node, limit_to_sub=limit_to_sub)
|
1838
|
+
|
1839
|
+
xmin = min([x[0] for x in up])
|
1840
|
+
xmax = max([x[0] for x in up])
|
1841
|
+
ymin = min([x[1] for x in up])
|
1842
|
+
ymax = max([x[1] for x in up])
|
1843
|
+
|
1844
|
+
newhead = header_wolf()
|
1845
|
+
newhead.dx = self.header.dx
|
1846
|
+
newhead.dy = self.header.dy
|
1847
|
+
|
1848
|
+
newhead.origx = xmin - self.header.dx/2. - self.header.dx
|
1849
|
+
newhead.origy = ymin - self.header.dy/2. - self.header.dy
|
1850
|
+
|
1851
|
+
newhead.nbx = int(np.ceil((xmax - xmin) / self.header.dx) + 3)
|
1852
|
+
newhead.nby = int(np.ceil((ymax - ymin) / self.header.dy) + 3)
|
1853
|
+
|
1854
|
+
if newhead.nbx == 0 or newhead.nby == 0:
|
1855
|
+
logging.error(_('No upstream nodes found!'))
|
1856
|
+
return None
|
1857
|
+
|
1858
|
+
newarray = WolfArray(srcheader=newhead)
|
1859
|
+
newarray.array[:,:] = 0.
|
1860
|
+
|
1861
|
+
ij = newhead.xy2ij_np(up)
|
1862
|
+
|
1863
|
+
newarray.array[ij[:,0], ij[:,1]] = 1.
|
1864
|
+
|
1865
|
+
newarray.mask_data(0.)
|
1866
|
+
|
1867
|
+
return newarray
|
1868
|
+
|
1869
|
+
def get_vector_from_upstream_node(self,
|
1870
|
+
starting_node:Node_Watershed,
|
1871
|
+
limit_to_sub:bool = False):
|
1872
|
+
""" Return a vector contouring the upstream area """
|
1873
|
+
|
1874
|
+
up_array = self.get_array_from_upstream_node(starting_node, limit_to_sub=limit_to_sub)
|
1875
|
+
|
1876
|
+
if up_array is None:
|
1877
|
+
return None
|
1878
|
+
|
1879
|
+
__, __, vect, __ = up_array.suxsuy_contour()
|
1880
|
+
|
1881
|
+
vect.find_minmax()
|
1882
|
+
return vect
|
1883
|
+
|
1719
1884
|
def get_subwatershed(self, idx_sorted_or_name:int | str) -> SubWatershed:
|
1720
1885
|
"""
|
1721
1886
|
Récupération d'un sous-bassin sur base de l'index trié
|
wolfhece/wolf_array.py
CHANGED
@@ -357,12 +357,23 @@ class header_wolf():
|
|
357
357
|
:return : numpy array containing (i, j, [k]) indices - shape (n, 2) or (n, 3)
|
358
358
|
"""
|
359
359
|
|
360
|
-
|
360
|
+
if isinstance(xy,tuple):
|
361
|
+
if len(xy) == 2:
|
362
|
+
if (isinstance(xy[0],np.ndarray)) and (isinstance(xy[1],np.ndarray)):
|
363
|
+
if len(xy[0]) == len(xy[1]):
|
364
|
+
locxy = np.vstack((xy[0], xy[1])).T
|
365
|
+
logging.warning(_('get_ij_from_xy_array - xy is a tuple of 2 arrays, it is converted to a 2D array'))
|
366
|
+
else:
|
367
|
+
locxy = np.array(xy)
|
368
|
+
elif isinstance(xy,list):
|
369
|
+
locxy = np.array(xy)
|
370
|
+
else:
|
371
|
+
locxy = xy.copy()
|
361
372
|
|
362
373
|
if forcedims2:
|
363
|
-
locij = np.zeros((
|
374
|
+
locij = np.zeros((locxy.shape[0],2), dtype=np.int32)
|
364
375
|
else:
|
365
|
-
locij = np.zeros(
|
376
|
+
locij = np.zeros(locxy.shape, dtype=np.int32)
|
366
377
|
|
367
378
|
locxy[:,0] -= self.origx
|
368
379
|
locxy[:,1] -= self.origy
|
@@ -446,7 +457,7 @@ class header_wolf():
|
|
446
457
|
"""
|
447
458
|
Converts array coordinates (numpy cells) to this array's world coodinates.
|
448
459
|
|
449
|
-
:param ij = numpy array containing (i, j, [k]) indices
|
460
|
+
:param ij = numpy array containing (i, j, [k]) indices - shape (n, 2) or (n, 3)
|
450
461
|
:param scale = scaling of the spatial resolution (dx,dy,[dz])
|
451
462
|
:param aswolf = if True, input is one-based (as Wolf VB6 or Fortran), otherwise 0-based (default Python standard)
|
452
463
|
:param abs = if True, add translation to results (x, y, [z]) (coordinate to global space)
|
@@ -464,7 +475,18 @@ class header_wolf():
|
|
464
475
|
if len(ij[0]) == len(ij[1]):
|
465
476
|
ij = np.vstack((ij[0], ij[1])).T
|
466
477
|
logging.warning(_('get_xy_from_ij_array - ij is a tuple of 2 arrays, it is converted to a 2D array'))
|
467
|
-
|
478
|
+
else:
|
479
|
+
ij = np.array(ij)
|
480
|
+
|
481
|
+
elif isinstance(ij,list):
|
482
|
+
if len(ij) == 2:
|
483
|
+
if (isinstance(ij[0],np.ndarray)) and (isinstance(ij[1],np.ndarray)):
|
484
|
+
if len(ij[0]) == len(ij[1]):
|
485
|
+
ij = np.vstack((ij[0], ij[1])).T
|
486
|
+
logging.warning(_('get_xy_from_ij_array - ij is a list of 2 arrays, it is converted to a 2D array'))
|
487
|
+
else:
|
488
|
+
ij = np.array(ij)
|
489
|
+
|
468
490
|
if abs:
|
469
491
|
tr_x = self.translx
|
470
492
|
tr_y = self.transly
|
@@ -529,7 +551,7 @@ class header_wolf():
|
|
529
551
|
|
530
552
|
:return : numpy array containing (i, j, [k]) indices - shape (n, 2) or (n, 3)
|
531
553
|
"""
|
532
|
-
return self.
|
554
|
+
return self.get_ij_from_xy_array(xy, scale, aswolf, abs)
|
533
555
|
|
534
556
|
def xyz2ijk_np(self, xyz:np.ndarray, scale:float=1., aswolf:bool=False, abs:bool=True) -> np.ndarray:
|
535
557
|
""" alias for get_xy_from_ij_array """
|
@@ -627,6 +649,49 @@ class header_wolf():
|
|
627
649
|
filename = str(filename)
|
628
650
|
|
629
651
|
if filename.endswith('.tif'):
|
652
|
+
from osgeo import gdal
|
653
|
+
|
654
|
+
raster:gdal.Dataset
|
655
|
+
raster = gdal.Open(filename)
|
656
|
+
geotr = raster.GetGeoTransform()
|
657
|
+
self.dx = geotr[1]
|
658
|
+
self.dy = abs(geotr[5])
|
659
|
+
self.origx = geotr[0]
|
660
|
+
self.origy = geotr[3]
|
661
|
+
self.nbx = raster.RasterXSize
|
662
|
+
self.nby = raster.RasterYSize
|
663
|
+
|
664
|
+
"""
|
665
|
+
https://docs.qgis.org/3.34/en/docs/user_manual/processing_algs/gdal/rasterconversion.html
|
666
|
+
|
667
|
+
0 — Use Input Layer Data Type
|
668
|
+
1 — Byte (Eight bit unsigned integer (quint8))
|
669
|
+
2 — Int16 (Sixteen bit signed integer (qint16))
|
670
|
+
3 — UInt16 (Sixteen bit unsigned integer (quint16))
|
671
|
+
4 — UInt32 (Thirty two bit unsigned integer (quint32))
|
672
|
+
5 — Int32 (Thirty two bit signed integer (qint32))
|
673
|
+
6 — Float32 (Thirty two bit floating point (float))
|
674
|
+
7 — Float64 (Sixty four bit floating point (double))
|
675
|
+
8 — CInt16 (Complex Int16)
|
676
|
+
9 — CInt32 (Complex Int32)
|
677
|
+
10 — CFloat32 (Complex Float32)
|
678
|
+
11 — CFloat64 (Complex Float64)
|
679
|
+
12 — Int8 (Eight bit signed integer (qint8))
|
680
|
+
"""
|
681
|
+
|
682
|
+
dtype = raster.GetRasterBand(1).DataType
|
683
|
+
|
684
|
+
if dtype in [1, 4]:
|
685
|
+
self.wolftype = WOLF_ARRAY_FULL_INTEGER
|
686
|
+
elif dtype ==6:
|
687
|
+
self.wolftype = WOLF_ARRAY_FULL_SINGLE
|
688
|
+
elif dtype == 7:
|
689
|
+
self.wolftype = WOLF_ARRAY_FULL_DOUBLE
|
690
|
+
else:
|
691
|
+
logging.error(_('The datatype of the raster is not supported -- {}'.format(dtype)))
|
692
|
+
logging.error(_('Please convert the raster to a supported datatype - or upgrade the code to support this datatype'))
|
693
|
+
logging.error(_('See : read_txt_header and import_geotif in wolf_array.py'))
|
694
|
+
return
|
630
695
|
return
|
631
696
|
|
632
697
|
if filename.endswith('.flt'):
|
@@ -1192,8 +1257,10 @@ class Ops_Array(wx.Frame):
|
|
1192
1257
|
self.vectmp = vector(name='tmp')
|
1193
1258
|
self.fnsave = ''
|
1194
1259
|
|
1195
|
-
self.myzonetmp.add_vector(self.vectmp)
|
1196
|
-
self.myzones.add_zone(self.myzonetmp)
|
1260
|
+
self.myzonetmp.add_vector(self.vectmp, forceparent=True)
|
1261
|
+
self.myzones.add_zone(self.myzonetmp, forceparent=True)
|
1262
|
+
|
1263
|
+
self.myzones.mapviewer = mapviewer
|
1197
1264
|
|
1198
1265
|
if self.wx_exists:
|
1199
1266
|
self.set_GUI()
|
@@ -2123,14 +2190,22 @@ class Ops_Array(wx.Frame):
|
|
2123
2190
|
def OnManageVectors(self, event:wx.MouseEvent):
|
2124
2191
|
""" Open vector manager """
|
2125
2192
|
|
2193
|
+
self.show_structure_OpsVectors()
|
2194
|
+
|
2195
|
+
def show_structure_OpsVectors(self):
|
2196
|
+
""" Show the structure of the vector manager """
|
2197
|
+
|
2126
2198
|
if self.mapviewer is not None:
|
2127
2199
|
if self.mapviewer.linked:
|
2200
|
+
# The viewer is linked to other viewers
|
2128
2201
|
if self.mapviewer.link_shareopsvect:
|
2129
|
-
|
2130
|
-
|
2131
|
-
|
2202
|
+
# The viewer shares the vector manager with the other viewers
|
2203
|
+
if self.myzones.get_mapviewer() in self.mapviewer.linkedList:
|
2204
|
+
# The viewer is in the active linked viewers
|
2205
|
+
self.myzones.showstructure()
|
2206
|
+
return
|
2132
2207
|
|
2133
|
-
self.myzones.showstructure()
|
2208
|
+
self.myzones.showstructure()
|
2134
2209
|
|
2135
2210
|
def OnLoadvec(self, event:wx.MouseEvent):
|
2136
2211
|
""" Load vector file """
|
@@ -2593,6 +2668,12 @@ class SelectionData():
|
|
2593
2668
|
self.hideselection = False
|
2594
2669
|
self.numlist_select = 0 # OpenGL list index
|
2595
2670
|
|
2671
|
+
def set_selection_from_list_xy(self, xylist: list[tuple[float, float]]):
|
2672
|
+
""" Set the current selection from a list of (x, y) coordinates """
|
2673
|
+
|
2674
|
+
self.myselection = xylist
|
2675
|
+
self.update_nb_nodes_selection()
|
2676
|
+
|
2596
2677
|
@property
|
2597
2678
|
def dx(self) -> float:
|
2598
2679
|
""" Resolution in x """
|
@@ -4285,6 +4366,11 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4285
4366
|
|
4286
4367
|
return self.mngselection
|
4287
4368
|
|
4369
|
+
@property
|
4370
|
+
def Operations(self) -> Ops_Array:
|
4371
|
+
""" Return the operations on the array """
|
4372
|
+
return self.myops
|
4373
|
+
|
4288
4374
|
@property
|
4289
4375
|
def active_blocks(self) -> list["WolfArray"]:
|
4290
4376
|
""" Return the active blocks """
|
@@ -4623,9 +4709,76 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4623
4709
|
|
4624
4710
|
if crop is not None :
|
4625
4711
|
if os.path.exists(fn):
|
4712
|
+
|
4713
|
+
tmpdx = self.dx
|
4714
|
+
|
4715
|
+
fn_crop = fn + '_crop.tif'
|
4716
|
+
if type(crop) is np.ndarray:
|
4717
|
+
pass
|
4718
|
+
elif type(crop) is list:
|
4719
|
+
pass
|
4720
|
+
else:
|
4721
|
+
if not self.wx_exists:
|
4722
|
+
logging.error(_('Crop must be a list or a numpy array with 4 values - xmin, xmax, ymin, ymax'))
|
4723
|
+
return
|
4724
|
+
|
4725
|
+
raster:gdal.Dataset
|
4726
|
+
raster = gdal.Open(fn)
|
4727
|
+
geotr = raster.GetGeoTransform()
|
4728
|
+
self.dx = geotr[1]
|
4729
|
+
self.dy = abs(geotr[5])
|
4730
|
+
|
4731
|
+
|
4732
|
+
newcrop = CropDialog(None)
|
4733
|
+
|
4734
|
+
if self.wx_exists:
|
4735
|
+
bounds = self.mapviewer.get_canvas_bounds()
|
4736
|
+
|
4737
|
+
newcrop.dx.Value = str(self.dx)
|
4738
|
+
newcrop.dy.Value = str(self.dy)
|
4739
|
+
|
4740
|
+
newcrop.dx.Enable(False)
|
4741
|
+
newcrop.dy.Enable(False)
|
4742
|
+
|
4743
|
+
newcrop.ox.Value = str(float((bounds[0] // 50.) * 50.))
|
4744
|
+
newcrop.ex.Value = str(float((bounds[2] // 50.) * 50.))
|
4745
|
+
newcrop.oy.Value = str(float((bounds[1] // 50.) * 50.))
|
4746
|
+
newcrop.ey.Value = str(float((bounds[3] // 50.) * 50.))
|
4747
|
+
|
4748
|
+
badvalues = True
|
4749
|
+
while badvalues:
|
4750
|
+
badvalues = False
|
4751
|
+
|
4752
|
+
ret = newcrop.ShowModal()
|
4753
|
+
if ret == wx.ID_CANCEL:
|
4754
|
+
newcrop.Destroy()
|
4755
|
+
return
|
4756
|
+
else:
|
4757
|
+
crop = [float(newcrop.ox.Value), float(newcrop.ex.Value),
|
4758
|
+
float(newcrop.oy.Value), float(newcrop.ey.Value)]
|
4759
|
+
|
4760
|
+
tmpdx = float(newcrop.dx.Value)
|
4761
|
+
tmpdy = float(newcrop.dy.Value)
|
4762
|
+
|
4763
|
+
if self.dx != tmpdx or self.dy != tmpdy:
|
4764
|
+
if tmpdx / self.dx != tmpdy / self.dy:
|
4765
|
+
badvalues = True
|
4766
|
+
|
4767
|
+
newcrop.Destroy()
|
4768
|
+
|
4626
4769
|
xmin, xmax, ymin, ymax = crop
|
4627
|
-
|
4628
|
-
|
4770
|
+
|
4771
|
+
with wx.FileDialog(None, _('Save the cropped file for later'), wildcard="Tiff files (*.tif)|*.tif",
|
4772
|
+
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as fileDialog:
|
4773
|
+
|
4774
|
+
if fileDialog.ShowModal() == wx.ID_CANCEL:
|
4775
|
+
return
|
4776
|
+
|
4777
|
+
fn_crop = fileDialog.GetPath()
|
4778
|
+
|
4779
|
+
|
4780
|
+
gdal.Translate(fn_crop, fn, projWin=[xmin, ymax, xmax, ymin])
|
4781
|
+
fn = fn_crop
|
4629
4782
|
|
4630
4783
|
raster:gdal.Dataset
|
4631
4784
|
raster = gdal.Open(fn)
|
@@ -6409,6 +6562,13 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6409
6562
|
else:
|
6410
6563
|
newcrop = CropDialog(None)
|
6411
6564
|
|
6565
|
+
if self.mapviewer is not None:
|
6566
|
+
bounds = self.mapviewer.get_canvas_bounds()
|
6567
|
+
newcrop.ox.Value = float((bounds[0] // 50.) * 50.)
|
6568
|
+
newcrop.ex.Value = float((bounds[2] // 50.) * 50.)
|
6569
|
+
newcrop.oy.Value = float((bounds[1] // 50.) * 50.)
|
6570
|
+
newcrop.ey.Value = float((bounds[3] // 50.) * 50.)
|
6571
|
+
|
6412
6572
|
badvalues = True
|
6413
6573
|
while badvalues:
|
6414
6574
|
badvalues = False
|
@@ -7663,7 +7823,7 @@ class WolfArrayMB(WolfArray):
|
|
7663
7823
|
"""
|
7664
7824
|
|
7665
7825
|
if copyarray:
|
7666
|
-
arr = WolfArray(mold=arr)
|
7826
|
+
arr = WolfArray(mold=arr, nullvalue=arr.nullvalue)
|
7667
7827
|
force_idx = True
|
7668
7828
|
|
7669
7829
|
if force_idx:
|