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

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Aug 26 05:30:33 PDT 2015


Author: huhabla
Date: 2015-08-26 05:30:33 -0700 (Wed, 26 Aug 2015)
New Revision: 66027

Modified:
   grass/trunk/lib/python/pygrass/utils.py
   grass/trunk/lib/python/pygrass/vector/__init__.py
   grass/trunk/lib/python/pygrass/vector/abstract.py
   grass/trunk/lib/python/pygrass/vector/find.py
   grass/trunk/lib/python/pygrass/vector/testsuite/test_doctests.py
   grass/trunk/lib/python/pygrass/vector/testsuite/test_geometry.py
Log:
pygrass vector: Better finder class documentation, usage and additional tests using the generated vector maps.
                Additional metadata for test vectors and better description.


Modified: grass/trunk/lib/python/pygrass/utils.py
===================================================================
--- grass/trunk/lib/python/pygrass/utils.py	2015-08-26 07:53:19 UTC (rev 66026)
+++ grass/trunk/lib/python/pygrass/utils.py	2015-08-26 12:30:33 UTC (rev 66027)
@@ -355,14 +355,28 @@
 
        This should be used in doc and unit tests to create location/mapset
        independent vector map layer. This map includes 3 points, 3 lines,
-       11 boundaries and 4 centroids. The attribute table contains cat and name
-       columns.
+       11 boundaries and 4 centroids. The attribute table contains cat, name
+       and value columns.
 
         param map_name: The vector map name that should be used
+
+
+
+                                  P1 P2 P3
+           6                       *  *  *
+           5
+           4    _______ ___ ___   L1 L2 L3
+        Y  3   |A1___ *|  *|  *|   |  |  |
+           2   | |A2*| |   |   |   |  |  |
+           1   | |___| |A3 |A4 |   |  |  |
+           0   |_______|___|___|   |  |  |
+          -1
+            -1 0 1 2 3 4 5 6 7 8 9 10 12 14
+                           X
     """
 
     from grass.pygrass.vector import VectorTopo
-    from grass.pygrass.vector.geometry import Point, Line, Centroid, Boundary, Area
+    from grass.pygrass.vector.geometry import Point, Line, Centroid, Boundary
 
     cols = [(u'cat', 'INTEGER PRIMARY KEY'),
             (u'name','varchar(50)'),
@@ -370,15 +384,6 @@
     with VectorTopo(map_name, mode='w', tab_name=map_name,
                     tab_cols=cols) as vect:
 
-        # Write 3 points, 3 lines and 11 boundaries with one nested isle and 4 centroids
-        #
-        #
-        #  ______ ___ ___   *  *  *
-        # |1 __ *|3 *|4 *|  |  |  |
-        # | |2*| |   |   |  |  |  |
-        # | |__| |   |   |  |  |  |
-        # |______|___|___|  |  |  |
-        #
         # Write 3 points
         vect.write(Point(10, 6), cat=1, attrs=("point", 1))
         vect.write(Point(12, 6), cat=1)
@@ -408,5 +413,85 @@
         vect.write(Centroid(x=5.5, y=3.5), cat=3)
         vect.write(Centroid(x=7.5, y=3.5), cat=3)
 
+        vect.organization = 'Thuenen Institut'
+        vect.person = 'Soeren Gebbert'
+        vect.title = 'Test dataset'
+        vect.comment = 'This is a comment'
+
         vect.table.conn.commit()
         vect.close()
+
+def create_test_stream_network_map(map_name="streams"):
+    """
+       This functions creates a vector map layer with lines that represent
+       a stream network with two different graphs. The first graph
+       contains a loop, the second can be used as directed graph.
+
+       This should be used in doc and unit tests to create location/mapset
+       independent vector map layer.
+
+        param map_name: The vector map name that should be used
+
+       1(0,2)  3(2,2)
+        \     /
+       1 \   / 2
+          \ /
+           2(1,1)
+    6(0,1) ||  5(2,1)
+       5 \ || / 4
+          \||/
+           4(1,0)
+           |
+           | 6
+           |7(1,-1)
+
+       7(0,-1) 8(2,-1)
+        \     /
+       8 \   / 9
+          \ /
+           9(1, -2)
+           |
+           | 10
+           |
+          10(1,-3)
+    """
+
+    from grass.pygrass.vector import VectorTopo
+    from grass.pygrass.vector.geometry import Line
+
+    cols = [(u'cat', 'INTEGER PRIMARY KEY'), (u'id', 'INTEGER')]
+    with VectorTopo(map_name, mode='w', tab_name=map_name,
+                    tab_cols=cols) as streams:
+
+        # First flow graph
+        l = Line([(0,2), (0.22, 1.75), (0.55, 1.5), (1,1)])
+        streams.write(l, cat=1, attrs=(1,))
+        l = Line([(2,2),(1,1)])
+        streams.write(l, cat=2, attrs=(2,))
+        l = Line([(1,1), (0.85, 0.5), (1,0)])
+        streams.write(l, cat=3, attrs=(3,))
+        l = Line([(2,1),(1,0)])
+        streams.write(l, cat=4, attrs=(4,))
+        l = Line([(0,1),(1,0)])
+        streams.write(l, cat=5, attrs=(5,))
+        l = Line([(1,0),(1,-1)])
+        streams.write(l, cat=6, attrs=(6,))
+        # Reverse line 3
+        l = Line([(1,0), (1.15, 0.5),(1,1)])
+        streams.write(l, cat=7, attrs=(7,))
+
+        # second flow graph
+        l = Line([(0,-1),(1,-2)])
+        streams.write(l, cat=8, attrs=(8,))
+        l = Line([(2,-1),(1,-2)])
+        streams.write(l, cat=9, attrs=(9,))
+        l = Line([(1,-2),(1,-3)])
+        streams.write(l, cat=10, attrs=(10,))
+
+        streams.organization = 'Thuenen Institut'
+        streams.person = 'Soeren Gebbert'
+        streams.title = 'Test dataset for stream networks'
+        streams.comment = 'This is a comment'
+
+        streams.table.conn.commit()
+        streams.close()

Modified: grass/trunk/lib/python/pygrass/vector/__init__.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/__init__.py	2015-08-26 07:53:19 UTC (rev 66026)
+++ grass/trunk/lib/python/pygrass/vector/__init__.py	2015-08-26 12:30:33 UTC (rev 66027)
@@ -562,16 +562,6 @@
             raise GrassError("I can not find the Bbox.")
         return bbox
 
-    @must_be_open
-    def select_by_bbox(self, bbox):
-        """Return the BBox of the vector map
-        """
-        # TODO replace with bbox if bbox else Bbox() ??
-        bbox = Bbox()
-        if libvect.Vect_get_map_box(self.c_mapinfo, bbox.c_bbox) == 0:
-            raise GrassError("I can not find the Bbox.")
-        return bbox
-
     def close(self, build=True, release=True):
         """Close the VectorTopo map, if release is True, the memory
         occupied by spatial index is released"""

Modified: grass/trunk/lib/python/pygrass/vector/abstract.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/abstract.py	2015-08-26 07:53:19 UTC (rev 66026)
+++ grass/trunk/lib/python/pygrass/vector/abstract.py	2015-08-26 12:30:33 UTC (rev 66027)
@@ -377,13 +377,18 @@
             self.layer = self.dblinks.by_layer(layer).layer
             self.table = self.dblinks.by_layer(layer).table()
             self.n_lines = self.table.n_rows()
-        self.writeable = self.mapset == utils.getenv("MAPSET")
+        self.writeable = False
+        self.mapset == utils.getenv("MAPSET")
+        # Initialize the finder
         self.find = {'by_point': PointFinder(self.c_mapinfo, self.table,
                                              self.writeable),
-                     'by_box': BboxFinder(self.c_mapinfo, self.table,
+                     'by_bbox': BboxFinder(self.c_mapinfo, self.table,
                                           self.writeable),
                      'by_polygon': PolygonFinder(self.c_mapinfo, self.table,
                                                  self.writeable), }
+        self.find_by_point = self.find["by_point"]
+        self.find_by_bbox  = self.find["by_bbox"]
+        self.find_by_polygon = self.find["by_polygon"]
 
     def close(self, build=False):
         """Method to close the Vector

Modified: grass/trunk/lib/python/pygrass/vector/find.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/find.py	2015-08-26 07:53:19 UTC (rev 66026)
+++ grass/trunk/lib/python/pygrass/vector/find.py	2015-08-26 12:30:33 UTC (rev 66027)
@@ -35,60 +35,119 @@
         from . import abstract
         return abstract.is_open(self.c_mapinfo)
 
-
 class PointFinder(AbstractFinder):
-    """PointFinder
+    """Point finder
 
-    Find the geometry features of a vector map that are close to a point.
-
-    >>> from grass.pygrass.vector import VectorTopo
-    >>> zipcodes = VectorTopo('zipcodes', 'PERMANENT')
-    >>> schools = VectorTopo('schools', 'PERMANENT')
-    >>> zipcodes.open('r')
-    >>> schools.open('r')
-    >>> result = []
-    >>> for school in schools:
-    ...     zipcode = zipcodes.find['by_point'].area(school)
-    ...     result.append((school.attrs['NAMESHORT'],
-    ...                    zipcode.attrs['ZIPCODE']))
-    ...
-    >>> result[0]
-    (u'SWIFT CREEK', u'RALEIGH 27606')
-    >>> result[1]
-    (u'BRIARCLIFF', u'CARY 27511')
-    >>> result[2]
-    (u'FARMINGTON WOODS', u'CARY 27511')
-    >>> from grass.pygrass.vector.geometry import Point
-    >>> pnt = Point(631213.349291, 224684.900084)
-    >>> school = schools.find['by_point'].geo(pnt, maxdist=300.)
-    >>> school.attrs['NAMELONG']
-    u'ADAMS ELEMENTARY'
-    >>> for school in schools.find['by_point'].geos(pnt, maxdist=1000.):
-    ...     print school.attrs['NAMELONG']
-    ...
-    CARY HIGH
-    EAST CARY MIDDLE SITE
-    ADAMS ELEMENTARY
-    >>> schools.close()
-    >>> zipcodes.close()
+        This class provides an interface to search geometry features
+        of a vector map that are close to a point. The PointFinder class
+        is part of a topological vector map object.
     """
     def __init__(self, c_mapinfo, table=None, writeable=False):
-        """Find geometry feature around a point.
+        """Find geometry feature(s) around a point.
+
+            :param c_mapinfo: Pointer to the vector layer mapinfo structure
+            :type c_mapinfo: ctypes pointer to mapinfo structure
+
+            :param table: Attribute table of the vector layer
+            :type table: Class Table from grass.pygrass.table
+
+            :param writable: True or False
+            :type writeable: boolean
         """
         super(PointFinder, self).__init__(c_mapinfo, table, writeable)
 
-# TODO: add the Node class and enable this method
-#    def node(self, point, maxdist):
-#        """Find the nearest node. Vect_find_node"""
-#        i = libvect.Vect_find_node(self.c_mapinfo, point.x, point.y, point.z,
-#                                   float(maxdist), int(not point.is2D))
-#        return geometry.Node(self.c_mapinfo.contents.plus.contents.Node[i])
+    @must_be_open
+    def node(self, point, maxdist):
+        """Find the nearest node around a specific point.
 
+            :param point: The point to search
+            :type point: grass.pygrass.vector.geometry.Point
+
+            :param maxdist: The maximum search distance around the point
+            :type maxdist: float
+
+            :return: A grass.pygrass.vector.geometry.Node if found or None
+
+            This methods uses libvect.Vect_find_node()()
+
+            Examples:
+
+            >>> from grass.pygrass.vector import VectorTopo
+            >>> from grass.pygrass.vector.geometry import Point
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open('r')
+
+            # Find nearest node
+            >>> points = (Point(10,0), Point(10,4), Point(14,0))
+            >>> result = []
+            >>> for point in points:
+            ...     f = test_vect.find_by_point.node(point=point, maxdist=1)
+            ...     if f:
+            ...         result.append(f)
+            >>> result
+            [Node(2), Node(1), Node(6)]
+
+            >>> test_vect.find_by_point.node(point=Point(20,20), maxdist=0)
+
+            >>> test_vect.close()
+        """
+        node_id = libvect.Vect_find_node(self.c_mapinfo, point.x,
+                                         point.y,
+                                         point.z if point.z else 0,
+                                         float(maxdist),
+                                         int(not point.is2D))
+        if node_id:
+            return Node(v_id=node_id, c_mapinfo=self.c_mapinfo,
+                 table=self.table, writeable=self.writeable)
+
     @must_be_open
     def geo(self, point, maxdist, type='all', exclude=0):
-        """Find the nearest line. Vect_find_line
+        """Find the nearest vector feature around a specific point.
 
-        Valid type are all the keys in find.vtype dictionary
+            :param point: The point to search
+            :type point: grass.pygrass.vector.geometry.Point
+
+            :param maxdist: The maximum search distance around the point
+            :type maxdist: float
+
+            :param type: The type of feature to search for
+                         Valid type are all the keys in find.vtype dictionary
+            :type type: string
+
+            :param exclude: if > 0 number of lines which should be
+                            excluded from selection
+
+            :return: A grass.pygrass.vector.geometry.Node if found or None
+
+            This methods uses libvect.Vect_find_line()()
+
+            Examples:
+
+            >>> from grass.pygrass.vector import VectorTopo
+            >>> from grass.pygrass.vector.geometry import Point
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open('r')
+
+            # Find single features
+            >>> points = (Point(10,0), Point(10,6), Point(14,2))
+            >>> result = []
+            >>> for point in points:
+            ...     f = test_vect.find_by_point.geo(point=point, maxdist=1)
+            ...     if f:
+            ...         result.append(f)
+            >>> for f in result:
+            ...     print(f.to_wkt())    #doctest: +NORMALIZE_WHITESPACE
+            LINESTRING(10.000000 4.000000,
+                       10.000000 2.000000,
+                       10.000000 0.000000)
+            POINT(10.000000 6.000000)
+            LINESTRING(14.000000 4.000000,
+                       14.000000 2.000000,
+                       14.000000 0.000000)
+
+            >>> test_vect.find_by_point.geo(point=Point(20,20), maxdist=0)
+
+            >>> test_vect.close()
         """
         feature_id = libvect.Vect_find_line(self.c_mapinfo,
                                             point.x, point.y,
@@ -101,9 +160,79 @@
 
     @must_be_open
     def geos(self, point, maxdist, type='all', exclude=None):
-        """Find the nearest line. Vect_find_line_list
+        """Find the nearest vector features around a specific point.
 
-        Valid type are all the keys in find.vtype dictionary
+            :param point: The point to search
+            :type point: grass.pygrass.vector.geometry.Point
+
+            :param maxdist: The maximum search distance around the point
+            :type maxdist: float
+
+            :param type: The type of feature to search for
+                         Valid type are all the keys in find.vtype dictionary
+            :type type: string
+
+            :param exclude: if > 0 number of lines which should be
+                            excluded from selection
+
+            :return: A list of grass.pygrass.vector.geometry
+                     (Line, Point, Boundary, Centroid) if found or None
+
+            This methods uses libvect.Vect_find_line_list()()
+
+            Examples:
+
+            >>> from grass.pygrass.vector import VectorTopo
+            >>> from grass.pygrass.vector.geometry import Point
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open('r')
+
+            # Find multiple features
+            >>> points = (Point(10,0), Point(10,5), Point(14,2))
+            >>> result = []
+            >>> for point in points:
+            ...     f = test_vect.find_by_point.geos(point=point,
+            ...                                      maxdist=1.5)
+            ...     if f:
+            ...         result.append(f)
+            >>> for f in result:
+            ...     print(f)             #doctest: +NORMALIZE_WHITESPACE
+            [Line([Point(10.000000, 4.000000),
+                   Point(10.000000, 2.000000),
+                   Point(10.000000, 0.000000)])]
+            [Line([Point(10.000000, 4.000000),
+                   Point(10.000000, 2.000000),
+                   Point(10.000000, 0.000000)]),
+             Point(10.000000, 6.000000)]
+            [Line([Point(14.000000, 4.000000),
+                   Point(14.000000, 2.000000),
+                   Point(14.000000, 0.000000)])]
+
+            # Find multiple boundaries
+            >>> point = Point(3,3)
+            >>> result = test_vect.find_by_point.geos(point=Point(3,3),
+            ...                                          type="boundary",
+            ...                                          maxdist=1.5)
+            >>> result                   #doctest: +NORMALIZE_WHITESPACE
+            [Boundary([Point(0.000000, 4.000000), Point(4.000000, 4.000000)]),
+             Boundary([Point(4.000000, 4.000000), Point(4.000000, 0.000000)]),
+             Boundary([Point(1.000000, 1.000000), Point(1.000000, 3.000000),
+                       Point(3.000000, 3.000000), Point(3.000000, 1.000000),
+                       Point(1.000000, 1.000000)]),
+             Boundary([Point(4.000000, 4.000000), Point(6.000000, 4.000000)])]
+
+            # Find multiple centroids
+            >>> point = Point(3,3)
+            >>> result = test_vect.find_by_point.geos(point=Point(3,3),
+            ...                                          type="centroid",
+            ...                                          maxdist=1.5)
+            >>> result                   #doctest: +NORMALIZE_WHITESPACE
+            [Centoid(2.500000, 2.500000),
+             Centoid(3.500000, 3.500000)]
+
+            >>> test_vect.find_by_point.geos(point=Point(20,20), maxdist=0)
+
+            >>> test_vect.close()
         """
         excl = Ilist(exclude) if exclude else Ilist([])
         found = Ilist()
@@ -115,12 +244,47 @@
                                        excl.c_ilist, found.c_ilist):
             return [read_line(f_id, self.c_mapinfo, self.table, self.writeable)
                     for f_id in found]
-        else:
-            return []
 
+
     @must_be_open
     def area(self, point):
-        """Find the nearest area. Vect_find_area"""
+        """Find the nearest area around a specific point.
+
+            :param point: The point to search
+            :type point: grass.pygrass.vector.geometry.Point
+
+            :return: A grass.pygrass.vector.geometry.Area if found or None
+
+            This methods uses libvect.Vect_find_area()
+
+            Examples:
+
+            >>> from grass.pygrass.vector import VectorTopo
+            >>> from grass.pygrass.vector.geometry import Point
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open('r')
+
+            # Find AREAS
+            >>> points = (Point(0.5,0.5), Point(5,1), Point(7,1))
+            >>> result = []
+            >>> for point in points:
+            ...     area = test_vect.find_by_point.area(point)
+            ...     result.append(area)
+            >>> result
+            [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))
+
+            >>> test_vect.find_by_point.area(Point(20,20))
+
+            >>> test_vect.close()
+        """
         area_id = libvect.Vect_find_area(self.c_mapinfo, point.x, point.y)
         if area_id:
             return Area(v_id=area_id, c_mapinfo=self.c_mapinfo,
@@ -128,7 +292,42 @@
 
     @must_be_open
     def island(self, point):
-        """Find the nearest island. Vect_find_island"""
+        """Find the nearest island around a specific point.
+
+            :param point: The point to search
+            :type point: grass.pygrass.vector.geometry.Point
+
+            :return: A grass.pygrass.vector.geometry.Isle if found or None
+
+            This methods uses Vect_find_island.Vect_find_area()
+
+            Examples:
+
+            >>> from grass.pygrass.vector import VectorTopo
+            >>> from grass.pygrass.vector.geometry import Point
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open('r')
+
+            # Find ISLANDS
+            >>> points = (Point(2,2), Point(5,1))
+            >>> result = []
+            >>> for point in points:
+            ...     area = test_vect.find_by_point.island(point)
+            ...     result.append(area)
+            >>> result
+            [Isle(2), Isle(1)]
+            >>> for isle in result:
+            ...     print(isle.to_wkt())         #doctest: +NORMALIZE_WHITESPACE
+            Polygon((1.000000 1.000000, 3.000000 1.000000,
+                     3.000000 3.000000, 1.000000 3.000000, 1.000000 1.000000))
+            Polygon((0.000000 4.000000, 0.000000 0.000000, 4.000000 0.000000,
+                     6.000000 0.000000, 8.000000 0.000000, 8.000000 4.000000,
+                     6.000000 4.000000, 4.000000 4.000000, 0.000000 4.000000))
+
+            >>> test_vect.find_by_point.island(Point(20,20))
+
+            >>> test_vect.close()
+        """
         isle_id = libvect.Vect_find_island(self.c_mapinfo, point.x, point.y)
         if isle_id:
             return Isle(v_id=isle_id, c_mapinfo=self.c_mapinfo,
@@ -136,62 +335,257 @@
 
 
 class BboxFinder(AbstractFinder):
+    """Bounding Box finder
+
+    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.
+
+    """
     def __init__(self, c_mapinfo, table=None, writeable=False):
+        """Find geometry feature(s)that are insider or intersect
+           with a boundingbox.
+
+            :param c_mapinfo: Pointer to the vector layer mapinfo structure
+            :type c_mapinfo: ctypes pointer to mapinfo structure
+
+            :param table: Attribute table of the vector layer
+            :type table: Class Table from grass.pygrass.table
+
+            :param writable: True or False
+            :type writeable: boolean
+        """
         super(BboxFinder, self).__init__(c_mapinfo, table, writeable)
 
     @must_be_open
-    def geos(self, bbox, type='all', bbox_list=False):
-        """Find the geometry features contained in the bbox.
-        Vect_select_lines_by_box
+    def geos(self, bbox, type='all', bboxlist_only=False):
+        """Find the nearest vector features around a specific point.
 
-        Valid type are all the keys in find.vtype dictionary
+            :param bbox: The boundingbox to search in
+            :type bbox: grass.pygrass.vector.basic.Bbox
+
+            :param type: The type of feature to search for
+                         Valid type are all the keys in find.vtype dictionary
+            :type type: string
+
+            :param bboxlist_only: If true the BoxList will be returned,
+                                  no features are generated
+            :type bboxlist_only: boolean
+
+            :return: A list of grass.pygrass.vector.geometry
+                     (Line, Point, Boundary, Centroid) if found,
+                     or None if nothing was found.
+                     If bboxlist_only is True a BoxList
+                     object will be returned, or None if nothing was found.
+
+            This methods uses libvect.Vect_select_lines_by_box()
+
+            Examples:
+
+            >>> from grass.pygrass.vector import VectorTopo
+            >>> from grass.pygrass.vector.basic import Bbox
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open('r')
+
+            >>> bbox = Bbox(north=5, south=-1, east=3, west=-1)
+            >>> result = test_vect.find_by_bbox.geos(bbox=bbox)
+            >>> result                   #doctest: +NORMALIZE_WHITESPACE
+            [Boundary([Point(4.000000, 0.000000), Point(0.000000, 0.000000)]),
+             Boundary([Point(0.000000, 0.000000), Point(0.000000, 4.000000)]),
+             Boundary([Point(0.000000, 4.000000), Point(4.000000, 4.000000)]),
+             Boundary([Point(1.000000, 1.000000), Point(1.000000, 3.000000),
+                       Point(3.000000, 3.000000), Point(3.000000, 1.000000),
+                       Point(1.000000, 1.000000)]),
+             Centoid(2.500000, 2.500000)]
+
+            >>> bbox = Bbox(north=5, south=-1, east=3, west=-1)
+            >>> result = test_vect.find_by_bbox.geos(bbox=bbox,
+            ...                                      bboxlist_only=True)
+            >>> result                   #doctest: +NORMALIZE_WHITESPACE
+            Boxlist([Bbox(0.0, 0.0, 4.0, 0.0),
+                     Bbox(4.0, 0.0, 0.0, 0.0),
+                     Bbox(4.0, 4.0, 4.0, 0.0),
+                     Bbox(3.0, 1.0, 3.0, 1.0),
+                     Bbox(2.5, 2.5, 2.5, 2.5)])
+
+            >>> bbox = Bbox(north=7, south=-1, east=15, west=9)
+            >>> result = test_vect.find_by_bbox.geos(bbox=bbox)
+            >>> result                   #doctest: +NORMALIZE_WHITESPACE
+            [Line([Point(10.000000, 4.000000), Point(10.000000, 2.000000),
+                   Point(10.000000, 0.000000)]),
+             Point(10.000000, 6.000000),
+             Line([Point(12.000000, 4.000000), Point(12.000000, 2.000000),
+                   Point(12.000000, 0.000000)]),
+             Point(12.000000, 6.000000),
+             Line([Point(14.000000, 4.000000), Point(14.000000, 2.000000),
+                   Point(14.000000, 0.000000)]),
+             Point(14.000000, 6.000000)]
+
+            >>> bbox = Bbox(north=20, south=18, east=20, west=18)
+            >>> test_vect.find_by_bbox.geos(bbox=bbox)
+
+            >>> bbox = Bbox(north=20, south=18, east=20, west=18)
+            >>> test_vect.find_by_bbox.geos(bbox=bbox, bboxlist_only=True)
+
+            >>> test_vect.close()
         """
         found = BoxList()
         if libvect.Vect_select_lines_by_box(self.c_mapinfo, bbox.c_bbox,
                                             self.vtype[type], found.c_boxlist):
-            if bbox_list:
+            if bboxlist_only:
                 return found
             else:
-                return (read_line(f_id, self.c_mapinfo, self.table,
-                                  self.writeable) for f_id in found.ids)
+                return [read_line(f_id, self.c_mapinfo, self.table,
+                                  self.writeable) for f_id in found.ids]
 
     @must_be_open
     def nodes(self, bbox):
-        """Find the nearest area. Vect_find_area"""
+        """Find the nodes inside a boundingbox.
+
+            :param bbox: The boundingbox to search in
+            :type bbox: grass.pygrass.vector.basic.Bbox
+
+            :return: A list of nodes or None if nothing was found
+
+            This methods uses libvect.Vect_select_nodes_by_box()
+
+            Examples:
+
+            >>> from grass.pygrass.vector import VectorTopo
+            >>> from grass.pygrass.vector.basic import Bbox
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open('r')
+
+            # Find nodes in box
+            >>> bbox = Bbox(north=5, south=-1, east=15, west=9)
+            >>> result = test_vect.find_by_bbox.nodes(bbox=bbox)
+            >>> result
+            [Node(2), Node(1), Node(4), Node(3), Node(5), Node(6)]
+
+            >>> bbox = Bbox(north=20, south=18, east=20, west=18)
+            >>> test_vect.find_by_bbox.nodes(bbox=bbox)
+
+            >>> test_vect.close()
+        """
         found = Ilist()
         if libvect.Vect_select_nodes_by_box(self.c_mapinfo, bbox.c_bbox,
                                             found.c_ilist):
-            for n_id in found:
-                yield Node(v_id=n_id, c_mapinfo=self.c_mapinfo,
-                           table=self.table, writeable=self.writeable)
+            if len(found) > 0:
+                return [Node(v_id=n_id, c_mapinfo=self.c_mapinfo,
+                             table=self.table, writeable=self.writeable)
+                        for n_id in found]
 
     @must_be_open
     def areas(self, bbox, boxlist=None, bboxlist_only=False):
-        """Find the nearest area. Vect_find_area"""
+        """Find the areas inside a boundingbox.
+
+            :param bbox: The boundingbox to search in
+            :type bbox: grass.pygrass.vector.basic.Bbox
+
+            :param boxlist: An existing BoxList to be filled with
+            :type_boxlist: grass.pygrass.vector.basic.BoxList
+
+            :param bboxlist_only: If true the BoxList will be returned,
+                                  no features are generated
+            :type bboxlist_only: boolean
+
+            :return: A list of areas or None if nothing was found
+
+            This methods uses libvect.Vect_select_areas_by_box()
+
+            Examples:
+
+            >>> from grass.pygrass.vector import VectorTopo
+            >>> from grass.pygrass.vector.basic import Bbox
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open('r')
+
+            # Find areas in box
+            >>> bbox = Bbox(north=5, south=-1, east=9, west=-1)
+            >>> result = test_vect.find_by_bbox.areas(bbox=bbox)
+            >>> result
+            [Area(1), Area(2), Area(3), Area(4)]
+
+            >>> bbox = Bbox(north=5, south=-1, east=9, west=-1)
+            >>> result = test_vect.find_by_bbox.areas(bbox=bbox,
+            ...                                       bboxlist_only=True)
+            >>> result                   #doctest: +NORMALIZE_WHITESPACE
+            Boxlist([Bbox(4.0, 0.0, 4.0, 0.0),
+                     Bbox(4.0, 0.0, 6.0, 4.0),
+                     Bbox(3.0, 1.0, 3.0, 1.0),
+                     Bbox(4.0, 0.0, 8.0, 6.0)])
+
+            >>> bbox = Bbox(north=20, south=18, east=20, west=18)
+            >>> test_vect.find_by_bbox.areas(bbox=bbox)
+
+            >>> test_vect.find_by_bbox.areas(bbox=bbox,
+            ...                              bboxlist_only=True)
+
+            >>> test_vect.close()
+        """
         boxlist = boxlist if boxlist else BoxList()
         if libvect.Vect_select_areas_by_box(self.c_mapinfo, bbox.c_bbox,
                                             boxlist.c_boxlist):
             if bboxlist_only:
                 return boxlist
             else:
-                return (Area(v_id=a_id, c_mapinfo=self.c_mapinfo,
+                return [Area(v_id=a_id, c_mapinfo=self.c_mapinfo,
                              table=self.table, writeable=self.writeable)
-                        for a_id in boxlist.ids)
-        return []
+                        for a_id in boxlist.ids]
 
     @must_be_open
-    def islands(self, bbox, bbox_list=False):
-        """Find the nearest island. Vect_find_island"""
+    def islands(self, bbox, bboxlist_only=False):
+        """Find the isles inside a boundingbox.
+
+            :param bbox: The boundingbox to search in
+            :type bbox: grass.pygrass.vector.basic.Bbox
+
+            :param bboxlist_only: If true the BoxList will be returned,
+                                  no features are generated
+            :type bboxlist_only: boolean
+
+            :return: A list of isles or None if nothing was found
+
+            This methods uses libvect.Vect_select_isles_by_box()
+
+            Examples:
+
+            >>> from grass.pygrass.vector import VectorTopo
+            >>> from grass.pygrass.vector.basic import Bbox
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open('r')
+
+            # Find isles in box
+            >>> bbox = Bbox(north=5, south=-1, east=9, west=-1)
+            >>> result = test_vect.find_by_bbox.islands(bbox=bbox)
+            >>> result
+            [Isle(1), Isle(2)]
+
+            >>> bbox = Bbox(north=5, south=-1, east=9, west=-1)
+            >>> result = test_vect.find_by_bbox.islands(bbox=bbox,
+            ...                                       bboxlist_only=True)
+            >>> result                   #doctest: +NORMALIZE_WHITESPACE
+            Boxlist([Bbox(4.0, 0.0, 8.0, 0.0),
+                     Bbox(3.0, 1.0, 3.0, 1.0)])
+
+            >>> bbox = Bbox(north=20, south=18, east=20, west=18)
+            >>> test_vect.find_by_bbox.islands(bbox=bbox)
+
+            >>> test_vect.find_by_bbox.islands(bbox=bbox,
+            ...                              bboxlist_only=True)
+
+            >>> test_vect.close()
+        """
         found = BoxList()
         if libvect.Vect_select_isles_by_box(self.c_mapinfo, bbox.c_bbox,
                                             found.c_boxlist):
-            if bbox_list:
+            if bboxlist_only:
                 return found
             else:
-                return (Isle(v_id=i_id, c_mapinfo=self.c_mapinfo,
+                return [Isle(v_id=i_id, c_mapinfo=self.c_mapinfo,
                              table=self.table, writeable=self.writeable)
-                        for i_id in found.ids)
-        return []
+                        for i_id in found.ids]
 
 
 class PolygonFinder(AbstractFinder):

Modified: grass/trunk/lib/python/pygrass/vector/testsuite/test_doctests.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/testsuite/test_doctests.py	2015-08-26 07:53:19 UTC (rev 66026)
+++ grass/trunk/lib/python/pygrass/vector/testsuite/test_doctests.py	2015-08-26 12:30:33 UTC (rev 66027)
@@ -31,17 +31,18 @@
     # TODO: ultimate solution is not to use _ as a buildin in lib/python
     # for now it is the only place where it works
     grass.gunittest.utils.do_doctest_gettext_workaround()
-    
+
     from grass.pygrass import utils
     utils.create_test_vector_map(gvector.test_vector_name)
     utils.create_test_vector_map(gvector.abstract.test_vector_name)
     utils.create_test_vector_map(gvector.geometry.test_vector_name)
-    
+    utils.create_test_vector_map(gvector.find.test_vector_name)
+
     # this should be called at some top level
     tests.addTests(doctest.DocTestSuite(gvector))
     tests.addTests(doctest.DocTestSuite(gvector.abstract))
     tests.addTests(doctest.DocTestSuite(gvector.basic))
-    #tests.addTests(doctest.DocTestSuite(gvector.find))
+    tests.addTests(doctest.DocTestSuite(gvector.find))
     tests.addTests(doctest.DocTestSuite(gvector.geometry))
     tests.addTests(doctest.DocTestSuite(gvector.sql))
     #tests.addTests(doctest.DocTestSuite(gvector.table))

Modified: grass/trunk/lib/python/pygrass/vector/testsuite/test_geometry.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/testsuite/test_geometry.py	2015-08-26 07:53:19 UTC (rev 66026)
+++ grass/trunk/lib/python/pygrass/vector/testsuite/test_geometry.py	2015-08-26 12:30:33 UTC (rev 66027)
@@ -94,10 +94,10 @@
 
     @classmethod
     def setUpClass(cls):
-        
+
         from grass.pygrass import utils
         utils.create_test_vector_map(cls.tmpname)
-        
+
         cls.vect = None
         cls.vect = VectorTopo(cls.tmpname)
         cls.vect.open('r')
@@ -172,15 +172,16 @@
             self.assertTupleEqual((5, 6), nodes2tuple(vect[6].nodes()))
 
 class NodeTestCase(TestCase):
-    
+
     tmpname = "NodeTestCase_map"
 
     @classmethod
     def setUpClass(cls):
-        
+
+        # Tests are based on a stream network
         from grass.pygrass import utils
-        utils.create_test_vector_map(cls.tmpname)
-        
+        utils.create_test_stream_network_map(cls.tmpname)
+
         cls.vect = None
         cls.vect = VectorTopo(cls.tmpname)
         cls.vect.open('r')
@@ -203,26 +204,27 @@
         node = Node(v_id=4, c_mapinfo=self.c_mapinfo)
         self.assertEqual(4, node.id)
         self.assertTrue(node.is2D)
-        self.assertEqual(1, node.nlines)
+        self.assertEqual(5, node.nlines)
 
     def test_coords(self):
         """Test Node coordinates"""
         node = Node(v_id=4, c_mapinfo=self.c_mapinfo)
-        self.assertTupleEqual((12.0, 0.0),
-                              node.coords())
+        self.assertTupleEqual((1.0, 0.0), node.coords())
 
     def test_ilines(self):
-        """Test Node coordinates"""
-        node = Node(v_id=4, c_mapinfo=self.c_mapinfo) # Line 5 ends in this node
-        self.assertTupleEqual((-5,), tuple(node.ilines())) 
-        self.assertTupleEqual((-5,), tuple(node.ilines(only_in=True)))
-        node = Node(v_id=3, c_mapinfo=self.c_mapinfo) # Line 5 starts at this node
-        self.assertTupleEqual((5,), tuple(node.ilines(only_out=True)))
+        """Test Node neighbors"""
+        node = Node(v_id=4, c_mapinfo=self.c_mapinfo)
+        self.assertTupleEqual((6, -4, 7, -3, -5), tuple(node.ilines()))
+        self.assertTupleEqual((-4, -3, -5), tuple(node.ilines(only_in=True)))
+        node = Node(v_id=4, c_mapinfo=self.c_mapinfo)
+        self.assertTupleEqual((6, 7), tuple(node.ilines(only_out=True)))
 
     def test_angles(self):
         """Test Node angles"""
         node = Node(v_id=4, c_mapinfo=self.c_mapinfo)
-        angles = (1.5707963705062866,) # 90°
+        angles = (-1.5707963705062866, 0.7853981852531433,
+                   1.2793395519256592, 1.8622530698776245,
+                   2.356194496154785)
         self.assertTupleEqual(angles, tuple(node.angles()))
 
 if __name__ == '__main__':



More information about the grass-commit mailing list