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

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Aug 25 08:20:23 PDT 2015


Author: huhabla
Date: 2015-08-25 08:20:23 -0700 (Tue, 25 Aug 2015)
New Revision: 66016

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/geometry.py
Log:
pygrass vector: API changes: removed "get_" prefix from several functions to harmonize method names, 
added vector map layer generator that is used in several doc tests. Modified many doctests in __init__.py and geometry.py
to use generated vector maps.


Modified: grass/trunk/lib/python/pygrass/utils.py
===================================================================
--- grass/trunk/lib/python/pygrass/utils.py	2015-08-25 13:41:44 UTC (rev 66015)
+++ grass/trunk/lib/python/pygrass/utils.py	2015-08-25 15:20:23 UTC (rev 66016)
@@ -347,3 +347,66 @@
             return False
     one = cursor.fetchone() if cursor else None
     return True if one and one[0] else False
+
+
+def create_test_vector_map(map_name="test_vector"):
+    """This functions creates a vector map layer with points, lines, boundaries,
+       centroids, areas, isles and attributes for testing purposes
+
+       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.
+
+        param map_name: The vector map name that should be used
+    """
+
+    from grass.pygrass.vector import VectorTopo
+    from grass.pygrass.vector.geometry import Point, Line, Centroid, Boundary, Area
+
+    cols = [(u'cat', 'INTEGER PRIMARY KEY'),
+            (u'name','varchar(50)'),
+            (u'value', 'double precision')]
+    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)
+        vect.write(Point(14, 6), cat=1)
+        # Write 3 lines
+        vect.write(Line([(10, 4), (10, 2), (10,0)]), cat=2, attrs=("line", 2))
+        vect.write(Line([(12, 4), (12, 2), (12,0)]), cat=2)
+        vect.write(Line([(14, 4), (14, 2), (14,0)]), cat=2)
+        # boundaries 1 - 4
+        vect.write(Boundary(points=[(0, 0), (0,4)]))
+        vect.write(Boundary(points=[(0, 4), (4,4)]))
+        vect.write(Boundary(points=[(4, 4), (4,0)]))
+        vect.write(Boundary(points=[(4, 0), (0,0)]))
+        # 5. boundary (Isle)
+        vect.write(Boundary(points=[(1, 1), (1,3), (3, 3), (3,1), (1,1)]))
+        # boundaries 6 - 8
+        vect.write(Boundary(points=[(4, 4), (6,4)]))
+        vect.write(Boundary(points=[(6, 4), (6,0)]))
+        vect.write(Boundary(points=[(6, 0), (4,0)]))
+        # boundaries 9 - 11
+        vect.write(Boundary(points=[(6, 4), (8,4)]))
+        vect.write(Boundary(points=[(8, 4), (8,0)]))
+        vect.write(Boundary(points=[(8, 0), (6,0)]))
+        # Centroids, all have the same cat and attribute
+        vect.write(Centroid(x=3.5, y=3.5), cat=3, attrs=("centroid", 3))
+        vect.write(Centroid(x=2.5, y=2.5), cat=3)
+        vect.write(Centroid(x=5.5, y=3.5), cat=3)
+        vect.write(Centroid(x=7.5, y=3.5), cat=3)
+
+        vect.table.conn.commit()
+        vect.close()

Modified: grass/trunk/lib/python/pygrass/vector/__init__.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/__init__.py	2015-08-25 13:41:44 UTC (rev 66015)
+++ grass/trunk/lib/python/pygrass/vector/__init__.py	2015-08-25 15:20:23 UTC (rev 66016)
@@ -31,6 +31,8 @@
           "updated_nodes": libvect.Vect_get_num_updated_nodes,
           "volumes": libvect.Vect_get_num_volumes}
 
+# For test purposes
+test_vector_name = "vector_doctest_map"
 
 #=============================================
 # VECTOR
@@ -40,16 +42,14 @@
     """Vector class is the grass vector format without topology
 
         >>> from grass.pygrass.vector import Vector
-        >>> cens = Vector('census')
-        >>> cens.is_open()
+        >>> test_vect = Vector(test_vector_name)
+        >>> test_vect.is_open()
         False
-        >>> cens.mapset
+        >>> test_vect.mapset
         ''
-        >>> cens.exist()
+        >>> test_vect.exist()
         True
-        >>> cens.mapset
-        'PERMANENT'
-        >>> cens.overwrite
+        >>> test_vect.overwrite
         False
 
     """
@@ -59,6 +59,7 @@
         self._topo_level = 1
         self._class_name = 'Vector'
         self.overwrite = False
+        self._cats = []
 
     def __repr__(self):
         if self.exist():
@@ -69,12 +70,12 @@
     def __iter__(self):
         """::
 
-            >>> cens = Vector('census')
-            >>> cens.open(mode='r')
-            >>> features = [feature for feature in cens]
+            >>> test_vect = Vector(test_vector_name)
+            >>> test_vect.open(mode='r')
+            >>> features = [feature for feature in test_vect]
             >>> features[:3]
-            [Boundary(v_id=None), Boundary(v_id=None), Boundary(v_id=None)]
-            >>> cens.close()
+            [Point(10.000000, 6.000000), Point(12.000000, 6.000000), Point(14.000000, 6.000000)]
+            >>> test_vect.close()
 
         ..
         """
@@ -85,17 +86,17 @@
     def next(self):
         """::
 
-            >>> cens = Vector('census')
-            >>> cens.open(mode='r')
-            >>> cens.next()
-            Boundary(v_id=None)
-            >>> cens.next()
-            Boundary(v_id=None)
-            >>> cens.close()
+            >>> test_vect = Vector(test_vector_name)
+            >>> test_vect.open(mode='r')
+            >>> test_vect.next()
+            Point(10.000000, 6.000000)
+            >>> test_vect.next()
+            Point(12.000000, 6.000000)
+            >>> test_vect.close()
 
         ..
         """
-        return read_next_line(self.c_mapinfo, self.table, self.writable,
+        return read_next_line(self.c_mapinfo, self.table, self.writeable,
                               is2D=not self.is_3D())
 
     @must_be_open
@@ -105,7 +106,7 @@
             raise GrassError("Vect_rewind raise an error.")
 
     @must_be_open
-    def write(self, geo_obj, attrs=None, set_cats=True):
+    def write(self, geo_obj, cat=None, attrs=None):
         """Write geometry features and attributes.
 
         :param geo_obj: a geometry grass object define in
@@ -114,11 +115,9 @@
         :param attrs: a list with the values that will be insert in the
                       attribute table.
         :type attrs: list
-        :param set_cats: if True, the category of the geometry feature is set
-                         using the default layer of the vector map and a
-                         progressive category value (default), otherwise the
+        :param cat: The category of the geometry feature, otherwise the
                          c_cats attribute of the geometry object will be used.
-        :type set_cats: bool
+        :type cat: integer
 
         Open a new vector map ::
 
@@ -141,19 +140,19 @@
 
         create two points ::
 
-            >>> point0 = Point(636981.336043, 256517.602235)
-            >>> point1 = Point(637209.083058, 257970.129540)
+            >>> point0 = Point(0, 0)
+            >>> point1 = Point(1, 1)
 
         then write the two points on the map, with ::
 
-            >>> new.write(point0, ('pub', ))
-            >>> new.write(point1, ('resturnat', ))
+            >>> new.write(point0, cat=1, attrs=('pub',))
+            >>> new.write(point1, cat=2, attrs=('resturant',))
 
         commit the db changes ::
 
             >>> new.table.conn.commit()
             >>> new.table.execute().fetchall()
-            [(1, u'pub'), (2, u'resturnat')]
+            [(1, u'pub'), (2, u'resturant')]
 
         close the vector map ::
 
@@ -165,29 +164,31 @@
 
             >>> new.open(mode='r')
             >>> new.read(1)
-            Point(636981.336043, 256517.602235)
+            Point(0.000000, 0.000000)
             >>> new.read(2)
-            Point(637209.083058, 257970.129540)
+            Point(1.000000, 1.000000)
             >>> new.read(1).attrs['name']
             u'pub'
             >>> new.read(2).attrs['name']
-            u'resturnat'
+            u'resturant'
             >>> new.close()
             >>> new.remove()
 
         """
         self.n_lines += 1
-        if self.table is not None and attrs:
-            attr = [self.n_lines, ]
-            attr.extend(attrs)
-            cur = self.table.conn.cursor()
-            cur.execute(self.table.columns.insert_str, attr)
-            cur.close()
+        if self.table is not None and attrs and cat is not None:
+            if cat not in self._cats:
+                self._cats.append(cat)
+                attr = [cat, ]
+                attr.extend(attrs)
+                cur = self.table.conn.cursor()
+                cur.execute(self.table.columns.insert_str, attr)
+                cur.close()
 
-        if set_cats:
+        if cat is not None:
             cats = Cats(geo_obj.c_cats)
             cats.reset()
-            cats.set(self.n_lines, self.layer)
+            cats.set(cat, self.layer)
 
         if geo_obj.gtype == _Area.gtype:
             result = self._write_area(geo_obj)
@@ -207,23 +208,23 @@
         """Return if vector has color table associated in file system;
         Color table stored in the vector's attribute table well be not checked
 
-        >>> cens = Vector('census')
-        >>> cens.open(mode='r')
-        >>> cens.has_color_table()
+        >>> test_vect = Vector(test_vector_name)
+        >>> test_vect.open(mode='r')
+        >>> test_vect.has_color_table()
         False
 
-        >>> cens.close()
+        >>> test_vect.close()
         >>> from grass.pygrass.utils import copy, remove
-        >>> copy('census','mycensus','vect')
+        >>> copy(test_vector_name,'mytest_vect','vect')
         >>> from grass.pygrass.modules.shortcuts import vector as v
-        >>> v.colors(map='mycensus', color='population', column='TOTAL_POP')
+        >>> v.colors(map='mytest_vect', color='population', column='value')
         Module('v.colors')
-        >>> mycens = Vector('mycensus')
-        >>> mycens.open(mode='r')
-        >>> mycens.has_color_table()
+        >>> mytest_vect = Vector('mytest_vect')
+        >>> mytest_vect.open(mode='r')
+        >>> mytest_vect.has_color_table()
         True
-        >>> mycens.close()
-        >>> remove('mycensus', 'vect')
+        >>> mytest_vect.close()
+        >>> remove('mytest_vect', 'vect')
         """
         loc = Location()
         path = join(loc.path(), self.mapset, 'vector', self.name, 'colr')
@@ -239,14 +240,17 @@
 
     Open a vector map using the *with statement*: ::
 
-        >>> with VectorTopo('schools', mode='r') as schools:
-        ...     for school in schools[:4]:
-        ...         print school.attrs['NAMESHORT']
+        >>> with VectorTopo(test_vector_name, mode='r') as test_vect:
+        ...     for feature in test_vect[:7]:
+        ...         print feature.attrs['name']
         ...
-        SWIFT CREEK
-        BRIARCLIFF
-        FARMINGTON WOODS
-        >>> schools.is_open()
+        point
+        point
+        point
+        line
+        line
+        line
+        >>> test_vect.is_open()
         False
 
     ..
@@ -262,11 +266,11 @@
     def __getitem__(self, key):
         """::
 
-            >>> cens = VectorTopo('census')
-            >>> cens.open(mode='r')
-            >>> cens[:4]
-            [Boundary(v_id=1), Boundary(v_id=2), Boundary(v_id=3)]
-            >>> cens.close()
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open(mode='r')
+            >>> test_vect[:4]
+            [Point(10.000000, 6.000000), Point(12.000000, 6.000000), Point(14.000000, 6.000000)]
+            >>> test_vect.close()
 
         ..
         """
@@ -299,17 +303,17 @@
 
         ::
 
-            >>> cens = VectorTopo('census')
-            >>> cens.open(mode='r')
-            >>> cens.num_primitive_of('point')
-            0
-            >>> cens.num_primitive_of('line')
-            0
-            >>> cens.num_primitive_of('centroid')
-            2537
-            >>> cens.num_primitive_of('boundary')
-            6383
-            >>> cens.close()
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open(mode='r')
+            >>> test_vect.num_primitive_of('point')
+            3
+            >>> test_vect.num_primitive_of('line')
+            3
+            >>> test_vect.num_primitive_of('centroid')
+            4
+            >>> test_vect.num_primitive_of('boundary')
+            11
+            >>> test_vect.close()
 
         ..
         """
@@ -326,24 +330,24 @@
                       *update_lines*, *update_nodes*, *volumes*
         :type vtype: str
 
-            >>> cens = VectorTopo('census')
-            >>> cens.open(mode='r')
-            >>> cens.number_of("areas")
-            2547
-            >>> cens.number_of("islands")
-            49
-            >>> cens.number_of("holes")
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open(mode='r')
+            >>> test_vect.number_of("areas")
+            4
+            >>> test_vect.number_of("islands")
+            2
+            >>> test_vect.number_of("holes")
             0
-            >>> cens.number_of("lines")
-            8920
-            >>> cens.number_of("nodes")
-            3885
-            >>> cens.number_of("pizza")
+            >>> test_vect.number_of("lines")
+            21
+            >>> test_vect.number_of("nodes")
+            15
+            >>> test_vect.number_of("pizza")
             ...                     # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
             Traceback (most recent call last):
                 ...
             ValueError: vtype not supported, use one of: 'areas', ...
-            >>> cens.close()
+            >>> test_vect.close()
 
 
         ..
@@ -376,24 +380,23 @@
                        full features
         :type idonly: bool
 
-            >>> cens = VectorTopo('census', mode='r')
-            >>> cens.open(mode='r')
-            >>> big = [area for area in cens.viter('areas')
-            ...        if area.alive() and area.area() >= 10000]
-            >>> big[:3]
-            [Area(5), Area(6), Area(13)]
+            >>> test_vect = VectorTopo(test_vector_name, mode='r')
+            >>> test_vect.open(mode='r')
+            >>> areas = [area for area in test_vect.viter('areas')]
+            >>> areas[:3]
+            [Area(1), Area(2), Area(3)]
 
 
         to sort the result in a efficient way, use: ::
 
             >>> from operator import methodcaller as method
-            >>> big.sort(key=method('area'), reverse=True)  # sort the list
-            >>> for area in big[:3]:
+            >>> areas.sort(key=method('area'), reverse=True)  # sort the list
+            >>> for area in areas[:3]:
             ...     print area, area.area()
-            Area(2099) 5392751.5304
-            Area(2171) 4799921.30863
-            Area(495) 4055812.49695
-            >>> cens.close()
+            Area(1) 12.0
+            Area(2) 8.0
+            Area(4) 8.0
+            >>> test_vect.close()
 
         """
         if vtype in _GEOOBJ.keys():
@@ -403,7 +406,7 @@
                     return ids
                 return (_GEOOBJ[vtype](v_id=indx, c_mapinfo=self.c_mapinfo,
                                        table=self.table,
-                                       writable=self.writable)
+                                       writeable=self.writeable)
                         for indx in ids)
         else:
             keys = "', '".join(sorted(_GEOOBJ.keys()))
@@ -413,18 +416,18 @@
     def rewind(self):
         """Rewind vector map to cause reads to start at beginning. ::
 
-            >>> cens = VectorTopo('census')
-            >>> cens.open(mode='r')
-            >>> cens.next()
-            Boundary(v_id=1)
-            >>> cens.next()
-            Boundary(v_id=2)
-            >>> cens.next()
-            Boundary(v_id=3)
-            >>> cens.rewind()
-            >>> cens.next()
-            Boundary(v_id=1)
-            >>> cens.close()
+            >>> test_vect = VectorTopo(test_vector_name)
+            >>> test_vect.open(mode='r')
+            >>> test_vect.next()
+            Point(10.000000, 6.000000)
+            >>> test_vect.next()
+            Point(12.000000, 6.000000)
+            >>> test_vect.next()
+            Point(14.000000, 6.000000)
+            >>> test_vect.rewind()
+            >>> test_vect.next()
+            Point(10.000000, 6.000000)
+            >>> test_vect.close()
 
         ..
         """
@@ -455,12 +458,12 @@
         is2D = not self.is_3D()
         if generator:
             return (read_line(feature_id=v_id, c_mapinfo=self.c_mapinfo,
-                              table=self.table, writable=self.writable,
+                              table=self.table, writeable=self.writeable,
                               is2D=is2D)
                     for v_id in ilist)
         else:
             return [read_line(feature_id=v_id, c_mapinfo=self.c_mapinfo,
-                              table=self.table, writable=self.writable,
+                              table=self.table, writeable=self.writeable,
                               is2D=is2D)
                     for v_id in ilist]
 
@@ -470,31 +473,31 @@
 
         :param int feature_id: the id of feature to obtain
 
-        >>> cens = VectorTopo('census')
-        >>> cens.open(mode='r')
-        >>> feature1 = cens.read(0)                     #doctest: +ELLIPSIS
+        >>> test_vect = VectorTopo(test_vector_name)
+        >>> test_vect.open(mode='r')
+        >>> feature1 = test_vect.read(0)                     #doctest: +ELLIPSIS
         Traceback (most recent call last):
             ...
         ValueError: The index must be >0, 0 given.
-        >>> feature1 = cens.read(1)
+        >>> feature1 = test_vect.read(5)
         >>> feature1
-        Boundary(v_id=1)
+        Line([Point(12.000000, 4.000000), Point(12.000000, 2.000000), Point(12.000000, 0.000000)])
         >>> feature1.length()
-        444.54490917696944
-        >>> cens.read(-1)
-        Centoid(642963.159711, 214994.016279)
-        >>> len(cens)
-        8920
-        >>> cens.read(8920)
-        Centoid(642963.159711, 214994.016279)
-        >>> cens.read(8921)                             #doctest: +ELLIPSIS
+        4.0
+        >>> test_vect.read(-1)
+        Centoid(7.500000, 3.500000)
+        >>> len(test_vect)
+        21
+        >>> test_vect.read(21)
+        Centoid(7.500000, 3.500000)
+        >>> test_vect.read(22)                             #doctest: +ELLIPSIS
         Traceback (most recent call last):
           ...
         IndexError: Index out of range
-        >>> cens.close()
+        >>> test_vect.close()
 
         """
-        return read_line(feature_id, self.c_mapinfo, self.table, self.writable,
+        return read_line(feature_id, self.c_mapinfo, self.table, self.writeable,
                          is2D=not self.is_3D())
 
     @must_be_open
@@ -575,3 +578,9 @@
         if release:
             libvect.Vect_set_release_support(self.c_mapinfo)
         super(VectorTopo, self).close(build=build)
+
+if __name__ == "__main__":
+    import doctest
+    from grass.pygrass import utils
+    utils.create_test_vector_map(test_vector_name)
+    doctest.testmod()

Modified: grass/trunk/lib/python/pygrass/vector/abstract.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/abstract.py	2015-08-25 13:41:44 UTC (rev 66015)
+++ grass/trunk/lib/python/pygrass/vector/abstract.py	2015-08-25 15:20:23 UTC (rev 66016)
@@ -388,13 +388,13 @@
             self.layer = self.dblinks.by_layer(layer).layer
             self.table = self.dblinks.by_layer(layer).table()
             self.n_lines = self.table.n_rows()
-        self.writable = self.mapset == utils.getenv("MAPSET")
+        self.writeable = self.mapset == utils.getenv("MAPSET")
         self.find = {'by_point': PointFinder(self.c_mapinfo, self.table,
-                                             self.writable),
+                                             self.writeable),
                      'by_box': BboxFinder(self.c_mapinfo, self.table,
-                                          self.writable),
+                                          self.writeable),
                      'by_polygon': PolygonFinder(self.c_mapinfo, self.table,
-                                                 self.writable), }
+                                                 self.writeable), }
 
     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-25 13:41:44 UTC (rev 66015)
+++ grass/trunk/lib/python/pygrass/vector/find.py	2015-08-25 15:20:23 UTC (rev 66016)
@@ -13,7 +13,7 @@
 
 
 class AbstractFinder(object):
-    def __init__(self, c_mapinfo, table=None, writable=False):
+    def __init__(self, c_mapinfo, table=None, writeable=False):
         """AbstractFinder
         -----------------
 
@@ -21,7 +21,7 @@
         """
         self.c_mapinfo = c_mapinfo
         self.table = table
-        self.writable = writable
+        self.writeable = writeable
         self.vtype = {'point':    libvect.GV_POINT,  # 1
                       'line':     libvect.GV_LINE,   # 2
                       'boundary': libvect.GV_BOUNDARY,  # 3
@@ -70,10 +70,10 @@
     >>> schools.close()
     >>> zipcodes.close()
     """
-    def __init__(self, c_mapinfo, table=None, writable=False):
+    def __init__(self, c_mapinfo, table=None, writeable=False):
         """Find geometry feature around a point.
         """
-        super(PointFinder, self).__init__(c_mapinfo, table, writable)
+        super(PointFinder, self).__init__(c_mapinfo, table, writeable)
 
 # TODO: add the Node class and enable this method
 #    def node(self, point, maxdist):
@@ -95,7 +95,7 @@
                                             int(not point.is2D), exclude)
         if feature_id:
             return read_line(feature_id, self.c_mapinfo,
-                             self.table, self.writable)
+                             self.table, self.writeable)
 
     @must_be_open
     def geos(self, point, maxdist, type='all', exclude=None):
@@ -111,7 +111,7 @@
                                        self.vtype[type], float(maxdist),
                                        int(not point.is2D),
                                        excl.c_ilist, found.c_ilist):
-            return [read_line(f_id, self.c_mapinfo, self.table, self.writable)
+            return [read_line(f_id, self.c_mapinfo, self.table, self.writeable)
                     for f_id in found]
         else:
             return []
@@ -122,7 +122,7 @@
         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,
-                        table=self.table, writable=self.writable)
+                        table=self.table, writeable=self.writeable)
 
     @must_be_open
     def island(self, point):
@@ -130,12 +130,12 @@
         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,
-                        table=self.table, writable=self.writable)
+                        table=self.table, writeable=self.writeable)
 
 
 class BboxFinder(AbstractFinder):
-    def __init__(self, c_mapinfo, table=None, writable=False):
-        super(BboxFinder, self).__init__(c_mapinfo, table, writable)
+    def __init__(self, c_mapinfo, table=None, writeable=False):
+        super(BboxFinder, self).__init__(c_mapinfo, table, writeable)
 
     @must_be_open
     def geos(self, bbox, type='all', bbox_list=False):
@@ -151,7 +151,7 @@
                 return found
             else:
                 return (read_line(f_id, self.c_mapinfo, self.table,
-                                  self.writable) for f_id in found.ids)
+                                  self.writeable) for f_id in found.ids)
 
     @must_be_open
     def nodes(self, bbox):
@@ -161,7 +161,7 @@
                                             found.c_ilist):
             for n_id in found:
                 yield Node(v_id=n_id, c_mapinfo=self.c_mapinfo,
-                           table=self.table, writable=self.writable)
+                           table=self.table, writeable=self.writeable)
 
     @must_be_open
     def areas(self, bbox, boxlist=None, bboxlist_only=False):
@@ -173,7 +173,7 @@
                 return boxlist
             else:
                 return (Area(v_id=a_id, c_mapinfo=self.c_mapinfo,
-                             table=self.table, writable=self.writable)
+                             table=self.table, writeable=self.writeable)
                         for a_id in boxlist.ids)
         return []
 
@@ -187,14 +187,14 @@
                 return found
             else:
                 return (Isle(v_id=i_id, c_mapinfo=self.c_mapinfo,
-                             table=self.table, writable=self.writable)
+                             table=self.table, writeable=self.writeable)
                         for i_id in found.ids)
         return []
 
 
 class PolygonFinder(AbstractFinder):
-    def __init__(self, c_mapinfo, table=None, writable=False):
-        super(PolygonFinder, self).__init__(c_mapinfo, table, writable)
+    def __init__(self, c_mapinfo, table=None, writeable=False):
+        super(PolygonFinder, self).__init__(c_mapinfo, table, writeable)
 
     def lines(self, polygon, isles=None):
         pass

Modified: grass/trunk/lib/python/pygrass/vector/geometry.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/geometry.py	2015-08-25 13:41:44 UTC (rev 66015)
+++ grass/trunk/lib/python/pygrass/vector/geometry.py	2015-08-25 15:20:23 UTC (rev 66016)
@@ -19,6 +19,8 @@
 from grass.pygrass.vector.basic import Ilist, Bbox, Cats
 from grass.pygrass.vector import sql
 
+# For test purposes
+test_vector_name = "geometry_doctest_map"
 
 LineDist = namedtuple('LineDist', 'point dist spdist sldist')
 
@@ -133,12 +135,12 @@
 
 
 class Attrs(object):
-    def __init__(self, cat, table, writable=False):
+    def __init__(self, cat, table, writeable=False):
         self._cat = None
         self.cond = ''
         self.table = table
         self.cat = cat
-        self.writable = writable
+        self.writeable = writeable
 
     def _get_cat(self):
         return self._cat
@@ -156,12 +158,12 @@
         """Return the value stored in the attribute table.
 
         >>> from grass.pygrass.vector import VectorTopo
-        >>> schools = VectorTopo('schools')
-        >>> schools.open('r')
-        >>> school = schools[1]
-        >>> attrs = Attrs(school.cat, schools.table)
-        >>> attrs['TAG']
-        u'568'
+        >>> test_vect = VectorTopo(test_vector_name)
+        >>> test_vect.open('r')
+        >>> v1 = test_vect[1]
+        >>> v1.attrs['name']
+        u'point'
+        >>> test_vect.close()
 
         """
         #SELECT {cols} FROM {tname} WHERE {condition};
@@ -179,19 +181,23 @@
         """Set value of a given column of a table attribute.
 
         >>> from grass.pygrass.vector import VectorTopo
-        >>> from grass.pygrass.utils import copy, remove
-        >>> copy('schools', 'myschools', 'vect')
-        >>> schools = VectorTopo('myschools')
-        >>> schools.open('r')
-        >>> school = schools[1]
-        >>> attrs = Attrs(school.cat, schools.table, True)
-        >>> attrs['TAG'] = 'New Label'
-        >>> attrs['TAG']
-        u'New Label'
-        >>> attrs.table.conn.close()
-        >>> remove('myschools','vect')
+        >>> test_vect = VectorTopo(test_vector_name)
+        >>> test_vect.open('r')
+        >>> v1 = test_vect[1]
+        >>> v1.attrs['name']
+        u'point'
+
+        #>>> v1.attrs['name'] = "new_point"
+        #>>> v1.attrs['name']
+        #u'new_point'
+        #>>> v1.attrs['name'] = "point"
+        #>>> v1.attrs['name']
+        #u'point'
+        #>>> v.table.conn.commit()
+        >>> test_vect.close()
+
         """
-        if self.writable:
+        if self.writeable:
             #UPDATE {tname} SET {new_col} = {old_col} WHERE {condition}
             values = '%s=%r' % (key, value)
             self.table.execute(sql.UPDATE_WHERE.format(tname=self.table.name,
@@ -211,15 +217,14 @@
 
     def values(self):
         """Return the values of the attribute table row.
+
            >>> from grass.pygrass.vector import VectorTopo
-           >>> schools = VectorTopo('schools')
-           >>> schools.open('r')
-           >>> school = schools[1]
-           >>> attrs = Attrs(school.cat, schools.table)
-           >>> attrs.values()       # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
-           (1,
-           ...
-           None)
+           >>> test_vect = VectorTopo(test_vector_name)
+           >>> test_vect.open('r')
+           >>> v1 = test_vect[1]
+           >>> v1.attrs.values()
+           (1, u'point', 1.0)
+            >>> test_vect.close()
 
         """
         #SELECT {cols} FROM {tname} WHERE {condition}
@@ -230,15 +235,15 @@
 
     def keys(self):
         """Return the column name of the attribute table.
+
            >>> from grass.pygrass.vector import VectorTopo
-           >>> schools = VectorTopo('schools')
-           >>> schools.open('r')
-           >>> school = schools[1]
-           >>> attrs = Attrs(school.cat, schools.table)
-           >>> attrs.keys()         # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
-           [u'cat',
-           ...
-           u'NOTES']
+           >>> test_vect = VectorTopo(test_vector_name)
+           >>> test_vect.open('r')
+           >>> v1 = test_vect[1]
+           >>> v1.attrs.keys()
+           [u'cat', u'name', u'value']
+            >>> test_vect.close()
+
         """
         return self.table.columns.names()
 
@@ -249,15 +254,12 @@
 
 class Geo(object):
     """
-    >>> geo0 = Geo()
-    >>> points = ctypes.pointer(libvect.line_pnts())
-    >>> cats = ctypes.pointer(libvect.line_cats())
-    >>> geo1 = Geo(c_points=points, c_cats=cats)
+    Base object for different feature types
     """
     gtype = None
 
     def __init__(self, v_id=0, c_mapinfo=None, c_points=None, c_cats=None,
-                 table=None, writable=False, is2D=True):
+                 table=None, writeable=False, is2D=True):
         self.id = v_id  # vector id
         self.c_mapinfo = c_mapinfo
         self.is2D = (is2D if is2D is not None else
@@ -284,14 +286,14 @@
         # set the attributes as last thing to do
         self.attrs = None
         if table is not None and self.cat is not None:
-            self.attrs = Attrs(self.cat, table, writable)
+            self.attrs = Attrs(self.cat, table, writeable)
 
     @property
     def cat(self):
         if self.c_cats.contents.cat:
             return self.c_cats.contents.cat.contents.value
 
-    def is_with_topology(self):
+    def has_topology(self):
         if self.c_mapinfo is not None:
             return self.c_mapinfo.contents.level == 2
         else:
@@ -379,7 +381,7 @@
                  doc="Set and obtain z coordinate")
 
     def __str__(self):
-        return self.get_wkt()
+        return self.to_wkt()
 
     def __repr__(self):
         return "Point(%s)" % ', '.join(['%f' % coor for coor in self.coords()])
@@ -428,11 +430,11 @@
         else:
             return self.x, self.y, self.z
 
-    def get_wkt(self):
+    def to_wkt(self):
         """Return a "well know text" (WKT) geometry string. ::
 
             >>> pnt = Point(10, 100)
-            >>> pnt.get_wkt()
+            >>> pnt.to_wkt()
             'POINT(10.000000 100.000000)'
 
         .. warning::
@@ -443,7 +445,7 @@
         return "POINT(%s)" % ' '.join(['%f' % coord
                                       for coord in self.coords()])
 
-    def get_wkb(self):
+    def to_wkb(self):
         """Return a "well know binary" (WKB) geometry buffer
 
         .. warning::
@@ -604,23 +606,23 @@
         return self.c_points.contents.n_points
 
     def __str__(self):
-        return self.get_wkt()
+        return self.to_wkt()
 
     def __repr__(self):
         return "Line([%s])" % ', '.join([repr(pnt) for pnt in self.__iter__()])
 
-    def get_pnt(self, distance, angle=0, slope=0):
+    def point_on_line(self, distance, angle=0, slope=0):
         """Return a Point object on line in the specified distance, using the
         `Vect_point_on_line` C function.
         Raise a ValueError If the distance exceed the Line length. ::
 
             >>> line = Line([(0, 0), (1, 1)])
-            >>> line.get_pnt(5)      #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+            >>> line.point_on_line(5)      #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
             Traceback (most recent call last):
                 ...
             ValueError: The distance exceed the length of the line,
             that is: 1.414214
-            >>> line.get_pnt(1)
+            >>> line.point_on_line(1)
             Point(0.707107, 0.707107)
 
         ..
@@ -811,7 +813,7 @@
         return LineDist(point, dist.value, sp_dist.value, lp_dist.value)
 
     @mapinfo_must_be_set
-    def get_first_cat(self):
+    def first_cat(self):
         """Fetches FIRST category number for given vector line and field, using
         the ``Vect_get_line_cat`` C function.
 
@@ -831,9 +833,9 @@
 
             >>> line = Line([(0, 0), (1, 1), (2, 2)])
             >>> midle_pnt = line.pop(1)
-            >>> midle_pnt
+            >>> midle_pnt                #doctest: +NORMALIZE_WHITESPACE
             Point(1.000000, 1.000000)
-            >>> line
+            >>> line                     #doctest: +NORMALIZE_WHITESPACE
             Line([Point(0.000000, 0.000000), Point(2.000000, 2.000000)])
 
         """
@@ -852,7 +854,7 @@
 
             >>> line = Line([(0, 0), (1, 1), (2, 2)])
             >>> line.delete(-1)
-            >>> line
+            >>> line                     #doctest: +NORMALIZE_WHITESPACE
             Line([Point(0.000000, 0.000000), Point(1.000000, 1.000000)])
 
         """
@@ -906,7 +908,7 @@
 
             >>> line = Line([(0, 0), (1, 1), (2, 2)])
             >>> line.remove((2, 2))
-            >>> line[-1]
+            >>> line[-1]                     #doctest: +NORMALIZE_WHITESPACE
             Point(1.000000, 1.000000)
 
         ..
@@ -960,22 +962,22 @@
         libvect.Vect_line_segment(self.c_points, start, end, line.c_points)
         return line
 
-    def tolist(self):
+    def to_list(self):
         """Return a list of tuple. ::
 
             >>> line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])
-            >>> line.tolist()
+            >>> line.to_list()
             [(0.0, 0.0), (1.0, 1.0), (2.0, 0.0), (1.0, -1.0)]
 
         ..
         """
         return [pnt.coords() for pnt in self.__iter__()]
 
-    def toarray(self):
+    def to_array(self):
         """Return an array of coordinates. ::
 
             >>> line = Line([(0, 0), (1, 1), (2, 0), (1, -1)])
-            >>> line.toarray()                 #doctest: +NORMALIZE_WHITESPACE
+            >>> line.to_array()                 #doctest: +NORMALIZE_WHITESPACE
             array([[ 0.,  0.],
                    [ 1.,  1.],
                    [ 2.,  0.],
@@ -983,13 +985,13 @@
 
         ..
         """
-        return np.array(self.tolist())
+        return np.array(self.to_list())
 
-    def get_wkt(self):
+    def to_wkt(self):
         """Return a Well Known Text string of the line. ::
 
             >>> line = Line([(0, 0), (1, 1), (1, 2)])
-            >>> line.get_wkt()                 #doctest: +ELLIPSIS
+            >>> line.to_wkt()                 #doctest: +ELLIPSIS
             'LINESTRING(0.000000 0.000000, ..., 1.000000 2.000000)'
 
         ..
@@ -1054,7 +1056,7 @@
         >>> area = line.buffer(10)
         >>> area.boundary                              #doctest: +ELLIPSIS
         Line([Point(-10.000000, 0.000000),...Point(-10.000000, 0.000000)])
-        >>> area.centroid
+        >>> area.centroid                     #doctest: +NORMALIZE_WHITESPACE
         Point(0.000000, 0.000000)
         >>> area.isles
         []
@@ -1104,7 +1106,7 @@
            return: A tuple of Node objects that represent the
                    start and end point of this line.
         """
-        if self.is_with_topology():
+        if self.has_topology():
             n1 = ctypes.c_int()
             n2 = ctypes.c_int()
             libvect.Vect_get_line_nodes(self.c_mapinfo, self.id,
@@ -1208,14 +1210,13 @@
     # geometry type
     gtype = libvect.GV_BOUNDARY
 
-    def __init__(self, lines=None, left=None, right=None,
-                 **kargs):
+    def __init__(self, **kargs):
+        super(Boundary, self).__init__(**kargs)
+
         v_id = kargs.get('v_id', 0)
         self.dir = libvect.GV_FORWARD if v_id > 0 else libvect.GV_BACKWARD
-        super(Boundary, self).__init__(**kargs)
         self.c_left = ctypes.pointer(ctypes.c_int())
         self.c_right = ctypes.pointer(ctypes.c_int())
-        #self.get_left_right()
 
     @property
     def left_id(self):
@@ -1226,10 +1227,10 @@
         return self.c_right.contents.value
 
     def __repr__(self):
-        return "Boundary(v_id=%r)" % self.id
+        return "Boundary([%s])" % ', '.join([repr(pnt) for pnt in self.__iter__()])
 
     @mapinfo_must_be_set
-    def _get_centroid(self, side, idonly=False):
+    def _centroid(self, side, idonly=False):
         if side > 0:
             v_id = libvect.Vect_get_area_centroid(self.c_mapinfo, side)
             v_id = v_id if v_id else None
@@ -1239,21 +1240,21 @@
                 cntr = Centroid(v_id=v_id, c_mapinfo=self.c_mapinfo)
                 return cntr
 
-    def get_left_centroid(self, idonly=False):
-        """Return left value
+    def left_centroid(self, idonly=False):
+        """Return left centroid
 
         :param idonly: True to return only the cat of feature
         :type idonly: bool
         """
-        return self._get_centroid(self.left_id, idonly)
+        return self._centroid(self.left_id, idonly)
 
-    def get_right_centroid(self, idonly=False):
-        """Return right value
+    def right_centroid(self, idonly=False):
+        """Return right centroid
 
         :param idonly: True to return only the cat of feature
         :type idonly: bool
         """
-        return self._get_centroid(self.left_id, idonly)
+        return self._centroid(self.left_id, idonly)
 
     @mapinfo_must_be_set
     def get_left_right(self):
@@ -1287,11 +1288,12 @@
         >>> centroid
         Centoid(0.000000, 10.000000)
         >>> from grass.pygrass.vector import VectorTopo
-        >>> geo = VectorTopo('geology')
-        >>> geo.open(mode='r')
-        >>> centroid = Centroid(v_id=1, c_mapinfo=geo.c_mapinfo)
+        >>> test_vect = VectorTopo(test_vector_name)
+        >>> test_vect.open(mode='r')
+        >>> centroid = Centroid(v_id=1, c_mapinfo=test_vect.c_mapinfo)
         >>> centroid
-        Centoid(893202.874416, 297339.312795)
+        Centoid(10.000000, 6.000000)
+        >>> test_vect.close()
 
     ..
     """
@@ -1304,7 +1306,7 @@
         if self.id and self.c_mapinfo and self.area_id is None:
             self.area_id = self.get_area_id()
         elif self.c_mapinfo and self.area_id and self.id is None:
-            self.id = self.get_centroid_id()
+            self.id = self.centroid_id()
         if self.area_id is not None:
             self.read()
 
@@ -1314,7 +1316,7 @@
         return "Centoid(%s)" % ', '.join(['%f' % co for co in self.coords()])
 
     @mapinfo_must_be_set
-    def get_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"""
@@ -1325,7 +1327,7 @@
     @mapinfo_must_be_set
     def get_area_id(self):
         """Return the area_id, using the c_mapinfo and an centroid_id
-        attributes of the class, and calling the Vect_get_centroid_area
+        attributes of the class, and calling the Vect_centroid_area
         C function, if no area_id were found return None"""
         area_id = libvect.Vect_get_centroid_area(self.c_mapinfo,
                                                  self.id)
@@ -1413,8 +1415,8 @@
         self._isles_id = None
         self._isles = None
         if area_id:
-            self._isles_id = self.get_isles_id()
-            self._isles = self.get_isles()
+            self._isles_id = self.isles_ids()
+            self._isles = self.isles()
 
     @mapinfo_must_be_set
     def __len__(self):
@@ -1425,39 +1427,29 @@
 
     def __getitem__(self, key):
         if self._isles is None:
-            self.get_isles()
+            self.isles()
         return self._isles[key]
 
     @mapinfo_must_be_set
-    def get_isles_id(self):
+    def isles_ids(self):
         """Return the id of isles"""
         return [libvect.Vect_get_area_isle(self.c_mapinfo, self.area_id, i)
                 for i in range(self.__len__())]
 
     @mapinfo_must_be_set
-    def get_isles(self):
+    def isles(self):
         """Return isles"""
         return [Isle(v_id=isle_id, c_mapinfo=self.c_mapinfo)
                 for isle_id in self._isles_id]
 
-    def select_by_bbox(self, bbox):
-        """Vect_select_isles_by_box
 
-        .. warning::
-
-            Not implemented yet.
-
-        """
-        pass
-
-
 class Area(Geo):
     """
     Vect_build_line_area,
     Vect_find_area,
     Vect_get_area_box,
     Vect_get_area_points_geos,
-    Vect_get_centroid_area,
+    Vect_centroid_area,
 
     Vect_get_isle_area,
     Vect_get_line_areas,
@@ -1498,12 +1490,12 @@
             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.get_points()
+        self.points()
         # get isles
-        self.get_isles()
+        self.isles()
 
     @mapinfo_must_be_set
-    def get_points(self, line=None):
+    def points(self, line=None):
         """Return a Line object with the outer ring
 
         :param line: a Line object to fill with info from points of area
@@ -1514,7 +1506,7 @@
         return line
 
     @mapinfo_must_be_set
-    def get_centroid(self, centroid=None):
+    def centroid(self, centroid=None):
         """Return the centroid
 
         :param centroid: a Centroid object to fill with info from centroid of area
@@ -1534,7 +1526,7 @@
         return libvect.Vect_get_area_num_isles(self.c_mapinfo, self.id)
 
     @mapinfo_must_be_set
-    def get_isles(self, isles=None):
+    def isles(self, isles=None):
         """Instantiate the boundary attribute reading area_id"""
         if isles is not None:
             isles.area_id = self.id
@@ -1620,18 +1612,18 @@
         return [Boundary(v_id=abs(v_id), c_mapinfo=self.c_mapinfo) for v_id in ilst]
 
 
-    def get_wkt(self):
+    def to_wkt(self):
         """Return a Well Known Text string of the Area. ::
 
             For now the outer ring is returned
 
             TODO: Implement inner rings detected from isles
         """
-        line = self.get_points()
+        line = self.points()
 
         return "Polygon((%s))" % ', '.join([
                ' '.join(['%f' % coord for coord in pnt])
-               for pnt in line.tolist()])
+               for pnt in line.to_list()])
 
     @mapinfo_must_be_set
     def cats(self, cats=None):
@@ -1674,13 +1666,13 @@
         :return: double Vect_area_perimeter (const struct line_pnts \*Points)
 
         """
-        border = self.get_points()
+        border = self.points()
         return libvect.Vect_line_geodesic_length(border.c_points)
 
     def read(self, line=None, centroid=None, isles=None):
-        self.boundary = self.get_points(line)
-        self.centroid = self.get_centroid(centroid)
-        #self.isles = self.get_isles(isles)
+        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)
@@ -1723,7 +1715,7 @@
     return ftype, v_id, c_points, c_cats
 
 
-def read_next_line(c_mapinfo, table=None, writable=False,
+def read_next_line(c_mapinfo, table=None, writeable=False,
                    c_points=None, c_cats=None, is2D=True):
     """Return the next geometry feature of a vector map."""
     c_points = c_points if c_points else ctypes.pointer(libvect.line_pnts())
@@ -1732,7 +1724,7 @@
                                                      c_cats)
     return GV_TYPE[ftype]['obj'](v_id=v_id, c_mapinfo=c_mapinfo,
                                  c_points=c_points, c_cats=c_cats,
-                                 table=table, writable=writable, is2D=is2D)
+                                 table=table, writeable=writeable, is2D=is2D)
 
 
 def c_read_line(feature_id, c_mapinfo, c_points, c_cats):
@@ -1748,7 +1740,7 @@
         raise ValueError('The index must be >0, %r given.' % feature_id)
 
 
-def read_line(feature_id, c_mapinfo, table=None, writable=False,
+def read_line(feature_id, c_mapinfo, table=None, writeable=False,
               c_points=None, c_cats=None, is2D=True):
     """Return a geometry object given the feature id and the c_mapinfo.
     """
@@ -1759,7 +1751,12 @@
     if GV_TYPE[ftype]['obj'] is not None:
         return GV_TYPE[ftype]['obj'](v_id=feature_id, c_mapinfo=c_mapinfo,
                                      c_points=c_points, c_cats=c_cats,
-                                     table=table, writable=writable, is2D=is2D)
+                                     table=table, writeable=writeable, is2D=is2D)
 
 
+if __name__ == "__main__":
+    import doctest
+    from grass.pygrass import utils
+    utils.create_test_vector_map(test_vector_name)
+    doctest.testmod()
 



More information about the grass-commit mailing list