[GRASS-SVN] r56534 - grass/trunk/vector/v.to.points

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Jun 1 09:55:56 PDT 2013


Author: martinl
Date: 2013-06-01 09:55:21 -0700 (Sat, 01 Jun 2013)
New Revision: 56534

Added:
   grass/trunk/vector/v.to.points/local_proto.h
   grass/trunk/vector/v.to.points/write.c
Modified:
   grass/trunk/vector/v.to.points/main.c
   grass/trunk/vector/v.to.points/v.to.points.html
Log:
v.to.points: split code into more files
             support faces and kernels
             change -v/n flag by `use` option


Added: grass/trunk/vector/v.to.points/local_proto.h
===================================================================
--- grass/trunk/vector/v.to.points/local_proto.h	                        (rev 0)
+++ grass/trunk/vector/v.to.points/local_proto.h	2013-06-01 16:55:21 UTC (rev 56534)
@@ -0,0 +1,9 @@
+#ifndef __LOCAL_PROTO_H
+#define GV_NODE   1
+#define GV_VERTEX 2
+
+void write_point(struct Map_info *, double, double, double,
+		 int, double, dbDriver *, struct field_info *);
+void write_line(struct Map_info *, struct line_pnts *, int,
+		int, int, double, dbDriver *, struct field_info *);
+#endif


Property changes on: grass/trunk/vector/v.to.points/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Modified: grass/trunk/vector/v.to.points/main.c
===================================================================
--- grass/trunk/vector/v.to.points/main.c	2013-06-01 16:47:34 UTC (rev 56533)
+++ grass/trunk/vector/v.to.points/main.c	2013-06-01 16:55:21 UTC (rev 56534)
@@ -8,7 +8,7 @@
  *               
  * PURPOSE:      Create points along lines 
  *               
- * COPYRIGHT:    (C) 2002-2010 by the GRASS Development Team
+ * COPYRIGHT:    (C) 2002-2010, 2013 by the GRASS Development Team
  *
  *               This program is free software under the GNU General
  *               Public License (>=v2).  Read the file COPYING that
@@ -23,242 +23,111 @@
 #include <grass/dbmi.h>
 #include <grass/glocale.h>
 
-/*
- * local macros
- */
-#define GV_NODE   1
-#define GV_VERTEX 2
+#include "local_proto.h"
 
-static int point_cat;
-static struct line_cats *PCats;
-static struct line_pnts *PPoints;
-static dbString stmt;
-static dbDriver *driver;
-static struct field_info *Fi;
-
-void write_point(struct Map_info *Out, double x, double y, double z,
-		 int line_cat, double along, int table)
-{
-    char buf[2000];
-
-    G_debug(3, "write_point()");
-
-    Vect_reset_line(PPoints);
-    Vect_reset_cats(PCats);
-
-    /* Write point */
-    Vect_append_point(PPoints, x, y, z);
-    if (line_cat > 0) {
-        Vect_cat_set(PCats, 1, line_cat);
-        Vect_cat_set(PCats, 2, point_cat);
-    }
-    else {
-        Vect_cat_set(PCats, 2, point_cat);
-    }
-    Vect_write_line(Out, GV_POINT, PPoints, PCats);
-
-    /* Attributes */
-    if (!table) {
-	db_zero_string(&stmt);
-        if (line_cat > 0)
-            sprintf(buf, "insert into %s values ( %d, %d, %.15g )", Fi->table,
-                point_cat, line_cat, along);
-        else
-            sprintf(buf, "insert into %s values ( %d, %.15g )", Fi->table,
-                point_cat, along);
-	db_append_string(&stmt, buf);
-
-	if (db_execute_immediate(driver, &stmt) != DB_OK) {
-	    G_warning(_("Unable to insert new record: '%s'"),
-		      db_get_string(&stmt));
-	}
-    }
-    point_cat++;
-}
-
-void write_line(struct Map_info *Out, struct line_pnts *LPoints, int cat,
-		int vertex, int interpolate, double dmax, int table)
-{
-    if (vertex == GV_VERTEX || vertex == GV_NODE) {	/* use line vertices */
-	double along;
-	int vert;
-
-	along = 0;
-	for (vert = 0; vert < LPoints->n_points; vert++) {
-	    G_debug(3, "vert = %d", vert);
-
-	    if (vertex == GV_VERTEX ||
-		(vertex == GV_NODE &&
-		 (vert == 0 || vert == LPoints->n_points - 1))) {
-		write_point(Out, LPoints->x[vert], LPoints->y[vert],
-			    LPoints->z[vert], cat, along, table);
-	    }
-
-	    if (vert < LPoints->n_points - 1) {
-		double dx, dy, dz, len;
-
-		dx = LPoints->x[vert + 1] - LPoints->x[vert];
-		dy = LPoints->y[vert + 1] - LPoints->y[vert];
-		dz = LPoints->z[vert + 1] - LPoints->z[vert];
-		len = hypot(hypot(dx, dy), dz);
-
-		/* interpolate segment */
-		if (interpolate && vert < (LPoints->n_points - 1)) {
-		    int i, n;
-		    double x, y, z, dlen;
-
-		    if (len > dmax) {
-			n = len / dmax + 1;	/* number of segments */
-			dx /= n;
-			dy /= n;
-			dz /= n;
-			dlen = len / n;
-
-			for (i = 1; i < n; i++) {
-			    x = LPoints->x[vert] + i * dx;
-			    y = LPoints->y[vert] + i * dy;
-			    z = LPoints->z[vert] + i * dz;
-
-			    write_point(Out, x, y, z, cat, along + i * dlen,
-					table);
-			}
-		    }
-		}
-		along += len;
-	    }
-	}
-    }
-    else {			/* do not use vertices */
-	int i, n;
-	double len, dlen, along, x, y, z;
-
-	len = Vect_line_length(LPoints);
-	n = len / dmax + 1;	/* number of segments */
-	dlen = len / n;		/* length of segment */
-
-	G_debug(3, "n = %d len = %f dlen = %f", n, len, dlen);
-
-	for (i = 0; i <= n; i++) {
-	    if (i > 0 && i < n) {
-		along = i * dlen;
-		Vect_point_on_line(LPoints, along, &x, &y, &z, NULL, NULL);
-	    }
-	    else {		/* first and last vertex */
-		if (i == 0) {
-		    along = 0;
-		    x = LPoints->x[0];
-		    y = LPoints->y[0];
-		    z = LPoints->z[0];
-		}
-		else {		/* last */
-		    along = len;
-		    x = LPoints->x[LPoints->n_points - 1];
-		    y = LPoints->y[LPoints->n_points - 1];
-		    z = LPoints->z[LPoints->n_points - 1];
-		}
-	    }
-	    G_debug(3, "  i = %d along = %f", i, along);
-	    write_point(Out, x, y, z, cat, along, table);
-	}
-    }
-}
-
 int main(int argc, char **argv)
 {
     int field, type, vertex_type;
     double dmax;
-    struct Option *in_opt, *out_opt, *type_opt, *dmax_opt, *lfield_opt;
-    struct Flag *inter_flag, *vertex_flag, *table_flag, *node_flag;
+    char buf[DB_SQL_MAX];
+
+    struct {
+        struct Option *input, *output, *type, *dmax, *lfield, *use;
+    } opt;
+    struct {
+        struct Flag *table, *inter;
+    } flag;
     struct GModule *module;
     struct Map_info In, Out;
     struct line_cats *LCats;
     struct line_pnts *LPoints;
-    char buf[2000];
 
+    dbDriver *driver;
+    struct field_info *Fi;
+
+    dbString stmt;
+
     G_gisinit(argv[0]);
 
     module = G_define_module();
     G_add_keyword(_("vector"));
     G_add_keyword(_("geometry"));
+    G_add_keyword("3D");
     module->description =
 	_("Creates points along input lines in new vector map with 2 layers.");
 
-    in_opt = G_define_standard_option(G_OPT_V_INPUT);
-    in_opt->label = _("Name of vector map containing lines");
+    opt.input = G_define_standard_option(G_OPT_V_INPUT);
 
-    lfield_opt = G_define_standard_option(G_OPT_V_FIELD);
-    lfield_opt->key = "llayer";
-    lfield_opt->answer = "1";
-    lfield_opt->label = "Line layer number or name";
-    lfield_opt->guisection = _("Selection");
+    opt.lfield = G_define_standard_option(G_OPT_V_FIELD);
+    opt.lfield->key = "llayer";
+    opt.lfield->answer = "1";
+    opt.lfield->label = "Line layer number or name";
+    opt.lfield->guisection = _("Selection");
 
-    type_opt = G_define_standard_option(G_OPT_V_TYPE);
-    type_opt->answer = "point,line,boundary,centroid";
-    type_opt->guisection = _("Selection");
+    opt.type = G_define_standard_option(G_OPT_V3_TYPE);
+    opt.type->answer = "point,line,boundary,centroid,face";
+    opt.type->guisection = _("Selection");
 
-    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
-    out_opt->description =
-	_("Name for output vector map where points will be written");
+    opt.output = G_define_standard_option(G_OPT_V_OUTPUT);
 
-    node_flag = G_define_flag();
-    node_flag->key = 'n';
-    node_flag->description = _("Write line nodes");
+    opt.use = G_define_option();
+    opt.use->key = "use";
+    opt.use->type = TYPE_STRING;
+    opt.use->required = NO;
+    opt.use->description = _("Use line nodes or vertices only");
+    opt.use->options = "node,vertex";
 
-    vertex_flag = G_define_flag();
-    vertex_flag->key = 'v';
-    vertex_flag->description = _("Write line vertices");
+    opt.dmax = G_define_option();
+    opt.dmax->key = "dmax";
+    opt.dmax->type = TYPE_DOUBLE;
+    opt.dmax->required = NO;
+    opt.dmax->answer = "100";
+    opt.dmax->description = _("Maximum distance between points in map units");
 
-    inter_flag = G_define_flag();
-    inter_flag->key = 'i';
-    inter_flag->description = _("Interpolate points between line vertices");
+    flag.inter = G_define_flag();
+    flag.inter->key = 'i';
+    flag.inter->description = _("Interpolate points between line vertices (only for use=vertex)");
+    
 
-    dmax_opt = G_define_option();
-    dmax_opt->key = "dmax";
-    dmax_opt->type = TYPE_DOUBLE;
-    dmax_opt->required = NO;
-    dmax_opt->answer = "100";
-    dmax_opt->description = _("Maximum distance between points in map units");
+    flag.table = G_define_standard_flag(G_FLG_V_TABLE);
 
-    table_flag = G_define_standard_flag(G_FLG_V_TABLE);
-
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
     LCats = Vect_new_cats_struct();
-    PCats = Vect_new_cats_struct();
     LPoints = Vect_new_line_struct();
-    PPoints = Vect_new_line_struct();
     db_init_string(&stmt);
 
-    type = Vect_option_to_types(type_opt);
-    dmax = atof(dmax_opt->answer);
+    type = Vect_option_to_types(opt.type);
+    dmax = atof(opt.dmax->answer);
 
-    if (node_flag->answer && vertex_flag->answer)
-	G_fatal_error(_("Use either -n or -v flag, not both"));
-
-    if (node_flag->answer)
-	vertex_type = GV_NODE;
-    else if (vertex_flag->answer)
-	vertex_type = GV_VERTEX;
-    else
-	vertex_type = 0;
-
-    Vect_check_input_output_name(in_opt->answer, out_opt->answer,
+    vertex_type = 0;
+    if (opt.use->answer) {
+        if (opt.use->answer[0] == 'n')
+            vertex_type = GV_NODE;
+        else
+            vertex_type = GV_VERTEX;
+    }
+    
+    Vect_check_input_output_name(opt.input->answer, opt.output->answer,
 				 G_FATAL_EXIT);
 
     /* Open input lines */
     Vect_set_open_level(2);
-    Vect_open_old2(&In, in_opt->answer, "", lfield_opt->answer);
-    field = Vect_get_field_number(&In, lfield_opt->answer);
+    Vect_open_old2(&In, opt.input->answer, "", opt.lfield->answer);
+    Vect_set_error_handler_io(&In, &Out);
     
+    field = Vect_get_field_number(&In, opt.lfield->answer);
+    
     /* Open output segments */
-    Vect_open_new(&Out, out_opt->answer, Vect_is_3d(&In));
+    Vect_open_new(&Out, opt.output->answer, Vect_is_3d(&In));
     Vect_copy_head_data(&In, &Out);
     Vect_hist_copy(&In, &Out);
     Vect_hist_command(&Out);
 
     /* Table */
-    if (!table_flag->answer) {
+    Fi = NULL;
+    if (!flag.table->answer) {
 	struct field_info *Fin;
 
 	/* copy input table */
@@ -289,6 +158,7 @@
 	if (driver == NULL)
 	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
 			  Fi->database, Fi->driver);
+        db_set_error_handler_driver(driver);
 
 	if (field == -1) 
             sprintf(buf,
@@ -301,7 +171,6 @@
 	db_append_string(&stmt, buf);
 
 	if (db_execute_immediate(driver, &stmt) != DB_OK) {
-	    db_close_database_shutdown_driver(driver);
 	    G_fatal_error(_("Unable to create table: '%s'"),
 			  db_get_string(&stmt));
 	}
@@ -310,18 +179,15 @@
 	    G_warning(_("Unable to create index for table <%s>, key <%s>"),
 		      Fi->table, GV_KEY_COLUMN);
 
-	if (db_grant_on_table
-	    (driver, Fi->table, DB_PRIV_SELECT,
-	     DB_GROUP | DB_PUBLIC) != DB_OK)
+	if (db_grant_on_table (driver, Fi->table, DB_PRIV_SELECT,
+                               DB_GROUP | DB_PUBLIC) != DB_OK)
 	    G_fatal_error(_("Unable to grant privileges on table <%s>"),
 			  Fi->table);
 
 	db_begin_transaction(driver);
     }
 
-    point_cat = 1;
-
-    if (type & (GV_POINTS | GV_LINES)) {
+    if (type & (GV_POINTS | GV_LINES | GV_FACE)) {
 	int line, nlines;
 
 	nlines = Vect_get_num_lines(&In);
@@ -329,25 +195,26 @@
 	    int ltype, cat;
 
 	    G_debug(3, "line = %d", line);
-
+	    G_percent(line, nlines, 2);
+            
 	    ltype = Vect_read_line(&In, LPoints, LCats, line);
 	    if (!(ltype & type))
 		continue;
             if (!Vect_cat_get(LCats, field, &cat) && field != -1)
 		continue;
+
             /* Assign CAT for layer 0 objects (i.e. boundaries) */
             if (field == -1)
                 cat = -1;
 
 	    if (LPoints->n_points <= 1) {
 		write_point(&Out, LPoints->x[0], LPoints->y[0], LPoints->z[0],
-			    cat, 0.0, table_flag->answer);
+			    cat, 0.0, driver, Fi);
 	    }
 	    else {		/* lines */
 		write_line(&Out, LPoints, cat, vertex_type,
-			   inter_flag->answer, dmax, table_flag->answer);
+			   flag.inter->answer, dmax, driver, Fi);
 	    }
-	    G_percent(line, nlines, 2);
 	}
     }
 
@@ -358,6 +225,8 @@
 	for (area = 1; area <= nareas; area++) {
 	    int i, isle, nisles;
 
+	    G_percent(area, nareas, 2);
+            
 	    centroid = Vect_get_area_centroid(&In, area);
 	    cat = -1;
 	    if (centroid > 0) {
@@ -368,8 +237,8 @@
 
 	    Vect_get_area_points(&In, area, LPoints);
 
-	    write_line(&Out, LPoints, cat, vertex_type, inter_flag->answer,
-		       dmax, table_flag->answer);
+	    write_line(&Out, LPoints, cat, vertex_type, flag.inter->answer,
+		       dmax, driver, Fi);
 
 	    nisles = Vect_get_area_num_isles(&In, area);
 
@@ -378,13 +247,12 @@
 		Vect_get_isle_points(&In, isle, LPoints);
 
 		write_line(&Out, LPoints, cat, vertex_type,
-			   inter_flag->answer, dmax, table_flag->answer);
+			   flag.inter->answer, dmax, driver, Fi);
 	    }
-	    G_percent(area, nareas, 2);
 	}
     }
 
-    if (!table_flag->answer) {
+    if (!flag.table->answer) {
 	db_commit_transaction(driver);
 	db_close_database_shutdown_driver(driver);
     }
@@ -393,9 +261,11 @@
 
     /* Free, close ... */
     Vect_close(&In);
-    Vect_close(&Out);
 
-    G_done_msg(_("%d points written to output vector map."), point_cat - 1);
+    G_done_msg(_("%d points written to output vector map."),
+               Vect_get_num_primitives(&Out, GV_POINT));
 
+    Vect_close(&Out);
+    
     exit(EXIT_SUCCESS);
 }

Modified: grass/trunk/vector/v.to.points/v.to.points.html
===================================================================
--- grass/trunk/vector/v.to.points/v.to.points.html	2013-06-01 16:47:34 UTC (rev 56533)
+++ grass/trunk/vector/v.to.points/v.to.points.html	2013-06-01 16:55:21 UTC (rev 56534)
@@ -1,86 +1,116 @@
 <h2>DESCRIPTION</h2>
 
-<p><em>v.to.points</em> creates points along input lines. The output is a vector with 2 layers.
-Layer 1 holds the category and attributes of the input lines; all points created along the
-same line have the same category, equal to the category of that line. In layer 2 each point
-has it's unique category; other attributes stored in layer 2 are <em>lcat</em> - the
-category of the input line and <em>along</em> - the distance from line's start.</p>
+<em>v.to.points</em> creates points along input lines, boundaries and
+faces. Point features including centroids and kernels are copied from
+input vector map to the output. For details see notes
+about <b>type</b> parameter.
 
+<p>
+The output is a vector map with 2 layers. Layer 1 holds the category
+of the input features; all points created along the same line have the
+same category, equal to the category of that line. In layer 2 each
+point has it's unique category; other attributes stored in layer 2
+are <em>lcat</em> - the category of the input line and <em>along</em>
+- the distance from line's start.
+
+<p>
+By default only features with category are processed,
+see <b>llayer</b> parameter for details.
+
 <h2>NOTES</h2>
 
-<p>The <em>dmax</em> parameter is the maximum limit but not an exact
-distance. To place points with exact distance from the beginning
-of the vector line the user should use
-<a href="v.segment.html">v.segment</a>.</p>
+The <b>dmax</b> parameter is the maximum limit but not an exact
+distance. To place points with exact distance from the beginning of
+the vector line the user should use
+<em><a href="v.segment.html">v.segment</a></em>.
 
-<p>Set llayer to -1 to ignore object category values. Objects will be assigned 
-new unique categories at layer 1. llayer -1 should be used to convert boundaries,
-as in most of cases boundaries lack category values.</p>
+<p>
+Set <b>llayer</b> to -1 to process features from all layers including
+features without category. Features will be assigned new unique
+categories at layer 1. Option <b>llayer=-1</b> should be used to
+convert boundaries, as in most of cases boundaries lack category
+values.
 
-<p>The <em>type</em> parameter is used to control which input vector
-geometry types to convert into points. 
-Some caveats to consider about this parameter:
+<p>
+The <b>type</b> parameter is used to control which input vector
+geometry types to convert into points. Some caveats to consider about
+this parameter:
 
 <ul>
-<li>
-Points and centroids can be considered as "lines" with only one
-node. Consequently, the result of selecting <em>point</em> or
-<em>centroid</em> as the type parameter is that all points/centroids
-get written into the output vector. The original category numbers of
-the input points/centroids get written to the '<em><i>lcat</i></em>'
-attribute in layer 2 of the output vector. All values for
-<em>along</em> are zero in the output vector, as only point geometry
-was used for input (there is no linear distance to calculate
-<i>along</i>, as each point/centroid is the start <em><i>and</i></em>
-end of its own "line".</li>
-<li>
-Boundaries are treated as lines, with points getting interpolated
-along the boundary perimeter according to <em>dmax</em>. If two
-adjoining polygons share a topological boundary, the boundary only
-gets converted to points once.</li>
-<li>
-If the <em>type</em> parameter is set to <em>area</em>, the boundary of
-each area is converted to points <i>regardless</i> of whether or not
-there is a topological boundary between adjacent areas. In other
-words, the common boundary of two adjoining areas, for example, gets
-converted to points twice. The centroid is not converted to a point in
-the output vector for <em>type=area</em>.</li>
+  <li>
+    Points and centroids can be considered as "lines" with only one
+    node. Consequently, the result of selecting <em>point</em> or
+    <em>centroid</em> as the type parameter is that all
+    points/centroids get written into the output vector map. The
+    original category numbers of the input points/centroids get
+    written to the '<em>lcat</em>' attribute in layer 2 of the output
+    vector map. All values for <em>along</em> are zero in the output
+    vector map, as only point geometry was used for input (there is no
+    linear distance to calculate
+    <em>along</em>, as each point/centroid is the start <em>and</em>
+    end of its own "line").</li>
+  <li>
+    Boundaries are treated as lines, with points getting interpolated
+    along the boundary perimeter according to <b>dmax</b>. If two
+    adjoining polygons share a topological boundary, the boundary only
+    gets converted to points once.</li>
+  <li>
+    If the <b>type</b> parameter is set to <em>area</em>, the boundary of
+    each area is converted to points <i>regardless</i> of whether or not
+    there is a topological boundary between adjacent areas. In other
+    words, the common boundary of two adjoining areas, for example, gets
+    converted to points twice. The centroid is not converted to a point in
+    the output vector for <em>type=area</em>.</li>
 </ul>
 
-<p>The -v flag is used to digitize points that fall on the line's vertices <em>only</em>.
-<em>dmax</em> is ignored in this case.</p>
-<p>If the -i flag is used in conjunction with the -v flag,
+<p>
+The <b>use=vertex</b> option is used to digitize points that fall on
+the line's vertices <em>only</em>. Parameter <b>dmax</b> is ignored in
+this case. Similarly to <b>use=node</b> when only line's node are
+used.
+
+<p>
+If the <b>-i</b> flag is used in conjunction with
+the <b>use=vertex</b> option,
 <em>v.to.points</em> will digitize points on the line vertices, as
-well as interpolate points between line vertices using <em>dmax</em>
-as the maximum allowable spacing.</p>
-<p>To get points created for the beginning, middle and end only, use
-the -i switch and set <em>dmax</em> so that: <br>
-    (length of input line / 2) <= <em>dmax</em> <= length of input line
-So if <em>dmax</em> is between 0.5x and 1.0x the line length, you
-will always get points created at exactly the beginning, middle and
-end of the input line.</p>
+well as interpolate points between line vertices using <b>dmax</b> as
+the maximum allowable spacing.
 
+<p>
+To get points created for the beginning, middle and end only, use
+the <b>-i</b> flag and set <b>dmax</b> so that:
+
+<div class="code"><pre>
+ (length of input line / 2) <= <em>dmax</em> <= length of input line
+</pre></div>
+
+So if <b>dmax</b> is between 0.5x and 1.0x the line length, you will
+always get points created at exactly the beginning, middle and end of
+the input line.
+
 <h2>EXAMPLE</h2>
 
-<p>In this example, the 't_powerlines' vector lines map in the
+In this example, the 't_powerlines' vector lines map in the
 <a href="http://grass.osgeo.org/download/data6.php">Spearfish 6</a>
-location is used to create points along the input lines:</p>
+location is used to create points along the input lines:
 
 <div class="code"><pre>
 v.to.points in=t_powerlines out=t_powerlines_points dmax=120
-d.vect t_powerlines_points
 </pre></div>
 
-
 <h2>SEE ALSO</h2>
 
 <em>
 <a href="v.segment.html">v.segment</a>,
 <a href="v.to.rast.html">v.to.rast</a>,
-<a href="v.to.db.html">v.to.db</a></em>
+<a href="v.to.db.html">v.to.db</a>
+</em>
 
 <h2>AUTHOR</h2>
 
-Radim Blazek
+Radim Blazek<br>
+Updated to GRASS 7 by Martin Landa, Czech Technical University in
+Prague, Czech Republic
 
-<p><i>Last changed: $Date$</i></p>
+<p>
+<i>Last changed: $Date$</i></p>

Added: grass/trunk/vector/v.to.points/write.c
===================================================================
--- grass/trunk/vector/v.to.points/write.c	                        (rev 0)
+++ grass/trunk/vector/v.to.points/write.c	2013-06-01 16:55:21 UTC (rev 56534)
@@ -0,0 +1,143 @@
+#include <grass/vector.h>
+#include <grass/glocale.h>
+
+#include "local_proto.h"
+
+static struct line_cats *PCats;
+static struct line_pnts *PPoints;
+static int point_cat = 1;
+
+void write_point(struct Map_info *Out, double x, double y, double z,
+		 int line_cat, double along, dbDriver *driver, struct field_info *Fi)
+{
+    G_debug(3, "write_point()");
+
+    if (!PPoints) {
+        PCats = Vect_new_cats_struct();
+        PPoints = Vect_new_line_struct();
+    }
+    else {
+        Vect_reset_line(PPoints);
+        Vect_reset_cats(PCats);
+    }
+    
+    /* Write point */
+    Vect_append_point(PPoints, x, y, z);
+    if (line_cat > 0) {
+        Vect_cat_set(PCats, 1, line_cat);
+        Vect_cat_set(PCats, 2, point_cat);
+    }
+    else {
+        Vect_cat_set(PCats, 2, point_cat);
+    }
+    Vect_write_line(Out, GV_POINT, PPoints, PCats);
+
+    /* Attributes */
+    if (Fi) {
+        char buf[DB_SQL_MAX];
+        dbString stmt;
+        
+	db_init_string(&stmt);
+        if (line_cat > 0)
+            sprintf(buf, "insert into %s values ( %d, %d, %.15g )", Fi->table,
+                point_cat, line_cat, along);
+        else
+            sprintf(buf, "insert into %s values ( %d, %.15g )", Fi->table,
+                point_cat, along);
+	db_append_string(&stmt, buf);
+
+	if (db_execute_immediate(driver, &stmt) != DB_OK) {
+	    G_warning(_("Unable to insert new record: '%s'"),
+		      db_get_string(&stmt));
+	}
+    }
+    point_cat++;
+}
+
+void write_line(struct Map_info *Out, struct line_pnts *LPoints, int cat,
+		int vertex, int interpolate, double dmax,
+                dbDriver *driver, struct field_info *Fi)
+{
+    if (vertex == GV_VERTEX || vertex == GV_NODE) {	/* use line vertices */
+	double along;
+	int vert;
+
+	along = 0;
+	for (vert = 0; vert < LPoints->n_points; vert++) {
+	    G_debug(3, "vert = %d", vert);
+
+	    if (vertex == GV_VERTEX ||
+		(vertex == GV_NODE &&
+		 (vert == 0 || vert == LPoints->n_points - 1))) {
+		write_point(Out, LPoints->x[vert], LPoints->y[vert],
+			    LPoints->z[vert], cat, along, driver, Fi);
+	    }
+
+	    if (vert < LPoints->n_points - 1) {
+		double dx, dy, dz, len;
+
+		dx = LPoints->x[vert + 1] - LPoints->x[vert];
+		dy = LPoints->y[vert + 1] - LPoints->y[vert];
+		dz = LPoints->z[vert + 1] - LPoints->z[vert];
+		len = hypot(hypot(dx, dy), dz);
+
+		/* interpolate segment */
+		if (interpolate && vert < (LPoints->n_points - 1)) {
+		    int i, n;
+		    double x, y, z, dlen;
+
+		    if (len > dmax) {
+			n = len / dmax + 1;	/* number of segments */
+			dx /= n;
+			dy /= n;
+			dz /= n;
+			dlen = len / n;
+
+			for (i = 1; i < n; i++) {
+			    x = LPoints->x[vert] + i * dx;
+			    y = LPoints->y[vert] + i * dy;
+			    z = LPoints->z[vert] + i * dz;
+
+			    write_point(Out, x, y, z, cat, along + i * dlen,
+					driver, Fi);
+			}
+		    }
+		}
+		along += len;
+	    }
+	}
+    }
+    else {			/* do not use vertices */
+	int i, n;
+	double len, dlen, along, x, y, z;
+
+	len = Vect_line_length(LPoints);
+	n = len / dmax + 1;	/* number of segments */
+	dlen = len / n;		/* length of segment */
+
+	G_debug(3, "n = %d len = %f dlen = %f", n, len, dlen);
+
+	for (i = 0; i <= n; i++) {
+	    if (i > 0 && i < n) {
+		along = i * dlen;
+		Vect_point_on_line(LPoints, along, &x, &y, &z, NULL, NULL);
+	    }
+	    else {		/* first and last vertex */
+		if (i == 0) {
+		    along = 0;
+		    x = LPoints->x[0];
+		    y = LPoints->y[0];
+		    z = LPoints->z[0];
+		}
+		else {		/* last */
+		    along = len;
+		    x = LPoints->x[LPoints->n_points - 1];
+		    y = LPoints->y[LPoints->n_points - 1];
+		    z = LPoints->z[LPoints->n_points - 1];
+		}
+	    }
+	    G_debug(3, "  i = %d along = %f", i, along);
+	    write_point(Out, x, y, z, cat, along, driver, Fi);
+	}
+    }
+}


Property changes on: grass/trunk/vector/v.to.points/write.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native



More information about the grass-commit mailing list