[GRASS-SVN] r73148 - in grass-addons/grass7/vector: . v.rast.bufferstats
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Aug 23 13:21:11 PDT 2018
Author: sbl
Date: 2018-08-23 13:21:11 -0700 (Thu, 23 Aug 2018)
New Revision: 73148
Added:
grass-addons/grass7/vector/v.rast.bufferstats/
grass-addons/grass7/vector/v.rast.bufferstats/Makefile
grass-addons/grass7/vector/v.rast.bufferstats/v.rast.bufferstats.html
grass-addons/grass7/vector/v.rast.bufferstats/v.rast.bufferstats.py
Log:
Add v.rast.bufferstats
Added: grass-addons/grass7/vector/v.rast.bufferstats/Makefile
===================================================================
--- grass-addons/grass7/vector/v.rast.bufferstats/Makefile (rev 0)
+++ grass-addons/grass7/vector/v.rast.bufferstats/Makefile 2018-08-23 20:21:11 UTC (rev 73148)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = v.rast.bufferstats
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script
Property changes on: grass-addons/grass7/vector/v.rast.bufferstats/Makefile
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/x-makefile
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: grass-addons/grass7/vector/v.rast.bufferstats/v.rast.bufferstats.html
===================================================================
--- grass-addons/grass7/vector/v.rast.bufferstats/v.rast.bufferstats.html (rev 0)
+++ grass-addons/grass7/vector/v.rast.bufferstats/v.rast.bufferstats.html 2018-08-23 20:21:11 UTC (rev 73148)
@@ -0,0 +1,62 @@
+<h2>DESCRIPTION:</h2>
+<p>The module <em>v.rast.bufferstats</em> computes statistics from multiple input raster
+maps within (multiple) buffers around selected geometries in the input vector map.<br>
+Available statistics are either</p>
+<ol type="a">
+<li>statistics provided by <em>r.univar</em> or</li>
+<li>if the <em>t-flag</em> is checked - area of, number of and/or the most frequent (mode) raster categories
+within the buffers using <em>r.stats</em>.</li>
+</ol>
+
+<p>If <em>output</em> option is specified table output is produced with the following column order:<br>
+cat | prefix | buffer| statistic/measure | value<br>
+separated by the selected separator.</p>
+
+<div id="note">
+<h2>NOTE</h2>
+<p>The module temporarily modifies the computational region. The region is set to the
+extent of the respecive buffers, while the alignement of the current region is kept.</p>
+</div>
+
+<div id="examples">
+
+<h2>EXAMPLES</h2>
+<div class="code"><pre>
+
+g.region -p raster=elevation,geology_30m
+v.clip --o -r input=bridges output=bridges_wake
+
+# Tabulate area of land cover map
+g.region -p raster=elevation,geology_30m align=geology_30m
+v.rast.bufferstats -t input=bridges_wake raster=geology_30m buffers=100,250,500 column_prefix=geology
+
+# Compute terrain statistics
+g.region -p raster=elevation,geology_30m align=elevation
+r.slope.aspect elevation=elevation slope=slope aspect=aspect
+v.rast.bufferstats input= raster=altitude,slope,aspect buffers=100,250,500 column_prefix=altitude,slope,aspect methods=minimum,maximum,average,stddev percentile=5,95
+
+</pre></div>
+</div>
+
+<div id="known issues">
+<h2>KNOWN ISSUES</h2>
+<p>In order to avoid topological issues with overlapping buffers, the module loops over the
+input geometries. However, this comes at costs with regards to performance.
+For a larger number of geometries in the vector map, it can be therefore more appropriate to
+compute neighborhood statistics with <em>r.neighbors</em> and to extract (<em>v.what.rast</em>,
+<em>r.what</em>) or aggregate (<em>v.rast.stats</em>) from those maps with neighborhood statistics.</p>
+</div>
+
+<div id="seealso">
+
+<h2>SEE ALSO</h2>
+<a href="r.univar.html">r.univar</a>
+<a href="r.stats.html">r.stats</a>
+<a href="v.rast.stats.html">v.rast.stats</a>
+</div>
+
+<div id="author">
+
+<h2>AUTHOR</h2>
+Stefan Blumentrath, Norwegian Institute for Nature Research, Oslo, Norway
+</div>
Property changes on: grass-addons/grass7/vector/v.rast.bufferstats/v.rast.bufferstats.html
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/html
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: grass-addons/grass7/vector/v.rast.bufferstats/v.rast.bufferstats.py
===================================================================
--- grass-addons/grass7/vector/v.rast.bufferstats/v.rast.bufferstats.py (rev 0)
+++ grass-addons/grass7/vector/v.rast.bufferstats/v.rast.bufferstats.py 2018-08-23 20:21:11 UTC (rev 73148)
@@ -0,0 +1,620 @@
+#!/usr/bin/env python
+
+"""
+MODULE: v.rast.bufferstats
+
+AUTHOR(S): Stefan Blumentrath < stefan.blumentrath AT nina.no>
+ With lots of inspiration from v.what.rast.buffer by
+ Hamish Bowman, Dunedin, New Zealand
+
+PURPOSE: Calculates statistics of raster map(s) for buffers around vector geometries.
+
+COPYRIGHT: (C) 2018 by the GRASS Development Team
+
+ This program is free software under the GNU General Public
+ License (>=v2). Read the file COPYING that comes with GRASS
+ for details.
+
+
+To Dos:
+- consider adding distance weights
+- add neighborhood stats ???
+- silence r.category
+- add where clause
+#%option G_OPT_DB_WHERE
+#% required: no
+#%end
+
+ where = options['where']
+
+"""
+
+#%Module
+#% label: Calculates statistics of raster map(s) for buffers around vector geometries.
+#% keyword: vector
+#% keyword: raster
+#% keyword: buffer
+#% keyword: statistics
+#%End
+
+#%option G_OPT_V_INPUT
+#% description: Vector map containing geometries to compute buffer statistics for
+#%end
+
+#%option G_OPT_R_INPUTS
+#% key: raster
+#% description: Raster map(s) to calculate statistics from
+#% multiple: yes
+#% required : yes
+#%end
+
+#%option
+#% key: buffers
+#% type: integer
+#% description: Buffer distance(s) in map units
+#% multiple: yes
+#% required : yes
+#%end
+
+#%option
+#% key: type
+#% type:string
+#% description: Vector type to work on
+#% options: points,lines,areas
+#% answer: points,lines,areas
+#% multiple: yes
+#% required: yes
+#%end
+
+## ,centroid not supported in pygrass
+
+#%option G_OPT_V_FIELD
+#% required: no
+#%end
+
+#%option
+#% key: column_prefix
+#% type: string
+#% description: Column prefix for new attribute columns
+#% required : yes
+#% multiple: yes
+#%end
+
+#%option
+#% key: methods
+#% type: string
+#% description: The methods to use
+#% required: no
+#% multiple: yes
+#% options: number,number_null,minimum,maximum,range,sum,average,average_abs,stddev,variance,coeff_var,first_quartile,median,third_quartile
+#% answer: number,number_null,minimum,maximum,range,sum,average,average_abs,stddev,variance,coeff_var,first_quartile,median,third_quartile
+#%end
+
+#%option
+#% key: percentile
+#% type: integer
+#% description: Percentile to calculate
+#% options: 0-100
+#% required : no
+#%end
+
+#%flag
+#% key: t
+#% description: Tabulate area within buffers for categories in raster map(s)
+#%end
+
+#%flag
+#% key: u
+#% description: Update columns if they already exist
+#%end
+
+
+#%option G_OPT_F_OUTPUT
+#% description: Name for output file (if "-" output to stdout)
+#% required: no
+#%end
+
+#%option G_OPT_F_SEP
+#% description: Field separator in output file
+#% answer: |
+#% required: no
+#%end
+
+import sys
+import os
+import atexit
+import math
+from subprocess import PIPE
+import grass.script as grass
+from grass.pygrass.vector import VectorTopo
+from grass.pygrass.raster.abstract import RasterAbstractBase
+from grass.pygrass.gis import Mapset
+from grass.pygrass.vector.geometry import Boundary
+from grass.pygrass.vector.geometry import Centroid
+from grass.pygrass.gis.region import Region
+#from grass.pygrass.vector.table import *
+from grass.pygrass.modules.interface.module import Module
+from itertools import chain
+
+if not "GISBASE" in os.environ.keys():
+ grass.message("You must be in GRASS GIS to run this program.")
+ sys.exit(1)
+
+TMP_MAPS = []
+
+def cleanup():
+ """Remove temporary data
+ """
+ #remove temporary region file
+ try:
+ grass.run_command('g.remove', flags='f', name=TMP_MAPS,
+ quiet=True, type=['vector', 'raster'],
+ stderr=os.devnull, stdout_=os.devnull)
+ except:
+ pass
+
+ try:
+ grass.run_command('g.remove', flags='f', name='MASK',
+ quiet=True, type='raster',
+ stderr=os.devnull, stdout_=os.devnull)
+ except:
+ pass
+
+def align_current(region, bbox):
+ """Align current region to bounding box
+
+ :param region: PyGRASS Region object
+ :param bbox: PyGRASS Bbox object
+ :returns: adjusted PyGRASS Region object
+ :type region: PyGRASS Region object
+ :type bbox: PyGRASS Bbox object
+ :rtype: dict
+
+ :Example:
+
+ >>> align_current(region, bbox)
+ region
+ """
+ north = region.north
+ east = region.east
+ west = region.west
+ south = region.south
+ nsres = region.nsres
+ ewres = region.ewres
+
+ region.north = north - (math.floor((north - bbox.north) / nsres)
+ * nsres)
+ region.south = south - (math.ceil((south - bbox.south) / nsres)
+ * nsres)
+ region.east = east - (math.floor((east - bbox.east) / ewres)
+ * ewres)
+ region.west = west - (math.ceil((west - bbox.west) / ewres)
+ * ewres)
+
+ return region
+
+def random_name(length):
+ """Generate a random name of length "length" starting with a letter
+
+ :param length: length of the random name to generate
+ :returns: String with a random name of length "length" starting with a letter
+ :type length: int
+ :rtype: string
+
+ :Example:
+
+ >>> random_name(12)
+ 'MxMa1kAS13s9'
+ """
+
+ import string
+ import random
+ chars = string.ascii_uppercase + string.ascii_lowercase + string.digits
+ randomname = '1'
+ while randomname[0].isdigit():
+ randomname = ''.join(random.choice(chars) for _ in range(length))
+
+ return randomname
+
+def raster_type(raster):
+ """Check raster map type (int or double) and return categories for int maps
+
+ :param raster: name of the raster map to check
+ :returns: string with raster map type and list of categories with lables
+ :type raster: string
+ :rtype: string
+ :rtype: list
+
+ :Example:
+
+ >>> raster_type('elevation')
+ 'double precision', []
+ """
+ rcats = []
+ try:
+ rcats = grass.read_command('r.category', map=raster,
+ quiet=True).rstrip('\n').split('\n')
+ rmap_type = 'int'
+ except:
+ pass
+
+ if len(rcats) == 0:
+ rmap_type = 'double precision'
+
+ return rmap_type, rcats
+
+def main():
+ in_vector = options['input'].split('@')[0]
+ if len(options['input'].split('@')) > 1:
+ in_mapset = options['input'].split('@')[1]
+ else:
+ in_mapset = None
+ raster_maps = options['raster'].split(',') # raster file(s) to extract from
+ output = options['output']
+ methods = tuple(options['methods'].split(','))
+ percentile = None if options['percentile'] == '' else map(float, options['percentile'].split(','))
+ column_prefix = tuple(options['column_prefix'].split(','))
+ buffers = options['buffers'].split(',')
+ types = options['type'].split(',')
+ layer = options['layer']
+ sep = options['separator']
+ update = flags['u']
+ tabulate = flags['t']
+
+ # Do checks using pygrass
+ for rmap in raster_maps:
+ r_map = RasterAbstractBase(rmap)
+ if not r_map.exist():
+ grass.fatal('Could not find raster map {}.'.format(rmap))
+
+ m_map = RasterAbstractBase('MASK')
+ if m_map.exist():
+ grass.fatal("Please remove MASK first")
+
+ invect = VectorTopo(in_vector)
+ if not invect.exist():
+ grass.fatal("Vector file {} does not exist".format(in_vector))
+
+ if output:
+ if output == '-':
+ out = None
+ else:
+ out = open(output, 'w')
+
+ # Check if input map is in current mapset (and thus editable)
+ if in_mapset and unicode(in_mapset) != unicode(Mapset()):
+ grass.fatal("Input vector map is not in current mapset and cannot be modified. \
+ Please consider copying it to current mapset.".format(output))
+
+ buffers = []
+ for buf in options['buffers'].split(','):
+ try:
+ b = float(buf)
+ if b.is_integer():
+ buffers.append(int(b))
+ else:
+ buffers.append(b)
+ except:
+ grass.fatal('')
+ if b < 0:
+ grass.fatal("Negative buffer distance not supported!")
+
+ ### Define column types depenting on statistic, map type and
+ ### DB backend (SQLite supports only double and not real)
+ # int: statistic produces allways integer precision
+ # double: statistic produces allways floating point precision
+ # map_type: precision f statistic depends on map type
+ int_dict = {'number': (0, 'int', 'n'),
+ 'number_null': (1, 'int', 'null_cells'),
+ 'minimum': (3, 'map_type', 'min'),
+ 'maximum': (4, 'map_type', 'max'),
+ 'range': (5, 'map_type', 'range'),
+ 'average': (6, 'double', 'mean'),
+ 'average_abs': (7, 'double', 'mean_of_abs'),
+ 'stddev': (8, 'double', 'stddev'),
+ 'variance': (9, 'double', 'variance'),
+ 'coeff_var': (10, 'double', 'coeff_var'),
+ 'sum': (11, 'map_type', 'sum'),
+ 'first_quartile': (12, 'map_type', 'first_quartile'),
+ 'median': (13, 'map_type', 'median'),
+ 'third_quartile': (14, 'map_type', 'third_quartile'),
+ 'percentile': (15, 'map_type', 'percentile')}
+
+ if len(raster_maps) != len(column_prefix):
+ grass.fatal('Number of maps and number of column prefixes has to be equal!')
+
+ # Generate list of required column names and types
+ col_names = []
+ col_types = []
+ for p in column_prefix:
+ rmaptype, rcats = raster_type(raster_maps[column_prefix.index(p)])
+ for b in buffers:
+ b_str = unicode(b).replace('.', '_')
+ if tabulate:
+ if rmaptype == 'double precision':
+ grass.fatal('{} has floating point precision. Can only tabulate integer maps'.format(raster_maps[column_prefix.index(p)]))
+ col_names.append('{}_{}_b{}'.format(p, 'ncats', b_str))
+ col_types.append('int')
+ col_names.append('{}_{}_b{}'.format(p, 'mode', b_str))
+ col_types.append('int')
+ col_names.append('{}_{}_b{}'.format(p, 'null', b_str))
+ col_types.append('double precision')
+ col_names.append('{}_{}_b{}'.format(p, 'area_tot', b_str))
+ col_types.append('double precision')
+ for rcat in rcats:
+ col_names.append('{}_{}_b{}'.format(p, rcat.split('\t')[0], b_str))
+ col_types.append('double precision')
+ else:
+ for m in methods:
+ col_names.append('{}_{}_b{}'.format(p, int_dict[m][2], b_str))
+ col_types.append(rmaptype if int_dict[m][1] == 'map_type' else int_dict[m][1])
+ if percentile:
+ for perc in percentile:
+ col_names.append('{}_percentile_{}_b{}'.format(p,
+ int(perc) if (perc).is_integer() else perc,
+ b_str))
+ col_types.append(rmaptype if int_dict[m][1] == 'map_type' else int_dict[m][1])
+
+ # Open input vector map
+ in_vect = VectorTopo(in_vector, layer=layer)
+ in_vect.open(mode='r')
+
+ # Get name for temporary map
+ tmp_map = random_name(21)
+ TMP_MAPS.append(tmp_map)
+
+ # Setup stats collectors
+ if tabulate:
+ # Collector for raster category statistics
+ stats = Module('r.stats', run_=False, stdout_=PIPE)
+ stats.inputs.sort = 'desc'
+ stats.inputs.null_value = 'null'
+ stats.flags.a = True
+ stats.flags.quiet = True
+ else:
+ # Collector for univariat statistics
+ univar = Module('r.univar', run_=False, stdout_=PIPE)
+ univar.inputs.separator = sep
+ univar.flags.g = True
+ univar.flags.quiet = True
+
+ # Add extended statistics if requested
+ if set(methods).intersection(set(['first_quartile',
+ 'median', 'third_quartile'])):
+ univar.flags.e = True
+
+ if percentile is not None:
+ univar.flags.e = True
+ univar.inputs.percentile = percentile
+
+ # Check if attribute table exists
+ if not output:
+ if not in_vect.table:
+ grass.fatal('No attribute table found for vector map {}'.format(in_vect))
+
+ # Modify table as needed
+ tab = in_vect.table
+ tab_name = tab.name
+ tab_cols = tab.columns
+
+ # Add required columns
+ existing_cols = list(set(tab_cols.names()).intersection(col_names))
+ if len(existing_cols) > 0:
+ if not update:
+ grass.fatal('Column(s) {} already exist! Please use the u-flag \
+ if you want to update values in those columns'.format(','.join(existing_cols)))
+ else:
+ grass.warning('Column(s) {} already exist!'.format(','.join(existing_cols)))
+ for e in existing_cols:
+ idx = col_names.index(e)
+ del col_names[idx]
+ del col_types[idx]
+ tab_cols.add(col_names, col_types)
+
+ conn = tab.conn
+ cur = conn.cursor()
+
+ sql_str_start = 'UPDATE {} SET '.format(tab_name)
+
+
+ # Get computational region
+ #grass.use_temp_region()
+ r = Region()
+ #r.read()
+
+ # Adjust region extent to buffer around geometry
+ #reg = deepcopy(r)
+
+ # Create iterator for geometries of all selected types
+ geoms = chain()
+ geoms_n = 0
+ n_geom = 1
+ for geom_type in types:
+ geoms_n += in_vect.number_of(geom_type)
+ if in_vect.number_of(geom_type) > 0:
+ geoms = chain(in_vect.viter(geom_type))
+
+ # Loop over geometries
+ for geom in geoms:
+ # Get cat
+ cat = geom.cat
+ # Give progress information
+ grass.percent(n_geom, geoms_n, 1)
+ n_geom = n_geom + 1
+
+ # Add where clause to UPDATE statement
+ sql_str_end = ' WHERE cat = {};'.format(cat)
+
+ # Loop over ser provided buffer distances
+ for buf in buffers:
+ b_str = unicode(buf).replace('.', '_')
+ # Buffer geometry
+ if buf <= 0:
+ buffer_geom = geom
+ else:
+ buffer_geom = geom.buffer(buf)
+ # Create temporary vector map with buffered geometry
+ tmp_vect = VectorTopo(tmp_map, quiet=True)
+ tmp_vect.open(mode='w')
+ #print(int(cat))
+ tmp_vect.write(Boundary(points=buffer_geom[0].to_list()))
+ # , c_cats=int(cat), set_cats=True
+ tmp_vect.write(Centroid(x=buffer_geom[1].x,
+ y=buffer_geom[1].y), cat=int(cat))
+
+ #################################################
+ # How to silence VectorTopo???
+ #################################################
+
+ # Save current stdout
+ #original = sys.stdout
+
+ #f = open(os.devnull, 'w')
+ #with open('output.txt', 'w') as f:
+ #sys.stdout = io.BytesIO()
+ #sys.stdout.fileno() = os.devnull
+ #sys.stderr = f
+ #os.environ.update(dict(GRASS_VERBOSE='0'))
+ tmp_vect.close(build=False)
+ grass.run_command('v.build', map=tmp_map, quiet=True)
+ #os.environ.update(dict(GRASS_VERBOSE='1'))
+
+ #reg = Region()
+ #reg.read()
+ #r.from_vect(tmp_map)
+ r = align_current(r, buffer_geom[0].bbox())
+ r.set_current()
+
+ # Check if the following is needed
+ #grass.run_command('g.region', vector=tmp_map)
+
+ # Create a MASK from buffered geometry
+ grass.run_command('v.to.rast', input=tmp_map,
+ output='MASK', use='val',
+ value=int(cat), quiet=True)
+
+
+ #reg.write()
+
+ updates = []
+ # Compute statistics for every raster map
+ for rm in range(len(raster_maps)):
+ rmap = raster_maps[rm]
+ prefix = column_prefix[rm]
+
+ if tabulate:
+ # Get statistics on occurrence of raster categories within buffer
+ stats.inputs.input = rmap
+ stats.run()
+ t_stats = stats.outputs['stdout'].value.rstrip(os.linesep).replace(' ', '_b{} = '.format(b_str)).split(os.linesep)
+
+ if t_stats[0].split('_b{} = '.format(b_str))[0].split('_')[-1] != 'null':
+ mode = t_stats[0].split('_b{} = '.format(b_str))[0].split('_')[-1]
+ elif len(t_stats) == 1:
+ mode = 'NULL'
+ else:
+ mode = t_stats[1].split('_b{} = '.format(b_str))[0].split('_')[-1]
+
+ if not output:
+ updates.append('\t{}_{}_b{} = {}'.format(prefix, 'ncats', b_str, len(t_stats)))
+ updates.append('\t{}_{}_b{} = {}'.format(prefix, 'mode', b_str, mode))
+
+ area_tot = 0
+ for l in t_stats:
+ updates.append('\t{}_{}'.format(prefix, l))
+ if l.split('_b{} ='.format(b_str))[0].split('_')[-1] != 'null':
+ area_tot = area_tot + float(l.split('= ')[1])
+
+ updates.append('\t{}_{}_b{} = {}'.format(prefix, 'area_tot', b_str, area_tot))
+
+ else:
+ out_str = '{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}'.format(sep, cat, prefix, buffer, 'ncats', len(t_stats), os.linesep)
+ out_str += '{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}'.format(sep, cat, prefix, buffer, 'mode', mode, os.linesep)
+ area_tot = 0
+ for l in t_stats:
+ rcat = l.split('_b{} ='.format(b_str))[0].split('_')[-1]
+ area = l.split('= ')[1]
+ out_str += '{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}'.format(sep, cat, prefix, buffer, 'area {}'.format(rcat), area, os.linesep)
+ if rcat != 'null':
+ area_tot = area_tot + float(l.split('= ')[1])
+ out_str += '{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}'.format(sep, cat, prefix, buffer, 'area_tot', area_tot, os.linesep)
+
+ if output == '-':
+ print(out_str.rstrip(os.linesep))
+ else:
+ out.write(out_str)
+
+ else:
+ # Get univariate statistics within buffer
+ univar.inputs.map = rmap
+ univar.run()
+ u_stats = univar.outputs['stdout'].value.rstrip(os.linesep).replace('=', '_b{} = '.format(b_str)).split(os.linesep)
+
+ # Test i u_stats is empty and give warning
+ if (percentile and len(u_stats) <= 14) or (univar.flags.e and len(u_stats) <= 13) or len(u_stats) <= 12:
+ grass.warning('No data within buffer {} around geometry {}'.format(buf, cat))
+ break
+
+ # Extract statistics for selected methods
+ for m in methods:
+ if not output:
+ # Add to list of UPDATE statements
+ updates.append('\t{}_{}'.format(prefix,
+ u_stats[int_dict[m][0]]))
+ else:
+ out_str = '{1}{0}{2}{0}{3}{0}{4}{0}{5}'.format(sep, cat, prefix, buf, m, u_stats[int_dict[m][0]].split('= ')[1])
+ if output == '-':
+ print(out_str)
+ else:
+ out.write(out_str)
+
+ if percentile:
+ perc_count = 0
+ for perc in percentile:
+ if not output:
+ updates.append('{}_percentile_{}_b{} = {}'.format(p,
+ int(perc) if (perc).is_integer() else perc,
+ b_str, u_stats[15+perc_count].split('= ')[1]))
+ else:
+ out_str = '{1}{0}{2}{0}{3}{0}{4}{0}{5}'.format(sep, cat, prefix, buffer, 'percentile_{}'.format(int(perc) if (perc).is_integer() else perc), u_stats[15+perc_count].split('= ')[1])
+ if output == '-':
+ print(out_str)
+ else:
+ out.write(out_str)
+ perc_count = perc_count + 1
+
+ if not output and len(updates) > 0:
+ cur.execute('{}{}{}'.format(sql_str_start,
+ ',\n'.join(updates),
+ sql_str_end))
+
+ # Remove temporary maps
+ #, stderr=os.devnull, stdout_=os.devnull)
+ grass.run_command('g.remove', flags='f', type='raster',
+ name='MASK', quiet=True)
+ grass.run_command('g.remove', flags='f', type='vector',
+ name=tmp_map, quiet=True)
+
+ if not output:
+ conn.commit()
+
+ # Close cursor and DB connection
+ if not output:
+ cur.close()
+ conn.close()
+ elif output != "-":
+ # write results to file
+ out.close()
+ elif output and output == "-":
+ # write results to STDOUT
+ pass
+
+
+ grass.vector.vector_history(in_vector)
+ cleanup()
+
+# Run the module
+if __name__ == "__main__":
+ options, flags = grass.parser()
+ atexit.register(cleanup)
+ sys.exit(main())
Property changes on: grass-addons/grass7/vector/v.rast.bufferstats/v.rast.bufferstats.py
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/x-python
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
More information about the grass-commit
mailing list