Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/django/contrib/gis/geos/linestring.py: 0%

108 statements  

« prev     ^ index     » next       coverage.py v7.0.5, created at 2023-01-17 06:13 +0000

1from django.contrib.gis.geos import prototypes as capi 

2from django.contrib.gis.geos.coordseq import GEOSCoordSeq 

3from django.contrib.gis.geos.error import GEOSException 

4from django.contrib.gis.geos.geometry import GEOSGeometry, LinearGeometryMixin 

5from django.contrib.gis.geos.point import Point 

6from django.contrib.gis.shortcuts import numpy 

7 

8 

9class LineString(LinearGeometryMixin, GEOSGeometry): 

10 _init_func = capi.create_linestring 

11 _minlength = 2 

12 has_cs = True 

13 

14 def __init__(self, *args, **kwargs): 

15 """ 

16 Initialize on the given sequence -- may take lists, tuples, NumPy arrays 

17 of X,Y pairs, or Point objects. If Point objects are used, ownership is 

18 _not_ transferred to the LineString object. 

19 

20 Examples: 

21 ls = LineString((1, 1), (2, 2)) 

22 ls = LineString([(1, 1), (2, 2)]) 

23 ls = LineString(array([(1, 1), (2, 2)])) 

24 ls = LineString(Point(1, 1), Point(2, 2)) 

25 """ 

26 # If only one argument provided, set the coords array appropriately 

27 if len(args) == 1: 

28 coords = args[0] 

29 else: 

30 coords = args 

31 

32 if not ( 

33 isinstance(coords, (tuple, list)) 

34 or numpy 

35 and isinstance(coords, numpy.ndarray) 

36 ): 

37 raise TypeError("Invalid initialization input for LineStrings.") 

38 

39 # If SRID was passed in with the keyword arguments 

40 srid = kwargs.get("srid") 

41 

42 ncoords = len(coords) 

43 if not ncoords: 

44 super().__init__(self._init_func(None), srid=srid) 

45 return 

46 

47 if ncoords < self._minlength: 

48 raise ValueError( 

49 "%s requires at least %d points, got %s." 

50 % ( 

51 self.__class__.__name__, 

52 self._minlength, 

53 ncoords, 

54 ) 

55 ) 

56 

57 numpy_coords = not isinstance(coords, (tuple, list)) 

58 if numpy_coords: 

59 shape = coords.shape # Using numpy's shape. 

60 if len(shape) != 2: 

61 raise TypeError("Too many dimensions.") 

62 self._checkdim(shape[1]) 

63 ndim = shape[1] 

64 else: 

65 # Getting the number of coords and the number of dimensions -- which 

66 # must stay the same, e.g., no LineString((1, 2), (1, 2, 3)). 

67 ndim = None 

68 # Incrementing through each of the coordinates and verifying 

69 for coord in coords: 

70 if not isinstance(coord, (tuple, list, Point)): 

71 raise TypeError( 

72 "Each coordinate should be a sequence (list or tuple)" 

73 ) 

74 

75 if ndim is None: 

76 ndim = len(coord) 

77 self._checkdim(ndim) 

78 elif len(coord) != ndim: 

79 raise TypeError("Dimension mismatch.") 

80 

81 # Creating a coordinate sequence object because it is easier to 

82 # set the points using its methods. 

83 cs = GEOSCoordSeq(capi.create_cs(ncoords, ndim), z=bool(ndim == 3)) 

84 point_setter = cs._set_point_3d if ndim == 3 else cs._set_point_2d 

85 

86 for i in range(ncoords): 

87 if numpy_coords: 

88 point_coords = coords[i, :] 

89 elif isinstance(coords[i], Point): 

90 point_coords = coords[i].tuple 

91 else: 

92 point_coords = coords[i] 

93 point_setter(i, point_coords) 

94 

95 # Calling the base geometry initialization with the returned pointer 

96 # from the function. 

97 super().__init__(self._init_func(cs.ptr), srid=srid) 

98 

99 def __iter__(self): 

100 "Allow iteration over this LineString." 

101 for i in range(len(self)): 

102 yield self[i] 

103 

104 def __len__(self): 

105 "Return the number of points in this LineString." 

106 return len(self._cs) 

107 

108 def _get_single_external(self, index): 

109 return self._cs[index] 

110 

111 _get_single_internal = _get_single_external 

112 

113 def _set_list(self, length, items): 

114 ndim = self._cs.dims 

115 hasz = self._cs.hasz # I don't understand why these are different 

116 srid = self.srid 

117 

118 # create a new coordinate sequence and populate accordingly 

119 cs = GEOSCoordSeq(capi.create_cs(length, ndim), z=hasz) 

120 for i, c in enumerate(items): 

121 cs[i] = c 

122 

123 ptr = self._init_func(cs.ptr) 

124 if ptr: 

125 capi.destroy_geom(self.ptr) 

126 self.ptr = ptr 

127 if srid is not None: 

128 self.srid = srid 

129 self._post_init() 

130 else: 

131 # can this happen? 

132 raise GEOSException("Geometry resulting from slice deletion was invalid.") 

133 

134 def _set_single(self, index, value): 

135 self._cs[index] = value 

136 

137 def _checkdim(self, dim): 

138 if dim not in (2, 3): 

139 raise TypeError("Dimension mismatch.") 

140 

141 # #### Sequence Properties #### 

142 @property 

143 def tuple(self): 

144 "Return a tuple version of the geometry from the coordinate sequence." 

145 return self._cs.tuple 

146 

147 coords = tuple 

148 

149 def _listarr(self, func): 

150 """ 

151 Return a sequence (list) corresponding with the given function. 

152 Return a numpy array if possible. 

153 """ 

154 lst = [func(i) for i in range(len(self))] 

155 if numpy: 

156 return numpy.array(lst) # ARRRR! 

157 else: 

158 return lst 

159 

160 @property 

161 def array(self): 

162 "Return a numpy array for the LineString." 

163 return self._listarr(self._cs.__getitem__) 

164 

165 @property 

166 def x(self): 

167 "Return a list or numpy array of the X variable." 

168 return self._listarr(self._cs.getX) 

169 

170 @property 

171 def y(self): 

172 "Return a list or numpy array of the Y variable." 

173 return self._listarr(self._cs.getY) 

174 

175 @property 

176 def z(self): 

177 "Return a list or numpy array of the Z variable." 

178 if not self.hasz: 

179 return None 

180 else: 

181 return self._listarr(self._cs.getZ) 

182 

183 

184# LinearRings are LineStrings used within Polygons. 

185class LinearRing(LineString): 

186 _minlength = 4 

187 _init_func = capi.create_linearring 

188 

189 @property 

190 def is_counterclockwise(self): 

191 if self.empty: 

192 raise ValueError("Orientation of an empty LinearRing cannot be determined.") 

193 return self._cs.is_counterclockwise