test_linear.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. import numpy as np
  2. import pytest
  3. import shapely
  4. from shapely import GeometryCollection, LinearRing, LineString, MultiLineString, Point
  5. from shapely.errors import UnsupportedGEOSVersionError
  6. from shapely.testing import assert_geometries_equal
  7. from shapely.tests.common import (
  8. empty_line_string,
  9. empty_point,
  10. line_string,
  11. linear_ring,
  12. multi_line_string,
  13. multi_point,
  14. multi_polygon,
  15. point,
  16. polygon,
  17. )
  18. def test_line_interpolate_point_geom_array():
  19. actual = shapely.line_interpolate_point(
  20. [line_string, linear_ring, multi_line_string], -1
  21. )
  22. assert_geometries_equal(actual[0], Point(1, 0))
  23. assert_geometries_equal(actual[1], Point(0, 1))
  24. assert_geometries_equal(actual[2], Point(0.5528, 1.1056), tolerance=0.001)
  25. def test_line_interpolate_point_geom_array_normalized():
  26. actual = shapely.line_interpolate_point(
  27. [line_string, linear_ring, multi_line_string], 1, normalized=True
  28. )
  29. assert_geometries_equal(actual[0], Point(1, 1))
  30. assert_geometries_equal(actual[1], Point(0, 0))
  31. assert_geometries_equal(actual[2], Point(1, 2))
  32. def test_line_interpolate_point_float_array():
  33. actual = shapely.line_interpolate_point(line_string, [0.2, 1.5, -0.2])
  34. assert_geometries_equal(actual[0], Point(0.2, 0))
  35. assert_geometries_equal(actual[1], Point(1, 0.5))
  36. assert_geometries_equal(actual[2], Point(1, 0.8))
  37. @pytest.mark.parametrize("normalized", [False, True])
  38. @pytest.mark.parametrize(
  39. "geom",
  40. [
  41. LineString(),
  42. LinearRing(),
  43. MultiLineString(),
  44. shapely.from_wkt("MULTILINESTRING (EMPTY, (0 0, 1 1))"),
  45. GeometryCollection(),
  46. GeometryCollection([LineString(), Point(1, 1)]),
  47. ],
  48. )
  49. def test_line_interpolate_point_empty(geom, normalized):
  50. assert_geometries_equal(
  51. shapely.line_interpolate_point(geom, 0.2, normalized=normalized), empty_point
  52. )
  53. @pytest.mark.parametrize("normalized", [False, True])
  54. @pytest.mark.parametrize(
  55. "geom",
  56. [
  57. empty_point,
  58. point,
  59. polygon,
  60. multi_point,
  61. multi_polygon,
  62. shapely.geometrycollections([point]),
  63. shapely.geometrycollections([polygon]),
  64. shapely.geometrycollections([multi_line_string]),
  65. shapely.geometrycollections([multi_point]),
  66. shapely.geometrycollections([multi_polygon]),
  67. ],
  68. )
  69. def test_line_interpolate_point_invalid_type(geom, normalized):
  70. with pytest.raises(TypeError):
  71. assert shapely.line_interpolate_point(geom, 0.2, normalized=normalized)
  72. def test_line_interpolate_point_none():
  73. assert shapely.line_interpolate_point(None, 0.2) is None
  74. def test_line_interpolate_point_nan():
  75. assert shapely.line_interpolate_point(line_string, np.nan) is None
  76. def test_line_interpolate_point_deprecate_positional():
  77. with pytest.deprecated_call(
  78. match="positional argument `normalized` for `line_interpolate_point` "
  79. "is deprecated"
  80. ):
  81. shapely.line_interpolate_point(line_string, 0, False)
  82. def test_line_locate_point_geom_array():
  83. point = shapely.points(0, 1)
  84. actual = shapely.line_locate_point([line_string, linear_ring], point)
  85. np.testing.assert_allclose(actual, [0.0, 3.0])
  86. def test_line_locate_point_geom_array2():
  87. points = shapely.points([[0, 0], [1, 0]])
  88. actual = shapely.line_locate_point(line_string, points)
  89. np.testing.assert_allclose(actual, [0.0, 1.0])
  90. @pytest.mark.parametrize("normalized", [False, True])
  91. def test_line_locate_point_none(normalized):
  92. assert np.isnan(shapely.line_locate_point(line_string, None, normalized=normalized))
  93. assert np.isnan(shapely.line_locate_point(None, point, normalized=normalized))
  94. @pytest.mark.parametrize("normalized", [False, True])
  95. def test_line_locate_point_empty(normalized):
  96. assert np.isnan(
  97. shapely.line_locate_point(line_string, empty_point, normalized=normalized)
  98. )
  99. assert np.isnan(
  100. shapely.line_locate_point(empty_line_string, point, normalized=normalized)
  101. )
  102. @pytest.mark.parametrize("normalized", [False, True])
  103. def test_line_locate_point_invalid_geometry(normalized):
  104. with pytest.raises(shapely.GEOSException):
  105. shapely.line_locate_point(line_string, line_string, normalized=normalized)
  106. with pytest.raises(shapely.GEOSException):
  107. shapely.line_locate_point(polygon, point, normalized=normalized)
  108. def test_line_locate_point_deprecate_positional():
  109. with pytest.deprecated_call(
  110. match="positional argument `normalized` for `line_locate_point` is deprecated"
  111. ):
  112. shapely.line_locate_point(line_string, point, False)
  113. def test_line_merge_geom_array():
  114. actual = shapely.line_merge([line_string, multi_line_string])
  115. assert_geometries_equal(actual[0], line_string)
  116. assert_geometries_equal(actual[1], LineString([(0, 0), (1, 2)]))
  117. @pytest.mark.skipif(shapely.geos_version < (3, 11, 0), reason="GEOS < 3.11.0")
  118. def test_line_merge_directed():
  119. lines = MultiLineString([[(0, 0), (1, 0)], [(0, 0), (3, 0)]])
  120. # Merge lines without directed, this requires changing the vertex ordering
  121. result = shapely.line_merge(lines)
  122. assert_geometries_equal(result, LineString([(1, 0), (0, 0), (3, 0)]))
  123. # Since the lines can't be merged when directed is specified
  124. # the original geometry is returned
  125. result = shapely.line_merge(lines, directed=True)
  126. assert_geometries_equal(result, lines)
  127. @pytest.mark.skipif(shapely.geos_version >= (3, 11, 0), reason="GEOS >= 3.11.0")
  128. def test_line_merge_error():
  129. lines = MultiLineString([[(0, 0), (1, 0)], [(0, 0), (3, 0)]])
  130. with pytest.raises(UnsupportedGEOSVersionError):
  131. shapely.line_merge(lines, directed=True)
  132. def test_shared_paths_linestring():
  133. g1 = shapely.linestrings([(0, 0), (1, 0), (1, 1)])
  134. g2 = shapely.linestrings([(0, 0), (1, 0)])
  135. actual1 = shapely.shared_paths(g1, g2)
  136. assert_geometries_equal(
  137. shapely.get_geometry(actual1, 0), shapely.multilinestrings([g2])
  138. )
  139. def test_shared_paths_none():
  140. assert shapely.shared_paths(line_string, None) is None
  141. assert shapely.shared_paths(None, line_string) is None
  142. assert shapely.shared_paths(None, None) is None
  143. def test_shared_paths_non_linestring():
  144. g1 = shapely.linestrings([(0, 0), (1, 0), (1, 1)])
  145. g2 = shapely.points(0, 1)
  146. with pytest.raises(shapely.GEOSException):
  147. shapely.shared_paths(g1, g2)
  148. def _prepare_input(geometry, prepare):
  149. """Prepare without modifying in-place"""
  150. if prepare:
  151. geometry = shapely.transform(geometry, lambda x: x) # makes a copy
  152. shapely.prepare(geometry)
  153. return geometry
  154. else:
  155. return geometry
  156. @pytest.mark.parametrize("prepare", [True, False])
  157. def test_shortest_line(prepare):
  158. g1 = shapely.linestrings([(0, 0), (1, 0), (1, 1)])
  159. g2 = shapely.linestrings([(0, 3), (3, 0)])
  160. actual = shapely.shortest_line(_prepare_input(g1, prepare), g2)
  161. expected = shapely.linestrings([(1, 1), (1.5, 1.5)])
  162. assert shapely.equals(actual, expected)
  163. @pytest.mark.parametrize("prepare", [True, False])
  164. def test_shortest_line_none(prepare):
  165. assert shapely.shortest_line(_prepare_input(line_string, prepare), None) is None
  166. assert shapely.shortest_line(None, line_string) is None
  167. assert shapely.shortest_line(None, None) is None
  168. @pytest.mark.parametrize("prepare", [True, False])
  169. def test_shortest_line_empty(prepare):
  170. g1 = _prepare_input(line_string, prepare)
  171. assert shapely.shortest_line(g1, empty_line_string) is None
  172. g1_empty = _prepare_input(empty_line_string, prepare)
  173. assert shapely.shortest_line(g1_empty, line_string) is None
  174. assert shapely.shortest_line(g1_empty, empty_line_string) is None