test_union.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import random
  2. import unittest
  3. from functools import partial
  4. from itertools import islice
  5. import pytest
  6. from shapely.geometry import MultiPolygon, Point
  7. from shapely.ops import unary_union
  8. def halton(base):
  9. """Returns an iterator over an infinite Halton sequence"""
  10. def value(index):
  11. result = 0.0
  12. f = 1.0 / base
  13. i = index
  14. while i > 0:
  15. result += f * (i % base)
  16. i = i // base
  17. f = f / base
  18. return result
  19. i = 1
  20. while i > 0:
  21. yield value(i)
  22. i += 1
  23. class UnionTestCase(unittest.TestCase):
  24. def test_unary_union_partial(self):
  25. # Use a partial function to make 100 points uniformly distributed
  26. # in a 40x40 box centered on 0,0.
  27. r = partial(random.uniform, -20.0, 20.0)
  28. points = [Point(r(), r()) for i in range(100)]
  29. # Buffer the points, producing 100 polygon spots
  30. spots = [p.buffer(2.5) for p in points]
  31. # Perform a cascaded union of the polygon spots, dissolving them
  32. # into a collection of polygon patches
  33. u = unary_union(spots)
  34. assert u.geom_type in ("Polygon", "MultiPolygon")
  35. def setUp(self):
  36. # Instead of random points, use deterministic, pseudo-random Halton
  37. # sequences for repeatability sake.
  38. self.coords = zip(
  39. list(islice(halton(5), 20, 120)),
  40. list(islice(halton(7), 20, 120)),
  41. )
  42. def test_unary_union(self):
  43. patches = [Point(xy).buffer(0.05) for xy in self.coords]
  44. u = unary_union(patches)
  45. assert u.geom_type == "MultiPolygon"
  46. assert u.area == pytest.approx(0.718572540569)
  47. def test_unary_union_multi(self):
  48. # Test of multipart input based on comment by @schwehr at
  49. # https://github.com/shapely/shapely/issues/47#issuecomment-21809308
  50. patches = MultiPolygon([Point(xy).buffer(0.05) for xy in self.coords])
  51. assert unary_union(patches).area == pytest.approx(0.71857254056)
  52. assert unary_union([patches, patches]).area == pytest.approx(0.71857254056)