test_point.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import numpy as np
  2. import pytest
  3. from shapely import Point, geos_version
  4. from shapely.coords import CoordinateSequence
  5. from shapely.errors import DimensionError, UnsupportedGEOSVersionError
  6. def test_from_coordinates():
  7. # Point
  8. p = Point(1.0, 2.0)
  9. assert p.coords[:] == [(1.0, 2.0)]
  10. assert p.has_z is False
  11. # PointZ
  12. p = Point(1.0, 2.0, 3.0)
  13. assert p.coords[:] == [(1.0, 2.0, 3.0)]
  14. assert p.has_z
  15. # empty
  16. p = Point()
  17. assert p.is_empty
  18. assert isinstance(p.coords, CoordinateSequence)
  19. assert p.coords[:] == []
  20. def test_from_sequence():
  21. # From single coordinate pair
  22. p = Point((3.0, 4.0))
  23. assert p.coords[:] == [(3.0, 4.0)]
  24. p = Point([3.0, 4.0])
  25. assert p.coords[:] == [(3.0, 4.0)]
  26. # From coordinate sequence
  27. p = Point([(3.0, 4.0)])
  28. assert p.coords[:] == [(3.0, 4.0)]
  29. p = Point([[3.0, 4.0]])
  30. assert p.coords[:] == [(3.0, 4.0)]
  31. # PointZ
  32. p = Point((3.0, 4.0, 5.0))
  33. assert p.coords[:] == [(3.0, 4.0, 5.0)]
  34. p = Point([3.0, 4.0, 5.0])
  35. assert p.coords[:] == [(3.0, 4.0, 5.0)]
  36. p = Point([(3.0, 4.0, 5.0)])
  37. assert p.coords[:] == [(3.0, 4.0, 5.0)]
  38. def test_from_numpy():
  39. # Construct from a numpy array
  40. p = Point(np.array([1.0, 2.0]))
  41. assert p.coords[:] == [(1.0, 2.0)]
  42. p = Point(np.array([1.0, 2.0, 3.0]))
  43. assert p.coords[:] == [(1.0, 2.0, 3.0)]
  44. def test_from_numpy_xy():
  45. # Construct from separate x, y numpy arrays - if those are length 1,
  46. # this is allowed for compat with shapely 1.8
  47. # (https://github.com/shapely/shapely/issues/1587)
  48. p = Point(np.array([1.0]), np.array([2.0]))
  49. assert p.coords[:] == [(1.0, 2.0)]
  50. p = Point(np.array([1.0]), np.array([2.0]), np.array([3.0]))
  51. assert p.coords[:] == [(1.0, 2.0, 3.0)]
  52. def test_from_point():
  53. # From another point
  54. p = Point(3.0, 4.0)
  55. q = Point(p)
  56. assert q.coords[:] == [(3.0, 4.0)]
  57. p = Point(3.0, 4.0, 5.0)
  58. q = Point(p)
  59. assert q.coords[:] == [(3.0, 4.0, 5.0)]
  60. def test_from_generator():
  61. gen = (coord for coord in [(1.0, 2.0)])
  62. p = Point(gen)
  63. assert p.coords[:] == [(1.0, 2.0)]
  64. def test_from_invalid():
  65. with pytest.raises(TypeError, match="takes at most 3 arguments"):
  66. Point(1, 2, 3, 4)
  67. # this worked in shapely 1.x, just ignoring the other coords
  68. with pytest.raises(
  69. ValueError, match="takes only scalar or 1-size vector arguments"
  70. ):
  71. Point([(2, 3), (11, 4)])
  72. class TestPoint:
  73. def test_point(self):
  74. # Test XY point
  75. p = Point(1.0, 2.0)
  76. assert p.x == 1.0
  77. assert type(p.x) is float
  78. assert p.y == 2.0
  79. assert type(p.y) is float
  80. assert p.coords[:] == [(1.0, 2.0)]
  81. assert str(p) == p.wkt
  82. assert p.has_z is False
  83. with pytest.raises(DimensionError):
  84. p.z
  85. if geos_version >= (3, 12, 0):
  86. assert p.has_m is False
  87. with pytest.raises(DimensionError):
  88. p.m
  89. else:
  90. with pytest.raises(UnsupportedGEOSVersionError):
  91. p.m
  92. # Check XYZ point
  93. p = Point(1.0, 2.0, 3.0)
  94. assert p.coords[:] == [(1.0, 2.0, 3.0)]
  95. assert str(p) == p.wkt
  96. assert p.has_z is True
  97. assert p.z == 3.0
  98. assert type(p.z) is float
  99. if geos_version >= (3, 12, 0):
  100. assert p.has_m is False
  101. with pytest.raises(DimensionError):
  102. p.m
  103. # TODO: Check XYM and XYZM points
  104. # Coordinate access
  105. p = Point((3.0, 4.0))
  106. assert p.x == 3.0
  107. assert p.y == 4.0
  108. assert tuple(p.coords) == ((3.0, 4.0),)
  109. assert p.coords[0] == (3.0, 4.0)
  110. with pytest.raises(IndexError): # index out of range
  111. p.coords[1]
  112. # Bounds
  113. assert p.bounds == (3.0, 4.0, 3.0, 4.0)
  114. # Geo interface
  115. assert p.__geo_interface__ == {"type": "Point", "coordinates": (3.0, 4.0)}
  116. def test_point_empty(self):
  117. # Test Non-operability of Null geometry
  118. p_null = Point()
  119. assert p_null.wkt == "POINT EMPTY"
  120. assert p_null.coords[:] == []
  121. assert p_null.area == 0.0
  122. assert p_null.__geo_interface__ == {"type": "Point", "coordinates": ()}
  123. def test_coords(self):
  124. # From Array.txt
  125. p = Point(0.0, 0.0, 1.0)
  126. coords = p.coords[0]
  127. assert coords == (0.0, 0.0, 1.0)
  128. # Convert to Numpy array, passing through Python sequence
  129. a = np.asarray(coords)
  130. assert a.ndim == 1
  131. assert a.size == 3
  132. assert a.shape == (3,)
  133. def test_point_immutable():
  134. p = Point(3.0, 4.0)
  135. with pytest.raises(AttributeError):
  136. p.coords = (2.0, 1.0)
  137. with pytest.raises(TypeError):
  138. p.coords[0] = (2.0, 1.0)
  139. def test_point_array_coercion():
  140. # don't convert to array of coordinates, keep objects
  141. p = Point(3.0, 4.0)
  142. arr = np.array(p)
  143. assert arr.ndim == 0
  144. assert arr.size == 1
  145. assert arr.dtype == np.dtype("object")
  146. assert arr.item() == p
  147. def test_numpy_empty_point_coords():
  148. pe = Point()
  149. # Access the coords
  150. a = np.asarray(pe.coords)
  151. assert a.shape == (0, 2)
  152. def test_numpy_object_array():
  153. geom = Point(3.0, 4.0)
  154. ar = np.empty(1, object)
  155. ar[:] = [geom]
  156. assert ar[0] == geom