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

52 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_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 += extract_lines(item, onlyValid = onlyValid) 

64 

65 # Return answer ... 

66 return lines 

67 

68 # Check type ... 

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

70 return [] 

71 

72 # Check type ... 

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

74 return [] 

75 

76 # Check type ... 

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

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

79 if not onlyValid: 

80 # Skip bad LineStrings ... 

81 if shape.is_empty: 

82 return [] 

83 

84 # Return answer ... 

85 return [shape] 

86 

87 # Check if it is valid ... 

88 if shape.is_valid: 

89 # Skip bad LineStrings ... 

90 if shape.is_empty: 

91 return [] 

92 

93 # Return answer ... 

94 return [shape] 

95 

96 # Return answer ... 

97 return [] 

98 

99 # Check type ... 

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

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

102 if not onlyValid: 

103 # Skip bad LineStrings ... 

104 if shape.is_empty: 

105 return [] 

106 

107 # Return answer ... 

108 return [shape] 

109 

110 # Check if it is valid ... 

111 if shape.is_valid: 

112 # Skip bad LineStrings ... 

113 if shape.is_empty: 

114 return [] 

115 

116 # Return answer ... 

117 return [shape] 

118 

119 # Return answer ... 

120 return [] 

121 

122 # Check type ... 

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

124 # Initialize list ... 

125 lines = [] 

126 

127 # Loop over LineStrings ... 

128 for line in shape.geoms: 

129 # Add lists together ... 

130 lines += extract_lines(line, onlyValid = onlyValid) 

131 

132 # Return answer ... 

133 return lines 

134 

135 # Check type ... 

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

137 return [] 

138 

139 # Check type ... 

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

141 return [] 

142 

143 # Check type ... 

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

145 # Initialize list ... 

146 lines = [] 

147 

148 # Loop over geometries ... 

149 for geom in shape.geoms: 

150 # Add lists together ... 

151 lines += extract_lines(geom, onlyValid = onlyValid) 

152 

153 # Return answer ... 

154 return lines 

155 

156 # ************************************************************************** 

157 

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