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

1#!/usr/bin/env python3 

2 

3# Define function ... 

4def extract_polys( 

5 shape, 

6 /, 

7 *, 

8 onlyValid = False, 

9 repair = False, 

10): 

11 """Extract the Polygons from the shape 

12 

13 This function accepts any Shapely geometry and returns a flat list of all of 

14 the Polygons contained within. 

15 

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 

25 

26 Returns 

27 ------- 

28 polys : list of shapely.geometry.polygon.Polygon 

29 a flat list of all of the Polygons 

30 

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)``. 

35 

36 Copyright 2017 Thomas Guymer [1]_ 

37 

38 References 

39 ---------- 

40 .. [1] PyGuymer3, https://github.com/Guymer/PyGuymer3 

41 """ 

42 

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 

49 

50 # ************************************************************************** 

51 

52 # Check type ... 

53 if shape is None: 

54 return [] 

55 

56 # ************************************************************************** 

57 

58 # Check type ... 

59 if isinstance(shape, list): 

60 # Initialize list ... 

61 polys = [] 

62 

63 # Loop over items ... 

64 for item in shape: 

65 # Add lists together ... 

66 polys += extract_polys(item, onlyValid = onlyValid, repair = repair) 

67 

68 # Return answer ... 

69 return polys 

70 

71 # Check type ... 

72 if isinstance(shape, shapely.geometry.point.Point): 

73 return [] 

74 

75 # Check type ... 

76 if isinstance(shape, shapely.geometry.multipoint.MultiPoint): 

77 return [] 

78 

79 # Check type ... 

80 if isinstance(shape, shapely.geometry.polygon.LinearRing): 

81 return [] 

82 

83 # Check type ... 

84 if isinstance(shape, shapely.geometry.linestring.LineString): 

85 return [] 

86 

87 # Check type ... 

88 if isinstance(shape, shapely.geometry.multilinestring.MultiLineString): 

89 return [] 

90 

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 [] 

98 

99 # Return answer ... 

100 return [shape] 

101 

102 # Check if it is valid ... 

103 if shape.is_valid: 

104 # Skip bad Polygons ... 

105 if shape.is_empty: 

106 return [] 

107 

108 # Return answer ... 

109 return [shape] 

110 

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) 

115 

116 # Check if it is valid ... 

117 if shape2.is_valid: 

118 # Skip bad Polygons ... 

119 if shape2.is_empty: 

120 return [] 

121 

122 # Return answer ... 

123 return [shape2] 

124 

125 # Return answer ... 

126 return [] 

127 

128 # Return answer ... 

129 return [] 

130 

131 # Check type ... 

132 if isinstance(shape, shapely.geometry.multipolygon.MultiPolygon): 

133 # Initialize list ... 

134 polys = [] 

135 

136 # Loop over Polygons ... 

137 for poly in shape.geoms: 

138 # Add lists together ... 

139 polys += extract_polys(poly, onlyValid = onlyValid, repair = repair) 

140 

141 # Return answer ... 

142 return polys 

143 

144 # Check type ... 

145 if isinstance(shape, shapely.geometry.collection.GeometryCollection): 

146 # Initialize list ... 

147 polys = [] 

148 

149 # Loop over geometries ... 

150 for geom in shape.geoms: 

151 # Add lists together ... 

152 polys += extract_polys(geom, onlyValid = onlyValid, repair = repair) 

153 

154 # Return answer ... 

155 return polys 

156 

157 # ************************************************************************** 

158 

159 raise TypeError(f"\"shape\" is an unexpected type ({repr(type(shape))})") from None