[GRASS-SVN] r73462 - grass/branches/releasebranch_7_6/scripts/v.rast.stats

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Sep 29 12:33:40 PDT 2018


Author: sbl
Date: 2018-09-29 12:33:40 -0700 (Sat, 29 Sep 2018)
New Revision: 73462

Modified:
   grass/branches/releasebranch_7_6/scripts/v.rast.stats/v.rast.stats.py
Log:
apply multiraster patch; fix #3523

Modified: grass/branches/releasebranch_7_6/scripts/v.rast.stats/v.rast.stats.py
===================================================================
--- grass/branches/releasebranch_7_6/scripts/v.rast.stats/v.rast.stats.py	2018-09-29 19:31:54 UTC (rev 73461)
+++ grass/branches/releasebranch_7_6/scripts/v.rast.stats/v.rast.stats.py	2018-09-29 19:33:40 UTC (rev 73462)
@@ -40,7 +40,7 @@
 #%end
 #%option G_OPT_V_FIELD
 #%end
-#%option G_OPT_R_INPUT
+#%option G_OPT_R_INPUTS
 #% key: raster
 #% description: Name of input raster map to calculate statistics from
 #%end
@@ -49,6 +49,7 @@
 #% type: string
 #% description: Column prefix for new attribute columns
 #% required : yes
+#% multiple: yes
 #%end
 #%option
 #% key: method
@@ -98,8 +99,8 @@
 
     nuldev = file(os.devnull, 'w')
 
-    raster = options['raster']
-    colprefix = options['column_prefix']
+    rasters = options['raster'].split(',')
+    colprefixes = options['column_prefix'].split(',')
     vector = options['map']
     layer = options['layer']
     percentile = options['percentile']
@@ -128,13 +129,20 @@
     # we need this for non-DBF driver:
     dbfdriver = fi['driver'] == 'dbf'
 
+    # colprefix for every raster map?
+    if len(colprefixes) != len(rasters):
+        grass.fatal(_("Number of raster maps ({0}) different from \
+                      number of column prefixes ({1})". format(len(rasters),
+                                                               len(colprefixes))))
+
     vector = vs[0]
 
     rastertmp = "%s_%s" % (vector, tmpname)
 
-    # check the input raster map
-    if not grass.find_file(raster, 'cell')['file']:
-        grass.fatal(_("Raster map <%s> not found") % raster)
+    for raster in rasters:
+        # check the input raster map
+        if not grass.find_file(raster, 'cell')['file']:
+            grass.fatal(_("Raster map <%s> not found") % raster)
 
     # save current settings:
     grass.use_temp_region()
@@ -141,7 +149,7 @@
 
     # Temporarily aligning region resolution to $RASTER resolution
     # keep boundary settings
-    grass.run_command('g.region', align=raster)
+    grass.run_command('g.region', align=rasters[0])
 
     # prepare base raster for zonal statistics
     try:
@@ -168,6 +176,29 @@
     if number < 1:
         grass.fatal(_("No categories found in raster map"))
 
+    # Check if all categories got converted
+    # Report categories from vector map
+    vect_cats = grass.read_command('v.category', input=vector, option='report',
+                        flags='g').rstrip('\n').split('\n')
+
+    # get number of all categories in selected layer
+    for vcl in vect_cats:
+        if vcl.split(' ')[0] == layer and vcl.split(' ')[1] == 'all':
+            vect_cats_n = int(vcl.split(' ')[2])
+        
+    if vect_cats_n != number:
+        grass.warning(_("Not all vector categories converted to raster. \
+                         Converted {0} of {1}.".format(number, vect_cats_n)))
+
+    # check if DBF driver used, in this case cut to 10 chars col names:
+    try:
+        fi = grass.vector_db(map=vector)[int(layer)]
+    except KeyError:
+        grass.fatal(
+            _('There is no table connected to this map. Run v.db.connect or v.db.addtable first.'))
+    # we need this for non-DBF driver:
+    dbfdriver = fi['driver'] == 'dbf'
+
     # Find out which table is linked to the vector map on the given layer
     if not fi['table']:
         grass.fatal(
@@ -176,132 +207,135 @@
     # replaced by user choiche
     #basecols = ['n', 'min', 'max', 'range', 'mean', 'stddev', 'variance', 'cf_var', 'sum']
 
-    # we need at least three chars to distinguish [mea]n from [med]ian
-    # so colprefix can't be longer than 6 chars with DBF driver
-    if dbfdriver:
-        colprefix = colprefix[:6]
-        variables_dbf = {}
-
-    # by default perccol variable is used only for "variables" variable
-    perccol = "percentile"
-    perc = None
-    for b in basecols:
-        if b.startswith('p'):
-            perc = b
-    if perc:
-        # namespace is limited in DBF but the % value is important
+    for i in xrange(len(rasters)):
+        raster = rasters[i]
+        colprefix = colprefixes[i]
+        # we need at least three chars to distinguish [mea]n from [med]ian
+        # so colprefix can't be longer than 6 chars with DBF driver
         if dbfdriver:
-            perccol = "per" + percentile
-        else:
-            perccol = "percentile_" + percentile
-        percindex = basecols.index(perc)
-        basecols[percindex] = perccol
+            colprefix = colprefix[:6]
+            variables_dbf = {}
 
-    # dictionary with name of methods and position in "r.univar -gt"  output
-    variables = {'number': 2, 'null_cells': 3, 'minimum': 4, 'maximum': 5, 'range': 6,
-                 'average': 7, 'stddev': 9, 'variance': 10, 'coeff_var': 11,
-                 'sum': 12, 'first_quartile': 14, 'median': 15,
-                 'third_quartile': 16, perccol: 17}
-    # this list is used to set the 'e' flag for r.univar
-    extracols = ['first_quartile', 'median', 'third_quartile', perccol]
-    addcols = []
-    colnames = []
-    extstat = ""
-    for i in basecols:
-        # this check the complete name of out input that should be truncated
-        for k in variables.keys():
-            if i in k:
-                i = k
-                break
-        if i in extracols:
-            extstat = 'e'
-        # check if column already present
-        currcolumn = ("%s_%s" % (colprefix, i))
-        if dbfdriver:
-            currcolumn = currcolumn[:10]
-            variables_dbf[currcolumn.replace("%s_" % colprefix, '')] = i
+        # by default perccol variable is used only for "variables" variable
+        perccol = "percentile"
+        perc = None
+        for b in basecols:
+            if b.startswith('p'):
+                perc = b
+        if perc:
+            # namespace is limited in DBF but the % value is important
+            if dbfdriver:
+                perccol = "per" + percentile
+            else:
+                perccol = "percentile_" + percentile
+            percindex = basecols.index(perc)
+            basecols[percindex] = perccol
 
-        colnames.append(currcolumn)
-        if currcolumn in grass.vector_columns(vector, layer).keys():
-            if not flags['c']:
-                grass.fatal((_("Cannot create column <%s> (already present). ") % currcolumn) +
-                            _("Use -c flag to update values in this column."))
-        else:
-            if i == "n":
-                coltype = "INTEGER"
+        # dictionary with name of methods and position in "r.univar -gt"  output
+        variables = {'number': 2, 'null_cells': 2, 'minimum': 4, 'maximum': 5, 'range': 6,
+                     'average': 7, 'stddev': 9, 'variance': 10, 'coeff_var': 11,
+                     'sum': 12, 'first_quartile': 14, 'median': 15,
+                     'third_quartile': 16, perccol: 17}
+        # this list is used to set the 'e' flag for r.univar
+        extracols = ['first_quartile', 'median', 'third_quartile', perccol]
+        addcols = []
+        colnames = []
+        extstat = ""
+        for i in basecols:
+            # this check the complete name of out input that should be truncated
+            for k in variables.keys():
+                if i in k:
+                    i = k
+                    break
+            if i in extracols:
+                extstat = 'e'
+            # check if column already present
+            currcolumn = ("%s_%s" % (colprefix, i))
+            if dbfdriver:
+                currcolumn = currcolumn[:10]
+                variables_dbf[currcolumn.replace("%s_" % colprefix, '')] = i
+
+            colnames.append(currcolumn)
+            if currcolumn in grass.vector_columns(vector, layer).keys():
+                if not flags['c']:
+                    grass.fatal((_("Cannot create column <%s> (already present). ") % currcolumn) +
+                                _("Use -c flag to update values in this column."))
             else:
-                coltype = "DOUBLE PRECISION"
-            addcols.append(currcolumn + ' ' + coltype)
+                if i == "n":
+                    coltype = "INTEGER"
+                else:
+                    coltype = "DOUBLE PRECISION"
+                addcols.append(currcolumn + ' ' + coltype)
 
-    if addcols:
-        grass.verbose(_("Adding columns '%s'") % addcols)
-        try:
-            grass.run_command('v.db.addcolumn', map=vector, columns=addcols,
-                              layer=layer)
-        except CalledModuleError:
-            grass.fatal(_("Adding columns failed. Exiting."))
+        if addcols:
+            grass.verbose(_("Adding columns '%s'") % addcols)
+            try:
+                grass.run_command('v.db.addcolumn', map=vector, columns=addcols,
+                                  layer=layer)
+            except CalledModuleError:
+                grass.fatal(_("Adding columns failed. Exiting."))
 
-    # calculate statistics:
-    grass.message(_("Processing input data (%d categories)...") % number)
+        # calculate statistics:
+        grass.message(_("Processing input data (%d categories)...") % number)
 
-    # get rid of any earlier attempts
-    grass.try_remove(sqltmp)
+        # get rid of any earlier attempts
+        grass.try_remove(sqltmp)
 
-    f = file(sqltmp, 'w')
+        f = file(sqltmp, 'w')
 
-    # do the stats
-    p = grass.pipe_command('r.univar', flags='t' + extstat, map=raster,
-                           zones=rastertmp, percentile=percentile, sep=';')
+        # do the stats
+        p = grass.pipe_command('r.univar', flags='t' + extstat, map=raster,
+                               zones=rastertmp, percentile=percentile, sep=';')
 
-    first_line = 1
+        first_line = 1
 
-    f.write("{0}\n".format(grass.db_begin_transaction(fi['driver'])))
-    for line in p.stdout:
-        if first_line:
-            first_line = 0
-            continue
+        f.write("{0}\n".format(grass.db_begin_transaction(fi['driver'])))
+        for line in p.stdout:
+            if first_line:
+                first_line = 0
+                continue
 
-        vars = line.rstrip('\r\n').split(';')
+            vars = line.rstrip('\r\n').split(';')
 
-        f.write("UPDATE %s SET" % fi['table'])
-        first_var = 1
-        for colname in colnames:
-            variable = colname.replace("%s_" % colprefix, '', 1)
-            if dbfdriver:
-                variable = variables_dbf[variable]
-            i = variables[variable]
-            value = vars[i]
-            # convert nan, +nan, -nan, inf, +inf, -inf, Infinity, +Infinity,
-            # -Infinity to NULL
-            if value.lower().endswith('nan') or 'inf' in value.lower():
-                value = 'NULL'
-            if not first_var:
-                f.write(" , ")
-            else:
-                first_var = 0
-            f.write(" %s=%s" % (colname, value))
+            f.write("UPDATE %s SET" % fi['table'])
+            first_var = 1
+            for colname in colnames:
+                variable = colname.replace("%s_" % colprefix, '', 1)
+                if dbfdriver:
+                    variable = variables_dbf[variable]
+                i = variables[variable]
+                value = vars[i]
+                # convert nan, +nan, -nan, inf, +inf, -inf, Infinity, +Infinity,
+                # -Infinity to NULL
+                if value.lower().endswith('nan') or 'inf' in value.lower():
+                    value = 'NULL'
+                if not first_var:
+                    f.write(" , ")
+                else:
+                    first_var = 0
+                f.write(" %s=%s" % (colname, value))
 
-        f.write(" WHERE %s=%s;\n" % (fi['key'], vars[0]))
-    f.write("{0}\n".format(grass.db_commit_transaction(fi['driver'])))
-    p.wait()
-    f.close()
+            f.write(" WHERE %s=%s;\n" % (fi['key'], vars[0]))
+        f.write("{0}\n".format(grass.db_commit_transaction(fi['driver'])))
+        p.wait()
+        f.close()
 
-    grass.message(_("Updating the database ..."))
-    exitcode = 0
-    try:
-        grass.run_command('db.execute', input=sqltmp,
-                          database=fi['database'], driver=fi['driver'])
-        grass.verbose((_("Statistics calculated from raster map <{raster}>"
-                         " and uploaded to attribute table"
-                         " of vector map <{vector}>."
-                         ).format(raster=raster, vector=vector)))
-    except CalledModuleError:
-        grass.warning(
-            _("Failed to upload statistics to attribute table of vector map <%s>.") %
-            vector)
-        exitcode = 1
+        grass.message(_("Updating the database ..."))
+        exitcode = 0
+        try:
+            grass.run_command('db.execute', input=sqltmp,
+                              database=fi['database'], driver=fi['driver'])
+            grass.verbose((_("Statistics calculated from raster map <{raster}>"
+                             " and uploaded to attribute table"
+                             " of vector map <{vector}>."
+                             ).format(raster=raster, vector=vector)))
+        except CalledModuleError:
+            grass.warning(
+                _("Failed to upload statistics to attribute table of vector map <%s>.") %
+                vector)
+            exitcode = 1
 
-    sys.exit(exitcode)
+            sys.exit(exitcode)
 
 if __name__ == "__main__":
     options, flags = grass.parser()



More information about the grass-commit mailing list