[GRASS-SVN] r66047 - in grass/trunk/lib/python/pygrass/vector: . testsuite

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Aug 27 06:11:15 PDT 2015


Author: huhabla
Date: 2015-08-27 06:11:15 -0700 (Thu, 27 Aug 2015)
New Revision: 66047

Modified:
   grass/trunk/lib/python/pygrass/vector/find.py
   grass/trunk/lib/python/pygrass/vector/geometry.py
   grass/trunk/lib/python/pygrass/vector/testsuite/test_geometry.py
Log:
pygrass vector: Implemented area, boundary, centroid and isle specific unit-tests.
Changed the API a bit and some functions. Buffer methods are not generating areas anymore, since
areas are topological objects. 
Implemented the use of GEOS WKT and WKB generation from the vector library (r66046).


Modified: grass/trunk/lib/python/pygrass/vector/find.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/find.py	2015-08-27 12:48:17 UTC (rev 66046)
+++ grass/trunk/lib/python/pygrass/vector/find.py	2015-08-27 13:11:15 UTC (rev 66047)
@@ -16,7 +16,7 @@
 
 class AbstractFinder(object):
     def __init__(self, c_mapinfo, table=None, writeable=False):
-        """AbstractFinder
+        """Abstract finder
         -----------------
 
         Find geometry feature around a point.
@@ -136,7 +136,7 @@
             ...     if f:
             ...         result.append(f)
             >>> for f in result:
-            ...     print(f.to_wkt())    #doctest: +NORMALIZE_WHITESPACE
+            ...     print(f.to_wkt_p())    #doctest: +NORMALIZE_WHITESPACE
             LINESTRING(10.000000 4.000000,
                        10.000000 2.000000,
                        10.000000 0.000000)
@@ -274,12 +274,35 @@
             [Area(1), Area(2), Area(4)]
             >>> for area in result:
             ...     print(area.to_wkt())         #doctest: +NORMALIZE_WHITESPACE
-            Polygon((0.000000 0.000000, 0.000000 4.000000, 4.000000 4.000000,
-                     4.000000 0.000000, 0.000000 0.000000))
-            Polygon((4.000000 0.000000, 4.000000 4.000000, 6.000000 4.000000,
-                     6.000000 0.000000, 4.000000 0.000000))
-            Polygon((6.000000 0.000000, 6.000000 4.000000, 8.000000 4.000000,
-                     8.000000 0.000000, 6.000000 0.000000))
+            POLYGON ((0.0000000000000000 0.0000000000000000,
+                      0.0000000000000000 4.0000000000000000,
+                      0.0000000000000000 4.0000000000000000,
+                      4.0000000000000000 4.0000000000000000,
+                      4.0000000000000000 4.0000000000000000,
+                      4.0000000000000000 0.0000000000000000,
+                      4.0000000000000000 0.0000000000000000,
+                      0.0000000000000000 0.0000000000000000),
+                     (1.0000000000000000 1.0000000000000000,
+                      3.0000000000000000 1.0000000000000000,
+                      3.0000000000000000 3.0000000000000000,
+                      1.0000000000000000 3.0000000000000000,
+                      1.0000000000000000 1.0000000000000000))
+            POLYGON ((4.0000000000000000 0.0000000000000000,
+                      4.0000000000000000 4.0000000000000000,
+                      4.0000000000000000 4.0000000000000000,
+                      6.0000000000000000 4.0000000000000000,
+                      6.0000000000000000 4.0000000000000000,
+                      6.0000000000000000 0.0000000000000000,
+                      6.0000000000000000 0.0000000000000000,
+                      4.0000000000000000 0.0000000000000000))
+            POLYGON ((6.0000000000000000 0.0000000000000000,
+                      6.0000000000000000 4.0000000000000000,
+                      6.0000000000000000 4.0000000000000000,
+                      8.0000000000000000 4.0000000000000000,
+                      8.0000000000000000 4.0000000000000000,
+                      8.0000000000000000 0.0000000000000000,
+                      8.0000000000000000 0.0000000000000000,
+                      6.0000000000000000 0.0000000000000000))
 
             >>> test_vect.find_by_point.area(Point(20,20))
 
@@ -339,8 +362,7 @@
 
     This class provides an interface to search geometry features
     of a vector map that are inside or intersect a boundingbox.
-    The BboxFinder class
-    is part of a topological vector map object.
+    The BboxFinder class is part of a topological vector map object.
 
     """
     def __init__(self, c_mapinfo, table=None, writeable=False):
@@ -360,7 +382,7 @@
 
     @must_be_open
     def geos(self, bbox, type='all', bboxlist_only=False):
-        """Find the nearest vector features around a specific point.
+        """Find vector features inside a boundingbox.
 
             :param bbox: The boundingbox to search in
             :type bbox: grass.pygrass.vector.basic.Bbox
@@ -441,7 +463,7 @@
 
     @must_be_open
     def nodes(self, bbox):
-        """Find the nodes inside a boundingbox.
+        """Find nodes inside a boundingbox.
 
             :param bbox: The boundingbox to search in
             :type bbox: grass.pygrass.vector.basic.Bbox
@@ -478,7 +500,7 @@
 
     @must_be_open
     def areas(self, bbox, boxlist=None, bboxlist_only=False):
-        """Find the areas inside a boundingbox.
+        """Find areas inside a boundingbox.
 
             :param bbox: The boundingbox to search in
             :type bbox: grass.pygrass.vector.basic.Bbox
@@ -536,7 +558,7 @@
 
     @must_be_open
     def islands(self, bbox, bboxlist_only=False):
-        """Find the isles inside a boundingbox.
+        """Find isles inside a boundingbox.
 
             :param bbox: The boundingbox to search in
             :type bbox: grass.pygrass.vector.basic.Bbox

Modified: grass/trunk/lib/python/pygrass/vector/geometry.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/geometry.py	2015-08-27 12:48:17 UTC (rev 66046)
+++ grass/trunk/lib/python/pygrass/vector/geometry.py	2015-08-27 13:11:15 UTC (rev 66047)
@@ -307,7 +307,41 @@
                                                        self.c_points,
                                                        self.c_cats)
 
+    def to_wkt(self):
+        """Return a "well know text" (WKT) geometry string, this method uses
+           the GEOS implementation in the vector library. ::
 
+            >>> pnt = Point(10, 100)
+            >>> pnt.to_wkt()
+            'POINT (10.0000000000000000 100.0000000000000000)'
+
+        .. warning::
+
+            Only ``POINT`` (2/3D) are supported, ``POINTM`` and ``POINT`` with:
+            ``XYZM`` are not supported yet.
+        """
+        return libvect.Vect_line_to_wkt(self.c_points, self.gtype, not self.is2D)
+
+    def to_wkb(self):
+        """Return a "well know binary" (WKB) geometry byte array, this method uses
+           the GEOS implementation in the vector library. ::
+
+            >>> pnt = Point(10, 100)
+            >>> wkb = pnt.to_wkb()
+            >>> len(wkb)
+            21
+
+
+        .. warning::
+
+            Only ``POINT`` (2/3D) are supported, ``POINTM`` and ``POINT`` with:
+            ``XYZM`` are not supported yet.
+        """
+        size = ctypes.c_size_t()
+        barray = libvect.Vect_line_to_wkb(self.c_points, self.gtype,
+                                          not self.is2D, ctypes.byref(size))
+        return(ctypes.string_at(barray, size.value))
+
 class Point(Geo):
     """Instantiate a Point object that could be 2 or 3D, default
     parameters are 0.
@@ -330,7 +364,7 @@
         >>> pnt
         Point(0.000000, 0.000000, 0.000000)
         >>> print(pnt)
-        POINT(0.000000 0.000000 0.000000)
+        POINT Z (0.0000000000000000 0.0000000000000000 0.0000000000000000)
 
     ..
     """
@@ -430,11 +464,11 @@
         else:
             return self.x, self.y, self.z
 
-    def to_wkt(self):
-        """Return a "well know text" (WKT) geometry string. ::
+    def to_wkt_p(self):
+        """Return a "well know text" (WKT) geometry string Python implementation. ::
 
             >>> pnt = Point(10, 100)
-            >>> pnt.to_wkt()
+            >>> pnt.to_wkt_p()
             'POINT(10.000000 100.000000)'
 
         .. warning::
@@ -445,16 +479,6 @@
         return "POINT(%s)" % ' '.join(['%f' % coord
                                       for coord in self.coords()])
 
-    def to_wkb(self):
-        """Return a "well know binary" (WKB) geometry buffer
-
-        .. warning::
-
-            Not implemented yet.
-
-        """
-        pass
-
     def distance(self, pnt):
         """Calculate distance of 2 points, using the Vect_points_distance
         C function, If one of the point have z == None, return the 2D distance.
@@ -502,13 +526,11 @@
         :returns: the buffer as Area object
 
         >>> pnt = Point(0, 0)
-        >>> area = pnt.buffer(10)
-        >>> area.boundary                              #doctest: +ELLIPSIS
+        >>> boundary, centroid = pnt.buffer(10)
+        >>> boundary                              #doctest: +ELLIPSIS
         Line([Point(10.000000, 0.000000),...Point(10.000000, 0.000000)])
-        >>> area.centroid
+        >>> centroid
         Point(0.000000, 0.000000)
-        >>> area.isles
-        []
 
         """
         if dist is not None:
@@ -522,7 +544,7 @@
                                    dist_x, dist_y,
                                    angle, int(round_), tol,
                                    p_points)
-        return Area(boundary=bound, centroid=self)
+        return (bound, self)
 
 
 class Line(Geo):
@@ -987,11 +1009,11 @@
         """
         return np.array(self.to_list())
 
-    def to_wkt(self):
+    def to_wkt_p(self):
         """Return a Well Known Text string of the line. ::
 
             >>> line = Line([(0, 0), (1, 1), (1, 2)])
-            >>> line.to_wkt()                 #doctest: +ELLIPSIS
+            >>> line.to_wkt_p()                 #doctest: +ELLIPSIS
             'LINESTRING(0.000000 0.000000, ..., 1.000000 2.000000)'
 
         ..
@@ -1023,15 +1045,6 @@
         else:
             return None
 
-    def get_wkb(self):
-        """Return a WKB buffer.
-
-        .. warning::
-
-            Not implemented yet.
-        """
-        pass
-
     def buffer(self, dist=None, dist_x=None, dist_y=None,
                angle=0, round_=True, caps=True, tol=0.1):
         """Return the buffer area around the line, using the
@@ -1053,12 +1066,12 @@
         :returns: the buffer as Area object
 
         >>> line = Line([(0, 0), (0, 2)])
-        >>> area = line.buffer(10)
-        >>> area.boundary                              #doctest: +ELLIPSIS
+        >>> boundary, centroid, isles = line.buffer(10)
+        >>> boundary                              #doctest: +ELLIPSIS
         Line([Point(-10.000000, 0.000000),...Point(-10.000000, 0.000000)])
-        >>> area.centroid                     #doctest: +NORMALIZE_WHITESPACE
+        >>> centroid                     #doctest: +NORMALIZE_WHITESPACE
         Point(0.000000, 0.000000)
-        >>> area.isles
+        >>> isles
         []
 
         ..
@@ -1076,9 +1089,9 @@
                                   dist_x, dist_y, angle,
                                   int(round_), int(caps), tol,
                                   p_bound, pp_isle, n_isles)
-        return Area(boundary=Line(c_points=p_bound.contents),
-                    centroid=self[0],
-                    isles=[Line(c_points=pp_isle[i].contents)
+        return(Line(c_points=p_bound.contents),
+                    self[0],
+                    [Line(c_points=pp_isle[i].contents)
                            for i in range(n_isles.contents.value)])
 
     def reset(self):
@@ -1176,6 +1189,13 @@
         return "POINT(%s)" % ' '.join(['%f' % coord
                                       for coord in self.coords()])
 
+    def to_wkb(self):
+        """Return a "well know binary" (WKB) geometry array. ::
+
+           TODO: Must be implemented
+        """
+        raise Exception("Not implemented")
+
     def ilines(self, only_in=False, only_out=False):
         """Return a generator with all lines id connected to a node.
         The line id is negative if line is ending on the node and positive if
@@ -1226,11 +1246,13 @@
         self.c_right = ctypes.pointer(ctypes.c_int())
 
     @property
-    def left_id(self):
+    def left_area_id(self):
+        """Left side area id, only available after read_area_ids() was called"""
         return self.c_left.contents.value
 
     @property
-    def right_id(self):
+    def right_area_id(self):
+        """Right side area id, only available after read_area_ids() was called"""
         return self.c_right.contents.value
 
     def __repr__(self):
@@ -1253,7 +1275,7 @@
         :param idonly: True to return only the cat of feature
         :type idonly: bool
         """
-        return self._centroid(self.left_id, idonly)
+        return self._centroid(self.c_left.contents.value, idonly)
 
     def right_centroid(self, idonly=False):
         """Return right centroid
@@ -1261,11 +1283,11 @@
         :param idonly: True to return only the cat of feature
         :type idonly: bool
         """
-        return self._centroid(self.left_id, idonly)
+        return self._centroid(self.c_right.contents.value, idonly)
 
     @mapinfo_must_be_set
-    def get_left_right(self):
-        """Return left and right value"""
+    def read_area_ids(self):
+        """Read and return left and right area ids of the boundary"""
 
         libvect.Vect_get_line_areas(self.c_mapinfo, self.id,
                                     self.c_left, self.c_right)
@@ -1297,9 +1319,9 @@
         >>> from grass.pygrass.vector import VectorTopo
         >>> test_vect = VectorTopo(test_vector_name)
         >>> test_vect.open(mode='r')
-        >>> centroid = Centroid(v_id=1, c_mapinfo=test_vect.c_mapinfo)
+        >>> centroid = Centroid(v_id=18, c_mapinfo=test_vect.c_mapinfo)
         >>> centroid
-        Centoid(10.000000, 6.000000)
+        Centoid(3.500000, 3.500000)
         >>> test_vect.close()
 
     ..
@@ -1311,9 +1333,9 @@
         super(Centroid, self).__init__(**kargs)
         self.area_id = area_id
         if self.id and self.c_mapinfo and self.area_id is None:
-            self.area_id = self.get_area_id()
+            self.area_id = self._area_id()
         elif self.c_mapinfo and self.area_id and self.id is None:
-            self.id = self.centroid_id()
+            self.id = self._centroid_id()
         if self.area_id is not None:
             self.read()
 
@@ -1323,7 +1345,7 @@
         return "Centoid(%s)" % ', '.join(['%f' % co for co in self.coords()])
 
     @mapinfo_must_be_set
-    def centroid_id(self):
+    def _centroid_id(self):
         """Return the centroid_id, using the c_mapinfo and an area_id
         attributes of the class, and calling the Vect_get_area_centroid
         C function, if no centroid_id were found return None"""
@@ -1332,7 +1354,7 @@
         return centroid_id if centroid_id != 0 else None
 
     @mapinfo_must_be_set
-    def get_area_id(self):
+    def _area_id(self):
         """Return the area_id, using the c_mapinfo and an centroid_id
         attributes of the class, and calling the Vect_centroid_area
         C function, if no area_id were found return None"""
@@ -1386,6 +1408,11 @@
                ' '.join(['%f' % coord for coord in pnt])
                for pnt in line.to_list()])
 
+    def to_wkb(self):
+        """Return a "well know text" (WKB) geometry array. ::
+        """
+        raise Exception("Not implemented")
+
     @mapinfo_must_be_set
     def points_geos(self):
         """Return a Line object with the outer ring points
@@ -1487,15 +1514,8 @@
     # geometry type
     gtype = libvect.GV_AREA
 
-    def __init__(self, boundary=None, centroid=None, isles=None, **kargs):
+    def __init__(self, **kargs):
         super(Area, self).__init__(**kargs)
-        self.boundary = None
-        self.centroid = None
-        self.isles = None
-        if boundary and centroid:
-            self.boundary = boundary
-            self.centroid = centroid
-            self.isles = isles if isles else []
 
         # set the attributes
         if self.attrs and self.cat:
@@ -1504,16 +1524,6 @@
     def __repr__(self):
         return "Area(%d)" % self.id if self.id else "Area( )"
 
-    def init_from_id(self, area_id=None):
-        """Return an Area object"""
-        if area_id is None and self.id is None:
-            raise ValueError("You need to give or set the area_id")
-        self.id = area_id if area_id is not None else self.id
-        # get boundary
-        self.points()
-        # get isles
-        self.isles()
-
     @mapinfo_must_be_set
     def points(self, line=None):
         """Return a Line object with the outer ring
@@ -1526,7 +1536,7 @@
         return line
 
     @mapinfo_must_be_set
-    def centroid(self, centroid=None):
+    def centroid(self):
         """Return the centroid
 
         :param centroid: a Centroid object to fill with info from centroid of area
@@ -1534,10 +1544,6 @@
         """
         centroid_id = libvect.Vect_get_area_centroid(self.c_mapinfo, self.id)
         if centroid_id:
-            if centroid:
-                centroid.id = centroid_id
-                centroid.read()
-                return centroid
             return Centroid(v_id=centroid_id, c_mapinfo=self.c_mapinfo,
                             area_id=self.id)
 
@@ -1547,7 +1553,7 @@
 
     @mapinfo_must_be_set
     def isles(self, isles=None):
-        """Instantiate the boundary attribute reading area_id"""
+        """Return a list of islands located in this area"""
         if isles is not None:
             isles.area_id = self.id
             return isles
@@ -1596,9 +1602,10 @@
         :param tol: fix the maximum distance between theoretical arc and
                     output segments
         :type tol: float
-        :returns: the buffer as Area object
+        :returns: the buffer as line, centroid, isles object tuple
 
         """
+
         if dist is not None:
             dist_x = dist
             dist_y = dist
@@ -1612,10 +1619,10 @@
                                   dist_x, dist_y, angle,
                                   int(round_), int(caps), tol,
                                   p_bound, pp_isle, n_isles)
-        return Area(boundary=Line(c_points=p_bound.contents),
-                    centroid=self.centroid,
-                    isles=[Line(c_points=pp_isle[i].contents)
-                           for i in range(n_isles.contents.value)])
+        return (Line(c_points=p_bound.contents),
+                self.centroid,
+                [Line(c_points=pp_isle[i].contents)
+                 for i in range(n_isles.contents.value)])
 
     @mapinfo_must_be_set
     def boundaries(self, ilist=False):
@@ -1631,20 +1638,21 @@
             return ilist
         return [Boundary(v_id=abs(v_id), c_mapinfo=self.c_mapinfo) for v_id in ilst]
 
-
     def to_wkt(self):
-        """Return a Well Known Text string of the Area. ::
+        """Return a "well know text" (WKT) area string, this method uses
+           the GEOS implementation in the vector library. ::
+        """
+        return libvect.Vect_read_area_to_wkt(self.c_mapinfo, self.id)
 
-            For now the outer ring is returned
-
-            TODO: Implement inner rings detected from isles
+    def to_wkb(self):
+        """Return a "well know binary" (WKB) area byte array, this method uses
+           the GEOS implementation in the vector library. ::
         """
-        line = self.points()
+        size = ctypes.c_size_t()
+        barray = libvect.Vect_read_area_to_wkb(self.c_mapinfo, self.id,
+                                              ctypes.byref(size))
+        return(ctypes.string_at(barray, size.value))
 
-        return "Polygon((%s))" % ', '.join([
-               ' '.join(['%f' % coord for coord in pnt])
-               for pnt in line.to_list()])
-
     @mapinfo_must_be_set
     def cats(self, cats=None):
         """Get area categories.
@@ -1666,16 +1674,16 @@
         pass
 
     @mapinfo_must_be_set
-    def contain_pnt(self, pnt, bbox=None):
+    def contains_point(self, point, bbox=None):
         """Check if point is in area.
 
-        :param pnt: the point to analyze
-        :type pnt: a Point object or a tuple with the coordinates
+        :param point: the point to analyze
+        :type point: a Point object or a tuple with the coordinates
         :param bbox: the bounding box where run the analysis
         :type bbox: a Bbox object
         """
         bbox = bbox if bbox else self.bbox()
-        return bool(libvect.Vect_point_in_area(pnt.x, pnt.y,
+        return bool(libvect.Vect_point_in_area(point.x, point.y,
                                                self.c_mapinfo, self.id,
                                                bbox.c_bbox))
 
@@ -1689,13 +1697,8 @@
         border = self.points()
         return libvect.Vect_line_geodesic_length(border.c_points)
 
-    def read(self, line=None, centroid=None, isles=None):
-        self.boundary = self.points(line)
-        self.centroid = self.centroid(centroid)
-        #self.isles = self.isles(isles)
-        if self.centroid:
-            libvect.Vect_read_line(self.c_mapinfo, None, self.c_cats,
-                                   self.centroid.id)
+    def read(self):
+        pass
 
 
 #

Modified: grass/trunk/lib/python/pygrass/vector/testsuite/test_geometry.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/testsuite/test_geometry.py	2015-08-27 12:48:17 UTC (rev 66046)
+++ grass/trunk/lib/python/pygrass/vector/testsuite/test_geometry.py	2015-08-27 13:11:15 UTC (rev 66047)
@@ -14,10 +14,11 @@
 import grass.lib.vector as libvect
 from grass.script.core import run_command
 
-from grass.pygrass.vector import VectorTopo
+from grass.pygrass.vector import Vector, VectorTopo
 from grass.pygrass.vector.geometry import Point, Line, Node
+from grass.pygrass.vector.geometry import Area, Boundary, Centroid
+from grass.pygrass.vector.basic import Bbox
 
-
 class PointTestCase(TestCase):
 
     def test_empty_init(self):
@@ -52,12 +53,22 @@
         self.assertEqual(Point(1, 2).coords(), (1, 2))
         self.assertEqual(Point(1, 2, 3).coords(), (1, 2, 3))
 
+    def test_to_wkt_p(self):
+        """Test coords method"""
+        self.assertEqual(Point(1, 2).to_wkt_p(), 'POINT(1.000000 2.000000)')
+        self.assertEqual(Point(1, 2, 3).to_wkt_p(),
+                         'POINT(1.000000 2.000000 3.000000)')
+
     def test_to_wkt(self):
         """Test coords method"""
-        self.assertEqual(Point(1, 2).to_wkt(), 'POINT(1.000000 2.000000)')
+        self.assertEqual(Point(1, 2).to_wkt(), 'POINT (1.0000000000000000 2.0000000000000000)')
         self.assertEqual(Point(1, 2, 3).to_wkt(),
-                         'POINT(1.000000 2.000000 3.000000)')
+                         'POINT Z (1.0000000000000000 2.0000000000000000 3.0000000000000000)')
 
+    def test_to_wkb(self):
+        """Test to_wkb method"""
+        self.assertEqual(len(Point(1, 2).to_wkb()), 21)
+
     def test_distance(self):
         """Test distance method"""
         point0 = Point(0, 0, 0)
@@ -151,6 +162,15 @@
         vals = (0.7071067811865475, 0.7071067811865475)
         self.assertTupleEqual(line.point_on_line(1).coords(), vals)
 
+    def test_to_wkt(self):
+        """Test to_wkt method"""
+        string = 'LINESTRING (0.0000000000000000 0.0000000000000000, 1.0000000000000000 1.0000000000000000)'
+        self.assertEqual(Line([(0, 0), (1, 1)]).to_wkt(), string)
+
+    def test_to_wkb(self):
+        """Test to_wkb method"""
+        self.assertEqual(len(Line([(0, 0), (1, 1)]).to_wkb()), 41)
+
     def test_bbox(self):
         """Test bbox method"""
         line = Line([(0, 10), (0, 11), (1, 11), (1, 10)])
@@ -227,5 +247,142 @@
                    2.356194496154785)
         self.assertTupleEqual(angles, tuple(node.angles()))
 
+class AreaTestCase(TestCase):
+
+    tmpname = "AreaTestCase_map"
+
+    @classmethod
+    def setUpClass(cls):
+
+        # Tests are based on a stream network
+        from grass.pygrass import utils
+        utils.create_test_vector_map(cls.tmpname)
+
+        cls.vect = None
+        cls.vect = VectorTopo(cls.tmpname)
+        cls.vect.open('r')
+        cls.c_mapinfo = cls.vect.c_mapinfo
+
+    @classmethod
+    def tearDownClass(cls):
+        if cls.vect is not None:
+            cls.vect.close()
+            cls.c_mapinfo = None
+
+        """Remove the generated vector map, if exist"""
+        from grass.pygrass.utils import get_mapset_vector
+        mset = get_mapset_vector(cls.tmpname, mapset='')
+        if mset:
+            run_command("g.remove", flags='f', type='vector', name=cls.tmpname)
+
+    def test_init(self):
+        """Test area __init__ and basic functions"""
+        area = Area(v_id=1, c_mapinfo=self.c_mapinfo)
+        self.assertEqual(1, area.id)
+        self.assertTrue(area.is2D)
+        self.assertTrue(area.alive())
+        self.assertEqual(area.area(), 12.0)
+
+    def test_to_wkt(self):
+        """Test to_wkt method"""
+        area = Area(v_id=1, c_mapinfo=self.c_mapinfo)
+        # Outer and inner ring!!
+        string = "POLYGON ((0.0000000000000000 0.0000000000000000, "\
+                           "0.0000000000000000 4.0000000000000000, "\
+                           "0.0000000000000000 4.0000000000000000, "\
+                           "4.0000000000000000 4.0000000000000000, "\
+                           "4.0000000000000000 4.0000000000000000, "\
+                           "4.0000000000000000 0.0000000000000000, "\
+                           "4.0000000000000000 0.0000000000000000, "\
+                           "0.0000000000000000 0.0000000000000000), "\
+                           "(1.0000000000000000 1.0000000000000000, "\
+                           "3.0000000000000000 1.0000000000000000, "\
+                           "3.0000000000000000 3.0000000000000000, "\
+                           "1.0000000000000000 3.0000000000000000, "\
+                           "1.0000000000000000 1.0000000000000000))"
+        self.assertEqual(area.to_wkt(), string)
+
+    def test_to_wkb(self):
+        """Test to_wkt method"""
+        area = Area(v_id=1, c_mapinfo=self.c_mapinfo)
+        self.assertEqual(len(area.to_wkb()), 225)
+
+    def test_contains_point(self):
+        """Test contain_point method"""
+        area = Area(v_id=1, c_mapinfo=self.c_mapinfo)
+        p = Point(0.5, 0.5)
+        bbox = Bbox(4.0, 0.0, 4.0, 0.0)
+        self.assertTrue(area.contains_point(p, bbox))
+        self.assertTrue(area.contains_point(p))
+
+    def test_bbox(self):
+        """Test contain_point method"""
+        area = Area(v_id=1, c_mapinfo=self.c_mapinfo)
+        self.assertEqual(str(area.bbox()), "Bbox(4.0, 0.0, 4.0, 0.0)")
+
+    def test_centroid(self):
+        """Test centroid access"""
+        area = Area(v_id=1, c_mapinfo=self.c_mapinfo)
+        centroid = area.centroid()
+
+        self.assertEqual(centroid.id, 18)
+        self.assertEqual(centroid.area_id, 1)
+        self.assertEqual(centroid.to_wkt(), 'POINT (3.5000000000000000 3.5000000000000000)')
+
+    def test_boundaries_1(self):
+        """Test boundary access"""
+        area = Area(v_id=1, c_mapinfo=self.c_mapinfo)
+        boundaries = area.boundaries()
+        self.assertEqual(len(boundaries), 4)
+
+        string_list = []
+        string_list.append("LINESTRING (0.0000000000000000 0.0000000000000000, 0.0000000000000000 4.0000000000000000)")
+        string_list.append("LINESTRING (0.0000000000000000 4.0000000000000000, 4.0000000000000000 4.0000000000000000)")
+        string_list.append("LINESTRING (4.0000000000000000 4.0000000000000000, 4.0000000000000000 0.0000000000000000)")
+        string_list.append("LINESTRING (4.0000000000000000 0.0000000000000000, 0.0000000000000000 0.0000000000000000)")
+
+        for boundary, i in zip(boundaries, range(4)):
+            self.assertEqual(len(boundary.to_wkb()), 41)
+            self.assertEqual(boundary.to_wkt(), string_list[i])
+
+    def test_boundaries_2(self):
+        """Test boundary access"""
+        area = Area(v_id=1, c_mapinfo=self.c_mapinfo)
+        boundaries = area.boundaries()
+        boundary = boundaries[2]
+        boundary.read_area_ids()
+        self.assertEqual(boundary.left_area_id, 2)
+        self.assertEqual(boundary.right_area_id, 1)
+
+        self.assertEqual(boundary.left_centroid().to_wkt(), 'POINT (5.5000000000000000 3.5000000000000000)')
+        self.assertEqual(boundary.right_centroid().to_wkt(), 'POINT (3.5000000000000000 3.5000000000000000)')
+
+    def test_isles_1(self):
+        """Test centroid access"""
+        area = Area(v_id=1, c_mapinfo=self.c_mapinfo)
+        self.assertEqual(area.num_isles(), 1)
+
+        isles = area.isles()
+        isle = isles[0]
+
+        self.assertEqual(isle.area(), 4.0)
+        self.assertEqual(isle.points().to_wkt(), "LINESTRING (1.0000000000000000 1.0000000000000000, "\
+                                                             "3.0000000000000000 1.0000000000000000, "\
+                                                             "3.0000000000000000 3.0000000000000000, "\
+                                                             "1.0000000000000000 3.0000000000000000, "\
+                                                             "1.0000000000000000 1.0000000000000000)")
+    def test_isles_2(self):
+        """Test centroid access"""
+        area = Area(v_id=1, c_mapinfo=self.c_mapinfo)
+        self.assertEqual(area.num_isles(), 1)
+
+        isles = area.isles()
+        isle = isles[0]
+        self.assertEqual(isle.area_id(), 1)
+        self.assertTrue(isle.alive())
+
+        self.assertEqual(str(isle.bbox()), "Bbox(3.0, 1.0, 3.0, 1.0)")
+
+
 if __name__ == '__main__':
     test()



More information about the grass-commit mailing list