OSDN Git Service

data write directory change. shapely library include.
[openembroidery/EmbroideryOutputExtensionForInkscape.git] / embroider / shapely / tests / test_polygon.py
diff --git a/embroider/shapely/tests/test_polygon.py b/embroider/shapely/tests/test_polygon.py
new file mode 100644 (file)
index 0000000..d973786
--- /dev/null
@@ -0,0 +1,186 @@
+"""Polygons and Linear Rings
+"""
+from . import unittest, numpy
+from shapely.wkb import loads as load_wkb
+from shapely.geometry import Point, Polygon, asPolygon
+from shapely.geometry.polygon import LinearRing, asLinearRing
+from shapely.geometry.base import dump_coords
+
+
+class PolygonTestCase(unittest.TestCase):
+
+    def test_polygon(self):
+
+        # Initialization
+        # Linear rings won't usually be created by users, but by polygons
+        coords = ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0))
+        ring = LinearRing(coords)
+        self.assertEqual(len(ring.coords), 5)
+        self.assertEqual(ring.coords[0], ring.coords[4])
+        self.assertEqual(ring.coords[0], ring.coords[-1])
+        self.assertTrue(ring.is_ring)
+
+        # Coordinate modification
+        ring.coords = ((0.0, 0.0), (0.0, 2.0), (2.0, 2.0), (2.0, 0.0))
+        self.assertEqual(
+            ring.__geo_interface__,
+            {'type': 'LinearRing',
+             'coordinates': ((0.0, 0.0), (0.0, 2.0), (2.0, 2.0), (2.0, 0.0),
+                             (0.0, 0.0))})
+
+        # Test ring adapter
+        coords = [[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 0.0]]
+        ra = asLinearRing(coords)
+        self.assertTrue(ra.wkt.upper().startswith('LINEARRING'))
+        self.assertEqual(dump_coords(ra),
+                         [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0),
+                          (0.0, 0.0)])
+        coords[3] = [2.0, -1.0]
+        self.assertEqual(dump_coords(ra),
+                         [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (2.0, -1.0),
+                          (0.0, 0.0)])
+
+        # Construct a polygon, exterior ring only
+        polygon = Polygon(coords)
+        self.assertEqual(len(polygon.exterior.coords), 5)
+
+        # Ring Access
+        self.assertIsInstance(polygon.exterior, LinearRing)
+        ring = polygon.exterior
+        self.assertEqual(len(ring.coords), 5)
+        self.assertEqual(ring.coords[0], ring.coords[4])
+        self.assertEqual(ring.coords[0], (0., 0.))
+        self.assertTrue(ring.is_ring)
+        self.assertEqual(len(polygon.interiors), 0)
+
+        # Create a new polygon from WKB
+        data = polygon.wkb
+        polygon = None
+        ring = None
+        polygon = load_wkb(data)
+        ring = polygon.exterior
+        self.assertEqual(len(ring.coords), 5)
+        self.assertEqual(ring.coords[0], ring.coords[4])
+        self.assertEqual(ring.coords[0], (0., 0.))
+        self.assertTrue(ring.is_ring)
+        polygon = None
+
+        # Interior rings (holes)
+        polygon = Polygon(coords, [((0.25, 0.25), (0.25, 0.5),
+                                    (0.5, 0.5), (0.5, 0.25))])
+        self.assertEqual(len(polygon.exterior.coords), 5)
+        self.assertEqual(len(polygon.interiors[0].coords), 5)
+        with self.assertRaises(IndexError):  # index out of range
+            polygon.interiors[1]
+
+        # Coordinate getters and setters raise exceptions
+        self.assertRaises(NotImplementedError, polygon._get_coords)
+        with self.assertRaises(NotImplementedError):
+            polygon.coords
+
+        # Geo interface
+        self.assertEqual(
+            polygon.__geo_interface__,
+            {'type': 'Polygon',
+             'coordinates': (((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (2.0, -1.0),
+                             (0.0, 0.0)), ((0.25, 0.25), (0.25, 0.5),
+                             (0.5, 0.5), (0.5, 0.25), (0.25, 0.25)))})
+
+        # Adapter
+        hole_coords = [((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25))]
+        pa = asPolygon(coords, hole_coords)
+        self.assertEqual(len(pa.exterior.coords), 5)
+        self.assertEqual(len(pa.interiors), 1)
+        self.assertEqual(len(pa.interiors[0].coords), 5)
+
+        # Test Non-operability of Null rings
+        r_null = LinearRing()
+        self.assertEqual(r_null.wkt, 'GEOMETRYCOLLECTION EMPTY')
+        self.assertEqual(r_null.length, 0.0)
+
+        # Check that we can set coordinates of a null geometry
+        r_null.coords = [(0, 0), (1, 1), (1, 0)]
+        self.assertAlmostEqual(r_null.length, 3.414213562373095)
+
+        # Error handling
+        with self.assertRaises(ValueError):
+            # A LinearRing must have at least 3 coordinate tuples
+            Polygon([[1, 2], [2, 3]])
+
+    @unittest.skipIf(not numpy, 'Numpy required')
+    def test_numpy(self):
+
+        from numpy import array, asarray
+        from numpy.testing import assert_array_equal
+
+        a = asarray(((0., 0.), (0., 1.), (1., 1.), (1., 0.), (0., 0.)))
+        polygon = Polygon(a)
+        self.assertEqual(len(polygon.exterior.coords), 5)
+        self.assertEqual(dump_coords(polygon.exterior),
+                         [(0., 0.), (0., 1.), (1., 1.), (1., 0.), (0., 0.)])
+        self.assertEqual(len(polygon.interiors), 0)
+        b = asarray(polygon.exterior)
+        self.assertEqual(b.shape, (5, 2))
+        assert_array_equal(
+            b, array([(0., 0.), (0., 1.), (1., 1.), (1., 0.), (0., 0.)]))
+
+    def test_dimensions(self):
+
+        # Background: see http://trac.gispython.org/lab/ticket/168
+    # http://lists.gispython.org/pipermail/community/2008-August/001859.html
+
+        coords = ((0.0, 0.0, 0.0), (0.0, 1.0, 0.0), (1.0, 1.0, 0.0),
+                  (1.0, 0.0, 0.0))
+        polygon = Polygon(coords)
+        self.assertEqual(polygon._ndim, 3)
+        gi = polygon.__geo_interface__
+        self.assertEqual(
+            gi['coordinates'],
+            (((0.0, 0.0, 0.0), (0.0, 1.0, 0.0), (1.0, 1.0, 0.0),
+              (1.0, 0.0, 0.0), (0.0, 0.0, 0.0)),))
+
+        e = polygon.exterior
+        self.assertEqual(e._ndim, 3)
+        gi = e.__geo_interface__
+        self.assertEqual(
+            gi['coordinates'],
+            ((0.0, 0.0, 0.0), (0.0, 1.0, 0.0), (1.0, 1.0, 0.0),
+             (1.0, 0.0, 0.0), (0.0, 0.0, 0.0)))
+
+    def test_attribute_chains(self):
+
+        # Attribute Chaining
+        # See also ticket #151.
+        p = Polygon(((0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0)))
+        self.assertEqual(
+            list(p.boundary.coords),
+            [(0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0), (0.0, 0.0)])
+
+        ec = list(Point(0.0, 0.0).buffer(1.0, 1).exterior.coords)
+        self.assertIsInstance(ec, list)  # TODO: this is a poor test
+
+        # Test chained access to interiors
+        p = Polygon(
+            ((0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0)),
+            [((-0.25, 0.25), (-0.25, 0.75), (-0.75, 0.75), (-0.75, 0.25))]
+        )
+        self.assertEqual(p.area, 0.75)
+
+        """Not so much testing the exact values here, which are the
+        responsibility of the geometry engine (GEOS), but that we can get
+        chain functions and properties using anonymous references.
+        """
+        self.assertEqual(
+            list(p.interiors[0].coords),
+            [(-0.25, 0.25), (-0.25, 0.75), (-0.75, 0.75), (-0.75, 0.25),
+             (-0.25, 0.25)])
+        xy = list(p.interiors[0].buffer(1).exterior.coords)[0]
+        self.assertEqual(len(xy), 2)
+
+        # Test multiple operators, boundary of a buffer
+        ec = list(p.buffer(1).boundary.coords)
+        self.assertIsInstance(ec, list)  # TODO: this is a poor test
+
+
+def test_suite():
+    return unittest.TestLoader().loadTestsFromTestCase(PolygonTestCase)