[GRASS-SVN] r32956 - grass/branches/develbranch_6/vector/v.out.vtk

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Aug 21 05:03:44 EDT 2008


Author: benducke
Date: 2008-08-21 05:03:44 -0400 (Thu, 21 Aug 2008)
New Revision: 32956

Modified:
   grass/branches/develbranch_6/vector/v.out.vtk/description.html
   grass/branches/develbranch_6/vector/v.out.vtk/local_proto.h
   grass/branches/develbranch_6/vector/v.out.vtk/main.c
   grass/branches/develbranch_6/vector/v.out.vtk/writeVTK.c
   grass/branches/develbranch_6/vector/v.out.vtk/writeVTK.h
Log:
This update introduces a new flag "-n" to v.out.vtk.
If -n is specified, then all numeric attributes found in the attribute table
of the vector map to be exported will also be exported to the resulting
VTK file.

Modified: grass/branches/develbranch_6/vector/v.out.vtk/description.html
===================================================================
--- grass/branches/develbranch_6/vector/v.out.vtk/description.html	2008-08-21 08:54:42 UTC (rev 32955)
+++ grass/branches/develbranch_6/vector/v.out.vtk/description.html	2008-08-21 09:03:44 UTC (rev 32956)
@@ -25,6 +25,10 @@
 will be exported.
 <br>
 <br>
+All numeric attribute fields of a given layer of the input map can be exported as scalar VTK
+variables using the "-n" flag.
+<br>
+<br>
 3d vectors are supported by default. The created VTK data always includes x, y and z coordinates 
 (z = 0 if not a 3d vector map).
 Note that you can easily convert your 2d vectors into 3d vectors with v.drape.

Modified: grass/branches/develbranch_6/vector/v.out.vtk/local_proto.h
===================================================================
--- grass/branches/develbranch_6/vector/v.out.vtk/local_proto.h	2008-08-21 08:54:42 UTC (rev 32955)
+++ grass/branches/develbranch_6/vector/v.out.vtk/local_proto.h	2008-08-21 09:03:44 UTC (rev 32956)
@@ -22,13 +22,13 @@
 double x_extent;
 double y_extent;
 #else
-extern double x_extent;
-extern double y_extent;
+extern double x_extent; 
+extern double y_extent; 
 #endif
 
 /*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/branches/develbranch_6/vector/v.out.vtk/main.c
===================================================================
--- grass/branches/develbranch_6/vector/v.out.vtk/main.c	2008-08-21 08:54:42 UTC (rev 32955)
+++ grass/branches/develbranch_6/vector/v.out.vtk/main.c	2008-08-21 09:03:44 UTC (rev 32956)
@@ -3,6 +3,7 @@
  *
  * MODULE:     v.out.vtk  
  * AUTHOR(S):  Soeren Gebbert
+ 	       Benjamin Ducke (support for scalars from attribute table)
  *
  * PURPOSE:    v.out.vtk: writes ASCII VTK file
  *             this module is based on v.out.ascii
@@ -30,15 +31,15 @@
 {
     FILE *ascii;
     struct Option *input, *output, *type_opt, *dp_opt, *layer_opt, *scale;
-    struct Flag *coorcorr;
+    struct Flag *coorcorr, *numatts, *labels;
     int *types = NULL, typenum = 0, dp, i;
     struct Map_info Map;
     struct GModule *module;
     int layer;
     struct Cell_head region;
     double zscale = 1.0, llscale = 1.0;
-
-
+   
+    
     G_gisinit(argv[0]);
 
     module = G_define_module();
@@ -81,11 +82,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);
 
@@ -98,10 +111,10 @@
     else {
 	G_fatal_error("Usage: Wrong vector type");
     }
-
+  
     i = 0;
     while (type_opt->answers[i]) {
-	types[i] = -1;
+        types[i] = -1;
 	switch (type_opt->answers[i][0]) {
 	case 'p':
 	    types[i] = GV_POINT;
@@ -132,26 +145,25 @@
 
     /*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(&region);
+       /*Get the default region for coordiante correction*/
+       G_get_default_window(&region);
 
-	/*Use the center of the current region as extent */
-	y_extent = (region.north + region.south) / 2;
-	x_extent = (region.west + region.east) / 2;
+       /*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;
     }
-    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) {
-	llscale = M_PI / (180) * 6378137;
-	zscale /= llscale;
-	printf("Scale %g\n", zscale);
+    /* if LL projection, convert the elevation values to degrees*/
+    if(region.proj == PROJECTION_LL) {
+      llscale = M_PI / (180) * 6378137;
+      zscale /= llscale;
+      printf("Scale %g\n", zscale);
     }
 
     /*We need level 2 functions */
@@ -191,7 +203,10 @@
     /*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);
@@ -200,3 +215,4 @@
 
     exit(EXIT_SUCCESS);
 }
+

Modified: grass/branches/develbranch_6/vector/v.out.vtk/writeVTK.c
===================================================================
--- grass/branches/develbranch_6/vector/v.out.vtk/writeVTK.c	2008-08-21 08:54:42 UTC (rev 32955)
+++ grass/branches/develbranch_6/vector/v.out.vtk/writeVTK.c	2008-08-21 09:03:44 UTC (rev 32956)
@@ -16,6 +16,7 @@
 
 #include <stdlib.h>
 #include <grass/Vect.h>
+#include <grass/dbmi.h>
 #include <grass/gis.h>
 #include <grass/glocale.h>
 #include "writeVTK.h"
@@ -25,15 +26,14 @@
 
 /*Prototype */
 /*Formated coordinates output */
-static void write_point_coordinates(struct line_pnts *Points, int dp,
-				    double scale, FILE * ascii);
+static void write_point_coordinates(struct line_pnts *Points, int dp, double scale, FILE * ascii);
 
 
 /* ************************************************************************* */
 /* This function writes the vtk points and coordinates ********************* */
 /* ************************************************************************* */
 int write_vtk_points(FILE * ascii, struct Map_info *Map, VTKInfo * info,
-		     int *types, int typenum, int dp, double scale)
+		    int *types, int typenum, int dp, double scale)
 {
     int type, cur, i, k, centroid;
     int pointoffset = 0;
@@ -288,12 +288,11 @@
 /* This function writes the vtk cells ************************************** */
 /* ************************************************************************* */
 int write_vtk_cells(FILE * ascii, struct Map_info *Map, VTKInfo * info,
-		    int *types, int typenum)
+		   int *types, int typenum)
 {
     int type, i, j, k, centroid;
     static struct line_pnts *Points;
     struct line_cats *Cats;
-
     /*The keywords may only be written once! */
     int vertkeyword = 1;
     int linekeyword = 1;
@@ -317,7 +316,7 @@
 	    if (info->typeinfo[types[k]]->numpoints > 0) {
 		if (vertkeyword) {
 		    fprintf(ascii, "VERTICES %i %i\n", info->maxnumvertices,
-			    info->maxnumvertices * 2);
+			    info->maxnumvertices * 2 );
 		    vertkeyword = 0;
 		}
 		for (i = 0; i < info->typeinfo[types[k]]->numpoints; i++) {
@@ -357,8 +356,7 @@
 			fprintf(ascii, "%i", Points->n_points);
 			while (Points->n_points--) {
 			    fprintf(ascii, " %i",
-				    i +
-				    info->typeinfo[types[k]]->pointoffset);
+				    i + info->typeinfo[types[k]]->pointoffset);
 			    i++;
 			}
 			fprintf(ascii, "\n");
@@ -397,8 +395,7 @@
 			fprintf(ascii, "%i", Points->n_points);
 			while (Points->n_points--) {
 			    fprintf(ascii, " %i",
-				    i +
-				    info->typeinfo[types[k]]->pointoffset);
+				    i + info->typeinfo[types[k]]->pointoffset);
 			    i++;
 			}
 			fprintf(ascii, "\n");
@@ -453,12 +450,11 @@
 /* This function writes the categories as vtk cell data ******************** */
 /* ************************************************************************* */
 int write_vtk_cat_data(FILE * ascii, struct Map_info *Map, VTKInfo * info,
-		       int layer, int *types, int typenum, int dp)
+		      int layer, int *types, int typenum, int dp)
 {
     int type, cat, i, k, centroid;
     static struct line_pnts *Points;
     struct line_cats *Cats;
-
     /*The keywords may only be written once! */
     int numcelldata =
 	info->maxnumvertices + info->maxnumlines + info->maxnumpolygons;
@@ -543,25 +539,306 @@
 		}
 	    }
 	}
+	
+	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 ) {
+    int      j;
+    char     buf[2000];
+    int      more;
+    dbTable  *Table;
+    dbString dbstring;
+    dbColumn *Column;
+    dbCursor cursor;
+    char *retval;
+    
+    db_init_string(&dbstring);
+    
+    sprintf ( buf, "SELECT * FROM %s WHERE %s = %d", 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);
+    
+    for (j = 0; j < ncol; j++) {
+        Column = db_get_table_column (Table, j);
+     	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 = strdup ( db_get_string (&dbstring) );
+		return (retval);
+	}
+    }
+    
+    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)
+		     int layer, int *types, int typenum, int dp)
 {
-    G_message("Writing database cell/point data");
+    int type, cat, i, k, centroid;
+    static 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, Points, 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, Points, 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, Points, 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 */
+	
+    }
+    
+      G_percent(progress,num_atts,1);
+      
+    } /* 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;
@@ -605,10 +882,17 @@
     /*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 */
     for (i = 0; i < infonum; i++) {
@@ -623,8 +907,7 @@
 /* ************************************************************************* */
 /* This function writes the point coordinates ****************************** */
 /* ************************************************************************* */
-void write_point_coordinates(struct line_pnts *Points, int dp, double scale,
-			     FILE * ascii)
+void write_point_coordinates(struct line_pnts *Points, int dp, double scale, FILE * ascii)
 {
     char *xstring = NULL, *ystring = NULL, *zstring = NULL;
     double *xptr, *yptr, *zptr;

Modified: grass/branches/develbranch_6/vector/v.out.vtk/writeVTK.h
===================================================================
--- grass/branches/develbranch_6/vector/v.out.vtk/writeVTK.h	2008-08-21 08:54:42 UTC (rev 32955)
+++ grass/branches/develbranch_6/vector/v.out.vtk/writeVTK.h	2008-08-21 09:03:44 UTC (rev 32956)
@@ -47,14 +47,14 @@
 
 /*Writes the point cooridanets for every vector type */
 int write_vtk_points(FILE * ascii, struct Map_info *Map, VTKInfo * info,
-		     int *type, int typenum, int dp, double scale);
+		    int *type, int typenum, int dp, double scale);
 /*Writes the polydata cells for every vector type */
 int write_vtk_cells(FILE * ascii, struct Map_info *Map, VTKInfo * info,
-		    int *type, int typenum);
+		   int *type, int typenum);
 /*Write the category (the first available) as cell or point data */
 int write_vtk_cat_data(FILE * ascii, struct Map_info *Map, VTKInfo * info,
-		       int layer, int *type, int typenum, int dp);
+		      int layer, int *type, int typenum, int dp);
 /*If a database connection is given, write the db data as cell or point data */
 int write_vtk_db_data(FILE * ascii, struct Map_info *Map, VTKInfo * info,
-		      int layer, int *type, int typenum, int dp);
+		     int layer, int *type, int typenum, int dp);
 #endif



More information about the grass-commit mailing list