Coverage for pyguymer3/geo/extract_polys.py: 54%

46 statements  

« prev     ^ index     » next       coverage.py v7.10.3, created at 2025-08-16 08:31 +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.extend( 

67 extract_polys( 

68 item, 

69 onlyValid = onlyValid, 

70 repair = repair, 

71 ) 

72 ) 

73 

74 # Return answer ... 

75 return polys 

76 

77 # Check type ... 

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

79 return [] 

80 

81 # Check type ... 

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

83 return [] 

84 

85 # Check type ... 

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

87 return [] 

88 

89 # Check type ... 

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

91 return [] 

92 

93 # Check type ... 

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

95 return [] 

96 

97 # Check type ... 

98 if isinstance(shape, shapely.geometry.polygon.Polygon): 

99 # Just return the answer if the user doesn't want any checks or fixes ... 

100 if not onlyValid: 

101 # Skip bad Polygons ... 

102 if shape.is_empty: 

103 return [] 

104 

105 # Return answer ... 

106 return [shape] 

107 

108 # Check if it is valid ... 

109 if shape.is_valid: 

110 # Skip bad Polygons ... 

111 if shape.is_empty: 

112 return [] 

113 

114 # Return answer ... 

115 return [shape] 

116 

117 # Check if the user wants to attempt to fix it ... 

118 if repair: 

119 # Try to repair it and return answer ... 

120 return extract_polys( 

121 shape.buffer(0.0), 

122 onlyValid = onlyValid, 

123 repair = repair, 

124 ) 

125 

126 # Return answer ... 

127 return [] 

128 

129 # Check type ... 

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

131 # Initialize list ... 

132 polys = [] 

133 

134 # Loop over Polygons ... 

135 for poly in shape.geoms: 

136 # Add lists together ... 

137 polys.extend( 

138 extract_polys( 

139 poly, 

140 onlyValid = onlyValid, 

141 repair = repair, 

142 ) 

143 ) 

144 

145 # Return answer ... 

146 return polys 

147 

148 # Check type ... 

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

150 # Initialize list ... 

151 polys = [] 

152 

153 # Loop over geometries ... 

154 for geom in shape.geoms: 

155 # Add lists together ... 

156 polys.extend( 

157 extract_polys( 

158 geom, 

159 onlyValid = onlyValid, 

160 repair = repair, 

161 ) 

162 ) 

163 

164 # Return answer ... 

165 return polys 

166 

167 # ************************************************************************** 

168 

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