Coverage for pyguymer3/geo/extract_polys.py: 49%
51 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-08 18:47 +0000
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-08 18:47 +0000
1#!/usr/bin/env python3
3# Define function ...
4def extract_polys(
5 shape,
6 /,
7 *,
8 onlyValid = False,
9 repair = False,
10):
11 """Extract the Polygons from the shape
13 This function accepts any Shapely geometry and returns a flat list of all of
14 the Polygons contained within.
16 Parameters
17 ----------
18 shape : list, shapely.geometry.point.Point, shapely.geometry.multipoint.MultiPoint, shapely.geometry.polygon.LinearRing, shapely.geometry.linestring.LineString, shapely.geometry.multilinestring.MultiLineString, shapely.geometry.polygon.Polygon, shapely.geometry.multipolygon.MultiPolygon, shapely.geometry.collection.GeometryCollection
19 the Shapely geometry
20 onlyValid : bool, optional
21 only return valid Polygons (checks for validity can take a while, if
22 being called often)
23 repair : bool, optional
24 attempt to repair invalid Polygons
26 Returns
27 -------
28 polys : list of shapely.geometry.polygon.Polygon
29 a flat list of all of the Polygons
31 Note
32 ----
33 To pass GeoJSON objects you must first convert them to Shapely objects by
34 doing something like ``shape = shapely.geometry.shape(shape)``.
36 Copyright 2017 Thomas Guymer [1]_
38 References
39 ----------
40 .. [1] PyGuymer3, https://github.com/Guymer/PyGuymer3
41 """
43 # Import special modules ...
44 try:
45 import shapely
46 import shapely.geometry
47 except:
48 raise Exception("\"shapely\" is not installed; run \"pip install --user Shapely\"") from None
50 # **************************************************************************
52 # Check type ...
53 if shape is None:
54 return []
56 # **************************************************************************
58 # Check type ...
59 if isinstance(shape, list):
60 # Initialize list ...
61 polys = []
63 # Loop over items ...
64 for item in shape:
65 # Add lists together ...
66 polys += extract_polys(item, onlyValid = onlyValid, repair = repair)
68 # Return answer ...
69 return polys
71 # Check type ...
72 if isinstance(shape, shapely.geometry.point.Point):
73 return []
75 # Check type ...
76 if isinstance(shape, shapely.geometry.multipoint.MultiPoint):
77 return []
79 # Check type ...
80 if isinstance(shape, shapely.geometry.polygon.LinearRing):
81 return []
83 # Check type ...
84 if isinstance(shape, shapely.geometry.linestring.LineString):
85 return []
87 # Check type ...
88 if isinstance(shape, shapely.geometry.multilinestring.MultiLineString):
89 return []
91 # Check type ...
92 if isinstance(shape, shapely.geometry.polygon.Polygon):
93 # Just return the answer if the user doesn't want any checks or fixes ...
94 if not onlyValid:
95 # Skip bad Polygons ...
96 if shape.is_empty:
97 return []
99 # Return answer ...
100 return [shape]
102 # Check if it is valid ...
103 if shape.is_valid:
104 # Skip bad Polygons ...
105 if shape.is_empty:
106 return []
108 # Return answer ...
109 return [shape]
111 # Check if the user wants to attempt to fix it ...
112 if repair:
113 # Try to repair it ...
114 shape2 = shape.buffer(0.0)
116 # Check if it is valid ...
117 if shape2.is_valid:
118 # Skip bad Polygons ...
119 if shape2.is_empty:
120 return []
122 # Return answer ...
123 return [shape2]
125 # Return answer ...
126 return []
128 # Return answer ...
129 return []
131 # Check type ...
132 if isinstance(shape, shapely.geometry.multipolygon.MultiPolygon):
133 # Initialize list ...
134 polys = []
136 # Loop over Polygons ...
137 for poly in shape.geoms:
138 # Add lists together ...
139 polys += extract_polys(poly, onlyValid = onlyValid, repair = repair)
141 # Return answer ...
142 return polys
144 # Check type ...
145 if isinstance(shape, shapely.geometry.collection.GeometryCollection):
146 # Initialize list ...
147 polys = []
149 # Loop over geometries ...
150 for geom in shape.geoms:
151 # Add lists together ...
152 polys += extract_polys(geom, onlyValid = onlyValid, repair = repair)
154 # Return answer ...
155 return polys
157 # **************************************************************************
159 raise TypeError(f"\"shape\" is an unexpected type ({repr(type(shape))})") from None