[GRASS-SVN] r62034 - in grass/trunk/lib/python/pygrass/vector: . testsuite
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Sep 18 03:09:47 PDT 2014
Author: zarch
Date: 2014-09-18 03:09:46 -0700 (Thu, 18 Sep 2014)
New Revision: 62034
Modified:
grass/trunk/lib/python/pygrass/vector/__init__.py
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: Add Node topology class (contribution: Maurizio Cingi)
Modified: grass/trunk/lib/python/pygrass/vector/__init__.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/__init__.py 2014-09-18 03:51:49 UTC (rev 62033)
+++ grass/trunk/lib/python/pygrass/vector/__init__.py 2014-09-18 10:09:46 UTC (rev 62034)
@@ -28,7 +28,6 @@
"islands": libvect.Vect_get_num_islands,
"kernels": libvect.Vect_get_num_kernels,
"lines": libvect.Vect_get_num_lines,
- "points": libvect.Vect_get_num_line_points,
"nodes": libvect.Vect_get_num_nodes,
"updated_lines": libvect.Vect_get_num_updated_lines,
"updated_nodes": libvect.Vect_get_num_updated_nodes,
Modified: grass/trunk/lib/python/pygrass/vector/find.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/find.py 2014-09-18 03:51:49 UTC (rev 62033)
+++ grass/trunk/lib/python/pygrass/vector/find.py 2014-09-18 10:09:46 UTC (rev 62034)
@@ -9,7 +9,7 @@
from grass.pygrass.errors import must_be_open
from grass.pygrass.vector.basic import Ilist, BoxList
-from grass.pygrass.vector.geometry import read_line, Isle, Area, Point
+from grass.pygrass.vector.geometry import read_line, Isle, Area, Point, Node
class AbstractFinder(object):
@@ -160,8 +160,8 @@
if libvect.Vect_select_nodes_by_box(self.c_mapinfo, bbox.c_bbox,
found.c_ilist):
for n_id in found:
- yield Point(v_id=n_id, c_mapinfo=self.c_mapinfo,
- table=self.table, writable=self.writable)
+ yield Node(v_id=n_id, c_mapinfo=self.c_mapinfo,
+ table=self.table, writable=self.writable)
@must_be_open
def areas(self, bbox, boxlist=None, bboxlist_only=False):
Modified: grass/trunk/lib/python/pygrass/vector/geometry.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/geometry.py 2014-09-18 03:51:49 UTC (rev 62033)
+++ grass/trunk/lib/python/pygrass/vector/geometry.py 2014-09-18 10:09:46 UTC (rev 62034)
@@ -253,11 +253,12 @@
"""
gtype = None
- def __init__(self, v_id=None, c_mapinfo=None, c_points=None, c_cats=None,
+ def __init__(self, v_id=0, c_mapinfo=None, c_points=None, c_cats=None,
table=None, writable=False, is2D=True):
self.id = v_id # vector id
self.c_mapinfo = c_mapinfo
- self.is2D = is2D
+ self.is2D = (is2D if is2D is not None else
+ bool(libvect.Vect_is_3d(self.c_mapinfo) != 1))
read = False
# set c_points
@@ -332,7 +333,7 @@
def __init__(self, x=0, y=0, z=None, **kargs):
super(Point, self).__init__(**kargs)
- if self.id is not None:
+ if self.id and self.c_mapinfo:
self.read()
else:
self.is2D = True if z is None else False
@@ -1060,11 +1061,76 @@
"""
libvect.Vect_reset_line(self.c_points)
+ def nodes(self):
+ """Return the nodes in the line"""
+ if self.is_with_topology():
+ n1 = ctypes.c_int()
+ n2 = ctypes.c_int()
+ libvect.Vect_get_line_nodes(self.c_mapinfo, self.id,
+ ctypes.byref(n1),
+ ctypes.byref(n2))
+ return (Node(n1.value, self.c_mapinfo),
+ Node(n2.value, self.c_mapinfo))
+
class Node(object):
- pass
+ def __init__(self, v_id, c_mapinfo):
+ self.id = v_id # vector id
+ self.c_mapinfo = c_mapinfo
+ self.is2D = bool(libvect.Vect_is_3d(self.c_mapinfo) != 1)
+ self.nlines = libvect.Vect_get_node_n_lines(self.c_mapinfo, self.id)
+ def __len__(self):
+ return self.nlines
+ def __iter__(self):
+ return self.ilines()
+
+ def __repr__(self):
+ return "Node(%d)" % self.id
+
+ def coords(self):
+ """Return a tuple with the node coordinates."""
+ x = ctypes.c_double()
+ y = ctypes.c_double()
+ z = ctypes.c_double()
+ libvect.Vect_get_node_coor(self.c_mapinfo, self.id, ctypes.byref(x),
+ ctypes.byref(y), ctypes.byref(z))
+ return (x.value, y.value) if self.is2D else (x.value, y.value, z.value)
+
+ 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
+ starting from the node.
+
+ :param only_in: Return only the lines that are ending in the node
+ :type only_in: bool
+ :param only_out: Return only the lines that are starting in the node
+ :type only_out: bool
+ """
+ for iline in range(self.nlines):
+ lid = libvect.Vect_get_node_line(self.c_mapinfo, self.id, iline)
+ if (not only_in and lid > 0) or (not only_out and lid < 0):
+ yield lid
+
+ def lines(self, only_in=False, only_out=False):
+ """Return a generator with all lines connected to a node.
+
+ :param only_in: Return only the lines that are ending in the node
+ :type only_in: bool
+ :param only_out: Return only the lines that are starting in the node
+ :type only_out: bool
+ """
+ for iline in self.ilines(only_in, only_out):
+ yield Line(id=abs(iline), c_mapinfo=self.c_mapinfo)
+
+ def angles(self):
+ """Return a generator with all lines angles in a node."""
+ for iline in range(self.nlines):
+ yield libvect.Vect_get_node_line_angle(self.c_mapinfo,
+ self.id, iline)
+
+
class Boundary(Line):
"""
"""
Modified: grass/trunk/lib/python/pygrass/vector/testsuite/test_geometry.py
===================================================================
--- grass/trunk/lib/python/pygrass/vector/testsuite/test_geometry.py 2014-09-18 03:51:49 UTC (rev 62033)
+++ grass/trunk/lib/python/pygrass/vector/testsuite/test_geometry.py 2014-09-18 10:09:46 UTC (rev 62034)
@@ -12,7 +12,8 @@
import grass.lib.vector as libvect
-from grass.pygrass.vector.geometry import Point, Line
+from grass.pygrass.vector import VectorTopo
+from grass.pygrass.vector.geometry import Point, Line, Node
class PointTestCase(TestCase):
@@ -124,9 +125,68 @@
self.assertTupleEqual(line.get_pnt(1).coords(), vals)
def test_bbox(self):
- line = Line([(0, 0), (0, 1), (2, 1), (2, 0)])
+ """Test bbox method"""
+ line = Line([(0, 10), (0, 11), (1, 11), (1, 10)])
bbox = line.bbox()
+ self.assertEqual(11, bbox.north)
+ self.assertEqual(10, bbox.south)
+ self.assertEqual(1, bbox.east)
+ self.assertEqual(0, bbox.west)
+ def test_nodes(self):
+ """Test inodes method"""
+ def nodes2tuple(nodes):
+ """Convert an iterable of nodes to a tuple of nodes id"""
+ return tuple(n.id for n in nodes)
+ with VectorTopo("roadsmajor", mode='r') as vect:
+ self.assertTupleEqual((206, 172), nodes2tuple(vect[284].nodes()))
+ self.assertTupleEqual((208, 206), nodes2tuple(vect[287].nodes()))
+ self.assertTupleEqual((206, 209), nodes2tuple(vect[288].nodes()))
+ self.assertTupleEqual((218, 206), nodes2tuple(vect[301].nodes()))
+
+
+
+class NodeTestCase(TestCase):
+ @classmethod
+ def setUpClass(cls):
+ cls.vect = None
+ cls.vect = VectorTopo("roadsmajor")
+ 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
+
+ def test_init(self):
+ """Test Node __init__"""
+ node = Node(v_id=206, c_mapinfo=self.c_mapinfo)
+ self.assertEqual(206, node.id)
+ self.assertTrue(node.is2D)
+ self.assertEqual(4, node.nlines)
+
+ def test_coords(self):
+ """Test Node coordinates"""
+ node = Node(v_id=206, c_mapinfo=self.c_mapinfo)
+ self.assertTupleEqual((620906.5786131569, 221685.65913128198),
+ node.coords())
+
+ def test_ilines(self):
+ """Test Node coordinates"""
+ node = Node(v_id=206, c_mapinfo=self.c_mapinfo)
+ self.assertTupleEqual((288, -301, -287, 284), tuple(node.ilines()))
+ self.assertTupleEqual((-301, -287), tuple(node.ilines(only_in=True)))
+ self.assertTupleEqual((288, 284), tuple(node.ilines(only_out=True)))
+
+ def test_angles(self):
+ """Test Node angles"""
+ node = Node(v_id=206, c_mapinfo=self.c_mapinfo)
+ angles = (-3.044905185699463, -1.026218056678772,
+ 0.10362745821475983, 2.2236430644989014)
+ self.assertTupleEqual(angles, tuple(node.angles()))
+
if __name__ == '__main__':
test()
More information about the grass-commit
mailing list