test_operations.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import unittest
  2. import pytest
  3. import shapely
  4. from shapely import geos_version
  5. from shapely.errors import TopologicalError
  6. from shapely.geometry import GeometryCollection, LineString, MultiPoint, Point, Polygon
  7. from shapely.wkt import loads
  8. class OperationsTestCase(unittest.TestCase):
  9. def test_operations(self):
  10. point = Point(0.0, 0.0)
  11. # General geometry
  12. assert point.area == 0.0
  13. assert point.length == 0.0
  14. assert point.distance(Point(-1.0, -1.0)) == pytest.approx(1.4142135623730951)
  15. # Topology operations
  16. # Envelope
  17. assert isinstance(point.envelope, Point)
  18. # Intersection
  19. assert point.intersection(Point(-1, -1)).is_empty
  20. # Buffer
  21. assert isinstance(point.buffer(10.0), Polygon)
  22. assert isinstance(point.buffer(10.0, quad_segs=32), Polygon)
  23. # Simplify
  24. p = loads(
  25. "POLYGON ((120 120, 140 199, 160 200, 180 199, 220 120, 122 122, 121 121, "
  26. "120 120))"
  27. )
  28. expected = loads(
  29. "POLYGON ((120 120, 140 199, 160 200, 180 199, 220 120, 120 120))"
  30. )
  31. s = p.simplify(10.0, preserve_topology=False)
  32. assert s.equals_exact(expected, 0.001)
  33. p = loads(
  34. "POLYGON ((80 200, 240 200, 240 60, 80 60, 80 200),"
  35. "(120 120, 220 120, 180 199, 160 200, 140 199, 120 120))"
  36. )
  37. expected = loads(
  38. "POLYGON ((80 200, 240 200, 240 60, 80 60, 80 200),"
  39. "(120 120, 220 120, 180 199, 160 200, 140 199, 120 120))"
  40. )
  41. s = p.simplify(10.0, preserve_topology=True)
  42. assert s.equals_exact(expected, 0.001)
  43. # Convex Hull
  44. assert isinstance(point.convex_hull, Point)
  45. # Differences
  46. assert isinstance(point.difference(Point(-1, 1)), Point)
  47. assert isinstance(point.symmetric_difference(Point(-1, 1)), MultiPoint)
  48. # Boundary
  49. assert isinstance(point.boundary, GeometryCollection)
  50. # Union
  51. assert isinstance(point.union(Point(-1, 1)), MultiPoint)
  52. assert isinstance(point.representative_point(), Point)
  53. assert isinstance(point.point_on_surface(), Point)
  54. assert point.representative_point() == point.point_on_surface()
  55. assert isinstance(point.centroid, Point)
  56. def test_relate(self):
  57. # Relate
  58. assert Point(0, 0).relate(Point(-1, -1)) == "FF0FFF0F2"
  59. # issue #294: should raise TopologicalError on exception
  60. invalid_polygon = loads(
  61. "POLYGON ((40 100, 80 100, 80 60, 40 60, 40 100), "
  62. "(60 60, 80 60, 80 40, 60 40, 60 60))"
  63. )
  64. assert not invalid_polygon.is_valid
  65. if geos_version < (3, 13, 0):
  66. with pytest.raises((TopologicalError, shapely.GEOSException)):
  67. invalid_polygon.relate(invalid_polygon)
  68. else: # resolved with RelateNG
  69. assert invalid_polygon.relate(invalid_polygon) == "2FFF1FFF2"
  70. def test_hausdorff_distance(self):
  71. point = Point(1, 1)
  72. line = LineString([(2, 0), (2, 4), (3, 4)])
  73. distance = point.hausdorff_distance(line)
  74. assert distance == point.distance(Point(3, 4))
  75. def test_interpolate(self):
  76. # successful interpolation
  77. test_line = LineString([(1, 1), (1, 2)])
  78. known_point = Point(1, 1.5)
  79. interpolated_point = test_line.interpolate(0.5, normalized=True)
  80. assert interpolated_point == known_point
  81. # Issue #653; should nog segfault for empty geometries
  82. empty_line = loads("LINESTRING EMPTY")
  83. assert empty_line.is_empty
  84. interpolated_point = empty_line.interpolate(0.5, normalized=True)
  85. assert interpolated_point.is_empty
  86. # invalid geometry should raise TypeError on exception
  87. polygon = loads("POLYGON EMPTY")
  88. with pytest.raises(TypeError, match="incorrect geometry type"):
  89. polygon.interpolate(0.5, normalized=True)
  90. def test_normalize(self):
  91. point = Point(1, 1)
  92. result = point.normalize()
  93. assert result == point
  94. line = loads("MULTILINESTRING ((1 1, 0 0), (1 1, 1 2))")
  95. result = line.normalize()
  96. expected = loads("MULTILINESTRING ((1 1, 1 2), (0 0, 1 1))")
  97. assert result == expected