1 """!@package grass.script.vector 
    3 @brief GRASS Python scripting module (vector functions) 
    5 Vector related functions to be used in Python scripts. 
   10 from grass.script import vector as grass 
   16 (C) 2008-2010 by the GRASS Development Team 
   17 This program is free software under the GNU General Public 
   18 License (>=v2). Read the file COPYING that comes with GRASS 
   21 @author Glynn Clements 
   22 @author Martin Landa <landa.martin gmail.com> 
   34 gettext.install(
'grasslibs', os.path.join(os.getenv(
"GISBASE"), 
'locale'), unicode=
True)
 
   39     """!Return the database connection details for a vector map 
   40     (interface to `v.db.connect -g'). Example: 
   43     >>> grass.vector_db('lakes') 
   44     {1: {'layer': '1', 'name': '', 
   45     'database': '/home/martin/grassdata/nc_spm_08/PERMANENT/dbf/', 
   46     'driver': 'dbf', 'key': 'cat', 'table': 'lakes'}} 
   52     @return dictionary { layer : { 'layer', 'table, 'database', 'driver', 'key' } 
   54     s = 
read_command(
'v.db.connect', flags = 
'g', map = map, fs = 
';', **args)
 
   57     for l 
in s.splitlines():
 
   70         result[int(layer)] = {
 
   81     """!Return the database connection details for a vector map layer. 
   82     If db connection for given layer is not defined, fatal() is called. 
   85     @param layer layer number 
   92         fatal(_(
"Database connection not defined for layer %s") % layer)
 
   99     """!Return a dictionary (or a list) of the columns for the 
  100     database table connected to a vector map (interface to `v.info 
  104     >>> vector_columns(urbanarea, getDict = True) 
  105     {'UA_TYPE': {'index': 4, 'type': 'CHARACTER'}, 'UA': {'index': 2, 'type': 'CHARACTER'}, 'NAME': {'index': 3, 'type': 'CHARACTER'}, 'OBJECTID': {'index': 1, 'type': 'INTEGER'}, 'cat': {'index': 0, 'type': 'INTEGER'}} 
  107     >>> vector_columns(urbanarea, getDict = False) 
  108     ['cat', 'OBJECTID', 'UA', 'NAME', 'UA_TYPE'] 
  112     @param layer layer number or name (None for all layers) 
  113     @param getDict True to return dictionary of columns otherwise list of column names is returned 
  114     @param args (v.info's arguments) 
  116     @return dictionary/list of columns 
  118     s = 
read_command(
'v.info', flags = 
'c', map = map, layer = layer, quiet = 
True, **args)
 
  124     for line 
in s.splitlines():
 
  125         ctype, cname = line.split(
'|')
 
  127             result[cname] = { 
'type' : ctype,
 
  138     """!Set the command history for a vector map to the command used to 
  139     invoke the script (interface to `v.support'). 
  143     @return v.support output 
  145     run_command(
'v.support', map = map, cmdhist = os.environ[
'CMDLINE'])
 
  150     """!Return information about a vector map (interface to `v.info 
  154     >>> grass.vector_info_topo('lakes') 
  155     {'kernels': 0, 'lines': 0, 'centroids': 15279, 
  156     'boundaries': 27764, 'points': 0, 'faces': 0, 
  157     'primitives': 43043, 'islands': 7470, 'nodes': 35234, 'map3d': 0, 'areas': 15279} 
  162     @return parsed output 
  167         ret[
'map3d'] = bool(ret[
'map3d'])
 
  174     """!Get attribute data of selected vector map layer. 
  176     Function returns list of columns and dictionary of values ordered by 
  177     key column value. Example: 
  180     >>> print grass.vector_db_select('lakes')['columns'] 
  181     ['cat', 'AREA', 'PERIMETER', 'FULL_HYDRO', 'FULL_HYDR2', 'FTYPE', 'FCODE', 'NAME'] 
  182     >>> print grass.vector_db_select('lakes')['values'][3] 
  183     ['3', '19512.86146', '708.44683', '4', '55652', 'LAKE/POND', '39000', ''] 
  184     >>> print grass.vector_db_select('lakes', columns = 'FTYPE')['values'][3] 
  189     @param layer layer number 
  190     @param kwargs v.db.select options 
  192     @return dictionary ('columns' and 'values') 
  197         error(_(
'Missing layer %(layer)d in vector map <%(map)s>') % \
 
  198                   { 
'layer' : layer, 
'map' : map })
 
  199         return { 
'columns' : [], 
'values' : {} }
 
  201     if 'columns' in kwargs:
 
  202         if key 
not in kwargs[
'columns'].
split(
','):
 
  204             debug(
"Adding key column to the output")
 
  205             kwargs[
'columns'] += 
',' + key
 
  213         error(_(
'vector_db_select() failed'))
 
  214         return { 
'columns' : [], 
'values' : {} }
 
  218     for line 
in ret.splitlines():
 
  220             columns = line.split(
'|')
 
  221             key_index = columns.index(key)
 
  224         value = line.split(
'|')
 
  225         key_value = int(value[key_index])
 
  226         values[key_value] = line.split(
'|')
 
  228     return { 
'columns' : columns,
 
  233     """!Query vector map at given locations 
  235     To query one vector map at one location 
  237     print grass.vector_what(map = 'archsites', coord = (595743, 4925281), distance = 250) 
  239     [{'Category': 8, 'Map': 'archsites', 'Layer': 1, 'Key_column': 'cat', 
  240       'Database': '/home/martin/grassdata/spearfish60/PERMANENT/dbf/', 
  241       'Mapset': 'PERMANENT', 'Driver': 'dbf', 
  242       'Attributes': {'str1': 'No_Name', 'cat': '8'}, 
  243       'Table': 'archsites', 'Type': 'Point', 'Id': 8}] 
  246     To query one vector map with multiple layers (no additional parameters required) 
  248     for q in grass.vector_what(map = 'some_map', coord = (596532.357143,4920486.21429), distance = 100.0): 
  249         print q['Map'], q['Layer'], q['Attributes'] 
  251     new_bug_sites 1 {'str1': 'Beetle_site', 'GRASSRGB': '', 'cat': '80'} 
  252     new_bug_sites 2 {'cat': '80'} 
  255     To query more vector maps at one location 
  257     for q in grass.vector_what(map = ('archsites', 'roads'), coord = (595743, 4925281), 
  259         print q['Map'], q['Attributes'] 
  261     archsites {'str1': 'No_Name', 'cat': '8'} 
  262     roads {'label': 'interstate', 'cat': '1'} 
  265     To query one vector map at more locations 
  267     for q in grass.vector_what(map = 'archsites', coord = [(595743, 4925281), (597950, 4918898)], 
  269         print q['Map'], q['Attributes'] 
  271     archsites {'str1': 'No_Name', 'cat': '8'} 
  272     archsites {'str1': 'Bob_Miller', 'cat': '22'} 
  275     @param map vector map(s) to query given as string or list/tuple 
  276     @param coord coordinates of query given as tuple (easting, northing) or list of tuples 
  277     @param distance query threshold distance (in map units) 
  281     if "LC_ALL" in os.environ:
 
  282         locale = os.environ[
"LC_ALL"]
 
  283         os.environ[
"LC_ALL"] = 
"C" 
  285     if type(map) 
in (types.StringType, types.UnicodeType):
 
  291     if type(coord) 
is types.TupleType:
 
  292         coord_list.append(
'%f,%f' % (coord[0], coord[1]))
 
  295             coord_list.append(
'%f,%f' % (e, n))
 
  300                        map        = 
','.join(map_list),
 
  301                        east_north = 
','.join(coord_list),
 
  302                        distance   = float(distance))
 
  304     if "LC_ALL" in os.environ:
 
  305         os.environ[
"LC_ALL"] = locale
 
  314     attr_pseudo_key = 
'Attributes' 
  315     for item 
in ret.splitlines():
 
  317             key, value = __builtin__.map(
lambda x: x.strip(), item.split(
'=', 1))
 
  320         if key 
in (
'East', 
'North'):
 
  325             if dict_layer 
is not None:
 
  326                 dict_main = copy.copy(dict_map)
 
  327                 dict_main.update(dict_layer)
 
  328                 data.append(dict_main)
 
  329             dict_map  = { key : value }
 
  334             if dict_layer 
is not None:
 
  335                 dict_main = copy.copy(dict_map)
 
  336                 dict_main.update(dict_layer)
 
  337                 data.append(dict_main)
 
  338             dict_layer = { key: int(value) }
 
  340         elif key == 
'Key_column':
 
  341             dict_layer[key] = value
 
  343             dict_layer[attr_pseudo_key] = dict_attrb
 
  344         elif dict_attrb 
is not None:
 
  345             dict_attrb[key] = value
 
  346         elif dict_layer 
is not None:
 
  347             if key == 
'Category':
 
  348                 dict_layer[key] = int(value)
 
  350                 dict_layer[key] = value
 
  352             dict_map[key] = value
 
  357     if dict_layer 
is not None:
 
  358         dict_main = copy.copy(dict_map)
 
  359         dict_main.update(dict_layer)
 
  360         data.append(dict_main)
 
def vector_layer_db
Return the database connection details for a vector map layer. 
 
def vector_info_topo
Return information about a vector map (interface to `v.info -t'). 
 
def split
Platform spefic shlex.split. 
 
def fatal
Display an error message using g.message -e, then abort. 
 
def vector_db_select
Get attribute data of selected vector map layer. 
 
def vector_db
Return the database connection details for a vector map (interface to `v.db.connect -g')...
 
def vector_columns
Return a dictionary (or a list) of the columns for the database table connected to a vector map (inte...
 
def parse_key_val
Parse a string into a dictionary, where entries are separated by newlines and the key and value are s...
 
def vector_what
Query vector map at given locations. 
 
def vector_history
Set the command history for a vector map to the command used to invoke the script (interface to `v...
 
def run_command
Passes all arguments to start_command(), then waits for the process to complete, returning its exit c...
 
def read_command
Passes all arguments to pipe_command, then waits for the process to complete, returning its stdout (i...