Unit 14 - PyGRASS Vector Access

PyGRASS allows directly accessing native GRASS raster and vector maps in the sense of Python objects. This unit shows how to deal with GRASS vector data by PyGRASS API, see Unit 13 - PyGRASS Raster Access for raster data.

Vector data

Vector map can be treated by Vector when dealing with basic vector primitives (points, lines, boundaries, centroids) or by VectorTopo which allows accessing topological primitives like areas or isles. See Vector topology section for details.

Example below prints nicely format region names and their area size in hectares.

from grass.pygrass.vector import VectorTopo
fylke = VectorTopo('Fylke')
fylke.open('r')

for feat in fylke.viter('areas'):
    print (u'{0}: {1:.1f}ha'.format(feat.attrs['navn'].split(':', 1)[1][:-1], feat.area() / 10e4))

fylke.close()
../_images/pygrass-shell-vector.png

Fig. 87 PyGRASS vector example in action.

Writing vector data

As for raster also for vector it is possible to create vector layer using PyGRASS. In the next example we are going to create a point vector data with attribute table. Let’s see how to do that

from grass.pygrass.vector.geometry import Point

# create the columns definition
cols = [(u'cat',   'INTEGER PRIMARY KEY'),
        (u'name',  'VARCHAR')]
# start new vector with columns definition
new = VectorTopo('pois')
new.open('w', tab_cols=cols, overwrite=True)
# add points
point0 = Point(597241.89, 6643036.03)
point1 = Point(592409.49, 6655332.75)
new.write(point0, ('Oslo', ))
new.write(point1, ('Studenterhytta', ))
# commit attributes, otherwise they will be not saved
new.table.conn.commit()
# close the vector
new.close()

Topology access example

In the following example is presented how to access vector topological primitives directly using PyGRASS. It requires full understanding of GRASS topological model, see Vector topology section in Unit 03 - Data Management.

Sample script below prints for each county (vector map Fylke imported in Unit 03 - Data Management) number of its neighbours.

  1. Vector map Fylke is open on line 10 by VectorTopo and its method open().
  2. Features (areas in this case) are sequentially read by for loop on line 12. Areas are interated by viter() function.
  3. For each feature (ie. county) its boudaries are looped, see line 14. Each boundary has two neighbours (line 15): on the left and right side (-1 for no area).

Note

To avoid unicode error when lauching the script from GRASS GUI, few lines are added to a beginnging of the script, see lines 3-5.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env python

import sys
import codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout)

from grass.pygrass.vector import VectorTopo

counties = VectorTopo('Fylke')
counties.open('r')

for o in counties.viter('areas'):
    neighbours = set()
    for b in o.boundaries():
        for n in b.read_area_ids():
            if n != -1 and n != o.id:
                neighbours.add(n)
    
    print (u'{:25}: {}'.format(o.attrs['navn'].split(':', 1)[1][:-1], len(neighbours)))

counties.close()

Possible output:

Troms,Romsa              : 2
Finnmark,Finnmárku       : 1
Hordaland                : 4