[GRASS-SVN] r62281 - in grass/trunk: general/g.list gui/wxpython/core gui/wxpython/lmgr gui/wxpython/mapdisp lib/python/script scripts scripts/d.to.rast vector/v.what

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Oct 17 13:42:22 PDT 2014


Author: annakrat
Date: 2014-10-17 13:42:22 -0700 (Fri, 17 Oct 2014)
New Revision: 62281

Added:
   grass/trunk/scripts/d.to.rast/
   grass/trunk/scripts/d.to.rast/Makefile
   grass/trunk/scripts/d.to.rast/d.to.rast.html
   grass/trunk/scripts/d.to.rast/d.to.rast.py
   grass/trunk/scripts/d.to.rast/d_to_rast_3D_example.jpg
Modified:
   grass/trunk/general/g.list/main.c
   grass/trunk/gui/wxpython/core/utils.py
   grass/trunk/gui/wxpython/lmgr/frame.py
   grass/trunk/gui/wxpython/mapdisp/frame.py
   grass/trunk/gui/wxpython/mapdisp/main.py
   grass/trunk/lib/python/script/vector.py
   grass/trunk/scripts/Makefile
   grass/trunk/vector/v.what/main.c
   grass/trunk/vector/v.what/what.c
   grass/trunk/vector/v.what/what.h
Log:
d.to.rast: new module for wxGUI and d.mon to save map display content as raster map

Modified: grass/trunk/general/g.list/main.c
===================================================================
--- grass/trunk/general/g.list/main.c	2014-10-17 15:56:35 UTC (rev 62280)
+++ grass/trunk/general/g.list/main.c	2014-10-17 20:42:22 UTC (rev 62281)
@@ -93,7 +93,7 @@
     opt.pattern->type = TYPE_STRING;
     opt.pattern->required = NO;
     opt.pattern->multiple = NO;
-    opt.pattern->gisprompt = "new,element,element";
+    opt.pattern->gisprompt = "old,element,element";
     opt.pattern->description = _("Map name search pattern (default: all)");
     opt.pattern->guisection = _("Pattern");
 

Modified: grass/trunk/gui/wxpython/core/utils.py
===================================================================
--- grass/trunk/gui/wxpython/core/utils.py	2014-10-17 15:56:35 UTC (rev 62280)
+++ grass/trunk/gui/wxpython/core/utils.py	2014-10-17 20:42:22 UTC (rev 62281)
@@ -1013,6 +1013,7 @@
                  'd.colortable'   : 'colortable',
                  'd.graph'        : 'graph',
                  'd.out.file'     : 'export',
+                 'd.to.rast'      : 'torast',
                  'd.text'         : 'text'
                  }
 ltype2command = {}

Modified: grass/trunk/gui/wxpython/lmgr/frame.py
===================================================================
--- grass/trunk/gui/wxpython/lmgr/frame.py	2014-10-17 15:56:35 UTC (rev 62280)
+++ grass/trunk/gui/wxpython/lmgr/frame.py	2014-10-17 20:42:22 UTC (rev 62281)
@@ -670,6 +670,16 @@
             GUI(parent=self, show=False).ParseCommand(command,
                                                       completed=(self.GetMapDisplay().DOutFileOptData,
                                                                  '', ''))
+        elif layertype == 'torast':
+            if len(command) <= 1:
+                task = GUI(parent=self, show=True).ParseCommand(command,
+                                                                completed=(self.GetMapDisplay().DToRastOptData,
+                                                                '', ''))
+            else:
+                task = GUI(parent=self, show=None).ParseCommand(command,
+                                                                completed=(self.GetMapDisplay().DToRastOptData,
+                                                                '', ''))
+                self.GetMapDisplay().DToRast(command=task.get_cmd())
         else:
             # add layer into layer tree
             lname, found = GetLayerNameFromCmd(command, fullyQualified = True,

Modified: grass/trunk/gui/wxpython/mapdisp/frame.py
===================================================================
--- grass/trunk/gui/wxpython/mapdisp/frame.py	2014-10-17 15:56:35 UTC (rev 62280)
+++ grass/trunk/gui/wxpython/mapdisp/frame.py	2014-10-17 20:42:22 UTC (rev 62281)
@@ -34,7 +34,7 @@
 from vdigit.toolbars    import VDigitToolbar
 from mapdisp.toolbars   import MapToolbar, NvizIcons
 from mapdisp.gprint     import PrintOptions
-from core.gcmd          import GError, GMessage
+from core.gcmd          import GError, GMessage, RunCommand
 from dbmgr.dialogs      import DisplayAttributesDialog
 from core.utils         import ListOfCatsToRange, GetLayerNameFromCmd, _
 from gui_core.dialogs import GetImageHandlers, ImageSizeDialog
@@ -648,6 +648,76 @@
 
         self.DOutFile(dcmd)
 
+    def DToRast(self, command):
+        """Saves currently loaded composition of layers as a raster map.
+        """
+        if self.IsPaneShown('3d'):
+            self._giface.WriteError(_('d.to.rast can be used only in 2D mode.'))
+            return
+        outputRaster = None
+        overwrite = False
+        for param in command[1:]:
+            try:
+                p, val = param.split('=')
+                if p == 'output':
+                    outputRaster = val
+            except ValueError:
+                if param.startswith('--overwrite'):
+                    overwrite = True
+
+        if not outputRaster:
+            return
+        # output file as PNG
+        tmpName = 'd_to_rast_tmp'
+        pngFile = grass.tempfile(create=False) + '.png'
+        dOutFileCmd = ['d.out.file', 'output=' + pngFile, 'format=png']
+        self.DOutFile(dOutFileCmd)
+        # import back as red, green, blue rasters
+        returncode, messages = RunCommand('r.in.png', input=pngFile, output=tmpName,
+                                          quiet=True, overwrite=overwrite, getErrorMsg=True)
+        if not returncode == 0:
+            self._giface.WriteError(_('Failed to run d.to.rast:\n') + messages)
+            return
+        # set region for composite
+        grass.use_temp_region()
+        returncode, messages = RunCommand('g.region', rast=tmpName + '.r',
+                                          quiet=True, getErrorMsg=True)
+        if not returncode == 0:
+            grass.del_temp_region()
+            self._giface.WriteError(_('Failed to run d.to.rast:\n') + messages)
+            return
+        # composite
+        returncode, messages = RunCommand('r.composite', red=tmpName + '.r',
+                                          green=tmpName + '.g', blue=tmpName + '.b',
+                                          output=outputRaster, quiet=True,
+                                          overwrite=overwrite, getErrorMsg=True)
+        grass.del_temp_region()
+        RunCommand('g.remove', type='rast', flags='f', quiet=True,
+                   names=[tmpName + '.r', tmpName + '.g', tmpName + '.b'])
+        if not returncode == 0:
+            self._giface.WriteError(_('Failed to run d.to.rast:\n') + messages)
+            grass.try_remove(pngFile)
+            return
+
+        # alignExtent changes only region variable
+        oldRegion = self.GetMap().GetCurrentRegion().copy()
+        self.GetMap().AlignExtentFromDisplay()
+        region = self.GetMap().GetCurrentRegion().copy()
+        self.GetMap().region.update(oldRegion)
+        RunCommand('r.region', map=outputRaster, n=region['n'], s=region['s'],
+                   e=region['e'], w=region['w'], quiet=True)
+
+        grass.try_remove(pngFile)
+
+    def DToRastOptData(self, dcmd, layer, params, propwin):
+        """Dummy function which is called when d.to.rast is called
+        and returns parsed and validated command which is then passed
+        to DToRast method."""
+        if not dcmd:
+            return
+
+        self.DToRast(dcmd)
+
     def _prepareSaveToFile(self):
         """Get wildcards and format extensions."""
         if self.IsPaneShown('3d'):

Modified: grass/trunk/gui/wxpython/mapdisp/main.py
===================================================================
--- grass/trunk/gui/wxpython/mapdisp/main.py	2014-10-17 15:56:35 UTC (rev 62280)
+++ grass/trunk/gui/wxpython/mapdisp/main.py	2014-10-17 20:42:22 UTC (rev 62281)
@@ -80,8 +80,9 @@
 
         # generated file for g.pnmcomp output for rendering the map
         self.mapfile = monFile['map'] + '.ppm'
-        # signal sent when d.out.file appears in cmd file, attribute is cmd
+        # signal sent when d.out.file/d.to.rast appears in cmd file, attribute is cmd
         self.saveToFile = Signal('DMonMap.saveToFile')
+        self.dToRast = Signal('DMonMap.dToRast')
         # signal sent when d.what.rast/vect appears in cmd file, attribute is cmd
         self.query = Signal('DMonMap.query')
 
@@ -99,12 +100,15 @@
             fd.close()
             # detect d.out.file, delete the line from the cmd file and export graphics
             if len(lines) > 0:
-                if lines[-1].startswith('d.out.file'):
-                    dOutFileCmd = lines[-1].strip()
+                if lines[-1].startswith('d.out.file') or lines[-1].startswith('d.to.rast'):
+                    dCmd = lines[-1].strip()
                     fd = open(self.cmdfile, 'w')
                     fd.writelines(lines[:-1])
                     fd.close()
-                    self.saveToFile.emit(cmd=utils.split(dOutFileCmd))
+                    if lines[-1].startswith('d.out.file'):
+                        self.saveToFile.emit(cmd=utils.split(dCmd))
+                    else:
+                        self.dToRast.emit(cmd=utils.split(dCmd))
                     return
                 if lines[-1].startswith('d.what'):
                     dWhatCmd = lines[-1].strip()
@@ -360,6 +364,7 @@
         # self.SetTopWindow(Map)
         self.mapFrm.GetMapWindow().SetAlwaysRenderEnabled(True)
         self.Map.saveToFile.connect(lambda cmd: self.mapFrm.DOutFile(cmd))
+        self.Map.dToRast.connect(lambda cmd: self.mapFrm.DToRast(cmd))
         self.Map.query.connect(lambda ltype, maps: self.mapFrm.SetQueryLayersAndActivate(ltype=ltype, maps=maps))
         self.mapFrm.Show()
         

Modified: grass/trunk/lib/python/script/vector.py
===================================================================
--- grass/trunk/lib/python/script/vector.py	2014-10-17 15:56:35 UTC (rev 62280)
+++ grass/trunk/lib/python/script/vector.py	2014-10-17 20:42:22 UTC (rev 62281)
@@ -258,7 +258,11 @@
     return {'columns': columns, 'values': values}
 
 
-def vector_what(map, coord, distance=0.0, ttype=None):
+json = None
+orderedDict = None
+
+
+def vector_what(map, coord, distance=0.0, ttype=None, encoding=None):
     """Query vector map at given locations
 
     To query one vector map at one location
@@ -336,7 +340,7 @@
             coord_list.append('%f,%f' % (e, n))
 
     cmdParams = dict(quiet      = True,
-                     flags      = 'ag',
+                     flags      = 'aj',
                      map        = ','.join(map_list),
                      layer      = ','.join(layer_list),
                      coordinates = ','.join(coord_list),
@@ -345,7 +349,7 @@
         cmdParams['type'] = ','.join(ttype)
 
     ret = read_command('v.what',
-                       **cmdParams)
+                       **cmdParams).strip()
 
     if "LC_ALL" in os.environ:
         os.environ["LC_ALL"] = locale
@@ -354,62 +358,31 @@
     if not ret:
         return data
 
-    # parse `v.what -g` output is a nightmare
-    # TODO: change `v.what -g` format or add parsable format (e.g. XML)
-    dict_attrb = None
-    dict_map = None
-    dict_layer = None
-    attr_pseudo_key = 'Attributes'
-    for item in ret.splitlines():
+    # lazy import
+    global json
+    global orderedDict
+    if json is None:
+        import json
+    if orderedDict is None:
         try:
-            key, value = __builtin__.map(lambda x: x.strip(), item.split('=', 1))
-        except ValueError:
-            continue
-        if key in ('East', 'North'):
-            continue
+            from collections import OrderedDict
+            orderedDict = OrderedDict
+        except ImportError:
+            orderedDict = dict
 
-        if key == 'Map':
-            # attach the last one from the previous map
-            if dict_map is not None:
-                dict_main = copy.copy(dict_map)
-                if dict_layer is not None:
-                    dict_main.update(dict_layer)
-                data.append(dict_main)
-            dict_map = {key : value}
-            dict_layer = None
-            dict_attrb = None
-        elif key == 'Layer':
-            if not dict_attrb:
-                # attach the last the previous Layer
-                if dict_layer is not None:
-                    dict_main = copy.copy(dict_map)
-                    dict_main.update(dict_layer)
-                    data.append(dict_main)
-                dict_layer = {key: int(value)}
-                dict_attrb = None
-            else:
-                dict_attrb[key] = value
-        elif key == 'Key_column':
-            dict_layer[key] = value
-            dict_attrb = dict()
-            dict_layer[attr_pseudo_key] = dict_attrb
-        elif dict_attrb is not None:
-            dict_attrb[key] = value
-        elif dict_layer is not None:
-            if key == 'Category':
-                dict_layer[key] = int(value)
-            else:
-                dict_layer[key] = value
+    if encoding:
+        result = json.loads(ret, object_pairs_hook=orderedDict, encoding=encoding)
+    else:
+        result = json.loads(ret, object_pairs_hook=orderedDict)
+    del result['Coordinates']
+    for vmap in result['Maps']:
+        cats = vmap.pop('Categories', None)
+        if cats:
+            for cat in cats:
+                tmp = vmap.copy()
+                tmp.update(cat)
+                data.append(tmp)
         else:
-            dict_map[key] = value
-            # TODO: there are some keys which has non-string values
-            # examples: Sq_Meters, Hectares, Acres, Sq_Miles
+            data.append(vmap)
 
-    # attach the last one
-    if dict_map is not None:
-        dict_main = copy.copy(dict_map)
-        if dict_layer:
-            dict_main.update(dict_layer)
-        data.append(dict_main)
-
     return data

Modified: grass/trunk/scripts/Makefile
===================================================================
--- grass/trunk/scripts/Makefile	2014-10-17 15:56:35 UTC (rev 62280)
+++ grass/trunk/scripts/Makefile	2014-10-17 20:42:22 UTC (rev 62281)
@@ -3,6 +3,7 @@
 SUBDIRS = \
 	d.correlate \
 	d.out.file \
+	d.to.rast \
 	d.polar \
 	d.rast.edit \
 	d.rast.leg \

Added: grass/trunk/scripts/d.to.rast/Makefile
===================================================================
--- grass/trunk/scripts/d.to.rast/Makefile	                        (rev 0)
+++ grass/trunk/scripts/d.to.rast/Makefile	2014-10-17 20:42:22 UTC (rev 62281)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = d.to.rast
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script


Property changes on: grass/trunk/scripts/d.to.rast/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass/trunk/scripts/d.to.rast/d.to.rast.html
===================================================================
--- grass/trunk/scripts/d.to.rast/d.to.rast.html	                        (rev 0)
+++ grass/trunk/scripts/d.to.rast/d.to.rast.html	2014-10-17 20:42:22 UTC (rev 62281)
@@ -0,0 +1,51 @@
+<h2>DESCRIPTION</h2>
+
+<em>d.to.rast</em> saves the content of the currently selected
+monitor into a raster map. The active monitor can be selected
+with <em>d.mon</em>. <em>d.to.rast</em> can be run from GUI
+command console, too. This module is not sensitive to computational region settings.
+
+<h2>EXAMPLE</h2>
+We combine different raster and vector map layers to create a composite layer
+which can be draped over elevation in 3D view.
+First, we add a couple of maps to layer manager:
+
+<div class="code"><pre>
+g.region rast=elevation
+d.rast map=elevation
+d.rast map=lakes
+d.vect map=roadsmajor width=4
+d.vect map=roadsmajor width=2 color=yellow
+
+# create a raster map from the display
+d.to.rast output=composite
+</pre></div>
+
+<p>
+Then uncheck all layers except for elevation and switch to 3D view.
+In Data tab, set color map to the newly created composite map.
+
+<p>
+<center>
+<img src="d_to_rast_3D_example.jpg">
+<p>
+Figure: Raster map created by <em>d.to.rast</em> draped over digital elevation model.
+</center>
+
+
+
+<h2>SEE ALSO</h2>
+ 
+<em>
+  <a href="d.out.file.html">d.out.file</a>,
+  <a href="d.erase.html">d.erase</a>,
+  <a href="d.rast.html">d.rast</a>,
+  <a href="d.vect.html">d.vect</a>,
+  <a href="d.mon.html">d.mon</a>
+</em>
+
+<h2>AUTHOR</h2>
+
+Anna Petrasova, <a href="http://gis.ncsu.edu/osgeorel/">NCSU OSGeoREL</a>
+
+<p><i>Last changed: $Date$</i>


Property changes on: grass/trunk/scripts/d.to.rast/d.to.rast.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass/trunk/scripts/d.to.rast/d.to.rast.py
===================================================================
--- grass/trunk/scripts/d.to.rast/d.to.rast.py	                        (rev 0)
+++ grass/trunk/scripts/d.to.rast/d.to.rast.py	2014-10-17 20:42:22 UTC (rev 62281)
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+############################################################################
+#
+# MODULE: d.to.rast
+# AUTHOR(S): Anna Petrasova <kratochanna gmail.com>
+# PURPOSE:	Script for exporting content of monitor to raster map
+# COPYRIGHT: (C) 2014 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.
+#
+#############################################################################
+
+#%module
+#% description: Saves the contents of the active display monitor to a raster map.
+#% keywords: display
+#% keywords: export
+#% keywords: raster
+#%end
+#%option G_OPT_R_OUTPUT
+#%end
+
+
+from grass.script import core as gcore
+
+
+def main():
+    options, flags = gcore.parser()
+    print options, flags
+    gisenv = gcore.gisenv()
+    if 'MONITOR' in gisenv:
+        cmd_file = gisenv['MONITOR_{monitor}_CMDFILE'.format(monitor=gisenv['MONITOR'].upper())]
+        d_cmd = 'd.to.rast'
+        for param, val in options.iteritems():
+            if val:
+                d_cmd += " {param}={val}".format(param=param, val=val)
+        if gcore.overwrite():
+            d_cmd += ' --overwrite'
+        with open(cmd_file, "a") as file_:
+            file_.write(d_cmd)
+    else:
+        gcore.fatal(_("No graphics device selected. Use d.mon to select graphics device."))
+
+
+if __name__ == "__main__":
+    main()


Property changes on: grass/trunk/scripts/d.to.rast/d.to.rast.py
___________________________________________________________________
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Added: grass/trunk/scripts/d.to.rast/d_to_rast_3D_example.jpg
===================================================================
(Binary files differ)


Property changes on: grass/trunk/scripts/d.to.rast/d_to_rast_3D_example.jpg
___________________________________________________________________
Added: svn:mime-type
   + image/jpeg

Modified: grass/trunk/vector/v.what/main.c
===================================================================
--- grass/trunk/vector/v.what/main.c	2014-10-17 15:56:35 UTC (rev 62280)
+++ grass/trunk/vector/v.what/main.c	2014-10-17 20:42:22 UTC (rev 62281)
@@ -33,7 +33,7 @@
 int main(int argc, char **argv)
 {
     struct {
-	struct Flag *print, *topo, *shell;
+	struct Flag *print, *topo, *shell, *json;
     } flag;
     struct {
 	struct Option *map, *field, *coords, *maxdist, *type;
@@ -97,6 +97,11 @@
     flag.shell->key = 'g';
     flag.shell->description = _("Print the stats in shell script style");
     flag.shell->guisection = _("Print");
+    
+    flag.json = G_define_flag();
+    flag.json->key = 'j';
+    flag.json->description = _("Print the stats in JSON");
+    flag.json->guisection = _("Print");
 
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
@@ -112,6 +117,9 @@
     else
 	G_fatal_error(_("No input vector maps!"));
 
+    if (flag.shell->answer && flag.json->answer)
+        G_fatal_error(_("Flags g and j are mutually exclusive"));
+
     maxd = atof(opt.maxdist->answer);
     type = Vect_option_to_types(opt.type);
 
@@ -178,7 +186,7 @@
 	    ret = sscanf(buf, "%lf%c%lf", &xval, &ch, &yval);
 	    if (ret == 3 && (ch == ',' || ch == ' ' || ch == '\t')) {
 		what(Map, nvects, vect, xval, yval, maxd, type, flag.topo->answer,
-		     flag.print->answer, flag.shell->answer, field);
+		     flag.print->answer, flag.shell->answer, flag.json->answer, field);
 	    }
 	    else {
 		G_warning(_("Unknown input format, skipping: '%s'"), buf);
@@ -192,7 +200,7 @@
 	    xval = atof(opt.coords->answers[i]);
 	    yval = atof(opt.coords->answers[i + 1]);
 	    what(Map, nvects, vect, xval, yval, maxd, type, flag.topo->answer,
-		 flag.print->answer, flag.shell->answer, field);
+		 flag.print->answer, flag.shell->answer, flag.json->answer, field);
 	}
     }
 

Modified: grass/trunk/vector/v.what/what.c
===================================================================
--- grass/trunk/vector/v.what/what.c	2014-10-17 15:56:35 UTC (rev 62280)
+++ grass/trunk/vector/v.what/what.c	2014-10-17 20:42:22 UTC (rev 62281)
@@ -17,7 +17,7 @@
 
 static void F_generate(const char *drvname, const char *dbname,
 		       const char *tblname, const char *key, int keyval,
-		       char **form)
+		       int script, int json, char **form)
 {
     int col, ncols, sqltype, more;
     char buf[5000];
@@ -87,8 +87,14 @@
 	    colname = db_get_column_name(column);
 
 	    G_debug(2, "%s: %s", colname, db_get_string(&str));
-
-	    sprintf(buf, "%s : %s\n", colname, db_get_string(&str));
+	    if (json) {
+		sprintf(buf, "%s\"%s\": \"%s\"", col == 0 ? "" : ",\n",
+			colname, db_get_string(&str));
+	    }
+	    else if (script)
+		sprintf(buf, "%s=%s\n", colname, db_get_string(&str));
+	    else
+		sprintf(buf, "%s : %s\n", colname, db_get_string(&str));
 	    db_append_string(&html, buf);
 	}
     }
@@ -106,7 +112,7 @@
 }
 
 void what(struct Map_info *Map, int nvects, char **vect, double east, double north,
-          double maxdist, int qtype, int topo, int showextra, int script, int *field)
+          double maxdist, int qtype, int topo, int showextra, int script, int json, int *field)
 {
     int type;
     char east_buf[40], north_buf[40];
@@ -173,6 +179,9 @@
 		    fprintf(stdout, "East=%s\nNorth=%s\n", east_buf,
 			    north_buf);
 		}
+		else if (json){
+		    fprintf(stdout, "{\"Coordinates\": {\"East\": %s, \"North\": %s}", east_buf,
+			    north_buf);}
 		else {
 		    fprintf(stdout, "East: %s\nNorth: %s\n", east_buf,
 			    north_buf);
@@ -189,6 +198,14 @@
 	    fprintf(stdout, "\nMap=%s\nMapset=%s\n", Map[i].name,
 		    Map[i].mapset);
 	}
+	else if (json) {
+	    if (!i)
+		fprintf(stdout, ",\n\"Maps\":\n[{\"Map\": \"%s\",\n\"Mapset\": \"%s\"",
+			Map[i].name, Map[i].mapset);
+	    else
+		fprintf(stdout, ",\n{\"Map\": \"%s\",\n\"Mapset\": \"%s\"",
+			Map[i].name, Map[i].mapset);
+	}
 	else {
 	    fprintf(stdout, "%s", SEP);
 	    fprintf(stdout, "\nMap: %s \nMapset: %s\n", Map[i].name,
@@ -252,6 +269,12 @@
 			    "Id=%d\nType=%s\nLeft=%d\nRight=%d\n",
 			    line, buf, left, right);
 		}
+		else if (json) {
+		    fprintf(stdout, ",\n\"Feature_max_distance\": %f", maxdist);
+		    fprintf(stdout,
+			    ",\n\"Id\": %d,\n\"Type\": \"%s\",\n\"Left\": %d,\n\"Right\": %d",
+			    line, buf, left, right);
+		}
 		else {
 		    fprintf(stdout, "Looking for features within: %f\n",
 			    maxdist);
@@ -283,6 +306,11 @@
 				_("Node[%d]=%d\nNumber_lines=%d\nCoordinates=%.6f,%.6f,%.6f\n"),
 				n, node[n], nnlines, nx, ny, nz);
 		    }
+		    else if (json) {
+			fprintf(stdout,
+				_(",\n\"Node[%d]\": %d,\n\"Number_lines\": %d,\n\"Coordinates\": %.6f,%.6f,%.6f"),
+				n, node[n], nnlines, nx, ny, nz);
+		    }
 		    else {
 			fprintf(stdout,
 				_("Node[%d]: %d\nNumber of lines: %d\nCoordinates: %.6f, %.6f, %.6f\n"),
@@ -298,6 +326,10 @@
 			    fprintf(stdout, "Id=%5d\nAngle=%.8f\n",
 				    nodeline, angle);
 			}
+			else if (json) {
+			    fprintf(stdout, ",\n\"Id\": %5d,\n\"Angle\": %.8f",
+				    nodeline, angle);
+			}
 			else {
 			    fprintf(stdout, _("Id: %5d\nAngle: %.8f\n"),
 				    nodeline, angle);
@@ -313,6 +345,12 @@
 		    if (type & GV_LINES)
 			fprintf(stdout, "Length=%f\n", l);
 		}
+		else if (json) {
+		    fprintf(stdout, ",\n\"Type\": \"%s\"", buf);
+		    fprintf(stdout, ",\n\"Id\": %d", line);
+		    if (type & GV_LINES)
+			fprintf(stdout, ",\n\"Length\": %f", l);
+		}
 		else {
 		    fprintf(stdout, _("Type: %s\n"), buf);
 		    fprintf(stdout, _("Id: %d\n"), line);
@@ -330,6 +368,9 @@
 		    if (script) {
 			fprintf(stdout, "Point_height=%f\n", Points->z[0]);
 		    }
+		    else if (json) {
+			fprintf(stdout, ",\n\"Point_height\": %f", Points->z[0]);
+		    }
 		    else {
 			fprintf(stdout, _("Point height: %f\n"),
 				Points->z[0]);
@@ -347,6 +388,9 @@
 			if (script) {
 			    fprintf(stdout, "Line_height=%f\n", min);
 			}
+			else if (json) {
+			    fprintf(stdout, ",\n\"Line_height\": %f", min);
+			}
 			else {
 			    fprintf(stdout, _("Line height: %f\n"), min);
 			}
@@ -357,6 +401,11 @@
 				    "Line_height_min=%f\nLine_height_max=%f\n",
 				    min, max);
 			}
+			else if (json) {
+			    fprintf(stdout,
+				    ",\n\"Line_height_min\": %f,\n\"Line_height_max\": %f",
+				    min, max);
+			}
 			else {
 			    fprintf(stdout,
 				    _("Line height min: %f\nLine height max: %f\n"),
@@ -372,6 +421,9 @@
 		if (script) {
 		    fprintf(stdout, "Type=Area\nArea_height=%f\n", z);
 		}
+		else if (json) {
+		    fprintf(stdout, ",\n\"Type\": \"Area\",\n\"Area_height\": %f", z);
+		}
 		else {
 		fprintf(stdout, _("Type: Area\nArea height: %f\n"), z);
 		}
@@ -380,6 +432,9 @@
 		if (script) {
 		    fprintf(stdout, "Type=Area\n");
 		}
+		else if (json) {
+		    fprintf(stdout, ",\n\"Type\": \"Area\"");
+		}
 		else {
 		    fprintf(stdout, _("Type: Area\n"));
 		}
@@ -402,6 +457,10 @@
 		    fprintf(stdout, "Area=%d\nNumber_isles=%d\n", area,
 			    nisles);
 		}
+		else if (json) {
+		    fprintf(stdout, ",\n\"Area\": %d,\n\"Number_isles\": %d", area,
+			    nisles);
+		}
 		else {
 		    fprintf(stdout, _("Area: %d\nNumber of isles: %d\n"),
 			    area, nisles);
@@ -412,6 +471,9 @@
 		    if (script) {
 			fprintf(stdout, "Isle[%d]=%d\n", isleidx, isle);
 		    }
+		    else if (json) {
+			fprintf(stdout, ",\n\"Isle[%d]\": %d", isleidx, isle);
+		    }
 		    else {
 			fprintf(stdout, _("Isle[%d]: %d\n"), isleidx, isle);
 		    }
@@ -425,6 +487,10 @@
 			fprintf(stdout, "Island=%d\nIsland_area=%d\n", isle,
 				isle_area);
 		    }
+		    else if (json) {
+			fprintf(stdout, ",\n\"Island\": %d,\n\"Island_area\": %d", isle,
+				isle_area);
+		    }
 		    else {
 			fprintf(stdout, _("Island: %d In area: %d\n"), isle,
 				isle_area);
@@ -438,6 +504,12 @@
 		    fprintf(stdout, "Acres=%.3f\nSq_Miles=%.4f\n",
 			    acres, sq_miles);
 		}
+		else if (json) {
+		    fprintf(stdout, ",\n\"Sq_Meters\": %.3f,\n\"Hectares\": %.3f",
+			    sq_meters, hectares);
+		    fprintf(stdout, ",\n\"Acres\": %.3f,\n\"Sq_Miles\": %.4f",
+			    acres, sq_miles);
+		}
 		else {
 		    fprintf(stdout, _("Sq Meters: %.3f\nHectares: %.3f\n"),
 			    sq_meters, hectares);
@@ -454,8 +526,10 @@
 
 	if (Cats->n_cats > 0) {
 	    int j;
-	    char *formbuf1, *formbuf2;
-
+	    char *formbuf1;
+	    if (json) {
+		fprintf(stdout, ",\n\"Categories\": [");
+	    }
 	    for (j = 0; j < Cats->n_cats; j++) {
 		G_debug(2, "field = %d  category = %d\n", Cats->field[j],
 			Cats->cat[j]);
@@ -463,6 +537,10 @@
 		    fprintf(stdout, "Layer=%d\nCategory=%d\n", Cats->field[j],
 			    Cats->cat[j]);
 		}
+		else if (json) {
+		    fprintf(stdout, "%s\n{\"Layer\": %d, \"Category\": %d", j == 0 ? "": ",", 
+			    Cats->field[j], Cats->cat[j]);
+		}
 		else {
 		    fprintf(stdout, _("Layer: %d\nCategory: %d\n"),
 			    Cats->field[j], Cats->cat[j]);
@@ -474,29 +552,46 @@
 				"Driver=%s\nDatabase=%s\nTable=%s\nKey_column=%s\n",
 				Fi->driver, Fi->database, Fi->table, Fi->key);
 		    }
+		    else if (json) {
+			fprintf(stdout,
+				",\n\"Driver\": \"%s\",\n\"Database\": \"%s\",\n\"Table\": \"%s\",\n\"Key_column\": \"%s\"",
+				Fi->driver, Fi->database, Fi->table, Fi->key);
+		    }
 		    else {
 			fprintf(stdout,
 				_("\nDriver: %s\nDatabase: %s\nTable: %s\nKey column: %s\n"),
 				Fi->driver, Fi->database, Fi->table, Fi->key);
 		    }
 		    F_generate(Fi->driver, Fi->database, Fi->table,
-			       Fi->key, Cats->cat[j], &form);
+			       Fi->key, Cats->cat[j], script, json, &form);
 
 		    if (script) {
-			formbuf1 = G_str_replace(form, " : ", "=");
-			formbuf2 = G_str_replace(formbuf1, " ", "_");
-			fprintf(stdout, "%s", formbuf2);
+			formbuf1 = G_str_replace(form, " ", "_");
+			fprintf(stdout, "%s", formbuf1);
 			G_free(formbuf1);
-			G_free(formbuf2);
 		    }
+		    else if (json)
+			fprintf(stdout, ",\n\"Attributes\": {%s}", form);
 		    else
 			fprintf(stdout, "%s", form);
 		    G_free(form);
 		    G_free(Fi);
 		}
+		if (json) {
+		    fprintf(stdout, "}");
+		}
 	    }
+	    if (json) {
+		fprintf(stdout, "]");
+	    }
 	}
+	if (json) {
+	    fprintf(stdout, "}");
+	}
     }				/* for nvects */
+    if (json) {
+        fprintf(stdout, "]}\n");
+    }
 
     fflush(stdout);
 }

Modified: grass/trunk/vector/v.what/what.h
===================================================================
--- grass/trunk/vector/v.what/what.h	2014-10-17 15:56:35 UTC (rev 62280)
+++ grass/trunk/vector/v.what/what.h	2014-10-17 20:42:22 UTC (rev 62281)
@@ -1,3 +1,3 @@
 /* what.c */
 void what(struct Map_info *, int, char **,
-	  double, double, double, int, int, int, int, int *);
+	  double, double, double, int, int, int, int, int, int *);



More information about the grass-commit mailing list