[GRASS-SVN] r45044 - grass/trunk/vector/v.out.ogr

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Jan 14 17:58:48 EST 2011


Author: benducke
Date: 2011-01-14 14:58:48 -0800 (Fri, 14 Jan 2011)
New Revision: 45044

Modified:
   grass/trunk/vector/v.out.ogr/args.c
   grass/trunk/vector/v.out.ogr/attrb.c
   grass/trunk/vector/v.out.ogr/local_proto.h
   grass/trunk/vector/v.out.ogr/main.c
   grass/trunk/vector/v.out.ogr/v.out.ogr.html
Log:
This commit contains some small bugfixes, code clean-ups, performance improvement, and a new feature for v.out.ogr.
1. Fixed a but that would spawn ugly error messages in conjunction with the "-s" flag
2. Reduced the SQL SELECT statements to just one instead of one per feature, increasing output speed by several magnitudes.
3. Added a new "-z" flag, which provides a simple and robust means of producing 3D ESRI Shapefiles
--> Please test intensively!

Modified: grass/trunk/vector/v.out.ogr/args.c
===================================================================
--- grass/trunk/vector/v.out.ogr/args.c	2011-01-14 22:51:32 UTC (rev 45043)
+++ grass/trunk/vector/v.out.ogr/args.c	2011-01-14 22:58:48 UTC (rev 45044)
@@ -95,6 +95,11 @@
     flags->esristyle->description = _("Use ESRI-style .prj file format "
 				      "(applies to Shapefile output only)");
     flags->esristyle->guisection = _("Creation");
+
+    flags->shapez = G_define_flag();
+    flags->shapez->key = 'z';
+    flags->shapez->description = _("Create 3D output if input is 3D "
+       			      "(applies to Shapefile output only)");
     
     flags->poly = G_define_flag();
     flags->poly->key = 'p';

Modified: grass/trunk/vector/v.out.ogr/attrb.c
===================================================================
--- grass/trunk/vector/v.out.ogr/attrb.c	2011-01-14 22:51:32 UTC (rev 45043)
+++ grass/trunk/vector/v.out.ogr/attrb.c	2011-01-14 22:58:48 UTC (rev 45044)
@@ -4,15 +4,13 @@
 
 int mk_att(int cat, struct field_info *Fi, dbDriver *Driver, int ncol,
 	   int doatt, int nocat, OGRFeatureH Ogr_feature, int *noatt,
-	   int *fout)
+	   int *fout, dbCursor cursor)
 {
     int j, ogrfieldnum;
-    char buf[2000];
     int colsqltype, colctype, more;
     dbTable *Table;
     dbString dbstring;
     dbColumn *Column;
-    dbCursor cursor;
     dbValue *Value;
 
     G_debug(2, "mk_att() cat = %d, doatt = %d", cat, doatt);
@@ -30,16 +28,6 @@
     /* Read & set attributes */
     if (cat >= 0) {		/* Line with category */
 	if (doatt) {
-	    sprintf(buf, "SELECT * FROM %s WHERE %s = %d", Fi->table, Fi->key,
-		    cat);
-	    G_debug(2, "SQL: %s", buf);
-	    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);
-	    }
-	    else {
 		if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
 		    G_fatal_error(_("Unable to fetch data from table"));
 		if (!more) {
@@ -76,10 +64,15 @@
 				db_get_column_name(Column), ogrfieldnum);
 
 			/* Reset */
-			OGR_F_UnsetField(Ogr_feature, ogrfieldnum);
+			if ( ( ( nocat ) && (strcmp(Fi->key, db_get_column_name(Column)) == 0) ) == 0 ) {
+				/* if this is 'cat', then execute the following only if the '-s' flag was NOT given*/
+				OGR_F_UnsetField(Ogr_feature, ogrfieldnum);
+			}
 
 			/* prevent writing NULL values */
 			if (!db_test_value_isnull(Value)) {
+				if ( ( (nocat) && (strcmp(Fi->key, db_get_column_name(Column)) == 0) ) == 0 ) {
+				/* if this is 'cat', then execute the following only if the '-s' flag was NOT given*/
 			    switch (colctype) {
 			    case DB_C_TYPE_INT:
 				OGR_F_SetFieldInteger(Ogr_feature,
@@ -107,9 +100,8 @@
 			    }
 			}
 		    }
+		    }
 		}
-		db_close_cursor(&cursor);
-	    }
 	}
 	else {			/* Use cat only */
 	    ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, "cat");

Modified: grass/trunk/vector/v.out.ogr/local_proto.h
===================================================================
--- grass/trunk/vector/v.out.ogr/local_proto.h	2011-01-14 22:51:32 UTC (rev 45043)
+++ grass/trunk/vector/v.out.ogr/local_proto.h	2011-01-14 22:58:48 UTC (rev 45044)
@@ -5,13 +5,18 @@
 #include "ogr_api.h"
 #include "cpl_string.h"
 
+
+/* some hard limits */
+#define SQL_BUFFER_SIZE 2000
+
+
 struct Options {
     struct Option *input, *dsn, *layer, *type, *format,
 	*field, *dsco, *lco;
 };
 
 struct Flags {
-    struct Flag *cat, *esristyle, *poly, *update, *nocat, *new, *append;
+    struct Flag *cat, *esristyle, *poly, *update, *nocat, *new, *append, *shapez;
 };
 
 /* args.c */
@@ -20,7 +25,7 @@
 
 /* attributes.c */
 int mk_att(int cat, struct field_info *Fi, dbDriver *Driver,
-	   int ncol, int doatt, int nocat, OGRFeatureH Ogr_feature, int *, int *);
+	   int ncol, int doatt, int nocat, OGRFeatureH Ogr_feature, int *, int *, dbCursor cursor);
 
 /* list.c */
 char *OGR_list_write_drivers();

Modified: grass/trunk/vector/v.out.ogr/main.c
===================================================================
--- grass/trunk/vector/v.out.ogr/main.c	2011-01-14 22:51:32 UTC (rev 45043)
+++ grass/trunk/vector/v.out.ogr/main.c	2011-01-14 22:58:48 UTC (rev 45044)
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+
 #include <grass/config.h>
 #include <grass/gis.h>
 #include <grass/gprojects.h>
@@ -37,9 +38,8 @@
     struct Options options;
     struct Flags flags;
 
-    char buf[2000];
-    char key1[200], key2[200];
-    struct Key_Value *projinfo, *projunits;
+    char buf[SQL_BUFFER_SIZE];
+    char key1[SQL_BUFFER_SIZE], key2[SQL_BUFFER_SIZE];    struct Key_Value *projinfo, *projunits;
     struct Cell_head cellhd;
     char **tokens;
 
@@ -56,6 +56,7 @@
     dbTable *Table;
     dbString dbstring;
     dbColumn *Column;
+    dbCursor cursor;
 
     int fout, fskip;		/* features written/ skip */
     int nocat, noatt, nocatskip;	/* number of features without cats/atts written/skip */
@@ -263,6 +264,133 @@
 	G_warning(_("The map contains islands. With the -c flag, "
 		    "islands will appear as filled areas, not holes in the output map."));
 
+
+    /* check what users wants to export and what's present in the map */
+    if (Vect_get_num_primitives(&In, GV_POINT) > 0 && !(otype & GV_POINTS))
+	G_warning(_("%d point(s) found, but not requested to be exported. "
+		    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
+									 GV_POINT));
+
+    if (Vect_get_num_primitives(&In, GV_LINE) > 0 && !(otype & GV_LINES))
+	G_warning(_("%d line(s) found, but not requested to be exported. "
+		    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
+									 GV_LINE));
+
+    if (Vect_get_num_primitives(&In, GV_BOUNDARY) > 0 &&
+	!(otype & GV_BOUNDARY) && !(otype & GV_AREA))
+	G_warning(_("%d boundary(ies) found, but not requested to be exported. "
+		   "Verify 'type' parameter."), Vect_get_num_primitives(&In,
+									GV_BOUNDARY));
+
+    if (Vect_get_num_primitives(&In, GV_CENTROID) > 0 &&
+	!(otype & GV_CENTROID) && !(otype & GV_AREA))
+	G_warning(_("%d centroid(s) found, but not requested to be exported. "
+		    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
+									 GV_CENTROID));
+
+    if (Vect_get_num_areas(&In) > 0 && !(otype & GV_AREA))
+	G_warning(_("%d areas found, but not requested to be exported. "
+		    "Verify 'type' parameter."), Vect_get_num_areas(&In));
+
+    if (Vect_get_num_primitives(&In, GV_FACE) > 0 && !(otype & GV_FACE))
+	G_warning(_("%d faces found, but not requested to be exported. "
+		    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
+									 GV_FACE));
+
+    if (Vect_get_num_volumes(&In) > 0 && !(otype & GV_VOLUME))
+	G_warning(_("%d volume(s) found, but not requested to be exported. "
+		    "Verify 'type' parameter."), Vect_get_num_volumes(&In));
+
+    /* warn and eventually abort if there is nothing to be exported */
+    num_to_export = 0;
+    if (Vect_get_num_primitives(&In, GV_POINT) < 1 && (otype & GV_POINTS)) {
+	G_warning(_("No points found, but requested to be exported. "
+		    "Will skip this feature type."));
+    }
+    else {
+	if (otype & GV_POINT)
+	    num_to_export =
+		num_to_export + Vect_get_num_primitives(&In, GV_POINT);
+    }
+
+    if (Vect_get_num_primitives(&In, GV_LINE) < 1 && (otype & GV_LINE)) {
+	G_warning(_("No lines found, but requested to be exported. "
+		    "Will skip this feature type."));
+    }
+    else {
+	if (otype & GV_LINE)
+	    num_to_export =
+		num_to_export + Vect_get_num_primitives(&In, GV_LINE);
+    }
+
+    if (Vect_get_num_primitives(&In, GV_BOUNDARY) < 1 &&
+	(otype & GV_BOUNDARY)) {
+	G_warning(_("No boundaries found, but requested to be exported. "
+		   "Will skip this feature type."));
+    }
+    else {
+	if (otype & GV_BOUNDARY)
+	    num_to_export =
+		num_to_export + Vect_get_num_primitives(&In, GV_BOUNDARY);
+    }
+
+    if (Vect_get_num_areas(&In) < 1 && (otype & GV_AREA)) {
+	G_warning(_("No areas found, but requested to be exported. "
+		    "Will skip this feature type."));
+    }
+    else {
+	if (otype & GV_AREA)
+	    num_to_export = num_to_export + Vect_get_num_areas(&In);
+    }
+
+    if (Vect_get_num_primitives(&In, GV_CENTROID) < 1 &&
+	(otype & GV_CENTROID)) {
+	G_warning(_("No centroids found, but requested to be exported. "
+		   "Will skip this feature type."));
+    }
+    else {
+	if (otype & GV_CENTROID)
+	    num_to_export =
+		num_to_export + Vect_get_num_primitives(&In, GV_CENTROID);
+    }
+
+    if (Vect_get_num_primitives(&In, GV_FACE) < 1 && (otype & GV_FACE)) {
+	G_warning(_("No faces found, but requested to be exported. "
+		    "Will skip this feature type."));
+    }
+    else {
+	if (otype & GV_FACE)
+	    num_to_export =
+		num_to_export + Vect_get_num_primitives(&In, GV_FACE);
+    }
+
+    if (Vect_get_num_primitives(&In, GV_KERNEL) < 1 && (otype & GV_KERNEL)) {
+	G_warning(_("No kernels found, but requested to be exported. "
+		    "Will skip this feature type."));
+    }
+    else {
+	if (otype & GV_KERNEL)
+	    num_to_export =
+		num_to_export + Vect_get_num_primitives(&In, GV_KERNEL);
+    }
+
+    if (Vect_get_num_volumes(&In) < 1 && (otype & GV_VOLUME)) {
+	G_warning(_("No volumes found, but requested to be exported. "
+		    "Will skip this feature type."));
+    }
+    else {
+	if (otype & GV_VOLUME)
+	    num_to_export = num_to_export + Vect_get_num_volumes(&In);
+    }
+
+    G_debug(1, "Requested to export %d features", num_to_export);
+
+    if (num_to_export < 1) {
+	G_warning(_("Nothing to export"));
+	exit(EXIT_SUCCESS);
+    }
+
+
     /* Open OGR DSN */
     G_debug(2, "driver count = %d", OGRGetDriverCount());
     drn = -1;
@@ -327,6 +455,36 @@
 	    }
 	}
     }
+
+    /* Automatically append driver options for 3D output to
+	 layer creation options if 'z' is given.*/
+	if ((flags.shapez->answer) && (Vect_is_3d(&In)) && (strcmp(options.format->answer,
+			"ESRI_Shapefile") == 0)) {
+		/* find right option */
+		char shape_geom[20];
+		if ((otype & GV_POINTS) || (otype & GV_KERNEL))
+			sprintf(shape_geom, "POINTZ");
+		if ((otype & GV_LINES))
+			sprintf(shape_geom, "ARCZ");
+		if ((otype & GV_AREA) || (otype & GV_FACE))
+			sprintf(shape_geom, "POLYGONZ");
+		/* check if the right LCO is already present */
+		const char *shpt;
+		shpt = CSLFetchNameValue(papszLCO, "SHPT");
+		if ((!shpt)) {
+			/* Not set at all? Good! */
+			papszLCO = CSLSetNameValue(papszLCO, "SHPT", shape_geom);
+		} else {
+			if (strcmp(shpt, shape_geom) != 0) {
+				/* Set but to a different value? Override! */
+				G_warning(_("Overriding existing user-defined 'SHPT=' LCO."));
+			}
+			/* Set correct LCO for this geometry type */
+			papszLCO = CSLSetNameValue(papszLCO, "SHPT", shape_geom);
+		}
+	}
+
+
     /* check if the map is 3d */
     if (Vect_is_3d(&In)) {
 	/* specific check for ESRI ShapeFile */
@@ -337,7 +495,7 @@
 	    if (!shpt || shpt[strlen(shpt) - 1] != 'Z') {
 		G_warning(_("Vector map <%s> is 3D. "
 			    "Use format specific layer creation options SHPT (parameter 'lco') "
-			    "to export in 3D rather than 2D (default)"),
+			    "or '-z' flag to export in 3D rather than 2D (default)"),
 			  options.input->answer);
 	    }
 	}
@@ -485,131 +643,20 @@
 
     fout = fskip = nocat = noatt = nocatskip = 0;
 
-    /* check what users wants to export and what's present in the map */
-    if (Vect_get_num_primitives(&In, GV_POINT) > 0 && !(otype & GV_POINTS))
-	G_warning(_("%d point(s) found, but not requested to be exported. "
-		    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
-									 GV_POINT));
 
-    if (Vect_get_num_primitives(&In, GV_LINE) > 0 && !(otype & GV_LINES))
-	G_warning(_("%d line(s) found, but not requested to be exported. "
-		    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
-									 GV_LINE));
-
-    if (Vect_get_num_primitives(&In, GV_BOUNDARY) > 0 &&
-	!(otype & GV_BOUNDARY) && !(otype & GV_AREA))
-	G_warning(_("%d boundary(ies) found, but not requested to be exported. "
-		   "Verify 'type' parameter."), Vect_get_num_primitives(&In,
-									GV_BOUNDARY));
-
-    if (Vect_get_num_primitives(&In, GV_CENTROID) > 0 &&
-	!(otype & GV_CENTROID) && !(otype & GV_AREA))
-	G_warning(_("%d centroid(s) found, but not requested to be exported. "
-		    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
-									 GV_CENTROID));
-
-    if (Vect_get_num_areas(&In) > 0 && !(otype & GV_AREA))
-	G_warning(_("%d areas found, but not requested to be exported. "
-		    "Verify 'type' parameter."), Vect_get_num_areas(&In));
-
-    if (Vect_get_num_primitives(&In, GV_FACE) > 0 && !(otype & GV_FACE))
-	G_warning(_("%d faces found, but not requested to be exported. "
-		    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
-									 GV_FACE));
-
-    if (Vect_get_num_volumes(&In) > 0 && !(otype & GV_VOLUME))
-	G_warning(_("%d volume(s) found, but not requested to be exported. "
-		    "Verify 'type' parameter."), Vect_get_num_volumes(&In));
-
-    /* warn and eventually abort if there is nothing to be exported */
-    num_to_export = 0;
-    if (Vect_get_num_primitives(&In, GV_POINT) < 1 && (otype & GV_POINTS)) {
-	G_warning(_("No points found, but requested to be exported. "
-		    "Will skip this feature type."));
+    /* Fetch all attribute records */
+    if (doatt) {
+    	sprintf(buf, "SELECT * FROM %s", Fi->table);
+    	G_debug(2, "SQL: %s", buf);
+    	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);
+    	}
     }
-    else {
-	if (otype & GV_POINT)
-	    num_to_export =
-		num_to_export + Vect_get_num_primitives(&In, GV_POINT);
-    }
 
-    if (Vect_get_num_primitives(&In, GV_LINE) < 1 && (otype & GV_LINE)) {
-	G_warning(_("No lines found, but requested to be exported. "
-		    "Will skip this feature type."));
-    }
-    else {
-	if (otype & GV_LINE)
-	    num_to_export =
-		num_to_export + Vect_get_num_primitives(&In, GV_LINE);
-    }
 
-    if (Vect_get_num_primitives(&In, GV_BOUNDARY) < 1 &&
-	(otype & GV_BOUNDARY)) {
-	G_warning(_("No boundaries found, but requested to be exported. "
-		   "Will skip this feature type."));
-    }
-    else {
-	if (otype & GV_BOUNDARY)
-	    num_to_export =
-		num_to_export + Vect_get_num_primitives(&In, GV_BOUNDARY);
-    }
-
-    if (Vect_get_num_areas(&In) < 1 && (otype & GV_AREA)) {
-	G_warning(_("No areas found, but requested to be exported. "
-		    "Will skip this feature type."));
-    }
-    else {
-	if (otype & GV_AREA)
-	    num_to_export = num_to_export + Vect_get_num_areas(&In);
-    }
-
-    if (Vect_get_num_primitives(&In, GV_CENTROID) < 1 &&
-	(otype & GV_CENTROID)) {
-	G_warning(_("No centroids found, but requested to be exported. "
-		   "Will skip this feature type."));
-    }
-    else {
-	if (otype & GV_CENTROID)
-	    num_to_export =
-		num_to_export + Vect_get_num_primitives(&In, GV_CENTROID);
-    }
-
-    if (Vect_get_num_primitives(&In, GV_FACE) < 1 && (otype & GV_FACE)) {
-	G_warning(_("No faces found, but requested to be exported. "
-		    "Will skip this feature type."));
-    }
-    else {
-	if (otype & GV_FACE)
-	    num_to_export =
-		num_to_export + Vect_get_num_primitives(&In, GV_FACE);
-    }
-
-    if (Vect_get_num_primitives(&In, GV_KERNEL) < 1 && (otype & GV_KERNEL)) {
-	G_warning(_("No kernels found, but requested to be exported. "
-		    "Will skip this feature type."));
-    }
-    else {
-	if (otype & GV_KERNEL)
-	    num_to_export =
-		num_to_export + Vect_get_num_primitives(&In, GV_KERNEL);
-    }
-
-    if (Vect_get_num_volumes(&In) < 1 && (otype & GV_VOLUME)) {
-	G_warning(_("No volumes found, but requested to be exported. "
-		    "Will skip this feature type."));
-    }
-    else {
-	if (otype & GV_VOLUME)
-	    num_to_export = num_to_export + Vect_get_num_volumes(&In);
-    }
-
-    G_debug(1, "Requested to export %d features", num_to_export);
-
-    if (num_to_export < 1) {
-	G_warning(_("Nothing to export"));
-	exit(EXIT_SUCCESS);
-    }
-
     /* Lines (run always to count features of different type) */
     if ((otype & GV_POINTS) || (otype & GV_LINES)) {
 	G_message(_("Exporting %i features..."), Vect_get_num_lines(&In));
@@ -683,7 +730,7 @@
 		}
 
 		mk_att(cat, Fi, Driver, ncol, doatt, flags.nocat->answer,
-		       Ogr_feature, &noatt, &fout);
+		       Ogr_feature, &noatt, &fout, cursor);
 		OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
 	    }
 	    OGR_G_DestroyGeometry(Ogr_geometry);
@@ -758,7 +805,7 @@
 		}
 
 		mk_att(cat, Fi, Driver, ncol, doatt, flags.nocat->answer,
-		       Ogr_feature, &noatt, &fout);
+		       Ogr_feature, &noatt, &fout, cursor);
 		OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
 	    }
 	    OGR_G_DestroyGeometry(Ogr_geometry);
@@ -818,7 +865,7 @@
 		    }
 
 		    mk_att(cat, Fi, Driver, ncol, doatt, flags.nocat->answer,
-			   Ogr_feature, &noatt, &fout);
+			   Ogr_feature, &noatt, &fout, cursor);
 		    OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
 		}
 
@@ -873,7 +920,7 @@
 		    }
 
 		    mk_att(cat, Fi, Driver, ncol, doatt, flags.nocat->answer,
-			   Ogr_feature, &noatt, &fout);
+			   Ogr_feature, &noatt, &fout, cursor);
 		    OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
 		}
 		OGR_G_DestroyGeometry(Ogr_geometry);
@@ -898,6 +945,7 @@
     Vect_close(&In);
 
     if (doatt) {
+    db_close_cursor(&cursor);
 	db_close_database(Driver);
 	db_shutdown_driver(Driver);
     }

Modified: grass/trunk/vector/v.out.ogr/v.out.ogr.html
===================================================================
--- grass/trunk/vector/v.out.ogr/v.out.ogr.html	2011-01-14 22:51:32 UTC (rev 45043)
+++ grass/trunk/vector/v.out.ogr/v.out.ogr.html	2011-01-14 22:58:48 UTC (rev 45044)
@@ -26,6 +26,9 @@
 By default, islands will appear as holes inside surrounding areas.
 To export areas with holes into, e.g., a Shapefile, and make the 
 holes appear as filled areas, the flag <em>-c</em> has to be used.
+<p>
+The "-z" flag can be used to automatically export a 3D map to a 3D Shapefile, instead 
+of setting the correct <em>lco=</em> option manually.
 
 <h2>EXAMPLES</h2>
 
@@ -56,6 +59,11 @@
 <div class="code"><pre>
 v.out.ogr input=objects_3d type=face dsn=faces_3d.shp lco="SHPT=POLYGONZ"
 </pre></div>
+<p>
+Export 3D faces from GRASS vector map to Shapefile format, automatic 3D setting:
+<div class="code"><pre>
+v.out.ogr input=objects_3d type=face dsn=faces_3d.shp -z"
+</pre></div>
 
 <h3>Export to GML</h3>
 



More information about the grass-commit mailing list