1919
2020from shapely .geometry import (
2121 LineString ,
22- MultiLineString ,
2322 shape
2423)
2524from shapely .ops import linemerge
25+ from shapelysmooth import chaikin_smooth
2626
2727from fct .config import (
2828 config ,
@@ -289,6 +289,24 @@ def FixOrientation(medialaxis, params):
289289
290290 return medialaxis
291291
292+
293+ def OrderAndMergeLines (geoms , params ):
294+ """
295+ Order list of LineString from upstream to downstream
296+ """
297+ measure_raster = params .measure .filename ()
298+
299+ coords = [list (l .coords ) for l in geoms ]
300+
301+ with rio .open (measure_raster ) as ds :
302+ heights = [(np .median (list (ds .sample (c ))).item (), c ) for c in coords ]
303+ heights = sorted (heights , key = lambda x : x [0 ], reverse = True )
304+
305+ coords = [l [1 ] for l in heights if l [0 ] != ds .nodata and l [0 ] > 0 ]
306+ medialaxis = LineString ([i for sublist in coords for i in sublist ])
307+
308+ return medialaxis
309+
292310def MedialAxis (params ):
293311 """
294312 Calculate corridor medial axis
@@ -380,7 +398,13 @@ def open_medialaxis_sink(output, crs, driver='ESRI Shapefile'):
380398 continue
381399
382400 lines = sorted (lines , key = lambda line : - line .length )
383- medialaxis = lines [0 ]
401+ # medialaxis = lines[0]
402+ filtered = [l for l in lines if l .length > 20 * params .swath_length ]
403+
404+ if not filtered :
405+ medialaxis = lines [0 ]
406+ else :
407+ medialaxis = linemerge (filtered )
384408
385409 else :
386410
@@ -399,7 +423,8 @@ def open_medialaxis_sink(output, crs, driver='ESRI Shapefile'):
399423
400424 geoms .append (FixOrientation (geom , params ))
401425
402- medialaxis = MultiLineString (geoms )
426+ medialaxis = OrderAndMergeLines (geoms , params )
427+ # medialaxis = MultiLineString(geoms)
403428
404429 else :
405430
@@ -551,21 +576,15 @@ def open_output_sink(filename, options):
551576
552577 widths = np .interp (measures , smoothed .measure , smoothed .values )
553578
554- # simplified = LineString(
555- # smooth_chaikin(
556- # np.array([
557- # c for c, weight, width
558- # in zip(coords, weights, widths)
559- # if filtr(weight, width)
560- # ])))
561-
562579 simplified = LineString ([
563580 coord for coord , weight , width
564581 in zip (coords , weights , widths )
565582 if filtr (weight , width )
566583 ])
567584
585+ smoothed = chaikin_smooth (simplified , iters = 2 )
586+
568587 # print(len(simplified.coords))
569- sink .send ((axis , simplified ))
588+ sink .send ((axis , smoothed ))
570589
571590 sink .close ()
0 commit comments