2
2
import logging
3
3
from typing import Tuple
4
4
5
+ from osgeo import osr
5
6
import numpy as np
6
7
from lxml import etree , isoschematron
7
8
@@ -86,7 +87,7 @@ def create_template(cls, name):
86
87
elevation .attrs .create (cls ._bag_elevation_min_ev , 0.0 , shape = (), dtype = np .float32 )
87
88
elevation .attrs .create (cls ._bag_elevation_max_ev , 0.0 , shape = (), dtype = np .float32 )
88
89
89
- new_bag .create_dataset (cls ._bag_metadata , shape = (1 , ), dtype = "S1" )
90
+ new_bag .create_dataset (cls ._bag_metadata , shape = (1 ,), dtype = "S1" )
90
91
91
92
tracking_list = new_bag .create_dataset (cls ._bag_tracking_list , shape = (), dtype = cls ._bag_tracking_list_type )
92
93
tracking_list .attrs .create (cls ._bag_tracking_list_len , 0 , shape = (), dtype = np .uint32 )
@@ -281,6 +282,51 @@ def uncertainty_min_max(self) -> Tuple[float, float]:
281
282
282
283
return unc_min , unc_max
283
284
285
+ def uncertainty_greater_than (self , th : float ) -> list [list [int | float ]]:
286
+ rows , cols = self .uncertainty_shape ()
287
+ # logger.debug('shape: %s, %s' % (rows, cols))
288
+
289
+ self .populate_metadata ()
290
+
291
+ x_min = self .meta .sw [0 ]
292
+ y_min = self .meta .sw [1 ]
293
+ x_res = self .meta .res_x
294
+ y_res = self .meta .res_y
295
+ logger .debug ("info: %f %f %f %f" % (x_min , y_min , x_res , y_res ))
296
+
297
+ in_srs = osr .SpatialReference ()
298
+ in_srs .ImportFromWkt (self .meta .wkt_srs )
299
+ out_srs = osr .SpatialReference ()
300
+ out_srs .ImportFromEPSG (4326 )
301
+ ctr = osr .CoordinateTransformation (in_srs , out_srs )
302
+
303
+ mem_row = cols * 32 / 1024 / 1024
304
+ # mem = mem_row * rows
305
+ # logger.debug('estimated memory: %.1f MB' % mem)
306
+ chunk_size = 8096
307
+ chunk_rows = int (chunk_size / mem_row ) + 1
308
+ # logger.debug('nr of rows per chunk: %s' % chunk_rows)
309
+
310
+ xyz = list ()
311
+ for start in range (0 , rows , chunk_rows ):
312
+ stop = start + chunk_rows
313
+ if stop > rows :
314
+ stop = rows
315
+
316
+ unc = self .uncertainty (row_range = slice (start , stop ))
317
+ ijs = np .argwhere (unc > th )
318
+ for ij in ijs :
319
+ i = ij [0 ]
320
+ j = ij [1 ]
321
+ e = x_min + j * x_res
322
+ n = y_min + i * y_res
323
+ lon , lat , _ = ctr .TransformPoint (e , n )
324
+ u = float (unc [i , j ])
325
+ xyz .append ([float (lat ), float (lon ), u ])
326
+ # logger.info("%s" % (xyz[-1]))
327
+
328
+ return xyz
329
+
284
330
def vr_uncertainty_min_max (self ) -> Tuple [float , float ]:
285
331
# rows, cols = self.vr_refinements_shape()
286
332
# logger.debug('shape: %s, %s' % (rows, cols))
@@ -293,7 +339,64 @@ def vr_uncertainty_min_max(self) -> Tuple[float, float]:
293
339
294
340
return np .nanmin (vr_unc ), np .nanmax (vr_unc )
295
341
342
+ def vr_uncertainty_greater_than (self , th : float ) -> list [list [int | float ]]:
343
+ # rows, cols = self.vr_refinements_shape()
344
+ # logger.debug('shape: %s, %s' % (rows, cols))
345
+
346
+ self .populate_metadata ()
347
+
348
+ x_min = self .meta .sw [0 ]
349
+ y_min = self .meta .sw [1 ]
350
+ x_res = self .meta .res_x
351
+ y_res = self .meta .res_y
352
+ logger .debug ("info: %f %f %f %f" % (x_min , y_min , x_res , y_res ))
353
+
354
+ in_srs = osr .SpatialReference ()
355
+ in_srs .ImportFromWkt (self .meta .wkt_srs )
356
+ out_srs = osr .SpatialReference ()
357
+ out_srs .ImportFromEPSG (4326 )
358
+ ctr = osr .CoordinateTransformation (in_srs , out_srs )
359
+
360
+ vr_unc = self [BAGFile ._bag_varres_refinements ][0 ]['depth_uncrt' ]
361
+ mask = vr_unc == BAGFile .BAG_NAN
362
+ vr_unc [mask ] = np .nan
363
+
364
+ xyz_dict = dict ()
365
+ for idx , unc in enumerate (vr_unc ):
366
+ if unc > th :
367
+ xyz_dict [idx ] = unc
368
+
369
+ logger .info ("Located %d outliers" % len (xyz_dict ))
370
+
371
+ xyz = list ()
372
+ vr_ixs = self [BAGFile ._bag_varres_metadata ][:]
373
+ rows , cols = vr_ixs .shape
374
+ i = 0
375
+ for sg_r in range (rows ):
376
+ for sg_c in range (cols ):
377
+ if vr_ixs [sg_r , sg_c ][1 ] == 0 :
378
+ continue
379
+ ir = vr_ixs [sg_r , sg_c ][1 ] * vr_ixs [sg_r , sg_c ][2 ]
380
+ for ir_idx in range (ir ):
381
+ j = i + ir_idx
382
+ if j not in xyz_dict :
383
+ continue
384
+ unc = float (xyz_dict [j ])
385
+ logger .debug ("Located outliers: %d %f in %d,%d: %s" % (j , unc , sg_r , sg_c , vr_ixs [sg_r , sg_c ]))
386
+ # vr_ixs[r, c]
387
+ rfn_r = ir_idx // vr_ixs [sg_r , sg_c ][1 ]
388
+ rfn_c = ir_idx % vr_ixs [sg_r , sg_c ][1 ]
389
+ logger .debug ("%d > %d,%d" % (ir_idx , rfn_r , rfn_c ))
390
+ e = x_min + (sg_c - 0.5 ) * x_res + vr_ixs [sg_r , sg_c ][5 ] + rfn_c * vr_ixs [sg_r , sg_c ][3 ]
391
+ n = y_min + (sg_r - 0.5 ) * y_res + vr_ixs [sg_r , sg_c ][6 ] + rfn_r * vr_ixs [sg_r , sg_c ][4 ]
392
+ lon , lat , _ = ctr .TransformPoint (e , n )
393
+ xyz .append ([float (lat ), float (lon ), unc ])
394
+ i += ir
395
+
396
+ return xyz
397
+
296
398
def has_density (self ):
399
+ # noinspection PyBroadException
297
400
try :
298
401
self [BAGFile ._bag_elevation_solution ]['num_soundings' ]
299
402
except Exception :
@@ -437,7 +540,7 @@ def substitute_metadata(self, path):
437
540
438
541
del self [BAGFile ._bag_metadata ]
439
542
xml_sz = len (xml_string )
440
- ds = self .create_dataset (self ._bag_metadata , (xml_sz , ), dtype = "S1" )
543
+ ds = self .create_dataset (self ._bag_metadata , (xml_sz ,), dtype = "S1" )
441
544
for i , bt in enumerate (xml_string ):
442
545
ds [i ] = bytes ([bt ])
443
546
@@ -566,7 +669,7 @@ def modify_wkt_prj(self, wkt_hor, wkt_ver=None):
566
669
567
670
new_xml = etree .tostring (xml_tree , pretty_print = True )
568
671
del self [BAGFile ._bag_metadata ]
569
- ds = self .create_dataset (BAGFile ._bag_metadata , shape = (len (new_xml ), ), dtype = "S1" )
672
+ ds = self .create_dataset (BAGFile ._bag_metadata , shape = (len (new_xml ),), dtype = "S1" )
570
673
for i , x in enumerate (new_xml ):
571
674
ds [i ] = bytes ([x ])
572
675
0 commit comments