test_geometry_base.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. import platform
  2. import weakref
  3. import numpy as np
  4. import pytest
  5. import shapely
  6. from shapely import (
  7. GeometryCollection,
  8. LinearRing,
  9. LineString,
  10. MultiLineString,
  11. MultiPoint,
  12. MultiPolygon,
  13. Point,
  14. Polygon,
  15. )
  16. from shapely.errors import ShapelyDeprecationWarning
  17. from shapely.testing import assert_geometries_equal
  18. def test_polygon():
  19. assert bool(Polygon()) is False
  20. def test_linestring():
  21. assert bool(LineString()) is False
  22. def test_point():
  23. assert bool(Point()) is False
  24. def test_geometry_collection():
  25. assert bool(GeometryCollection()) is False
  26. geometries_all_types = [
  27. Point(1, 1),
  28. LinearRing([(0, 0), (1, 1), (0, 1), (0, 0)]),
  29. LineString([(0, 0), (1, 1), (0, 1), (0, 0)]),
  30. Polygon([(0, 0), (1, 1), (0, 1), (0, 0)]),
  31. MultiPoint([(1, 1)]),
  32. MultiLineString([[(0, 0), (1, 1), (0, 1), (0, 0)]]),
  33. MultiPolygon([Polygon([(0, 0), (1, 1), (0, 1), (0, 0)])]),
  34. GeometryCollection([Point(1, 1)]),
  35. ]
  36. @pytest.mark.skipif(
  37. platform.python_implementation() == "PyPy",
  38. reason="Setting custom attributes doesn't fail on PyPy",
  39. )
  40. @pytest.mark.parametrize("geom", geometries_all_types)
  41. def test_setattr_disallowed(geom):
  42. with pytest.raises(AttributeError):
  43. geom.name = "test"
  44. @pytest.mark.parametrize("geom", geometries_all_types)
  45. def test_weakrefable(geom):
  46. _ = weakref.ref(geom)
  47. def test_base_class_not_callable():
  48. with pytest.raises(TypeError):
  49. shapely.Geometry("POINT (1 1)")
  50. def test_GeometryType_deprecated():
  51. geom = Point(1, 1)
  52. with pytest.warns(ShapelyDeprecationWarning):
  53. geom_type = geom.geometryType()
  54. assert geom_type == geom.geom_type
  55. def test_type_deprecated():
  56. geom = Point(1, 1)
  57. with pytest.warns(ShapelyDeprecationWarning):
  58. geom_type = geom.type
  59. assert geom_type == geom.geom_type
  60. @pytest.mark.skipif(shapely.geos_version < (3, 10, 0), reason="GEOS < 3.10")
  61. def test_segmentize():
  62. line = LineString([(0, 0), (0, 10)])
  63. result = line.segmentize(max_segment_length=5)
  64. assert result.equals(LineString([(0, 0), (0, 5), (0, 10)]))
  65. def test_reverse():
  66. coords = [(0, 0), (1, 2)]
  67. line = LineString(coords)
  68. result = line.reverse()
  69. assert result.coords[:] == coords[::-1]
  70. @pytest.mark.parametrize(
  71. "op", ["union", "intersection", "difference", "symmetric_difference"]
  72. )
  73. @pytest.mark.parametrize("grid_size", [0, 1, 2])
  74. def test_binary_op_grid_size(op, grid_size):
  75. geom1 = shapely.box(0, 0, 2.5, 2.5)
  76. geom2 = shapely.box(2, 2, 3, 3)
  77. result = getattr(geom1, op)(geom2, grid_size=grid_size)
  78. expected = getattr(shapely, op)(geom1, geom2, grid_size=grid_size)
  79. assert result == expected
  80. @pytest.mark.skipif(shapely.geos_version < (3, 10, 0), reason="GEOS < 3.10")
  81. def test_dwithin():
  82. point = Point(1, 1)
  83. line = LineString([(0, 0), (0, 10)])
  84. assert point.dwithin(line, 0.5) is False
  85. assert point.dwithin(line, 1.5) is True
  86. def test_contains_properly():
  87. polygon = Polygon([(0, 0), (10, 10), (10, -10)])
  88. line = LineString([(0, 0), (10, 0)])
  89. assert polygon.contains_properly(line) is False
  90. assert polygon.contains(line) is True
  91. @pytest.mark.parametrize(
  92. "op", ["convex_hull", "envelope", "oriented_envelope", "minimum_rotated_rectangle"]
  93. )
  94. def test_constructive_properties(op):
  95. geom = LineString([(0, 0), (0, 10), (10, 10)])
  96. result = getattr(geom, op)
  97. expected = getattr(shapely, op)(geom)
  98. assert result == expected
  99. @pytest.mark.parametrize(
  100. "op",
  101. [
  102. "crosses",
  103. "contains",
  104. "contains_properly",
  105. "covered_by",
  106. "covers",
  107. "disjoint",
  108. "equals",
  109. "intersects",
  110. "overlaps",
  111. "touches",
  112. "within",
  113. ],
  114. )
  115. def test_array_argument_binary_predicates(op):
  116. polygon = Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)])
  117. points = shapely.points([(0, 0), (0.5, 0.5), (1, 1)])
  118. result = getattr(polygon, op)(points)
  119. assert isinstance(result, np.ndarray)
  120. expected = np.array([getattr(polygon, op)(p) for p in points], dtype=bool)
  121. np.testing.assert_array_equal(result, expected)
  122. # check scalar
  123. result = getattr(polygon, op)(points[0])
  124. assert type(result) is bool
  125. @pytest.mark.parametrize(
  126. "op, kwargs",
  127. [
  128. pytest.param(
  129. "dwithin",
  130. dict(distance=0.5),
  131. marks=pytest.mark.skipif(
  132. shapely.geos_version < (3, 10, 0), reason="GEOS < 3.10"
  133. ),
  134. ),
  135. ("equals_exact", dict(tolerance=0.01)),
  136. ("relate_pattern", dict(pattern="T*F**F***")),
  137. ],
  138. )
  139. def test_array_argument_binary_predicates2(op, kwargs):
  140. polygon = Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)])
  141. points = shapely.points([(0, 0), (0.5, 0.5), (1, 1)])
  142. result = getattr(polygon, op)(points, **kwargs)
  143. assert isinstance(result, np.ndarray)
  144. expected = np.array([getattr(polygon, op)(p, **kwargs) for p in points], dtype=bool)
  145. np.testing.assert_array_equal(result, expected)
  146. # check scalar
  147. result = getattr(polygon, op)(points[0], **kwargs)
  148. assert type(result) is bool
  149. @pytest.mark.parametrize(
  150. "op",
  151. [
  152. "difference",
  153. "intersection",
  154. "symmetric_difference",
  155. "union",
  156. ],
  157. )
  158. def test_array_argument_binary_geo(op):
  159. box = Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)])
  160. polygons = shapely.buffer(shapely.points([(0, 0), (0.5, 0.5), (1, 1)]), 0.5)
  161. result = getattr(box, op)(polygons)
  162. assert isinstance(result, np.ndarray)
  163. expected = np.array([getattr(box, op)(g) for g in polygons], dtype=object)
  164. assert_geometries_equal(result, expected)
  165. # check scalar
  166. result = getattr(box, op)(polygons[0])
  167. assert isinstance(result, (Polygon, MultiPolygon))
  168. @pytest.mark.parametrize("op", ["distance", "hausdorff_distance"])
  169. def test_array_argument_float(op):
  170. polygon = Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)])
  171. points = shapely.points([(0, 0), (0.5, 0.5), (1, 1)])
  172. result = getattr(polygon, op)(points)
  173. assert isinstance(result, np.ndarray)
  174. expected = np.array([getattr(polygon, op)(p) for p in points], dtype="float64")
  175. np.testing.assert_array_equal(result, expected)
  176. # check scalar
  177. result = getattr(polygon, op)(points[0])
  178. assert type(result) is float
  179. @pytest.mark.parametrize("op", ["line_interpolate_point", "interpolate"])
  180. def test_array_argument_linear_point(op):
  181. line = LineString([(0, 0), (0, 1), (1, 1)])
  182. distances = np.array([0, 0.5, 1])
  183. result = getattr(line, op)(distances)
  184. assert isinstance(result, np.ndarray)
  185. expected = np.array(
  186. [line.line_interpolate_point(d) for d in distances], dtype=object
  187. )
  188. assert_geometries_equal(result, expected)
  189. # check scalar
  190. result = getattr(line, op)(distances[0])
  191. assert isinstance(result, Point)
  192. @pytest.mark.parametrize("op", ["line_locate_point", "project"])
  193. def test_array_argument_linear_float(op):
  194. line = LineString([(0, 0), (0, 1), (1, 1)])
  195. points = shapely.points([(0, 0), (0.5, 0.5), (1, 1)])
  196. result = getattr(line, op)(points)
  197. assert isinstance(result, np.ndarray)
  198. expected = np.array([line.line_locate_point(p) for p in points], dtype="float64")
  199. np.testing.assert_array_equal(result, expected)
  200. # check scalar
  201. result = getattr(line, op)(points[0])
  202. assert type(result) is float
  203. def test_array_argument_buffer():
  204. point = Point(1, 1)
  205. distances = np.array([0, 0.5, 1])
  206. result = point.buffer(distances)
  207. assert isinstance(result, np.ndarray)
  208. expected = np.array([point.buffer(d) for d in distances], dtype=object)
  209. assert_geometries_equal(result, expected)
  210. # check scalar
  211. result = point.buffer(distances[0])
  212. assert isinstance(result, Polygon)
  213. def test_buffer_deprecate_positional():
  214. point = Point(1, 1)
  215. with pytest.deprecated_call(
  216. match="positional argument `cap_style` for `buffer` is deprecated"
  217. ):
  218. point.buffer(1.0, 8, "round")
  219. with pytest.deprecated_call(
  220. match="positional arguments `cap_style` and `join_style` "
  221. "for `buffer` are deprecated"
  222. ):
  223. point.buffer(1.0, 8, "round", "round")
  224. with pytest.deprecated_call():
  225. point.buffer(1.0, 8, "round", "round", 5.0)
  226. with pytest.deprecated_call():
  227. point.buffer(1.0, 8, "round", "round", 5.0, False)
  228. def test_simplify_deprecate_positional():
  229. linestring = LineString([(0, 0), (1, 1)])
  230. with pytest.deprecated_call(
  231. match="positional argument `preserve_topology` for `simplify` is deprecated"
  232. ):
  233. linestring.simplify(1.0, True)
  234. def test_difference_deprecate_positional():
  235. point = Point(1, 1)
  236. with pytest.deprecated_call(
  237. match="positional argument `grid_size` for `difference` is deprecated"
  238. ):
  239. point.difference(point, None)
  240. def test_intersection_deprecate_positional():
  241. point = Point(1, 1)
  242. with pytest.deprecated_call(
  243. match="positional argument `grid_size` for `intersection` is deprecated"
  244. ):
  245. point.intersection(point, None)
  246. def test_symmetric_difference_deprecate_positional():
  247. point = Point(1, 1)
  248. with pytest.deprecated_call(
  249. match="positional argument `grid_size` for `symmetric_difference` is deprecated"
  250. ):
  251. point.symmetric_difference(point, None)
  252. def test_union_deprecate_positional():
  253. point = Point(1, 1)
  254. with pytest.deprecated_call(
  255. match="positional argument `grid_size` for `union` is deprecated"
  256. ):
  257. point.union(point, None)
  258. def test_line_locate_point_deprecate_positional():
  259. line_string = LineString([(1.0, 2.0), (3.0, 4.0)])
  260. with pytest.deprecated_call(
  261. match="positional argument `normalized` for `line_locate_point` is deprecated"
  262. ):
  263. line_string.line_locate_point(Point(1, 1), False)
  264. def test_project_deprecate_positional():
  265. line_string = LineString([(1.0, 2.0), (3.0, 4.0)])
  266. with pytest.deprecated_call(
  267. match="positional argument `normalized` for `project` is deprecated"
  268. ):
  269. line_string.project(Point(1, 1), False)
  270. def test_line_interpolate_point_deprecate_positional():
  271. line_string = LineString([(1.0, 2.0), (3.0, 4.0)])
  272. with pytest.deprecated_call(
  273. match="positional argument `normalized` for `line_interpolate_point` "
  274. "is deprecated"
  275. ):
  276. line_string.line_interpolate_point(0, False)
  277. def test_interpolate_deprecate_positional():
  278. line_string = LineString([(1.0, 2.0), (3.0, 4.0)])
  279. with pytest.deprecated_call(
  280. match="positional argument `normalized` for `interpolate` is deprecated"
  281. ):
  282. line_string.interpolate(0, False)