From 4bc0a7157e54aee32e420a85f41f85dd729de6ec Mon Sep 17 00:00:00 2001 From: esgn <5435148+esgn@users.noreply.github.com> Date: Mon, 9 Jan 2023 11:55:38 +0100 Subject: [PATCH 1/6] cascaded_union is deprecated. Moving to unary_union --- building_boundary/shapes/alpha_shape.py | 6 +++--- building_boundary/shapes/fit.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/building_boundary/shapes/alpha_shape.py b/building_boundary/shapes/alpha_shape.py index 577c26d..9c8d929 100644 --- a/building_boundary/shapes/alpha_shape.py +++ b/building_boundary/shapes/alpha_shape.py @@ -14,10 +14,10 @@ from CGAL.CGAL_Alpha_shape_2 import Alpha_shape_2 from CGAL.CGAL_Alpha_shape_2 import REGULAR CGAL_AVAILABLE = True - cascaded_union = None + unary_union = None Delaunay = None except ImportError: - from shapely.ops import cascaded_union + from shapely.ops import unary_union from scipy.spatial import Delaunay CGAL_AVAILABLE = False Point_2 = None @@ -144,7 +144,7 @@ def alpha_shape_python(points, alpha): if circum_r < 1.0 / alpha: triangles.append(Polygon(points[t])) - alpha_shape = cascaded_union(triangles) + alpha_shape = unary_union(triangles) if type(alpha_shape) == MultiPolygon: alpha_shape = MultiPolygon([Polygon(s.exterior) for s in alpha_shape]) else: diff --git a/building_boundary/shapes/fit.py b/building_boundary/shapes/fit.py index 39ce9d8..a057814 100644 --- a/building_boundary/shapes/fit.py +++ b/building_boundary/shapes/fit.py @@ -7,7 +7,7 @@ import numpy as np from scipy.spatial import ConvexHull from shapely.geometry import Polygon -from shapely.ops import cascaded_union +from shapely.ops import unary_union import concave_hull @@ -45,7 +45,7 @@ def compute_shape(points, alpha=None, k=None): if k is not None: boundary_points = concave_hull.compute(points, k, True) shape_ch = Polygon(boundary_points).buffer(0) - shape = cascaded_union([shape, shape_ch]) + shape = unary_union([shape, shape_ch]) if type(shape) != Polygon: shape = max(shape, key=lambda s: s.area) From f1d89218f16e45ad91a7811cd1e680ade0298e2c Mon Sep 17 00:00:00 2001 From: esgn <5435148+esgn@users.noreply.github.com> Date: Mon, 9 Jan 2023 13:15:19 +0100 Subject: [PATCH 2/6] .geoms is necessary to iterate on shapely MultiPolygon --- building_boundary/shapes/alpha_shape.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/building_boundary/shapes/alpha_shape.py b/building_boundary/shapes/alpha_shape.py index 9c8d929..01ff2f4 100644 --- a/building_boundary/shapes/alpha_shape.py +++ b/building_boundary/shapes/alpha_shape.py @@ -146,7 +146,7 @@ def alpha_shape_python(points, alpha): alpha_shape = unary_union(triangles) if type(alpha_shape) == MultiPolygon: - alpha_shape = MultiPolygon([Polygon(s.exterior) for s in alpha_shape]) + alpha_shape = MultiPolygon([Polygon(s.exterior) for s in alpha_shape.geoms]) else: alpha_shape = Polygon(alpha_shape.exterior) From f50ed1ca1a5042770698a78820342203d7c1d46d Mon Sep 17 00:00:00 2001 From: esgn <5435148+esgn@users.noreply.github.com> Date: Mon, 9 Jan 2023 13:53:19 +0100 Subject: [PATCH 3/6] another .geoms needed here to iterate over multipolygon --- building_boundary/shapes/fit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/building_boundary/shapes/fit.py b/building_boundary/shapes/fit.py index a057814..7861f4e 100644 --- a/building_boundary/shapes/fit.py +++ b/building_boundary/shapes/fit.py @@ -48,7 +48,7 @@ def compute_shape(points, alpha=None, k=None): shape = unary_union([shape, shape_ch]) if type(shape) != Polygon: - shape = max(shape, key=lambda s: s.area) + shape = max(shape.geoms, key=lambda s: s.area) elif k is not None: boundary_points = concave_hull.compute(points, k, True) From ccd3f4cbbb6af1e2b83125863dd312caefca6b33 Mon Sep 17 00:00:00 2001 From: esgn <5435148+esgn@users.noreply.github.com> Date: Mon, 9 Jan 2023 14:03:48 +0100 Subject: [PATCH 4/6] handle sqrt of negative number case --- building_boundary/shapes/alpha_shape.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/building_boundary/shapes/alpha_shape.py b/building_boundary/shapes/alpha_shape.py index 01ff2f4..701c43b 100644 --- a/building_boundary/shapes/alpha_shape.py +++ b/building_boundary/shapes/alpha_shape.py @@ -110,7 +110,11 @@ def triangle_geometry(triangle): # Semiperimeter of triangle s = (a + b + c) / 2.0 # Area of triangle by Heron's formula - area = math.sqrt(s * (s - a) * (s - b) * (s - c)) + area = 0 + try: + area = math.sqrt(s * (s - a) * (s - b) * (s - c)) + except ValueError: + pass if area != 0: circum_r = (a * b * c) / (4.0 * area) else: From 43ffce4c67cfe7ee9c3811118a404637a754a2df Mon Sep 17 00:00:00 2001 From: esgn <5435148+esgn@users.noreply.github.com> Date: Mon, 9 Jan 2023 14:56:52 +0100 Subject: [PATCH 5/6] check if concave_hull polygon is valid before union --- building_boundary/shapes/fit.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/building_boundary/shapes/fit.py b/building_boundary/shapes/fit.py index 7861f4e..92ee088 100644 --- a/building_boundary/shapes/fit.py +++ b/building_boundary/shapes/fit.py @@ -45,7 +45,8 @@ def compute_shape(points, alpha=None, k=None): if k is not None: boundary_points = concave_hull.compute(points, k, True) shape_ch = Polygon(boundary_points).buffer(0) - shape = unary_union([shape, shape_ch]) + if shape_ch.is_valid: + shape = unary_union([shape, shape_ch]) if type(shape) != Polygon: shape = max(shape.geoms, key=lambda s: s.area) From e7e0460ae30e7b321e861e4bde4f92fce9ff3d13 Mon Sep 17 00:00:00 2001 From: esgn <5435148+esgn@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:22:15 +0100 Subject: [PATCH 6/6] np.bool support has been dropped in numpy 1.24.0 --- building_boundary/core/segmentation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/building_boundary/core/segmentation.py b/building_boundary/core/segmentation.py index cc33c45..bcfe669 100644 --- a/building_boundary/core/segmentation.py +++ b/building_boundary/core/segmentation.py @@ -277,7 +277,7 @@ def boundary_segmentation(points, distance): shift = np.min(points_shifted, axis=0) points_shifted -= shift - mask = np.ones(len(points_shifted), dtype=np.bool) + mask = np.ones(len(points_shifted), dtype=bool) indices = np.arange(len(points_shifted)) segments = []