[GRASS-SVN] r66645 - grass-addons/grass7/raster/r.category.trim
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Oct 28 10:41:22 PDT 2015
Author: pvanbosgeo
Date: 2015-10-28 10:41:22 -0700 (Wed, 28 Oct 2015)
New Revision: 66645
Added:
grass-addons/grass7/raster/r.category.trim/Makefile
grass-addons/grass7/raster/r.category.trim/r.category.trim.html
grass-addons/grass7/raster/r.category.trim/r.category.trim.py
Log:
addon to trim categories and colours of non-existing categories and optionally to export the category colors and labels as qgis color map text file
Added: grass-addons/grass7/raster/r.category.trim/Makefile
===================================================================
--- grass-addons/grass7/raster/r.category.trim/Makefile (rev 0)
+++ grass-addons/grass7/raster/r.category.trim/Makefile 2015-10-28 17:41:22 UTC (rev 66645)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.category.trim
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script
Property changes on: grass-addons/grass7/raster/r.category.trim/Makefile
___________________________________________________________________
Added: svn:eol-style
+ native
Added: grass-addons/grass7/raster/r.category.trim/r.category.trim.html
===================================================================
--- grass-addons/grass7/raster/r.category.trim/r.category.trim.html (rev 0)
+++ grass-addons/grass7/raster/r.category.trim/r.category.trim.html 2015-10-28 17:41:22 UTC (rev 66645)
@@ -0,0 +1,65 @@
+<h2>DESCRIPTION</h2>
+
+<p>In GRASS you can 'cut out' a subset of a larger raster layer by
+setting the extent to something smaller then the extent of the
+original map using g.region and/or by setting a mask using r.mask,
+after which you simply run r.mapcalc "newmap = oldmap".
+
+<p>You may have noticed that when creating the new map, all category
+category labels and colour table of the original map are copied over
+to the new map, even for category values that are not in the new
+map. If you are working with categorical maps, this may not be what
+you want. See <a href=
+"https://pvanb.wordpress.com/2015/09/22/categorical-maps-and-legends/"
+>here</a> for a more detailed discussion.
+
+<p>With this addon you can trim the category and colour tables so it
+only contains category labels and colour definitions for the values
+present in the new map. You can do this on the input map, or do this
+on a copy of the map.
+
+<p>If you prefer the map to have consecutive values (i.e., without
+gaps), there is the option to change the category values to a
+consecutive series by setting the n-flag. For example, if the map
+has the following categories values and labels (after the redundant
+category labels have been removed):
+
+<div class="code"><pre>2 label2
+5 label5
+9 label9
+</pre></div>
+
+<p>Then the new recoded layer will have the category values and labels:
+
+<div class="code"><pre>1 label2
+2 label5
+3 label9
+</pre></div>
+
+<p>Although it is possible to <a href=
+"https://pvanb.wordpress.com/2015/10/18/the-qgis-grass-plugin-is-back/
+">open GRASS GIS raster layers directly in QGIS</a>, the legend in
+QGIS will show the right colours, but not the category labels. The
+addon let's you export the categories, category labels and colours
+as QGIS colour map file. This is just a simple text file with the
+raster categories and corresponding colour definitions and category
+labels. QGIS can use this to set the colour and labels for a raster
+layer. See <a href="https://pvanb.wordpress.com/?p=3650">this
+blogpost</a> for more details how to use the colour map file in
+QGIS. Alternatively, you can also export the categories and category
+labels in a normal csv file.
+
+
+<h2>NOTE</h2>
+The file is only useful for categorical maps. Therefore only integer maps are accepted as input.
+
+<h2>SEE ALSO</h2>
+
+<a href="https://pvanb.wordpress.com/?p=3650">GRASS GIS categorical raster layers in QGIS </a></em>
+<a href="https://pvanb.wordpress.com/2015/09/22/categorical-maps-and-legends/">GRASS GIS categorical maps and legends</a></em>
+
+<h2>AUTHOR</h2>
+
+Paulo van Breugel, paulo at ecodiv.org
+
+<p><em>Last changed: $Date$</em>
Property changes on: grass-addons/grass7/raster/r.category.trim/r.category.trim.html
___________________________________________________________________
Added: svn:eol-style
+ native
Added: grass-addons/grass7/raster/r.category.trim/r.category.trim.py
===================================================================
--- grass-addons/grass7/raster/r.category.trim/r.category.trim.py (rev 0)
+++ grass-addons/grass7/raster/r.category.trim/r.category.trim.py 2015-10-28 17:41:22 UTC (rev 66645)
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+########################################################################
+#
+# MODULE: r.category.clean
+# AUTHOR(S): Paulo van Breugel
+# DESCRIPTION: Trim a cut out raster layer by removing non-existing categories
+# and their color defintions. Optionally, a new map can be
+# created to ensure consecutive categories values, but retaining
+# the category labels and colors.
+# The user can opt to export the categories, category labels and
+# color codes (RGB) as csv file or as a QGIS color map file. The
+# latter can be used in QGIS to define the colors and category
+# labels of the raster.
+#
+# COPYRIGHT: (C) 2015 Paulo van Breugel
+# http://ecodiv.org
+# http://pvanb.wordpress.com/
+#
+# This program is free software under the GNU General Public
+# License (>=v2). Read the file COPYING that comes with GRASS
+# for details.
+#
+########################################################################
+#
+#%Module
+#% description: Removing non-existing categories and their color defintions
+#% keyword: raster
+#% keyword: color
+#% keyword: category
+#% keyword: raster
+#%End
+
+#%option
+#% key: input
+#% type: string
+#% gisprompt: old,cell,raster
+#% description: input map
+#% key_desc: name
+#% required: yes
+#% multiple: no
+#% guisection: Raster
+#%end
+
+#%option
+#% key: output
+#% type: string
+#% gisprompt: new,cell,raster
+#% description: output map
+#% key_desc: name
+#% required: no
+#% multiple: no
+#% guisection: Raster
+#%end
+
+#%option G_OPT_F_OUTPUT
+#% key:csv
+#% description: Attribute table (csv format)
+#% key_desc: name
+#% required: no
+#% guisection: Export
+#%end
+
+#%option G_OPT_F_OUTPUT
+#% key:qgis
+#% description: QGIS color file (txt format)
+#% key_desc: name
+#% required: no
+#% guisection: Export
+#%end
+
+#%flag:
+#% key: n
+#% description: Recode layer to get consecutive category values
+#%end
+
+#%rules
+#% requires_all: -n, output
+#%end
+
+#----------------------------------------------------------------------------
+#Test
+#----------------------------------------------------------------------------
+#options = {"input":"test", "output":"test3", "csv":"test.csv", "qgis":"qgiscolor.txt"}
+#flags = {"n":True}
+
+#=======================================================================
+## General
+#=======================================================================
+
+# import libraries
+import os
+import sys
+from subprocess import PIPE
+from grass.pygrass.modules import Module
+import grass.script as grass
+
+# Check if running in GRASS
+if not os.environ.has_key("GISBASE"):
+ grass.message("You must be in GRASS GIS to run this program.")
+ sys.exit(1)
+
+# main function
+def main():
+
+ # Input
+ IP = options['input']
+ OP = options['output']
+ CSV = options['csv']
+ QGIS = options['qgis']
+ flags_n = flags['n']
+
+ # Check if raster is integer
+ iscell = grass.raster.raster_info(IP)["datatype"]
+ if iscell != u'CELL':
+ grass.error('Input should be an integer raster layer')
+
+ # Get category values that are actually in the map, and their category
+ # labels
+ CATV = Module('r.category', map=IP, stdout_=PIPE).outputs.stdout
+ RCAT = CATV.split('\n')
+ RCAT = filter(None,RCAT)
+ RID = [z.split('\t')[0] for z in RCAT]
+ RIDI = map(int, RID)
+
+ # Get list of all colors in the color table (i.e., this includes
+ # colors defined for categories that are not in the map
+ RCOL = grass.read_command("r.colors.out", map=IP).split('\n')
+ RCOL = [ x for x in RCOL if "nv" not in x and 'default' not in x]
+ RCOL = filter(None, RCOL)
+ CCAT = [z.split(' ')[0] for z in RCOL]
+ CCAT = map(int, CCAT)
+ CR = ""
+ CV = []
+
+ # If attribute values should be recoded to consecutive numbers
+ if flags_n:
+ RIDN = range(1, len(RID) + 1)
+ RECO = ""
+ CL = ""
+ RLAB = [z.split('\t')[1] for z in RCAT] # Category labels
+ for j in xrange(len(RID)):
+ RECO = RECO + RID[j] + ":" + RID[j] + ":" + str(RIDN[j]) + "\n"
+ A = map(int, [i for i, x in enumerate(CCAT) if x == RIDI[j]])
+ CV.append(RCOL[A[0]].split(' ')[1])
+ CR = CR + str(RIDN[j]) + " " + CV[j] + "\n"
+ CL = CL + str(RIDN[j]) + "|" + RLAB[j] + "\n"
+
+ CR = CR + 'nv 255:255:255\ndefault 255:255:255\n'
+ Module("r.recode", input=IP, output=OP, rules="-", stdin_=RECO, quiet=True)
+ Module("r.colors", map=OP, rules="-", stdin_=CR, quiet=True)
+ Module("r.category", map=OP, rules="-", stdin_=CL, quiet=True, separator="pipe")
+ else:
+ # Check if new layer should be created
+ if len(OP) > 0:
+ k = IP + "," + OP
+ grass.run_command("g.copy", raster=k)
+ else:
+ OP = IP
+
+ # Remove redundant categories
+ Module('r.category', map=OP, rules="-", stdin_=CATV, quiet=True)
+
+ # Write color rules and assign colors
+ for j in xrange(len(RIDI)):
+ A = map(int, [i for i, x in enumerate(CCAT) if x == RIDI[j]])
+ CV.append(RCOL[A[0]].split(' ')[1])
+ CR = CR + str(RIDI[j]) + " " + CV[j] + "\n"
+ CR = CR + 'nv 255:255:255\ndefault 255:255:255\n'
+ Module("r.colors", map=OP, rules="-", stdin_=CR, quiet=True)
+
+ # If attribute table (csv format) should be written
+ if len(CSV) > 0:
+ if flags_n:
+ RCAT1 = CL.split('\n'); RCAT1 = filter(None,RCAT1)
+ RCAT1 = [w.replace('|', ',') for w in RCAT1]
+ else:
+ RCAT1 = [w.replace('\t', ',') for w in RCAT]
+ RCAT1.insert(0, "CATEGORY,CATEGORY LABEL")
+ CV1 = CV; CV1.insert(0,"RGB")
+ text_file = open(CSV, "w")
+ for k in xrange(len(RCAT1)):
+ text_file.write(RCAT1[k] + "," + CV1[k] + "\n")
+ text_file.close()
+
+ # If QGIS Color Map text files should be written
+ if len(QGIS) > 0:
+ RGB = [w.replace(':', ',') for w in CV]
+ if flags_n:
+ RCAT = CL.split('\n'); RCAT = filter(None,RCAT)
+ RCAT = [w.replace('|', ',') for w in RCAT]
+ else:
+ RCAT = [w.replace('\t', ',') for w in RCAT]
+ text_file = open(QGIS, "w")
+ text_file.write("# QGIS color map for " + OP + " raster, generated by r.category.trim\n")
+ text_file.write("INTERPOLATION:EXACT\n")
+ for k in xrange(len(RCAT)):
+ RC2 = RCAT[k].split(',')
+ text_file.write(RC2[0] + "," + RGB[k] + ",255," + RC2[1] + "\n")
+ text_file.close()
+
+if __name__ == "__main__":
+ options, flags = grass.parser()
+ sys.exit(main())
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Property changes on: grass-addons/grass7/raster/r.category.trim/r.category.trim.py
___________________________________________________________________
Added: svn:executable
+ *
Added: svn:eol-style
+ native
More information about the grass-commit
mailing list