coords.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. """Coordinate sequence utilities."""
  2. from array import array
  3. class CoordinateSequence:
  4. """Access to coordinate tuples from the parent geometry's coordinate sequence.
  5. Examples
  6. --------
  7. >>> from shapely.wkt import loads
  8. >>> g = loads('POINT (0.0 0.0)')
  9. >>> list(g.coords)
  10. [(0.0, 0.0)]
  11. >>> g = loads('POINT M (1 2 4)')
  12. >>> g.coords[:]
  13. [(1.0, 2.0, 4.0)]
  14. """
  15. def __init__(self, coords):
  16. """Initialize the CoordinateSequence.
  17. Parameters
  18. ----------
  19. coords : array
  20. The coordinate array.
  21. """
  22. self._coords = coords
  23. def __len__(self):
  24. """Return the length of the CoordinateSequence.
  25. Returns
  26. -------
  27. int
  28. The length of the CoordinateSequence.
  29. """
  30. return self._coords.shape[0]
  31. def __iter__(self):
  32. """Iterate over the CoordinateSequence."""
  33. for i in range(self.__len__()):
  34. yield tuple(self._coords[i].tolist())
  35. def __getitem__(self, key):
  36. """Get the item at the specified index or slice.
  37. Parameters
  38. ----------
  39. key : int or slice
  40. The index or slice.
  41. Returns
  42. -------
  43. tuple or list
  44. The item at the specified index or slice.
  45. """
  46. m = self.__len__()
  47. if isinstance(key, int):
  48. if key + m < 0 or key >= m:
  49. raise IndexError("index out of range")
  50. if key < 0:
  51. i = m + key
  52. else:
  53. i = key
  54. return tuple(self._coords[i].tolist())
  55. elif isinstance(key, slice):
  56. res = []
  57. start, stop, stride = key.indices(m)
  58. for i in range(start, stop, stride):
  59. res.append(tuple(self._coords[i].tolist()))
  60. return res
  61. else:
  62. raise TypeError("key must be an index or slice")
  63. def __array__(self, dtype=None, copy=None):
  64. """Return a copy of the coordinate array.
  65. Parameters
  66. ----------
  67. dtype : data-type, optional
  68. The desired data-type for the array.
  69. copy : bool, optional
  70. If None (default) or True, a copy of the array is always returned.
  71. If False, a ValueError is raised as this is not supported.
  72. Returns
  73. -------
  74. array
  75. The coordinate array.
  76. Raises
  77. ------
  78. ValueError
  79. If `copy=False` is specified.
  80. """
  81. if copy is False:
  82. raise ValueError("`copy=False` isn't supported. A copy is always created.")
  83. elif copy is True:
  84. return self._coords.copy()
  85. else:
  86. return self._coords
  87. @property
  88. def xy(self):
  89. """X and Y arrays."""
  90. m = self.__len__()
  91. x = array("d")
  92. y = array("d")
  93. for i in range(m):
  94. xy = self._coords[i].tolist()
  95. x.append(xy[0])
  96. y.append(xy[1])
  97. return x, y