collections.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. """
  2. This module houses the Geometry Collection objects:
  3. GeometryCollection, MultiPoint, MultiLineString, and MultiPolygon
  4. """
  5. from django.contrib.gis.geos import prototypes as capi
  6. from django.contrib.gis.geos.geometry import GEOSGeometry, LinearGeometryMixin
  7. from django.contrib.gis.geos.libgeos import GEOM_PTR
  8. from django.contrib.gis.geos.linestring import LinearRing, LineString
  9. from django.contrib.gis.geos.point import Point
  10. from django.contrib.gis.geos.polygon import Polygon
  11. class GeometryCollection(GEOSGeometry):
  12. _typeid = 7
  13. def __init__(self, *args, **kwargs):
  14. "Initialize a Geometry Collection from a sequence of Geometry objects."
  15. # Checking the arguments
  16. if len(args) == 1:
  17. # If only one geometry provided or a list of geometries is provided
  18. # in the first argument.
  19. if isinstance(args[0], (tuple, list)):
  20. init_geoms = args[0]
  21. else:
  22. init_geoms = args
  23. else:
  24. init_geoms = args
  25. # Ensuring that only the permitted geometries are allowed in this collection
  26. # this is moved to list mixin super class
  27. self._check_allowed(init_geoms)
  28. # Creating the geometry pointer array.
  29. collection = self._create_collection(len(init_geoms), init_geoms)
  30. super().__init__(collection, **kwargs)
  31. def __iter__(self):
  32. "Iterate over each Geometry in the Collection."
  33. for i in range(len(self)):
  34. yield self[i]
  35. def __len__(self):
  36. "Return the number of geometries in this Collection."
  37. return self.num_geom
  38. # ### Methods for compatibility with ListMixin ###
  39. def _create_collection(self, length, items):
  40. # Creating the geometry pointer array.
  41. geoms = (GEOM_PTR * length)(
  42. *[
  43. # this is a little sloppy, but makes life easier
  44. # allow GEOSGeometry types (python wrappers) or pointer types
  45. capi.geom_clone(getattr(g, "ptr", g))
  46. for g in items
  47. ]
  48. )
  49. return capi.create_collection(self._typeid, geoms, length)
  50. def _get_single_internal(self, index):
  51. return capi.get_geomn(self.ptr, index)
  52. def _get_single_external(self, index):
  53. "Return the Geometry from this Collection at the given index (0-based)."
  54. # Checking the index and returning the corresponding GEOS geometry.
  55. return GEOSGeometry(
  56. capi.geom_clone(self._get_single_internal(index)), srid=self.srid
  57. )
  58. def _set_list(self, length, items):
  59. "Create a new collection, and destroy the contents of the previous pointer."
  60. prev_ptr = self.ptr
  61. srid = self.srid
  62. self.ptr = self._create_collection(length, items)
  63. if srid:
  64. self.srid = srid
  65. capi.destroy_geom(prev_ptr)
  66. _set_single = GEOSGeometry._set_single_rebuild
  67. _assign_extended_slice = GEOSGeometry._assign_extended_slice_rebuild
  68. @property
  69. def kml(self):
  70. "Return the KML for this Geometry Collection."
  71. return "<MultiGeometry>%s</MultiGeometry>" % "".join(g.kml for g in self)
  72. @property
  73. def tuple(self):
  74. "Return a tuple of all the coordinates in this Geometry Collection"
  75. return tuple(g.tuple for g in self)
  76. coords = tuple
  77. # MultiPoint, MultiLineString, and MultiPolygon class definitions.
  78. class MultiPoint(GeometryCollection):
  79. _allowed = Point
  80. _typeid = 4
  81. class MultiLineString(LinearGeometryMixin, GeometryCollection):
  82. _allowed = (LineString, LinearRing)
  83. _typeid = 5
  84. class MultiPolygon(GeometryCollection):
  85. _allowed = Polygon
  86. _typeid = 6
  87. # Setting the allowed types here since GeometryCollection is defined before
  88. # its subclasses.
  89. GeometryCollection._allowed = (
  90. Point,
  91. LineString,
  92. LinearRing,
  93. Polygon,
  94. MultiPoint,
  95. MultiLineString,
  96. MultiPolygon,
  97. )