[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