[GRASS-SVN] r72215 - grass/branches/releasebranch_7_4/vector/v.in.ogr
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Feb 8 13:34:17 PST 2018
Author: neteler
Date: 2018-02-08 13:34:17 -0800 (Thu, 08 Feb 2018)
New Revision: 72215
Modified:
grass/branches/releasebranch_7_4/vector/v.in.ogr/main.c
Log:
v.in.ogr: fix duplicate column names (trunk, r72209; fixes #3488)
Modified: grass/branches/releasebranch_7_4/vector/v.in.ogr/main.c
===================================================================
--- grass/branches/releasebranch_7_4/vector/v.in.ogr/main.c 2018-02-08 09:23:33 UTC (rev 72214)
+++ grass/branches/releasebranch_7_4/vector/v.in.ogr/main.c 2018-02-08 21:34:17 UTC (rev 72215)
@@ -82,6 +82,31 @@
OGRFeatureH ogr_getnextfeature(struct OGR_iterator *, int, char *,
OGRGeometryH , const char *);
+struct grass_col_info
+{
+ int idx; /* index for create table */
+ const char *name;
+ const char *type;
+};
+
+/* for qsort: compare columns by name */
+int cmp_col_name(const void *a, const void *b)
+{
+ struct grass_col_info *ca = (struct grass_col_info *)a;
+ struct grass_col_info *cb = (struct grass_col_info *)b;
+
+ return strcmp(ca->name, cb->name);
+}
+
+/* for qsort: compare columns by index */
+int cmp_col_idx(const void *a, const void *b)
+{
+ struct grass_col_info *ca = (struct grass_col_info *)a;
+ struct grass_col_info *cb = (struct grass_col_info *)b;
+
+ return (ca->idx - cb->idx);
+}
+
int main(int argc, char *argv[])
{
struct GModule *module;
@@ -892,6 +917,9 @@
/* Add DB link and create table */
if (!flag.notab->answer) {
+ int i_out, ncols_out, done;
+ struct grass_col_info *col_info;
+
G_important_message(_("Creating attribute table for layer <%s>..."),
layer_names[layer]);
@@ -913,14 +941,24 @@
ncols = OGR_FD_GetFieldCount(Ogr_featuredefn);
G_debug(2, "%d columns", ncols);
+ ncols_out = ncols;
+ if (key_idx[layer] < 0)
+ ncols_out++;
+
+ col_info = G_malloc(ncols_out * sizeof(struct grass_col_info));
+
/* Create table */
- sprintf(buf, "create table %s (%s integer", Fi->table,
- key_column[layer]);
- db_set_string(&sql, buf);
+ i_out = 0;
+ col_info[i_out].idx = i_out;
+ col_info[i_out].name = key_column[layer];
+ col_info[i_out].type = "integer";
+
for (i = 0; i < ncols; i++) {
if (key_idx[layer] > -1 && key_idx[layer] == i)
continue; /* skip defined key (FID column) */
+
+ i_out++;
Ogr_field = OGR_FD_GetFieldDefn(Ogr_featuredefn, i);
Ogr_ftype = OGR_Fld_GetType(Ogr_field);
@@ -941,8 +979,8 @@
}
- /* avoid that we get the 'cat' column twice */
- if (strcmp(Ogr_fieldname, GV_KEY_COLUMN) == 0) {
+ /* avoid that we get the key column twice */
+ if (strcmp(Ogr_fieldname, key_column[layer]) == 0) {
sprintf(namebuf, "%s_", Ogr_fieldname);
Ogr_fieldname = G_store(namebuf);
}
@@ -955,6 +993,8 @@
G_important_message(_("Column name <%s> renamed to <%s>"),
OGR_Fld_GetNameRef(Ogr_field), Ogr_fieldname);
}
+ col_info[i_out].idx = i_out;
+ col_info[i_out].name = G_store(Ogr_fieldname);
/** Simple 32bit integer OFTInteger = 0 **/
/** List of 32bit integers OFTIntegerList = 1 **/
@@ -973,14 +1013,14 @@
/** List of 64bit integers OFTInteger64List = 13 **/
if (Ogr_ftype == OFTInteger) {
- sprintf(buf, ", %s integer", Ogr_fieldname);
+ col_info[i_out].type = "integer";
}
#if GDAL_VERSION_NUM >= 2000000
else if (Ogr_ftype == OFTInteger64) {
if (strcmp(Fi->driver, "pg") == 0)
- sprintf(buf, ", %s bigint", Ogr_fieldname);
+ col_info[i_out].type = "bigint";
else {
- sprintf(buf, ", %s integer", Ogr_fieldname);
+ col_info[i_out].type = "integer";
if (strcmp(Fi->driver, "sqlite") != 0)
G_warning(_("Writing column <%s> with integer 64 as integer 32"),
Ogr_fieldname);
@@ -993,23 +1033,24 @@
#endif
) {
/* hack: treat as string */
- sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname,
- OFTIntegerListlength);
+ sprintf(buf, "varchar ( %d )", OFTIntegerListlength);
+ col_info[i_out].type = G_store(buf);
G_warning(_("Writing column <%s> with fixed length %d chars (may be truncated)"),
Ogr_fieldname, OFTIntegerListlength);
}
else if (Ogr_ftype == OFTReal) {
- sprintf(buf, ", %s double precision", Ogr_fieldname);
+ col_info[i_out].type = "double precision";
#if GDAL_VERSION_NUM >= 1320
}
else if (Ogr_ftype == OFTDate) {
- sprintf(buf, ", %s date", Ogr_fieldname);
+ col_info[i_out].type = "date";
}
else if (Ogr_ftype == OFTTime) {
- sprintf(buf, ", %s time", Ogr_fieldname);
+ col_info[i_out].type = "time";
}
else if (Ogr_ftype == OFTDateTime) {
- sprintf(buf, ", %s %s", Ogr_fieldname, datetime_type);
+ sprintf(buf, "%s", datetime_type);
+ col_info[i_out].type = G_store(buf);
#endif
}
else if (Ogr_ftype == OFTString) {
@@ -1023,13 +1064,13 @@
Ogr_fieldname);
fwidth = 255;
}
- sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname,
- fwidth);
+ sprintf(buf, "varchar ( %d )", fwidth);
+ col_info[i_out].type = G_store(buf);
}
else if (Ogr_ftype == OFTStringList) {
/* hack: treat as string */
- sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname,
- OFTIntegerListlength);
+ sprintf(buf, "varchar ( %d )", OFTIntegerListlength);
+ col_info[i_out].type = G_store(buf);
G_warning(_("Writing column %s with fixed length %d chars (may be truncated)"),
Ogr_fieldname, OFTIntegerListlength);
}
@@ -1037,10 +1078,48 @@
G_warning(_("Column type (Ogr_ftype: %d) not supported (Ogr_fieldname: %s)"),
Ogr_ftype, Ogr_fieldname);
buf[0] = 0;
+ col_info[i_out].type = G_store(buf);
}
- db_append_string(&sql, buf);
G_free(Ogr_fieldname);
}
+
+ /* fix duplicate column names */
+ done = 0;
+
+ while (!done) {
+ done = 1;
+ qsort(col_info, ncols_out, sizeof(struct grass_col_info),
+ cmp_col_name);
+ for (i = 0; i < ncols_out - 1; i++) {
+ int i_a;
+
+ i_a = 1;
+ while (i + i_a < ncols_out &&
+ strcmp(col_info[i].name, col_info[i + i_a].name) == 0) {
+ G_important_message(_("Column name <%s> renamed to <%s_%d>"),
+ col_info[i + i_a].name,
+ col_info[i + i_a].name, i_a);
+ sprintf(buf, "%s_%d", col_info[i + i_a].name, i_a);
+ col_info[i + i_a].name = G_store(buf);
+ i_a++;
+ done = 0;
+ }
+ }
+ }
+ qsort(col_info, ncols_out, sizeof(struct grass_col_info),
+ cmp_col_idx);
+
+ /* construct sql from column names and types */
+ i = 0;
+ sprintf(buf, "create table %s (%s %s", Fi->table,
+ col_info[i].name, col_info[i].type);
+ db_set_string(&sql, buf);
+
+ for (i = 1; i < ncols_out; i++) {
+ sprintf(buf, ", %s %s", col_info[i].name, col_info[i].type);
+ db_append_string(&sql, buf);
+ }
+
db_append_string(&sql, ")");
G_debug(3, "%s", db_get_string(&sql));
@@ -1067,6 +1146,8 @@
Fi->table);
db_close_database_shutdown_driver(driver);
+
+ G_free(col_info);
}
}
More information about the grass-commit
mailing list