[GRASS-SVN] r54597 - grass/trunk/lib/python/pygrass/vector
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Jan 11 08:38:56 PST 2013
Author: zarch
Date: 2013-01-11 08:38:56 -0800 (Fri, 11 Jan 2013)
New Revision: 54597
Modified:
grass/trunk/lib/python/pygrass/vector/basic.py
Log:
Refactoring of the Cats class and add CatsList class
Modified: grass/trunk/lib/python/pygrass/vector/basic.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/basic.py 2013-01-11 16:38:48 UTC (rev 54596)
+++ grass/trunk/lib/python/pygrass/vector/basic.py 2013-01-11 16:38:56 UTC (rev 54597)
@@ -263,6 +263,9 @@
def __repr__(self):
return "Ilist(%r)" % repr(self.__iter__())
+ def __contains__(self, item):
+ return item in self.__iter__()
+
def append(self, value):
"""Append an integer to the list"""
if libvect.Vect_list_append(self.c_ilist, value):
@@ -300,25 +303,157 @@
class Cats(object):
"""Instantiate a Category class that contains a ctypes pointer
- to the Map_info C struct, and a ctypes pointer to that C cats struct,
- that could be used by C functions.
+ to the C line_cats struct. ::
+
+ >>> cats = Cats()
+ >>> for cat in xrange(100, 110): cats.set(cat, layer=cat-50)
+ >>> cats.n_cats
+ 10
+ >>> cats.cat
+ [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
+ >>> cats.layer
+ [50, 51, 52, 53, 54, 55, 56, 57, 58, 59]
+ >>> cats.get() # default layer is 1
+ (-1, 0)
+ >>> cats.get(50)
+ (100, 1)
+ >>> cats.get(51)
+ (101, 1)
+ >>> cats.set(1001, 52)
+ >>> cats.cat
+ [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 1001]
+ >>> cats.layer
+ [50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 52]
+ >>> cats.get(52)
+ (102, 2)
+ >>> cats.reset()
+ >>> cats.layer
+ []
+ >>> cats.cat
+ []
+
+
"""
+ @property
+ def layer(self):
+ field = self.c_cats.contents.field
+ return [field[i] for i in xrange(self.n_cats)]
- def __init__(self, c_mapinfo, v_id, c_cats=None):
- self.c_mapinfo = c_mapinfo
- self.id = v_id
- if c_cats is not None:
- self.c_cats = c_cats
- else:
- self.c_cats = ctypes.pointer(libvect.line_cats())
- self.get_area_cats()
+ @property
+ def cat(self):
+ cat = self.c_cats.contents.cat
+ return [cat[i] for i in xrange(self.n_cats)]
- def get_area_cats(self):
- """Get area categories, set the c_cats struct given an area, using the
- ``Vect_get_area_cats`` function.
- """
- libvect.Vect_get_area_cats(self.c_mapinfo, self.id, self.c_cats)
+ @property
+ def n_cats(self):
+ return self.c_cats.contents.n_cats
+ def __init__(self, c_cats=None):
+ self.c_cats = c_cats if c_cats else ctypes.pointer(libvect.line_cats())
+
def reset(self):
"""Reset the C cats struct from previous values."""
libvect.Vect_reset_cats(self.c_cats)
+
+ def get(self, layer=1):
+ """Return the first found category of given layer
+ and the number of category found. """
+ cat = ctypes.c_int()
+ n_cats = libvect.Vect_cat_get(self.c_cats, layer, ctypes.byref(cat))
+ return cat.value, n_cats
+
+ def set(self, cat, layer=1):
+ """Add new field/cat to category structure if doesn't exist yet."""
+ libvect.Vect_cat_set(self.c_cats, layer, cat)
+
+ def delete(self, cat=None, layer=1):
+ """If cat is given delete cat from line_cats structure
+ (using Vect_field_cat_del) else delete all categories of given layer
+ (using Vect_cat_del).
+ """
+ if cat:
+ self.n_del = libvect.Vect_field_cat_del(self.c_cats, layer, cat)
+ err_msg = "Layer(%d)/category(%d) number does not exist"
+ err_msg = err_msg % (layer, cat)
+ else:
+ self.n_del = libvect.Vect_cat_del(self.c_cats, layer)
+ err_msg = 'Layer: %r does not exist' % layer
+ if self.n_del == 0:
+ raise ValueError(err_msg)
+
+ def check_cats_constraints(self, cats_list, layer=1):
+ """Check if categories match with category constraints"""
+ return bool(libvect.Vect_cats_in_constraint(self.c_cats, layer,
+ cats_list.c_cat_list))
+
+ def get_list(self, layer=1):
+ """Get list of categories of given field."""
+ ilist = Ilist()
+ if libvect.Vect_field_cat_get(self.c_cats, layer,
+ ilist.c_ilist) < 0:
+ raise ValueError('Layer: %r does not exist' % layer)
+ return ilist
+
+
+class CatsList(object):
+ """::
+
+ >>> cats_list = CatsList()
+ >>> cats_list.min
+ []
+ >>> cats_list.max
+ []
+ >>> cats_list.n_ranges
+ 0
+ >>> cats_list.layer
+ 0
+ >>> string = "2,3,5-9,20"
+ >>> cats_list.from_string(string)
+ >>> cats_list.min
+ [2, 3, 5, 20]
+ >>> cats_list.max
+ [2, 3, 9, 20]
+ >>> cats_list.n_ranges
+ 4
+
+ """
+ @property
+ def layer(self):
+ return self.c_cat_list.contents.field
+
+ @property
+ def n_ranges(self):
+ return self.c_cat_list.contents.n_ranges
+
+ @property
+ def min(self):
+ min_values = self.c_cat_list.contents.min
+ return [min_values[i] for i in xrange(self.n_ranges)]
+
+ @property
+ def max(self):
+ max_values = self.c_cat_list.contents.max
+ return [max_values[i] for i in xrange(self.n_ranges)]
+
+ def __init__(self, c_cat_list=None):
+ self.c_cat_list = c_cat_list if c_cat_list \
+ else ctypes.pointer(libvect.cat_list())
+
+ def from_string(self, string):
+ """Converts string of categories and cat ranges separated by commas
+ to cat_list."""
+ num_errors = libvect.Vect_str_to_cat_list(string, self.c_cat_list)
+ if num_errors:
+ from grass.pygrass.errors import GrassError
+ raise GrassError("%d number of errors in ranges" % num_errors)
+
+ def from_array(self, array):
+ """Convert ordered array of integers to cat_list structure."""
+ # Vect_array_to_cat_list(const int *vals, int nvals, ***)
+ # TODO: it's not working
+ libvect.Vect_array_to_cat_list(array, len(array), self.c_cat_list)
+
+ def __contains__(self, cat):
+ """Check if category number is in list.
+ int Vect_cat_in_cat_list (int cat, const struct cat_list *list)"""
+ return bool(libvect.Vect_cat_in_cat_list(cat, self.c_cat_list))
\ No newline at end of file
More information about the grass-commit
mailing list