Coverage for pyguymer3/geo/extract_lines.py: 35%

52 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_lines( 

5 shape, 

6 /, 

7 *, 

8 onlyValid = False, 

9): 

10 """Extract the LineStrings from the shape 

11 

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

13 the LineStrings contained within. 

14 

15 Parameters 

16 ---------- 

17 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 

18 the Shapely geometry 

19 onlyValid : bool, optional 

20 only return valid LineStrings (checks for validity can take a while, if 

21 being called often) 

22 

23 Returns 

24 ------- 

25 lines : list of shapely.geometry.linestring.LineString 

26 a flat list of all of the LineStrings 

27 

28 Notes 

29 ----- 

30 To pass GeoJSON objects you must first convert them to Shapely objects by 

31 doing something like ``shape = shapely.geometry.shape(shape)``. 

32 

33 Copyright 2017 Thomas Guymer [1]_ 

34 

35 References 

36 ---------- 

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

38 """ 

39 

40 # Import special modules ... 

41 try: 

42 import shapely 

43 import shapely.geometry 

44 except: 

45 raise Exception("\"shapely\" is not installed; run \"pip install --user Shapely\"") from None 

46 

47 # ************************************************************************** 

48 

49 # Check type ... 

50 if shape is None: 

51 return [] 

52 

53 # ************************************************************************** 

54 

55 # Check type ... 

56 if isinstance(shape, list): 

57 # Initialize list ... 

58 lines = [] 

59 

60 # Loop over items ... 

61 for item in shape: 

62 # Add lists together ... 

63 lines.extend( 

64 extract_lines( 

65 item, 

66 onlyValid = onlyValid, 

67 ) 

68 ) 

69 

70 # Return answer ... 

71 return lines 

72 

73 # Check type ... 

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

75 return [] 

76 

77 # Check type ... 

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

79 return [] 

80 

81 # Check type ... 

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

83 # Just return the answer if the user doesn't want any checks ... 

84 if not onlyValid: 

85 # Skip bad LineStrings ... 

86 if shape.is_empty: 

87 return [] 

88 

89 # Return answer ... 

90 return [shape] 

91 

92 # Check if it is valid ... 

93 if shape.is_valid: 

94 # Skip bad LineStrings ... 

95 if shape.is_empty: 

96 return [] 

97 

98 # Return answer ... 

99 return [shape] 

100 

101 # Return answer ... 

102 return [] 

103 

104 # Check type ... 

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

106 # Just return the answer if the user doesn't want any checks ... 

107 if not onlyValid: 

108 # Skip bad LineStrings ... 

109 if shape.is_empty: 

110 return [] 

111 

112 # Return answer ... 

113 return [shape] 

114 

115 # Check if it is valid ... 

116 if shape.is_valid: 

117 # Skip bad LineStrings ... 

118 if shape.is_empty: 

119 return [] 

120 

121 # Return answer ... 

122 return [shape] 

123 

124 # Return answer ... 

125 return [] 

126 

127 # Check type ... 

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

129 # Initialize list ... 

130 lines = [] 

131 

132 # Loop over LineStrings ... 

133 for line in shape.geoms: 

134 # Add lists together ... 

135 lines.extend( 

136 extract_lines( 

137 line, 

138 onlyValid = onlyValid, 

139 ) 

140 ) 

141 

142 # Return answer ... 

143 return lines 

144 

145 # Check type ... 

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

147 return [] 

148 

149 # Check type ... 

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

151 return [] 

152 

153 # Check type ... 

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

155 # Initialize list ... 

156 lines = [] 

157 

158 # Loop over geometries ... 

159 for geom in shape.geoms: 

160 # Add lists together ... 

161 lines.extend( 

162 extract_lines( 

163 geom, 

164 onlyValid = onlyValid, 

165 ) 

166 ) 

167 

168 # Return answer ... 

169 return lines 

170 

171 # ************************************************************************** 

172 

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