[GRASS-SVN] r56213 - grass/trunk/vector/v.extrude

svn_grass at osgeo.org svn_grass at osgeo.org
Sun May 12 04:40:23 PDT 2013


Author: martinl
Date: 2013-05-12 04:40:23 -0700 (Sun, 12 May 2013)
New Revision: 56213

Added:
   grass/trunk/vector/v.extrude/db.c
   grass/trunk/vector/v.extrude/extrude.c
   grass/trunk/vector/v.extrude/local_proto.h
Modified:
   grass/trunk/vector/v.extrude/main.c
   grass/trunk/vector/v.extrude/v.extrude.html
Log:
v.extrude: major clean up & code reorganization
           new parameters: cats, where, method
           support for lines disabled (use v.to.3d instead)


Added: grass/trunk/vector/v.extrude/db.c
===================================================================
--- grass/trunk/vector/v.extrude/db.c	                        (rev 0)
+++ grass/trunk/vector/v.extrude/db.c	2013-05-12 11:40:23 UTC (rev 56213)
@@ -0,0 +1,43 @@
+#include <grass/vector.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+/* get height for DB
+   returns 0 on success -1 on failure
+*/
+int get_height(const struct field_info *Fi, const char *hcolumn,
+               dbDriver *driver, int cat, double *height)
+{
+    int more;
+    double objheight;
+    char query[DB_SQL_MAX];
+    
+    dbString sql;
+    dbCursor cursor;
+    dbTable *table;
+    dbColumn *column;
+    dbValue *value;
+
+    db_init_string(&sql);
+    sprintf(query, "SELECT %s FROM %s WHERE %s = %d",
+            hcolumn, Fi->table, Fi->key, cat);
+    G_debug(3, "SQL: %s", query);
+    db_set_string(&sql, query);
+    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK)
+        G_fatal_error(_("Unable to select attributes category %d"),
+                      cat);
+    table = db_get_cursor_table(&cursor);
+    column = db_get_table_column(table, 0);	/* first column */
+    
+    if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
+        return -1;
+    
+    value = db_get_column_value(column);
+    G_debug(3, "column_host_type: %d", db_get_column_host_type(column));
+    objheight = db_get_value_as_double(value, DB_C_TYPE_DOUBLE);
+    G_debug(3, "height from DB: %f", objheight);
+    
+    *height = objheight;
+    
+    return 0;
+}


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

Added: grass/trunk/vector/v.extrude/extrude.c
===================================================================
--- grass/trunk/vector/v.extrude/extrude.c	                        (rev 0)
+++ grass/trunk/vector/v.extrude/extrude.c	2013-05-12 11:40:23 UTC (rev 56213)
@@ -0,0 +1,187 @@
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/vector.h>
+
+struct line_pnts *Points_wall, *Points_roof;
+struct line_cats *Cats_roof;
+
+/**
+  \brief Extrude vector object
+
+  - point -> 3d line (vertical)
+  - boundary -> face
+  - area -> face + kernel
+
+  \param In input vector map
+  \param[in,out] Out output vector map
+  \param Cats categories
+  \param Points points
+  \param fdrast background raster map
+  \param trace trace raster map values
+  \param interpolation method
+  \param objheight object height
+  \param voffset vertical offset
+  \param window raster region
+  \param type feature type
+  \param centroid number of centroid for area
+
+  \return number of writen objects
+*/
+int extrude(struct Map_info *In, struct Map_info *Out,
+            const struct line_cats *Cats, const struct line_pnts *Points,
+            int fdrast, int trace, int interp_method, double objheight, double voffset,
+            const struct Cell_head *window, int type, int centroid)
+{
+    int k;			/* Points->n_points */
+    int nlines;
+    
+    double voffset_dem;		/* minimal offset */
+    double voffset_curr;	/* offset of current point */
+    double voffset_next;	/* offset of next point */
+
+    nlines = 0;
+
+    if (type != GV_POINT && Points->n_points < 2)
+	return nlines;
+
+    if (!Points_wall) {
+        Points_wall = Vect_new_line_struct();
+        Points_roof = Vect_new_line_struct();
+        Cats_roof = Vect_new_cats_struct();
+    }
+    else {
+        Vect_reset_line(Points_wall);
+        Vect_reset_line(Points_roof);        
+        Vect_reset_cats(Cats_roof);
+    }
+
+    voffset_dem = 0.0;
+    /* do not trace -> calculate minimum dem offset */
+    if (fdrast >= 0 && !trace) {
+	for (k = 0; k < Points->n_points; k++) {
+	    voffset_curr = Rast_get_sample(fdrast, window, NULL,
+                                           Points->y[k], Points->x[k], 0, /* north, east */
+                                           interp_method);
+	    if (Rast_is_d_null_value(&voffset_curr))
+		continue;
+
+	    if (k == 0) {
+		voffset_dem = voffset_curr;
+	    }
+	    else {
+		if (voffset_curr < voffset_dem)
+		    voffset_dem = voffset_curr;
+	    }
+	}
+    }
+
+    
+    /* walls */
+    for (k = 0; ; k++) {
+	voffset_curr = voffset_next = 0.0;
+
+	/* trace */
+	if (fdrast >= 0 && trace) {
+	    voffset_curr = Rast_get_sample(fdrast, window, NULL,
+                                           Points->y[k], Points->x[k], 0, /* north, east */
+                                           interp_method);
+
+	    if (type != GV_POINT) {
+		voffset_next = Rast_get_sample(fdrast, window, NULL,
+                                               Points->y[k + 1],         /* north, east */
+                                               Points->x[k + 1], 0,
+                                               interp_method);
+	    }
+	}
+
+	if (Rast_is_d_null_value(&voffset_curr) ||
+	    Rast_is_d_null_value(&voffset_next)) {
+	    if (type == GV_POINT)
+		break;
+	    else if (type == GV_LINE) {
+		if (k >= Points->n_points - 1)
+		    break;
+	    }
+	    else if (type & (GV_BOUNDARY | GV_AREA)) {
+		if (k >= Points->n_points - 2)
+		    break;
+	    }
+	    continue;
+	}
+
+	if (trace) {
+	    voffset_curr += voffset;
+	    voffset_next += voffset;
+	}
+	else {
+	    voffset_curr = voffset_dem + voffset;
+	    voffset_next = voffset_dem + voffset;
+	}
+
+	if (type == GV_POINT) {
+	    /* point -> 3d line (vertical) */
+	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
+			      Points->z[k] + voffset_curr);
+	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
+			      Points->z[k] + objheight + voffset_curr);
+	    break;
+	}
+	else if (type == GV_LINE) {
+	    /* line -> 3d line (currently disabled) */
+	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
+			      Points->z[k] + objheight + voffset_curr);
+	    if (k >= Points->n_points - 1)
+		break;
+	}
+	else if (type & (GV_BOUNDARY | GV_AREA)) {
+	    /* reset */
+	    Vect_reset_line(Points_wall);
+
+	    /* boudary -> face */
+	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
+			      Points->z[k] + voffset_curr);
+	    Vect_append_point(Points_wall, Points->x[k + 1], Points->y[k + 1],
+			      Points->z[k + 1] + voffset_next);
+	    Vect_append_point(Points_wall, Points->x[k + 1], Points->y[k + 1],
+			      Points->z[k + 1] + objheight + voffset_next);
+	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
+			      Points->z[k] + objheight + voffset_curr);
+	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
+			      Points->z[k] + voffset_curr);
+
+	    Vect_write_line(Out, GV_FACE, Points_wall, Cats);
+	    nlines++;
+
+	    if (type == GV_AREA) {
+		/* roof */
+		Vect_append_point(Points_roof, Points->x[k], Points->y[k],
+				  Points->z[k] + objheight + voffset_curr);
+	    }
+
+	    if (k >= Points->n_points - 2)
+		break;
+	}
+    }
+
+    if (type & (GV_POINT | GV_LINE)) {
+	Vect_write_line(Out, GV_LINE, Points_wall, Cats);
+	nlines++;
+    }
+    else if (type == GV_AREA && Points_roof->n_points > 3) {
+	Vect_append_point(Points_roof,
+			  Points_roof->x[0], Points_roof->y[0],
+			  Points_roof->z[0]);
+	Vect_write_line(Out, GV_FACE, Points_roof, Cats);
+	nlines++;
+
+	if (centroid > 0) {
+	    /* centroid -> kernel */
+            Vect_read_line(In, Points_roof, Cats_roof, centroid);
+	    Points->z[0] = Points_roof->z[0] / 2.0;
+	    Vect_write_line(Out, GV_KERNEL, Points_roof, Cats_roof);
+	    nlines++;
+	}
+    }
+    
+    return nlines;
+}


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

Added: grass/trunk/vector/v.extrude/local_proto.h
===================================================================
--- grass/trunk/vector/v.extrude/local_proto.h	                        (rev 0)
+++ grass/trunk/vector/v.extrude/local_proto.h	2013-05-12 11:40:23 UTC (rev 56213)
@@ -0,0 +1,9 @@
+/* db.c */
+int get_height(const struct field_info *, const char *,
+               dbDriver *, int, double *);
+
+/* extrude.c */
+int extrude(struct Map_info *, struct Map_info *,
+            const struct line_cats *, const struct line_pnts *,
+            int, int, int, double, double,
+            const struct Cell_head *, int, int);


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

Modified: grass/trunk/vector/v.extrude/main.c
===================================================================
--- grass/trunk/vector/v.extrude/main.c	2013-05-12 11:30:24 UTC (rev 56212)
+++ grass/trunk/vector/v.extrude/main.c	2013-05-12 11:40:23 UTC (rev 56213)
@@ -4,16 +4,19 @@
  * MODULE:     v.extrude
  *
  * AUTHOR(S):  Jachym Cepicky <jachym.cepicky gmail.com>
+ *             Support for points & OGR support (08/2007, 2009), new
+ *             parameters cats, where, method (2013) added by Martin
+ *             Landa <landa.martin gmail.com>
+ *
+ * PURPOSE:    "Extrudes" flat polygons and lines to 3D with defined height
+ *             Useful for creating buildings for displaying with NVIZ
+ *
  *             Based on v.example by Radim Blazek
  *             Inspired by d.vect and v.drape
  *             Coding help and code cleaning by Markus Neteler
- *             Support for points & OGR support added by Martin Landa (08/2007 / 2009)
  *
- * PURPOSE:    "Extrudes" flat polygons and lines to 3D with defined height
- *              Useful for creating buildings for displaying with NVIZ
+ * COPYRIGHT:  (C) 2005-2010,2013 by the GRASS Development Team
  *
- * COPYRIGHT:  (C) 2005-2010 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.
@@ -27,44 +30,39 @@
 #include <grass/glocale.h>
 #include <grass/dbmi.h>
 
-static int extrude(struct Map_info *, struct Map_info *,
-		   struct line_cats *, struct line_pnts *,
-		   int, int, double, double, struct Cell_head, int, int);
+#include "local_proto.h"
 
 int main(int argc, char *argv[])
 {
     struct GModule *module;
-    struct Option *old, *new, *zshift, *height, *elevation, *hcolumn,
-	*type_opt, *field_opt;
-    struct Flag *t_flag;
-
+    struct {
+        struct Option *input, *output, *zshift, *height, *elevation, *hcolumn,
+            *type, *field, *cats, *where, *interp;
+    } opt;
+    struct {
+        struct Flag *trace;
+    } flag;
+    
     struct Map_info In, Out;
     struct line_pnts *Points;
     struct line_cats *Cats;
     struct bound_box map_box;
 
+    struct cat_list *cat_list;
+    
     struct Cell_head window;
-    struct cat_list *Clist;
-
+    
     int field;
-    int i, only_type, cat, ctype = -1, fdrast = -1, areanum = 0;
-    int nelements;
-    int line, type;
-    int area, trace, centroid;
-    double objheight, voffset;
-
-    /* dbmi */
+    int only_type, cat;
+    int fdrast, interp_method;
+    int process_area, trace;
+    double objheight, objheight_default, voffset;
+    
     struct field_info *Fi;
     dbDriver *driver = NULL;
-    char query[1024];
-    dbString sql;
-    dbCursor cursor;
-    dbTable *table;
-    dbColumn *column;
-    dbValue *value;
-    int more;
+    
     char *comment;
-
+    
     module = G_define_module();
     G_add_keyword(_("vector"));
     G_add_keyword(_("geometry"));
@@ -72,66 +70,87 @@
     module->description =
 	_("Extrudes flat vector features to 3D with defined height.");
 
-    t_flag = G_define_flag();
-    t_flag->key = 't';
-    t_flag->description = _("Trace elevation");
+    flag.trace = G_define_flag();
+    flag.trace->key = 't';
+    flag.trace->description = _("Trace elevation");
+    flag.trace->guisection = _("Elevation");
 
-    old = G_define_standard_option(G_OPT_V_INPUT);
+    opt.input = G_define_standard_option(G_OPT_V_INPUT);
 
-    field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
+    opt.field = G_define_standard_option(G_OPT_V_FIELD_ALL);
+    opt.field->guisection = _("Selection");
 
-    type_opt = G_define_standard_option(G_OPT_V_TYPE);
-    type_opt->answer = "point,line,boundary,area";
-    type_opt->options = "point,line,boundary,area";
+    opt.cats = G_define_standard_option(G_OPT_V_CATS);
+    opt.cats->guisection = _("Selection");
+    
+    opt.where = G_define_standard_option(G_OPT_DB_WHERE);
+    opt.where->guisection = _("Selection");
 
-    new = G_define_standard_option(G_OPT_V_OUTPUT);
+    opt.type = G_define_standard_option(G_OPT_V_TYPE);
+    opt.type->answer = "point,boundary,area";
+    opt.type->options = "point,boundary,area";
+    opt.type->guisection = _("Selection");
 
-    zshift = G_define_option();
-    zshift->key = "zshift";
-    zshift->description = _("Shifting value for z coordinates");
-    zshift->type = TYPE_DOUBLE;
-    zshift->required = NO;
-    zshift->answer = "0";
+    opt.output = G_define_standard_option(G_OPT_V_OUTPUT);
 
-    /* raster sampling */
-    elevation = G_define_standard_option(G_OPT_R_ELEV);
-    elevation->required = NO;
-    elevation->description = _("Elevation raster for height extraction");
+    opt.zshift = G_define_option();
+    opt.zshift->key = "zshift";
+    opt.zshift->description = _("Shifting value for z coordinates");
+    opt.zshift->type = TYPE_DOUBLE;
+    opt.zshift->required = NO;
+    opt.zshift->answer = "0";
+    opt.zshift->guisection = _("Height");
 
-    height = G_define_option();
-    height->key = "height";
-    height->type = TYPE_DOUBLE;
-    height->required = NO;
-    height->multiple = NO;
-    height->description = _("Fixed height for 3D vector objects");
+    opt.height = G_define_option();
+    opt.height->key = "height";
+    opt.height->type = TYPE_DOUBLE;
+    opt.height->required = NO;
+    opt.height->multiple = NO;
+    opt.height->description = _("Fixed height for 3D vector features");
+    opt.height->guisection = _("Height");
 
-    hcolumn = G_define_standard_option(G_OPT_DB_COLUMN);
-    hcolumn->key = "hcolumn";
-    hcolumn->multiple = NO;
-    hcolumn->description = _("Name of attribute column with object heights");
+    opt.hcolumn = G_define_standard_option(G_OPT_DB_COLUMN);
+    opt.hcolumn->key = "hcolumn";
+    opt.hcolumn->multiple = NO;
+    opt.hcolumn->description = _("Name of attribute column with feature height");
+    opt.hcolumn->guisection = _("Height");
+ 
+    /* raster sampling */
+    opt.elevation = G_define_standard_option(G_OPT_R_ELEV);
+    opt.elevation->required = NO;
+    opt.elevation->description = _("Elevation raster map for height extraction");
+    opt.elevation->guisection = _("Elevation");
 
+    opt.interp = G_define_standard_option(G_OPT_R_INTERP_TYPE);
+    opt.interp->answer = "nearest";
+    opt.interp->guisection = _("Elevation");
+
     G_gisinit(argv[0]);
 
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
-    if (!height->answer && !hcolumn->answer) {
+    if (!opt.height->answer && !opt.hcolumn->answer) {
 	G_fatal_error(_("One of '%s' or '%s' parameters must be set"),
-		      height->key, hcolumn->key);
+		      opt.height->key, opt.hcolumn->key);
     }
 
-    sscanf(zshift->answer, "%lf", &voffset);
-
-    if (height->answer)
-	sscanf(height->answer, "%lf", &objheight);
+    sscanf(opt.zshift->answer, "%lf", &voffset);
+    G_debug(1, "voffset = %f", voffset);
+    
+    if (opt.height->answer)
+	sscanf(opt.height->answer, "%lf", &objheight);
     else
 	objheight = 0.;
+    G_debug(1, "objheight = %f", objheight);
+    objheight_default = objheight;
 
-    only_type = Vect_option_to_types(type_opt);
+    only_type = Vect_option_to_types(opt.type);
+    interp_method = Rast_option_to_interp_type(opt.interp);
 
-    trace = (t_flag->answer) ? 1 : 0;
-    area = (only_type & GV_AREA) ? 1 : 0;
-    if (area) {
+    trace = (flag.trace->answer) ? TRUE : FALSE;
+    process_area = (only_type & GV_AREA) ? TRUE : FALSE;
+    if (process_area) {
 	if (only_type & GV_BOUNDARY) {
 	    /* do not write wall twice -> disable boundary type */
 	    only_type &= ~GV_BOUNDARY;
@@ -139,194 +158,178 @@
 	only_type &= ~GV_AREA;
     }
 
-    centroid = 0;
-
     /* set input vector map name and mapset */
-    Vect_check_input_output_name(old->answer, new->answer, G_FATAL_EXIT);
+    Vect_check_input_output_name(opt.input->answer, opt.output->answer, G_FATAL_EXIT);
 
-    /* vector setup */
     Points = Vect_new_line_struct();
     Cats = Vect_new_cats_struct();
 
-    Vect_set_open_level(2);
-    Vect_open_new(&Out, new->answer, WITH_Z);
+    Vect_set_open_level(2); /* topology required for input */
+    /* opening input vector map */
+    Vect_open_old2(&In, opt.input->answer, "", opt.field->answer);
+    Vect_set_error_handler_io(&In, &Out);
 
-    /* opening old vector */
-    Vect_open_old2(&In, old->answer, "", field_opt->answer);
-    field = Vect_get_field_number(&In, field_opt->answer);
+    /* creating output vector map */
+    Vect_open_new(&Out, opt.output->answer, WITH_Z);
 
+    field = Vect_get_field_number(&In, opt.field->answer);
+
+    if ((opt.hcolumn->answer || opt.cats->answer || opt.where->answer) && field == -1) {
+        G_warning(_("Invalid layer number (%d). "
+                    "Parameter '%s', '%s' or '%s' specified, assuming layer '1'."),
+                  field, opt.hcolumn->key, opt.cats->key, opt.where->key);
+        field = 1;
+    }
+
+    /* set constraint for cats or where */
+    cat_list = NULL;
+    if (field > 0)
+	cat_list = Vect_cats_set_constraint(&In, field, opt.where->answer,
+                                            opt.cats->answer);
+    
+    
     Vect_hist_copy(&In, &Out);
     Vect_hist_command(&Out);
 
     /* opening database connection, if required */
-    if (hcolumn->answer) {
-	Clist = Vect_new_cat_list();
-	Clist->field = atoi(field_opt->answer);
-	if ((Fi = Vect_get_field(&In, Clist->field)) == NULL)
+    if (opt.hcolumn->answer) {
+        int ctype;
+        dbColumn *column;
+        
+	if ((Fi = Vect_get_field(&In, field)) == NULL)
 	    G_fatal_error(_("Database connection not defined for layer %d"),
-			  Clist->field);
+			  field);
 
 	if ((driver =
 	     db_start_driver_open_database(Fi->driver, Fi->database)) == NULL)
 	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
 			  Fi->database, Fi->driver);
-
-	if (db_get_column(driver, Fi->table, hcolumn->answer, &column) != DB_OK)
+        db_set_error_handler_driver(driver);
+        
+	if (db_get_column(driver, Fi->table, opt.hcolumn->answer, &column) != DB_OK)
 	    G_fatal_error(_("Column <%s> does not exist"),
-			  hcolumn->answer);
+			  opt.hcolumn->answer);
 	else
 	    db_free_column(column);
 
-	ctype = db_column_Ctype(driver, Fi->table, hcolumn->answer);
+	ctype = db_column_Ctype(driver, Fi->table, opt.hcolumn->answer);
 
 	if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_STRING &&
 	    ctype != DB_C_TYPE_DOUBLE) {
 	    G_fatal_error(_("Column <%s>: invalid data type"),
-			  hcolumn->answer);
+			  opt.hcolumn->answer);
 	}
     }
 
     /* do we work with elevation raster? */
-    if (elevation->answer) {
+    fdrast = -1;
+    if (opt.elevation->answer) {
 	/* raster setup */
 	G_get_window(&window);
 
 	/* open the elev raster, and check for error condition */
-	fdrast = Rast_open_old(elevation->answer, "");
+	fdrast = Rast_open_old(opt.elevation->answer, "");
     }
 
     /* if area */
-    if (area) {
-	G_debug(1, "drawing areas");
-	nelements = Vect_get_num_areas(&In);
-	G_debug(2, "n_areas = %d", nelements);
-	if (nelements > 0)
+    if (process_area) {
+        int area, nareas, centroid;
+        
+        nareas = Vect_get_num_areas(&In);
+	G_debug(2, "n_areas = %d", nareas);
+	if (nareas > 0)
 	    G_message(_("Extruding areas..."));
-	for (areanum = 1; areanum <= nelements; areanum++) {
-
-	    G_debug(3, "area = %d", areanum);
-
-	    if (!Vect_area_alive(&In, areanum))
+	for (area = 1; area <= nareas; area++) {
+	    G_debug(3, "area = %d", area);
+	    G_percent(area, nareas, 2);
+            
+	    if (!Vect_area_alive(&In, area))
 		continue;
-
-	    centroid = Vect_get_area_centroid(&In, areanum);
+            
+	    centroid = Vect_get_area_centroid(&In, area);
 	    if (!centroid) {
-		G_warning(_("Skipping area %d without centroid"), areanum);
+		G_warning(_("Skipping area %d without centroid"), area);
 		continue;
 	    }
 
+	    Vect_read_line(&In, NULL, Cats, centroid);
+	    if (field > 0 && !Vect_cats_in_constraint(Cats, field, cat_list))
+		continue;
+            
 	    /* height attribute */
-	    if (hcolumn->answer) {
-		cat = Vect_get_area_cat(&In, areanum, Clist->field);
-		db_init_string(&sql);
-		sprintf(query, "SELECT %s FROM %s WHERE %s = %d",
-			hcolumn->answer, Fi->table, Fi->key, cat);
-		G_debug(3, "SQL: %s", query);
-		db_append_string(&sql, query);
-		if (db_open_select_cursor
-		    (driver, &sql, &cursor, DB_SEQUENTIAL)
-		    != DB_OK)
-		    G_fatal_error(_("Cannot select attributes for area %d"),
-				  areanum);
-		table = db_get_cursor_table(&cursor);
-		column = db_get_table_column(table, 0);	/* first column */
+	    if (opt.hcolumn->answer) {
+		cat = Vect_get_area_cat(&In, area, field);
+                if (cat == -1) {
+                    G_warning(_("No category defined for area %d. Using default fixed height %f."),
+                              area, objheight_default);
+                    objheight = objheight_default;
+                }
+                if (get_height(Fi, opt.hcolumn->answer,
+                               driver, cat, &objheight) != 0) {
+                    G_warning(_("Unable to fetch height from DB for area %d. Using default fixed height %f."),
+                              area, objheight_default);
+                    objheight = objheight_default;
+                }
+	    } /* if opt.hcolumn->answer */
 
-		if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
-		    continue;
+	    Vect_get_area_points(&In, area, Points);
 
-		value = db_get_column_value(column);
-		G_debug(3, "column_host_type: %d", db_get_column_host_type(column));
-		objheight = db_get_value_as_double(value, DB_C_TYPE_DOUBLE);
-		G_debug(3, "height from DB: %f", objheight);
-		/* only draw if hcolumn was defined */
-		if (objheight != 0) {
-		    G_debug(3, "area centroid %d: object height: %f",
-			    centroid, objheight);
-		}
+	    G_debug(3, "area: %d height: %f", area, objheight);
 
-	    }			/* if hcolumn->answer */
-
-	    Vect_get_area_points(&In, areanum, Points);
-
-	    G_debug(3, "height: %f", objheight);
-
 	    extrude(&In, &Out, Cats, Points,
-		    fdrast, trace, objheight, voffset, window, GV_AREA,
+		    fdrast, trace, interp_method,
+                    objheight, voffset, &window, GV_AREA,
 		    centroid);
+	} /* foreach area */
 
-	    G_percent(areanum, nelements, 2);
-
-	}			/* foreach area */
-
     }
 
     if (only_type > 0) {
-	G_debug(1, "drawing other than areas");
-	i = 1;
+        int line, nlines;
+        int type;
+        
+	G_debug(1, "other than areas");
 	/* loop through each line in the dataset */
-	nelements = Vect_get_num_lines(&In);
+        nlines = Vect_get_num_lines(&In);
 	G_message(_("Extruding features..."));
-	for (line = 1; line <= nelements; line++) {
+	for (line = 1; line <= nlines; line++) {
+	    /* progress feedback */
+	    G_percent(line, nlines, 2);
 
+	    if (!Vect_line_alive(&In, line))
+		continue;
+
 	    /* read line */
 	    type = Vect_read_line(&In, Points, Cats, line);
 
-	    if (!Vect_line_alive(&In, line))
+	    if (!(type & only_type))
 		continue;
 
-	    if (!(type & only_type))
+	    if (field > 0 && !Vect_cats_in_constraint(Cats, field, cat_list))
 		continue;
 
-	    /* fetch categories */
-	    if (field != -1 && !Vect_cat_get(Cats, field, &cat)) {
-		Vect_cat_set(Cats, 1, i);
-		i++;
-	    }
-
 	    /* height attribute */
-	    if (hcolumn->answer) {
-		cat = Vect_get_line_cat(&In, line, Clist->field);
-
-		/* sql init */
-		db_init_string(&sql);
-		sprintf(query, "SELECT %s FROM %s WHERE %s = %d",
-			hcolumn->answer, Fi->table, Fi->key, cat);
-		G_debug(3, "SQL: %s", query);
-		db_append_string(&sql, query);
-
-		/* cursor init */
-		if (db_open_select_cursor
-		    (driver, &sql, &cursor, DB_SEQUENTIAL)
-		    != DB_OK)
-		    G_fatal_error(_("Cannot select attributes for area #%d"),
-				  areanum);
-		table = db_get_cursor_table(&cursor);
-		column = db_get_table_column(table, 0);	/* first column */
-
-		if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
-		    continue;
-
-		/* objheight value */
-		value = db_get_column_value(column);
-		objheight = db_get_value_as_double(value, ctype);
-
-		/* only draw if hcolumn was defined */
-		if (objheight != 0) {
-		    G_debug(3, "area centroid %d: object height: %f",
-			    centroid, objheight);
-		}
-
-	    }
-
+	    if (opt.hcolumn->answer) {
+		cat = Vect_get_line_cat(&In, line, field);
+                if (cat == -1) {
+                    G_warning(_("No category defined for feature %d. Using default fixed height %f."),
+                              line, objheight_default);
+                    objheight = objheight_default;
+                }
+                if (get_height(Fi, opt.hcolumn->answer,
+                               driver, cat, &objheight) != 0) {
+                    G_warning(_("Unable to fetch height from DB for line %d. Using default fixed height %f."),
+                              line, objheight_default);
+                    objheight = objheight_default;
+                }
+	    } /* if opt.hcolumn->answer */
+            
 	    extrude(&In, &Out, Cats, Points,
-		    fdrast, trace, objheight, voffset, window, type, -1);
+		    fdrast, trace, interp_method,
+                    objheight, voffset, &window, type, -1);
+	} /* for each line */
+    }	  /* else if area */
 
-	    /* progress feedback */
-	    G_percent(line, nelements, 2);
-
-	}			/* for each line */
-    }				/* else if area */
-
     if (driver) {
 	db_close_database(driver);
 	db_shutdown_driver(driver);
@@ -336,7 +339,7 @@
 
     /* header */
     G_asprintf(&comment, "Generated by %s from vector map <%s>",
-	       G_program_name(), old->answer);
+	       G_program_name(), Vect_get_full_name(&In));
     Vect_set_comment(&Out, comment);
     G_free(comment);
 
@@ -352,180 +355,3 @@
     
     exit(EXIT_SUCCESS);
 }
-
-
-/**
-  \brief Extrude vector object
-
-  - point -> 3d line (vertical)
-  - line  -> 3d line
-  - boundary -> face
-  - area -> face + kernel
-
-  \param[in] In input vector map
-  \param[out] Out output vector map
-  \param[in] Cats categories
-  \param[in] Points points
-  \param[in] fdrast background raster map
-  \param[in] trace trace raster map values
-  \param[in] objheight object height
-  \param[in] voffset vertical offset
-  \param[in] window raster region
-  \param[in] type feature type
-  \param[in] centroid number of centroid for area
-  \return number of writen objects
-*/
-static int extrude(struct Map_info *In, struct Map_info *Out,
-		   struct line_cats *Cats, struct line_pnts *Points,
-		   int fdrast, int trace, double objheight, double voffset,
-		   struct Cell_head window, int type, int centroid)
-{
-    int k;			/* Points->n_points */
-    int nlines;
-    struct line_pnts *Points_wall, *Points_roof;
-
-    double voffset_dem;		/* minimal offset */
-    double voffset_curr;	/* offset of current point */
-    double voffset_next;	/* offset of next point */
-
-    nlines = 0;
-
-    if (type != GV_POINT && Points->n_points < 2)
-	return nlines;
-
-    Points_wall = Vect_new_line_struct();
-    Points_roof = Vect_new_line_struct();
-
-    voffset_dem = 0.0;
-    /* do not trace -> calculate minumum dem offset */
-    if (fdrast >= 0 && !trace) {
-	for (k = 0; k < Points->n_points; k++) {
-	    voffset_curr = Rast_get_sample(fdrast, &window, NULL,
-					       Points->y[k], Points->x[k], 0,
-					       NEAREST);
-	    if (Rast_is_d_null_value(&voffset_curr))
-		continue;
-
-	    if (k == 0) {
-		voffset_dem = voffset_curr;
-	    }
-	    else {
-		if (voffset_curr < voffset_dem)
-		    voffset_dem = voffset_curr;
-	    }
-	}
-    }
-
-    
-    /* walls */
-    for (k = 0; ; k++) {
-	voffset_curr = voffset_next = 0.0;
-
-	/* trace */
-	if (fdrast >= 0 && trace) {
-	    voffset_curr = Rast_get_sample(fdrast, &window, NULL,
-					       Points->y[k], Points->x[k], 0,
-					       NEAREST);
-
-	    if (type != GV_POINT) {
-		voffset_next = Rast_get_sample(fdrast, &window, NULL,
-						   Points->y[k + 1],
-						   Points->x[k + 1], 0,
-						   NEAREST);
-	    }
-	}
-
-	if (Rast_is_d_null_value(&voffset_curr) ||
-	    Rast_is_d_null_value(&voffset_next)) {
-	    if (type == GV_POINT)
-		break;
-	    else if (type == GV_LINE) {
-		if (k >= Points->n_points - 1)
-		    break;
-	    }
-	    else if (type & (GV_BOUNDARY | GV_AREA)) {
-		if (k >= Points->n_points - 2)
-		    break;
-	    }
-	    continue;
-	}
-
-	if (trace) {
-	    voffset_curr += voffset;
-	    voffset_next += voffset;
-	}
-	else {
-	    voffset_curr = voffset_dem + voffset;
-	    voffset_next = voffset_dem + voffset;
-	}
-
-	if (type == GV_POINT) {
-	    /* point -> 3d line (vertical) */
-	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
-			      Points->z[k] + voffset_curr);
-	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
-			      Points->z[k] + objheight + voffset_curr);
-	    break;
-	}
-	else if (type == GV_LINE) {
-	    /* line -> 3d line */
-	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
-			      Points->z[k] + objheight + voffset_curr);
-	    if (k >= Points->n_points - 1)
-		break;
-	}
-	else if (type & (GV_BOUNDARY | GV_AREA)) {
-	    /* reset */
-	    Vect_reset_line(Points_wall);
-
-	    /* boudary -> face */
-	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
-			      Points->z[k] + voffset_curr);
-	    Vect_append_point(Points_wall, Points->x[k + 1], Points->y[k + 1],
-			      Points->z[k + 1] + voffset_next);
-	    Vect_append_point(Points_wall, Points->x[k + 1], Points->y[k + 1],
-			      Points->z[k + 1] + objheight + voffset_next);
-	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
-			      Points->z[k] + objheight + voffset_curr);
-	    Vect_append_point(Points_wall, Points->x[k], Points->y[k],
-			      Points->z[k] + voffset_curr);
-
-	    Vect_write_line(Out, GV_FACE, Points_wall, Cats);
-	    nlines++;
-
-	    if (type == GV_AREA) {
-		/* roof */
-		Vect_append_point(Points_roof, Points->x[k], Points->y[k],
-				  Points->z[k] + objheight + voffset_curr);
-	    }
-
-	    if (k >= Points->n_points - 2)
-		break;
-	}
-    }
-
-    if (type & (GV_POINT | GV_LINE)) {
-	Vect_write_line(Out, GV_LINE, Points_wall, Cats);
-	nlines++;
-    }
-    else if (type == GV_AREA && Points_roof->n_points > 3) {
-	Vect_append_point(Points_roof,
-			  Points_roof->x[0], Points_roof->y[0],
-			  Points_roof->z[0]);
-	Vect_write_line(Out, GV_FACE, Points_roof, Cats);
-	nlines++;
-
-	if (centroid > 0) {
-	    /* centroid -> kernel */
-	    Vect_read_line(In, Points, Cats, centroid);
-	    Points->z[0] = Points_roof->z[0] / 2.0;
-	    Vect_write_line(Out, GV_KERNEL, Points, Cats);
-	    nlines++;
-	}
-    }
-
-    Vect_destroy_line_struct(Points_wall);
-    Vect_destroy_line_struct(Points_roof);
-
-    return nlines;
-}

Modified: grass/trunk/vector/v.extrude/v.extrude.html
===================================================================
--- grass/trunk/vector/v.extrude/v.extrude.html	2013-05-12 11:30:24 UTC (rev 56212)
+++ grass/trunk/vector/v.extrude/v.extrude.html	2013-05-12 11:40:23 UTC (rev 56213)
@@ -1,17 +1,40 @@
 <h2>DESCRIPTION</h2>
 
+<em>v.extrude</em> creates faces, kernels or 3D lines based on 2D
+vector features. Points are converted to 3D vertical lines, boundaries
+to faces and areas to volumes (composition of faces and kernel).
+
 <p>
-<em>v.extrude</em> creates faces, kernels, volumes or 3D lines based
-on 2D vector objects, i.e. points become 3D vertical lines, lines to
-3D lines, boundaries to faces and areas to volumes (composition of
-faces and kernel).
+If the flag <b>-t</b> and <b>elevation</b> parameter is used then 3D
+vector features follow the elevation model by using individual
+elevation values for the vertices and nodes. Height is interpolated
+from elevation model using given interpolation <b>method</b>. This can
+be useful for models of large objects (eg. forest stands).
 
+<h2>NOTES</h2>
+
+<em>v.extrude</em> extrudes vector features which means that points
+are converted to vertical lines. Lines are not supported by this
+module.
+
 <p>
-If the flag <b>-t</b> is used then 3D vector objects follow the
-elevation model by using individual elevation values for the vertices
-and nodes. This can be useful for models of large objects (forest
-stands).
+For conversion of 2D points or lines to 3D can be also
+used <em><a href="v.to.3d.html">v.to.3d</a></em>. In opposite
+to <em>v.extrude</em>, <em><a href="v.to.3d.html">v.to.3d</a></em>
+doesn't extrude vector features, it just defines z-coordinate for the
+feature geometry. It means that no feature type conversion is applied,
+points remains still points. Same applies for the lines.
 
+<p>
+<em>v.extrude</em> modifies only features geometry, attribute data
+remain untouched.
+
+<p>
+By default, all features (including features without category) from
+input vector map are processed (<b>layer=-1</b>). Feature selection
+can be applied by <b>layer</b>, <b>cats</b> or <b>where</b>
+parameter.
+
 <h2>EXAMPLES</h2>
 
 <h3>3D houses with fixed height</h3>
@@ -26,10 +49,10 @@
 v.extrude input=houses output=houses3D elevation=dem hcolumn=height type=area
 </pre></div>
 
-<h3>Convert 2D lines to 3D with fixed height</h3>
+<h3>Convert 2D points to 3D vertical lines with fixed height</h3>
 
 <div class="code"><pre>
-v.extrude input=lines output=lines3D elevation=dem height=0 type=line
+v.extrude input=geodetic_pts output=points3D height=200 type=point
 </pre></div>
 
 <h2>SEE ALSO</h2>
@@ -37,7 +60,8 @@
 <em>
 <a href="v.transform.html">v.transform</a>,
 <a href="v.extrude.html">v.extrude</a>,
-<a href="v.drape.html">v.drape</a>
+<a href="v.drape.html">v.drape</a>,
+<a href="v.to.3d.html">v.to.3d</a>
 </em>
 
 <p>
@@ -48,7 +72,8 @@
 <h2>AUTHORS</h2>
 
 Jachym Cepicky,<br>
-Updated by Martin Landa, FBK-irst, Italy
+Updated for GRASS 7 by Martin Landa, FBK-irst,
+Italy and Czech Technical University in Prague, Czech Republic
 
 <p>
 <i>Last changed: $Date$</i>



More information about the grass-commit mailing list