[GRASS-SVN] r47791 - grass/trunk/lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Aug 21 07:03:07 EDT 2011
Author: martinl
Date: 2011-08-21 04:03:07 -0700 (Sun, 21 Aug 2011)
New Revision: 47791
Modified:
grass/trunk/lib/vector/Vlib/write_ogr.c
Log:
vlib: improve writing attributes for OGR
Modified: grass/trunk/lib/vector/Vlib/write_ogr.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_ogr.c 2011-08-21 11:01:07 UTC (rev 47790)
+++ grass/trunk/lib/vector/Vlib/write_ogr.c 2011-08-21 11:03:07 UTC (rev 47791)
@@ -7,8 +7,13 @@
Inspired by v.out.ogr's code.
- (C) 2009-2010 by the GRASS Development Team
+ \todo OGR version of V2__delete_area_cats_from_cidx_nat()
+ \todo function to delete corresponding entry in fidx
+ \todo OGR version of V2__add_area_cats_to_cidx_nat
+ \todo OGR version of V2__add_line_to_topo_nat
+ (C) 2009-2011 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.
@@ -22,20 +27,16 @@
#ifdef HAVE_OGR
#include <ogr_api.h>
-static int write_attributes(int, const struct field_info *,
+static int sqltype_to_ogrtype(int);
+static dbDriver *create_table(OGRLayerH, const struct field_info *);
+static int write_attributes(dbDriver *, int, const struct field_info *,
OGRLayerH, OGRFeatureH);
-/* TODO:
- * OGR version of V2__delete_area_cats_from_cidx_nat()
- * function to delete corresponding entry in fidx
- * OGR version of V2__add_area_cats_to_cidx_nat
- * OGR version of V2__add_line_to_topo_nat
- */
-
void V2__add_line_to_topo_ogr(struct Map_info *Map, int line,
- const struct line_pnts *points, const struct line_cats *cats)
+ const struct line_pnts *points,
+ const struct line_cats *cats)
{
- /* recycle code from build_ogr */
+ /* recycle code from build_ogr */
G_warning("feature not yet implemented, coming soon...");
return;
@@ -52,13 +53,16 @@
\return feature offset into file
\return -1 on error
*/
-off_t V1_write_line_ogr(struct Map_info *Map,
- int type, const struct line_pnts *points, const struct line_cats *cats)
+off_t V1_write_line_ogr(struct Map_info *Map, int type,
+ const struct line_pnts *points,
+ const struct line_cats *cats)
{
int i, cat, ret;
struct field_info *Fi;
+ dbDriver *driver;
+
OGRGeometryH Ogr_geometry;
OGRFeatureH Ogr_feature;
OGRFeatureDefnH Ogr_featuredefn;
@@ -69,6 +73,20 @@
return -1;
}
+ /* check for attributes */
+ Fi = Vect_get_field(Map, cats->field[0]);
+ driver = NULL;
+ cat = -1; /* no attributes to be written */
+ if (Fi && cats->n_cats > 0) {
+ cat = cats->cat[0];
+ if (cats->n_cats > 1) {
+ G_warning(_("Feature has more categories, using "
+ "category %d (from layer %d)"),
+ cat, cats->field[0]);
+ }
+ driver = create_table(Map->fInfo.ogr.layer, Fi);
+ }
+
Ogr_featuredefn = OGR_L_GetLayerDefn(Map->fInfo.ogr.layer);
Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
@@ -120,15 +138,9 @@
OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
/* write attributes */
- Fi = Vect_get_field(Map, cats->field[0]);
- if (Fi && cats->n_cats > 0) {
- cat = cats->cat[0];
- if (cats->n_cats > 1) {
- G_warning(_("Feature has more categories, using "
- "category %d (from layer %d)"),
- cat, cats->field[0]);
- }
- write_attributes(cat, Fi, Map->fInfo.ogr.layer, Ogr_feature);
+ if (driver && cat > -1) {
+ write_attributes(driver, cat, Fi, Map->fInfo.ogr.layer, Ogr_feature);
+ db_close_database_shutdown_driver(driver);
}
/* write feature into layer */
@@ -348,20 +360,97 @@
return ret;
}
-int write_attributes(int cat, const struct field_info *Fi,
+dbDriver *create_table(OGRLayerH hLayer, const struct field_info *Fi)
+{
+ int col, ncols;
+ int sqltype, ogrtype;
+
+ const char *colname;
+
+ dbDriver *driver;
+ dbHandle handle;
+ dbCursor cursor;
+ dbTable *table;
+ dbColumn *column;
+ dbString sql;
+
+ OGRFieldDefnH hFieldDefn;
+ OGRFeatureDefnH hFeatureDefn;
+
+ db_init_string(&sql);
+ db_init_handle(&handle);
+
+ driver = db_start_driver(Fi->driver);
+ if (!driver) {
+ G_warning(_("Unable to start driver <%s>"), Fi->driver);
+ return NULL;
+ }
+ db_set_handle(&handle, Fi->database, NULL);
+ if (db_open_database(driver, &handle) != DB_OK) {
+ G_warning(_("Unable to open database <%s> by driver <%s>"),
+ Fi->database, Fi->driver);
+ db_close_database_shutdown_driver(driver);
+ return NULL;
+ }
+
+ /* to get no data */
+ db_set_string(&sql, "select * from ");
+ db_append_string(&sql, Fi->table);
+ db_append_string(&sql, " where 0 = 1");
+
+ if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) !=
+ DB_OK) {
+ G_warning(_("Unable to open select cursor: '%s'"),
+ db_get_string(&sql));
+ db_close_database_shutdown_driver(driver);
+ return NULL;
+ }
+
+ table = db_get_cursor_table(&cursor);
+ ncols = db_get_table_number_of_columns(table);
+
+ hFeatureDefn = OGR_L_GetLayerDefn(hLayer);
+
+ for (col = 0; col < ncols; col++) {
+ column = db_get_table_column(table, col);
+ colname = db_get_column_name(column);
+ sqltype = db_get_column_sqltype(column);
+ ogrtype = sqltype_to_ogrtype(sqltype);
+
+ if (OGR_FD_GetFieldIndex(hFeatureDefn, colname) > -1) {
+ /* field already exists */
+ continue;
+ }
+
+ hFieldDefn = OGR_Fld_Create(colname, ogrtype);
+ /* OGR_Fld_SetWidth(hFieldDefn, length); */
+ if (OGR_L_CreateField(hLayer, hFieldDefn, TRUE) != OGRERR_NONE) {
+ G_warning(_("Creating field <%s> failed\n"), colname);
+ db_close_database_shutdown_driver(driver);
+ return NULL;
+ }
+
+ OGR_Fld_Destroy(hFieldDefn);
+ }
+
+ return driver;
+}
+
+int write_attributes(dbDriver *driver, int cat, const struct field_info *Fi,
OGRLayerH Ogr_layer, OGRFeatureH Ogr_feature)
{
int j, ogrfieldnum;
char buf[2000];
int ncol, colsqltype, colctype, more;
- const char *fidcol;
- dbDriver *Driver;
- dbTable *Table;
+ const char *fidcol, *colname;
+ dbTable *table;
dbString dbstring;
- dbColumn *Column;
+ dbColumn *column;
dbCursor cursor;
- dbValue *Value;
+ dbValue *value;
+ OGRFieldDefnH hFieldDefn;
+
G_debug(3, "write_attributes(): cat = %d", cat);
if (cat < 0) {
@@ -377,12 +466,8 @@
G_debug(4, "SQL: %s", buf);
db_set_string(&dbstring, buf);
- /* open driver & select data */
- Driver = db_start_driver_open_database(Fi->driver, Fi->database);
- if (!Driver)
- G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
- Fi->database, Fi->driver);
- if (db_open_select_cursor(Driver, &dbstring, &cursor, DB_SEQUENTIAL) != DB_OK) {
+ /* select data */
+ if (db_open_select_cursor(driver, &dbstring, &cursor, DB_SEQUENTIAL) != DB_OK) {
G_fatal_error(_("Unable to select attributes for category %d"),
cat);
}
@@ -393,57 +478,63 @@
}
if (!more) {
- G_warning (_("No database record for category %d - export of 'cat' disabled"),
- cat);
+ G_warning(_("No database record for category %d, "
+ "no attributes will be written"),
+ cat);
return -1;
}
fidcol = OGR_L_GetFIDColumn(Ogr_layer);
- Table = db_get_cursor_table(&cursor);
- ncol = db_get_table_number_of_columns(Table);
+ table = db_get_cursor_table(&cursor);
+ ncol = db_get_table_number_of_columns(table);
for (j = 0; j < ncol; j++) {
- Column = db_get_table_column(Table, j);
- if (fidcol && strcmp(db_get_column_name(Column), fidcol) == 0) {
+ column = db_get_table_column(table, j);
+ colname = db_get_column_name(column);
+ if (fidcol && *fidcol && strcmp(colname, fidcol) == 0) {
/* skip fid column */
continue;
}
- Value = db_get_column_value(Column);
- db_convert_column_value_to_string(Column, &dbstring); /* for debug only */
+ value = db_get_column_value(column);
+ /* for debug only */
+ db_convert_column_value_to_string(column, &dbstring);
G_debug(2, "col %d : val = %s", j,
db_get_string(&dbstring));
- colsqltype = db_get_column_sqltype(Column);
+ colsqltype = db_get_column_sqltype(column);
colctype = db_sqltype_to_Ctype(colsqltype);
G_debug(2, " colctype = %d", colctype);
- ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature,
- db_get_column_name(Column));
+ ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname);
if (ogrfieldnum < 0) {
- G_warning(_("Uknown column <%s>"),
- db_get_column_name(Column));
- continue;
+ /* create field if not exists */
+ hFieldDefn = OGR_Fld_Create(colname,
+ sqltype_to_ogrtype(colsqltype));
+ if (OGR_L_CreateField(Ogr_layer, hFieldDefn, TRUE) != OGRERR_NONE)
+ G_warning(_("Unable to create field <%s>"), colname);
+ ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname);
}
+
/* Reset */
OGR_F_UnsetField(Ogr_feature, ogrfieldnum);
/* prevent writing NULL values */
- if (!db_test_value_isnull(Value)) {
+ if (!db_test_value_isnull(value)) {
switch (colctype) {
case DB_C_TYPE_INT:
OGR_F_SetFieldInteger(Ogr_feature, ogrfieldnum,
- db_get_value_int(Value));
+ db_get_value_int(value));
break;
case DB_C_TYPE_DOUBLE:
OGR_F_SetFieldDouble(Ogr_feature, ogrfieldnum,
- db_get_value_double(Value));
+ db_get_value_double(value));
break;
case DB_C_TYPE_STRING:
OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
- db_get_value_string(Value));
+ db_get_value_string(value));
break;
case DB_C_TYPE_DATETIME:
- db_convert_column_value_to_string(Column,
+ db_convert_column_value_to_string(column,
&dbstring);
OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
db_get_string(&dbstring));
@@ -453,12 +544,38 @@
}
db_close_cursor (&cursor);
- db_close_database(Driver);
- db_shutdown_driver(Driver);
db_free_string(&dbstring);
return 1;
}
+int sqltype_to_ogrtype(int sqltype)
+{
+ switch(sqltype) {
+ case DB_SQL_TYPE_CHARACTER:
+ case DB_SQL_TYPE_TEXT:
+ return OFTString;
+ case DB_SQL_TYPE_SMALLINT:
+ case DB_SQL_TYPE_INTEGER:
+ case DB_SQL_TYPE_SERIAL:
+ return OFTInteger;
+ case DB_SQL_TYPE_REAL:
+ case DB_SQL_TYPE_DOUBLE_PRECISION:
+ case DB_SQL_TYPE_DECIMAL:
+ case DB_SQL_TYPE_NUMERIC:
+ return OFTReal;
+ case DB_SQL_TYPE_DATE:
+ return OFTDate;
+ case DB_SQL_TYPE_TIME:
+ return OFTTime;
+ case DB_SQL_TYPE_TIMESTAMP:
+ return OFTDateTime;
+ case DB_SQL_TYPE_INTERVAL:
+ return OFTString; /* ??? */
+ }
+
+ return OFTString;
+}
+
#endif /* HAVE_OGR */
More information about the grass-commit
mailing list