[GRASS-SVN] r51473 - grass/trunk/vector/v.out.vtk
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Apr 18 13:05:00 EDT 2012
Author: mmetz
Date: 2012-04-18 10:05:00 -0700 (Wed, 18 Apr 2012)
New Revision: 51473
Modified:
grass/trunk/vector/v.out.vtk/local_proto.h
grass/trunk/vector/v.out.vtk/main.c
grass/trunk/vector/v.out.vtk/writeVTK.c
Log:
v.out.vtk: port -n flag to trunk
Modified: grass/trunk/vector/v.out.vtk/local_proto.h
===================================================================
--- grass/trunk/vector/v.out.vtk/local_proto.h 2012-04-18 15:52:45 UTC (rev 51472)
+++ grass/trunk/vector/v.out.vtk/local_proto.h 2012-04-18 17:05:00 UTC (rev 51473)
@@ -23,7 +23,7 @@
/*Write the vtk output */
int write_vtk(FILE * ascii, struct Map_info *, int layer, int *types,
- int typenum, int dp, double scale);
+ int typenum, int dp, double scale, int numatts, int labels );
/*Write the VTK header */
int write_vtk_head(FILE * ascii, struct Map_info *Map);
Modified: grass/trunk/vector/v.out.vtk/main.c
===================================================================
--- grass/trunk/vector/v.out.vtk/main.c 2012-04-18 15:52:45 UTC (rev 51472)
+++ grass/trunk/vector/v.out.vtk/main.c 2012-04-18 17:05:00 UTC (rev 51473)
@@ -32,12 +32,12 @@
{
FILE *ascii;
struct Option *input, *output, *type_opt, *dp_opt, *layer_opt, *scale;
- struct Flag *coorcorr;
- int *types = NULL, typenum = 0, dp, i;
+ struct Flag *coorcorr, *numatts, *labels;
+ int itype, *types = NULL, typenum = 0, dp, i;
struct Map_info Map;
+ struct bound_box box;
struct GModule *module;
- int layer;
- struct Cell_head region;
+ int layer, level;
double zscale = 1.0, llscale = 1.0;
@@ -84,11 +84,23 @@
layer_opt->answer = "1";
layer_opt->description = _("Layer number");
- coorcorr = G_define_flag();
- coorcorr->key = 'c';
- coorcorr->description =
- _("Correct the coordinates to fit the VTK-OpenGL precision");
+ coorcorr = G_define_flag();
+ coorcorr->key = 'c';
+ coorcorr->description =
+ _("Correct the coordinates to fit the VTK-OpenGL precision");
+
+ numatts = G_define_flag();
+ numatts->key = 'n';
+ numatts->description =
+ _("Export numeric attribute table fields as VTK scalar variables");
+ labels = NULL; /* to avoid compiler warning about "unused variable"*/
+ /* not yet supported
+ labels = G_define_flag();
+ labels->key = 'l';
+ labels->description = _("Export text attribute table fields as VTK labels");
+ */
+
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
@@ -130,47 +142,17 @@
}
i++;
}
+ itype = Vect_option_to_types(type_opt);
- G_get_set_window(®ion);
-
- /*Correct the coordinates, so the precision of VTK is not hurt :( */
- if (coorcorr->answer) {
- /*Get the default region for coordiante correction */
- G_get_default_window(®ion);
-
- /*Use the center of the current region as extent */
- y_extent = (region.north + region.south) / 2;
- x_extent = (region.west + region.east) / 2;
- }
- else {
- x_extent = 0;
- y_extent = 0;
- }
-
-
/* read and compute the scale factor */
sscanf(scale->answer, "%lf", &zscale);
/*if LL projection, convert the elevation values to degrees */
- if (region.proj == PROJECTION_LL) {
+ if (G_projection() == PROJECTION_LL) {
llscale = M_PI / (180) * 6378137;
zscale /= llscale;
printf("Scale %g\n", zscale);
}
- /*We need level 2 functions */
- Vect_set_open_level(2);
- Vect_open_old(&Map, input->answer, "");
-
- if (output->answer) {
- ascii = fopen(output->answer, "w");
- if (ascii == NULL) {
- G_fatal_error(_("Unable to open file <%s>"), output->answer);
- }
- }
- else {
- ascii = stdout;
- }
-
/*The precision of the output */
if (dp_opt->answer) {
if (sscanf(dp_opt->answer, "%d", &dp) != 1)
@@ -191,10 +173,77 @@
layer = 1;
}
+ if (output->answer) {
+ ascii = fopen(output->answer, "w");
+ if (ascii == NULL) {
+ G_fatal_error(_("Unable to open file <%s>"), output->answer);
+ }
+ }
+ else {
+ ascii = stdout;
+ }
+
+ /* Open input vector */
+ level = Vect_open_old(&Map, input->answer, "");
+ if (level < 2 && (itype & GV_AREA))
+ G_fatal_error(_("Export of areas requires topology. "
+ "Please adjust '%s' option or rebuild topology."),
+ type_opt->key);
+
+ if (level == 2)
+ Vect_get_map_box(&Map, &box);
+ else {
+ int i, type, first = TRUE;
+ struct line_pnts *Points = Vect_new_line_struct();
+
+ Vect_rewind(&Map);
+ while ((type = Vect_read_next_line(&Map, Points, NULL)) > 0) {
+
+ if (first) {
+ box.E = box.W = Points->x[0];
+ box.N = box.S = Points->y[0];
+ box.B = box.T = Points->z[0];
+ first = FALSE;
+ }
+ for (i = 1; i < Points->n_points; i++) {
+ if (Points->x[i] > box.E)
+ box.E = Points->x[i];
+ else if (Points->x[i] < box.W)
+ box.W = Points->x[i];
+
+ if (Points->y[i] > box.N)
+ box.N = Points->y[i];
+ else if (Points->y[i] < box.S)
+ box.S = Points->y[i];
+
+ if (Points->z[i] > box.T)
+ box.T = Points->z[i];
+ else if (Points->z[i] < box.B)
+ box.B = Points->z[i];
+ }
+ }
+ Vect_destroy_line_struct(Points);
+ }
+
+ /*Correct the coordinates, so the precision of VTK is not hurt :( */
+ if (coorcorr->answer) {
+
+ /*Use the center of the vector's bbox as extent */
+ y_extent = (box.N + box.S) / 2;
+ x_extent = (box.W + box.E) / 2;
+ }
+ else {
+ x_extent = 0;
+ y_extent = 0;
+ }
+
/*Write the header */
write_vtk_head(ascii, &Map);
/*Write the geometry and data */
- write_vtk(ascii, &Map, layer, types, typenum, dp, zscale);
+ write_vtk(ascii, &Map, layer, types, typenum, dp, zscale, numatts->answer, 0 );
+ /* change to this, when labels get supported:
+ write_vtk(ascii, &Map, layer, types, typenum, dp, zscale, numatts->answer, labels->answer );
+ */
if (ascii != NULL)
fclose(ascii);
Modified: grass/trunk/vector/v.out.vtk/writeVTK.c
===================================================================
--- grass/trunk/vector/v.out.vtk/writeVTK.c 2012-04-18 15:52:45 UTC (rev 51472)
+++ grass/trunk/vector/v.out.vtk/writeVTK.c 2012-04-18 17:05:00 UTC (rev 51473)
@@ -16,6 +16,7 @@
#include <stdlib.h>
#include <grass/vector.h>
+#include <grass/dbmi.h>
#include <grass/gis.h>
#include <grass/glocale.h>
#include "writeVTK.h"
@@ -44,7 +45,7 @@
Points = Vect_new_line_struct(); /* init line_pnts struct */
Cats = Vect_new_cats_struct();
- G_message("Writing the coordinates");
+ G_message("Writing coordinates ...");
/*For every available vector type */
for (k = 0; k < typenum; k++) {
@@ -54,8 +55,19 @@
/*Get the number of the points to generate */
info->typeinfo[types[k]]->pointoffset = pointoffset;
- info->typeinfo[types[k]]->numpoints =
- Vect_get_num_primitives(Map, types[k]);
+
+ /*count the number of line_nodes and lines */
+ Vect_rewind(Map);
+ while (1) {
+ if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
+ break;
+ if (type == -2) /* EOF */
+ break;
+ if (type == types[k]) {
+ info->typeinfo[types[k]]->numpoints++;
+ }
+ }
+
pointoffset += info->typeinfo[types[k]]->numpoints;
info->typeinfo[types[k]]->numvertices =
@@ -102,7 +114,6 @@
* info->typeinfo[types[k]]->lineoffset);
*/
}
-
}
for (k = 0; k < typenum; k++) {
@@ -137,7 +148,6 @@
* info->typeinfo[types[k]]->polygonoffset);
*/
}
-
}
for (k = 0; k < typenum; k++) {
@@ -185,10 +195,8 @@
if (info->maxnumpoints == 0)
G_fatal_error(_("No coordinates to generate the output! Maybe an empty vector type chosen?"));
-
/************************************************/
/*Write the coordinates into the vtk ascii file */
-
/************************************************/
fprintf(ascii, "POINTS %i float\n", info->maxnumpoints);
@@ -217,7 +225,6 @@
}
cur++;
}
-
}
}
@@ -238,7 +245,6 @@
}
cur++;
}
-
}
}
@@ -259,7 +265,6 @@
}
cur++;
}
-
}
}
@@ -275,7 +280,6 @@
Vect_get_area_points(Map, i, Points);
write_point_coordinates(Points, dp, scale, ascii);
}
-
}
}
@@ -298,7 +302,7 @@
int linekeyword = 1;
int polykeyword = 1;
- G_message("Writing vtk cells");
+ G_message("Writing vtk cells ...");
Points = Vect_new_line_struct(); /* init line_pnts struct */
Cats = Vect_new_cats_struct();
@@ -306,7 +310,6 @@
/*For every available vector type */
for (k = 0; k < typenum; k++) {
-
/*POINT KERNEL CENTROID */
if (types[k] == GV_POINT || types[k] == GV_KERNEL ||
types[k] == GV_CENTROID) {
@@ -465,7 +468,7 @@
Points = Vect_new_line_struct(); /* init line_pnts struct */
Cats = Vect_new_cats_struct();
- G_message("Writing category cell data");
+ G_message("Writing category cell data ...");
if (numcelldata > 0) {
/*Write the pointdata */
@@ -542,25 +545,329 @@
}
}
}
+ fprintf(ascii, "\n");
}
-
return 1;
}
+
+/*
+ Reads the attribute field "name" for current cat and returns the value as a string
+ or NULL on error
+
+ Memory for the result string is allocated by this function and must be free'd by
+ the caller.
+ */
+char *get_att(char *name, int cat, struct field_info *Fi, dbDriver * Driver,
+ int ncol)
+{
+ char buf[2000];
+ int more;
+ dbTable *Table;
+ static dbString dbstring;
+ dbColumn *Column;
+ dbCursor cursor;
+ char *retval;
+ static int first = 1;
+
+ if (first) {
+ db_init_string(&dbstring);
+ first = 0;
+ }
+
+ sprintf(buf, "SELECT %s FROM %s WHERE %s = %d", name, Fi->table, Fi->key, cat);
+
+ db_set_string(&dbstring, buf);
+
+ if (db_open_select_cursor(Driver, &dbstring, &cursor, DB_SEQUENTIAL) !=
+ DB_OK) {
+ G_fatal_error(_("Cannot select attributes for cat = %d"), cat);
+ }
+
+ if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
+ G_fatal_error(_("Unable to fetch data from table"));
+
+ Table = db_get_cursor_table(&cursor);
+
+ Column = db_get_table_column(Table, 0);
+ if (!strcmp(name, db_get_column_name(Column))) {
+ db_convert_column_value_to_string(Column, &dbstring);
+ retval =
+ G_malloc(sizeof(char) *
+ (strlen(db_get_string(&dbstring)) + 1));
+ retval = G_store(db_get_string(&dbstring));
+ db_close_cursor(&cursor);
+ return (retval);
+ }
+
+ db_close_cursor(&cursor);
+ return (NULL);
+}
+
+
+/* ************************************************************************* */
+/* This function writes numerical attribute table fields as VTK scalars **** */
+/* ************************************************************************* */
int write_vtk_db_data(FILE * ascii, struct Map_info *Map, VTKInfo * info,
int layer, int *types, int typenum, int dp)
{
- G_message("Writing database cell/point data");
+ int type, cat, i, k, centroid;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ /*The keywords may only be written once! */
+ int numcelldata =
+ info->maxnumvertices + info->maxnumlines + info->maxnumpolygons;
+ /* attribute table info */
+ int ncol = 0, colsqltype, colctype, num_atts, cur_att, progress;
+ struct field_info *Fi = NULL;
+ dbDriver *Driver = NULL;
+ dbHandle handle;
+ dbTable *Table;
+ dbString dbstring;
+ dbColumn *Column;
+ char *valbuf;
+
+ if (layer < 1) {
+ G_warning(_("Cannot export attribute table fields for layer < 1. Skipping export"));
+ return 1;
+ }
+
+ /* attempt to open attribute table for selected layer */
+ db_init_string(&dbstring);
+ Fi = Vect_get_field(Map, layer);
+ if (Fi == NULL) {
+ G_fatal_error(_("No attribute table found"));
+ }
+ Driver = db_start_driver(Fi->driver);
+ if (Driver == NULL)
+ G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
+
+ db_init_handle(&handle);
+ db_set_handle(&handle, Fi->database, NULL);
+ if (db_open_database(Driver, &handle) != DB_OK)
+ G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
+ Fi->database, Fi->driver);
+
+ db_set_string(&dbstring, Fi->table);
+ if (db_describe_table(Driver, &dbstring, &Table) != DB_OK)
+ G_fatal_error(_("Unable to describe table <%s>"), Fi->table);
+
+ /* analyse field structure */
+ ncol = db_get_table_number_of_columns(Table);
+ num_atts = 0;
+ for (i = 0; i < ncol; i++) {
+ Column = db_get_table_column(Table, i);
+ colsqltype = db_get_column_sqltype(Column);
+ colctype = db_sqltype_to_Ctype(colsqltype);
+ if ((colctype == DB_C_TYPE_INT) || (colctype == DB_C_TYPE_DOUBLE)) {
+ /* we don't want to export the category field twice */
+ if (strcmp(db_get_column_name(Column), "cat")) {
+ num_atts++;
+ /* fprintf ( stderr, "%i: %s\n", num_atts, db_get_column_name(Column) ); */
+ }
+ }
+ }
+ if (num_atts < 1) {
+ G_warning(_("No numerical attributes found. Skipping export"));
+ db_close_database(Driver);
+ db_shutdown_driver(Driver);
+ return 1;
+ }
+
+ Points = Vect_new_line_struct(); /* init line_pnts struct */
+ Cats = Vect_new_cats_struct();
+
+ G_message("Writing %i scalar variables as cell data ...", num_atts);
+
+ progress = 0;
+ for (cur_att = 0; cur_att < ncol; cur_att++) {
+
+ if (numcelldata > 0) {
+ /*Write the pointdata */
+ Column = db_get_table_column(Table, cur_att);
+ colsqltype = db_get_column_sqltype(Column);
+ colctype = db_sqltype_to_Ctype(colsqltype);
+
+ if ((strcmp("cat", db_get_column_name(Column))) &&
+ ((colctype == DB_C_TYPE_INT) ||
+ (colctype == DB_C_TYPE_DOUBLE))) {
+
+ if (colctype == DB_C_TYPE_INT) {
+ /* G_message(" Writing integer scalar %s", db_get_column_name(Column) ); */
+ fprintf(ascii, "SCALARS %s int 1\n",
+ db_get_column_name(Column));
+ }
+ if (colctype == DB_C_TYPE_DOUBLE) {
+ /* *G_message(" Writing double scalar %s", db_get_column_name(Column) ); */
+ fprintf(ascii, "SCALARS %s double 1\n",
+ db_get_column_name(Column));
+ }
+
+ fprintf(ascii, "LOOKUP_TABLE default\n");
+ progress++;
+
+ /*For every available vector type */
+ for (k = 0; k < typenum; k++) {
+ /*POINT KERNEL CENTROID */
+ if (types[k] == GV_POINT || types[k] == GV_KERNEL ||
+ types[k] == GV_CENTROID) {
+
+ Vect_rewind(Map);
+
+ while (1) {
+ if (-1 ==
+ (type =
+ Vect_read_next_line(Map, NULL, Cats)))
+ break;
+ if (type == -2) /* EOF */
+ break;
+ if (type == types[k]) {
+ Vect_cat_get(Cats, layer, &cat);
+ valbuf =
+ get_att((char *)
+ db_get_column_name(Column), cat,
+ Fi, Driver, ncol);
+ if (valbuf == NULL) {
+ db_close_database(Driver);
+ db_shutdown_driver(Driver);
+ G_fatal_error(_("Error reading value of attribute '%s'"),
+ db_get_column_name(Column));
+ }
+ /* DEBUG
+ fprintf ( stderr, "%s (%i) = %s\n", db_get_column_name(Column), cat, valbuf );
+ */
+ fprintf(ascii, " %s", valbuf);
+ G_free(valbuf);
+ }
+ }
+ }
+ }
+
+ for (k = 0; k < typenum; k++) {
+ /*LINE BOUNDARY */
+ if (types[k] == GV_LINE || types[k] == GV_BOUNDARY) {
+ Vect_rewind(Map);
+ while (1) {
+ if (-1 ==
+ (type =
+ Vect_read_next_line(Map, NULL, Cats)))
+ break;
+ if (type == -2) /* EOF */
+ break;
+ if (type == types[k]) {
+ Vect_cat_get(Cats, layer, &cat);
+ valbuf =
+ get_att((char *)
+ db_get_column_name(Column), cat,
+ Fi, Driver, ncol);
+ if (valbuf == NULL) {
+ db_close_database(Driver);
+ db_shutdown_driver(Driver);
+ G_fatal_error(_("Error reading value of attribute '%s'"),
+ db_get_column_name(Column));
+ }
+ /* DEBUG
+ fprintf ( stderr, "%s (%i) = %s\n", db_get_column_name(Column), cat, valbuf );
+ */
+ fprintf(ascii, " %s", valbuf);
+ G_free(valbuf);
+ }
+ }
+ }
+ }
+
+ for (k = 0; k < typenum; k++) {
+ /*FACE */
+ if (types[k] == GV_FACE) {
+ Vect_rewind(Map);
+ while (1) {
+ if (-1 ==
+ (type =
+ Vect_read_next_line(Map, NULL, Cats)))
+ break;
+ if (type == -2) /* EOF */
+ break;
+ if (type == types[k]) {
+ Vect_cat_get(Cats, layer, &cat);
+ valbuf =
+ get_att((char *)
+ db_get_column_name(Column), cat,
+ Fi, Driver, ncol);
+ if (valbuf == NULL) {
+ db_close_database(Driver);
+ db_shutdown_driver(Driver);
+ G_fatal_error(_("Error reading value of attribute '%s'"),
+ db_get_column_name(Column));
+ }
+ /* DEBUG
+ fprintf ( stderr, "%s (%i) = %s\n", db_get_column_name(Column), cat, valbuf );
+ */
+ fprintf(ascii, " %s", valbuf);
+ G_free(valbuf);
+ }
+ }
+ }
+ }
+
+ for (k = 0; k < typenum; k++) {
+ /*AREA */
+ if (types[k] == GV_AREA) {
+ Vect_rewind(Map);
+ for (i = 1;
+ i <= info->typeinfo[types[k]]->numpolygons;
+ i++) {
+ centroid = Vect_get_area_centroid(Map, i);
+ if (centroid > 0) {
+ Vect_read_line(Map, NULL, Cats, centroid);
+ }
+ Vect_cat_get(Cats, layer, &cat);
+ valbuf =
+ get_att((char *)db_get_column_name(Column),
+ cat, Fi, Driver, ncol);
+ if (valbuf == NULL) {
+ db_close_database(Driver);
+ db_shutdown_driver(Driver);
+ G_fatal_error(_("Error reading value of attribute '%s'"),
+ db_get_column_name(Column));
+ }
+ /* DEBUG
+ fprintf ( stderr, "%s (%i) = %s\n", db_get_column_name(Column), cat, valbuf );
+ */
+ fprintf(ascii, " %s", valbuf);
+ G_free(valbuf);
+ }
+ }
+ }
+ fprintf(ascii, "\n");
+ } /* END (do for all scalars != cat */
+ }
+ } /* END (step through all numerical attributes) */
+ fprintf(stdout, "\n");
+ fflush(stdout);
+
+ db_close_database(Driver);
+ db_shutdown_driver(Driver);
+
return 1;
}
+
/* ************************************************************************* */
+/* This function writes attribute table fields as VTK labels **** */
+/* ************************************************************************* */
+int write_vtk_db_labels(FILE * ascii, struct Map_info *Map, VTKInfo * info,
+ int layer, int *types, int typenum, int dp)
+{
+ return 1;
+}
+
+/* ************************************************************************* */
/* This function writes the point coordinates and the geometric feature **** */
/* ************************************************************************* */
int write_vtk(FILE * ascii, struct Map_info *Map, int layer, int *types,
- int typenum, int dp, double scale)
+ int typenum, int dp, double scale, int numatts, int labels)
{
VTKInfo *info;
VTKTypeInfo **typeinfo;
@@ -569,7 +876,6 @@
GV_POINT + GV_KERNEL + GV_CENTROID + GV_LINE + GV_BOUNDARY + GV_FACE +
GV_AREA;
-
/*Initiate the typeinfo structure for every supported type */
typeinfo = (VTKTypeInfo **) calloc(infonum, sizeof(VTKTypeInfo *));
for (i = 0; i < infonum; i++) {
@@ -604,9 +910,15 @@
/*3. write the cat data */
write_vtk_cat_data(ascii, Map, info, layer, types, typenum, dp);
- /*4. write the DB data */
- /* not yet implemented
- write_vtk_db_data(ascii, Map, info, layer, types, typenum, dp);
+ /*4. write the DB data: numerical attributes */
+ if (numatts) {
+ write_vtk_db_data(ascii, Map, info, layer, types, typenum, dp);
+ }
+
+ /*5. Write labels (not yet supported)
+ if ( labels ) {
+ write_vtk_db_labels(ascii, Map, info, layer, types, typenum, dp);
+ }
*/
/*Release the memory */
More information about the grass-commit
mailing list