[GRASS-SVN] r72819 - grass-addons/grass7/raster/r.lfp

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Jun 13 22:12:15 PDT 2018


Author: hcho
Date: 2018-06-13 22:12:14 -0700 (Wed, 13 Jun 2018)
New Revision: 72819

Modified:
   grass-addons/grass7/raster/r.lfp/r.lfp.html
   grass-addons/grass7/raster/r.lfp/r.lfp.py
Log:
r.lfp: Add parameters to assign unique IDs to longest flow paths

Modified: grass-addons/grass7/raster/r.lfp/r.lfp.html
===================================================================
--- grass-addons/grass7/raster/r.lfp/r.lfp.html	2018-06-14 03:19:32 UTC (rev 72818)
+++ grass-addons/grass7/raster/r.lfp/r.lfp.html	2018-06-14 05:12:14 UTC (rev 72819)
@@ -1,17 +1,26 @@
 <h2>DESCRIPTION</h2>
-<em>r.lfp</em> calculates the longest flow path for a given outlet point and
-creates a new vector map with the longest flow path.
+<em>r.lfp</em> calculates the longest flow paths for given outlet points and
+creates a new vector map with those lines.
 This module requires the <em>r.stream.distance</em> addon.
 
 <h2>NOTES</h2>
 
 <em>r.lfp</em> creates a longest flow path vector map using a drainage
-direction raster map and the coordinates of an outlet point. The module
-internally runs <em>r.stream.distance</em> twice to calculate flow length
-downstream and upstream raster maps, and combines them to get the longest flow
-path. An input drainage map can be created using <em>r.watershed</em> or
-<em>r.stream.extract</em>.
+direction raster map and the coordinates of outlet points. The module
+internally runs <em>r.stream.distance</em> to calculate a flow length
+downstream raster map and <em>r.path</em> to trace the longest flow path from
+headwater cells. An input drainage map can be created using
+<em>r.watershed</em> or <em>r.stream.extract</em>.
 
+<p><em>r.lfp</em> can read outlet coordinates from the <b>coordinates</b>
+and/or <b>outlet</b> parameters. For multiple outlets, the user can assign a
+unique ID to each longest flow path per outlet point using <b>id</b>,
+<b>id_column</b>, and <b>outlet_id_column</b> parameters. The <b>id</b>
+parameter specifies unique IDs for all outlets given in the <b>coordinates</b>
+parameter in the same order. The <b>outlet_id_column</b> specifies a column in
+the <b>outlet</b> map that contains unique IDs to be copied over to the
+<b>id_column</b> column in the <b>output</b> map.
+
 <h2>EXAMPLES</h2>
 
 <h3>North Carolina sample dataset example</h3>
@@ -32,6 +41,28 @@
 
 <img src="r_lfp_nc_example.png">
 
+<h3>Multiple outlets</h3>
+
+<div class="code"><pre>
+# calculate longest flow paths at two outlets
+r.lfp input=drain_directions output=lfp coordinates=642455,222614,642306,222734
+
+# calculate longest flow paths at two outlets and assign IDs
+r.lfp input=drain_directions output=lfp coordinates=642455,222614,642306,222734 \
+    id=1,2 id_column=lfp_id 
+
+# calculate longest flow paths at all points in the outlets map
+r.lfp input=drain_directions output=lfp outlet=outlets
+
+# calculate longest flow paths at all points in the outlets map and assign IDs using a column in this map
+r.lfp input=drain_directions output=lfp outlet=outlets \
+    id_column=lfp_id outlet_id_column=outlet_id
+
+# calculate longest flow paths at given coordinates and all points in the outlets map and assign IDs
+r.lfp input=drain_directions output=lfp coordinates=642455,222614,642306,222734 outlet=outlets \
+    id=1,2 id_column=lfp_id outlet_id_column=outlet_id
+</pre></div>
+
 <h2>SEE ALSO</h2>
 
 <em>

Modified: grass-addons/grass7/raster/r.lfp/r.lfp.py
===================================================================
--- grass-addons/grass7/raster/r.lfp/r.lfp.py	2018-06-14 03:19:32 UTC (rev 72818)
+++ grass-addons/grass7/raster/r.lfp/r.lfp.py	2018-06-14 05:12:14 UTC (rev 72819)
@@ -3,7 +3,7 @@
 #
 # MODULE:       r.lfp
 # AUTHOR(S):    Huidae Cho
-# PURPOSE:      Calculates the longest flow path for a given outlet point.
+# PURPOSE:      Calculates the longest flow paths for given outlet points.
 #
 # COPYRIGHT:    (C) 2014, 2017, 2018 by the GRASS Development Team
 #
@@ -14,7 +14,7 @@
 #############################################################################
 
 #%module
-#% description: Calculates the longest flow path for a given outlet point using the r.stream.distance addon.
+#% description: Calculates the longest flow paths for given outlet points using the r.stream.distance addon.
 #% keyword: hydrology
 #% keyword: watershed
 #%end
@@ -24,6 +24,16 @@
 #%option G_OPT_V_OUTPUT
 #% description: Name for output longest flow path vector map
 #%end
+#%option G_OPT_DB_COLUMN
+#% key: id_column
+#% description: Name for output longest flow path ID column
+#%end
+#%option
+#% key: id
+#% type: integer
+#% description: ID for longest flow path
+#% multiple: yes
+#%end
 #%option G_OPT_M_COORDS
 #% description: Coordinates of outlet point
 #% multiple: yes
@@ -33,8 +43,15 @@
 #% label: Name of outlet vector map
 #% required: no
 #%end
+#%option G_OPT_DB_COLUMN
+#% key: outlet_id_column
+#% description: Name of longest flow path ID column in outlet map
+#%end
 #%rules
 #% required: coordinates, outlet
+#% requires_all: id, id_column, coordinates
+#% requires: id_column, id, outlet_id_column
+#% requires_all: outlet_id_column, outlet, id_column
 #%end
 
 import sys
@@ -59,19 +76,21 @@
 
     input = options["input"]
     output = options["output"]
+    idcol = options["id_column"]
+    id = options["id"]
     coords = options["coordinates"]
     outlet = options["outlet"]
+    outletidcol = options["outlet_id_column"]
 
-    calculate_lfp(input, output, coords, outlet)
-
-def calculate_lfp(input, output, coords, outlet):
+    calculate_lfp(input, output, idcol, id, coords, outlet, outletidcol)
+                                            
+def calculate_lfp(input, output, idcol, id, coords, outlet, outletidcol):
     prefix = "r_lfp_%d_" % os.getpid()
 
-    # create the output vector map
-    try:
-        grass.run_command("v.edit", map=output, tool="create")
-    except CalledModuleError:
-        grass.fatal(_("Cannot create the output vector map"))
+    if id:
+        ids = id.split(",")
+    else:
+        ids = []
 
     if coords:
         coords = coords.split(",")
@@ -80,17 +99,54 @@
 
     # append outlet points to coordinates
     if outlet:
-        p = grass.pipe_command("v.to.db", flags="p", map=outlet, option="coor")
+        p = grass.pipe_command("v.report", map=outlet, option="coor")
         for line in p.stdout:
             line = line.rstrip("\n")
-            if line == "cat|x|y|z":
+            if line.startswith("cat|"):
+                colnames = line.split("|")
+                outletid_ind = -1
+                for i in range(0, len(colnames)):
+                    colname = colnames[i]
+                    if colname == outletidcol:
+                        outletid_ind = i
+                    elif colname == "x":
+                        x_ind = i
+                    elif colname == "y":
+                        y_ind = i
+                if outletidcol and outletid_ind == -1:
+                    grass.fatal(_("Cannot find <%s> column in <%s> map") %
+                                (outletidcol, outlet))
                 continue
             cols = line.split("|")
-            coords.extend([cols[1], cols[2]])
+            coords.extend([cols[x_ind], cols[y_ind]])
+            if outletid_ind >= 0:
+                ids.extend([cols[outletid_ind]])
         p.wait()
         if p.returncode != 0:
             grass.fatal(_("Cannot read outlet points"))
 
+    if len(ids) > 0:
+        if len(ids) > len(coords) / 2:
+            grass.fatal(_("Too many IDs"))
+        elif len(ids) < len(coords) / 2:
+            grass.fatal(_("Too few IDs"))
+        assign_id = True
+    else:
+        assign_id = False
+
+    # create the output vector map
+    try:
+        grass.run_command("v.edit", map=output, tool="create")
+    except CalledModuleError:
+        grass.fatal(_("Cannot create the output vector map"))
+
+    if assign_id:
+        try:
+            grass.run_command("v.db.addtable", map=output,
+                              columns="%s integer" % idcol)
+        except CalledModuleError:
+            grass.fatal(_("Cannot add a table to the output vector map"))
+
     for i in range(0, len(coords) / 2):
         coor = "%s,%s" % (coords[2*i], coords[2*i+1])
         grass.message(_("Processing the outlet at %s..." % coor))
@@ -194,6 +250,16 @@
         except CalledModuleError:
             grass.fatal(_("Cannot select the final longest flow path"))
 
+        lfp2 = lfp + "2"
+        try:
+            grass.run_command("v.category", overwrite=True,
+                              input=lfp, output=lfp2, option="del", cat=-1)
+            grass.run_command("v.category", overwrite=True,
+                              input=lfp2, output=lfp, option="add", cat=i+1,
+                              step=0)
+        except CalledModuleError:
+            grass.fatal(_("Cannot add categories"))
+
         # copy the final longest flow path to the output map
         try:
             grass.run_command("v.edit", flags="r",
@@ -201,6 +267,15 @@
         except CalledModuleError:
             grass.fatal(_("Cannot copy the final longest flow path"))
 
+        if assign_id:
+            try:
+                grass.run_command("v.to.db", map=output, option="cat",
+                                  columns="cat")
+                grass.run_command("v.db.update", map=output, column=idcol,
+                                  value=ids[i], where="cat=%d" % (i+1))
+            except CalledModuleError:
+                grass.fatal(_("Cannot assign ID"))
+
     # remove intermediate outputs
     grass.run_command("g.remove", flags="f", type="raster,vector",
                       pattern="%s*" % prefix)



More information about the grass-commit mailing list