[GRASS-SVN] r51126 - in grass/trunk: include/defs lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Mar 21 07:08:56 EDT 2012
Author: martinl
Date: 2012-03-21 04:08:56 -0700 (Wed, 21 Mar 2012)
New Revision: 51126
Modified:
grass/trunk/include/defs/vector.h
grass/trunk/lib/vector/Vlib/build_pg.c
grass/trunk/lib/vector/Vlib/close_ogr.c
grass/trunk/lib/vector/Vlib/open.c
grass/trunk/lib/vector/Vlib/open_ogr.c
grass/trunk/lib/vector/Vlib/open_pg.c
grass/trunk/lib/vector/Vlib/write.c
grass/trunk/lib/vector/Vlib/write_pg.c
Log:
vlib(pg): implement V2_open_new_pg()
various improvements when writing creating new PostGIS layer
cosmetics in OGR interface (use OGR_L_GetName)
Modified: grass/trunk/include/defs/vector.h
===================================================================
--- grass/trunk/include/defs/vector.h 2012-03-21 11:05:18 UTC (rev 51125)
+++ grass/trunk/include/defs/vector.h 2012-03-21 11:08:56 UTC (rev 51126)
@@ -477,6 +477,7 @@
int V1_open_new_ogr(struct Map_info *, const char *, int);
int V1_open_new_pg(struct Map_info *, const char *, int);
int V2_open_new_ogr(struct Map_info *, int);
+int V2_open_new_pg(struct Map_info *, int);
int V1_rewind_nat(struct Map_info *);
int V1_rewind_ogr(struct Map_info *);
int V1_rewind_pg(struct Map_info *);
Modified: grass/trunk/lib/vector/Vlib/build_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_pg.c 2012-03-21 11:05:18 UTC (rev 51125)
+++ grass/trunk/lib/vector/Vlib/build_pg.c 2012-03-21 11:08:56 UTC (rev 51126)
@@ -74,7 +74,7 @@
if (!pg_info->fid_column) {
G_warning(_("Feature table <%s> has no primary key defined"),
pg_info->table_name);
- G_warning(_("Random read is not supported by OGR for this layer. "
+ G_warning(_("Random read is not supported for this layer. "
"Unable to build topology."));
return 0;
}
Modified: grass/trunk/lib/vector/Vlib/close_ogr.c
===================================================================
--- grass/trunk/lib/vector/Vlib/close_ogr.c 2012-03-21 11:05:18 UTC (rev 51125)
+++ grass/trunk/lib/vector/Vlib/close_ogr.c 2012-03-21 11:08:56 UTC (rev 51126)
@@ -68,6 +68,8 @@
G_free(ogr_info->driver_name);
G_free(ogr_info->dsn);
G_free(ogr_info->layer_name);
+ if (ogr_info->layer_options)
+ G_free_tokens(ogr_info->layer_options);
return 0;
#else
Modified: grass/trunk/lib/vector/Vlib/open.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open.c 2012-03-21 11:05:18 UTC (rev 51125)
+++ grass/trunk/lib/vector/Vlib/open.c 2012-03-21 11:08:56 UTC (rev 51126)
@@ -693,29 +693,97 @@
}
/* determine output format native or ogr */
- if (strcmp(G_program_name(), "v.external") != 0 &&
- G_find_file2("", "OGR", G_mapset())) {
- /* OGR */
- FILE *fp;
- struct Key_Value *key_val;
- const char *p;
-
- G_debug(2, " using OGR format");
- Map->format = GV_FORMAT_OGR_DIRECT;
- fp = G_fopen_old("", "OGR", G_mapset());
- if (!fp) {
- G_warning(_("Unable to open OGR file"));
+ if (strcmp(G_program_name(), "v.external") != 0) {
+ if (G_find_file2("", "OGR", G_mapset())) {
+ /* OGR */
+ FILE *fp;
+ const char *p;
+
+ struct Key_Value *key_val;
+ struct Format_info_ogr *ogr_info;
+
+ G_debug(2, " using OGR format");
+ Map->format = GV_FORMAT_OGR_DIRECT;
+ fp = G_fopen_old("", "OGR", G_mapset());
+ if (!fp) {
+ G_fatal_error(_("Unable to open OGR file"));
+ }
+ key_val = G_fread_key_value(fp);
+ fclose(fp);
+
+ ogr_info = &(Map->fInfo.ogr);
+ /* format */
+ p = G_find_key_value("format", key_val);
+ if (p)
+ ogr_info->driver_name = G_store(p);
+ /* dsn */
+ p = G_find_key_value("dsn", key_val);
+ if (p)
+ ogr_info->dsn = G_store(p);
+ /* options */
+ p = G_find_key_value("options", key_val);
+ if (p)
+ ogr_info->layer_options = G_tokenize(p, ",");
+
+ ogr_info->layer_name = G_store(name);
}
- key_val = G_fread_key_value(fp);
- fclose(fp);
-
- p = G_find_key_value("format", key_val);
- if (p)
- Map->fInfo.ogr.driver_name = G_store(p);
- p = G_find_key_value("dsn", key_val);
- if (p)
- Map->fInfo.ogr.dsn = G_store(p);
- Map->fInfo.ogr.layer_name = G_store(name);
+ if (G_find_file2("", "PG", G_mapset())) {
+ /* PostGIS */
+ if (Map->fInfo.ogr.driver_name) {
+ G_warning(_("OGR output also detected, using OGR"));
+ }
+ else {
+ FILE *fp;
+ const char *p;
+
+ struct Key_Value *key_val;
+ struct Format_info_pg *pg_info;
+
+ G_debug(2, " using PostGIS format");
+ Map->format = GV_FORMAT_POSTGIS;
+ fp = G_fopen_old("", "PG", G_mapset());
+ if (!fp) {
+ G_fatal_error(_("Unable to open PG file"));
+ }
+ key_val = G_fread_key_value(fp);
+ fclose(fp);
+
+ pg_info = &(Map->fInfo.pg);
+ /* conninfo */
+ p = G_find_key_value("conninfo", key_val);
+ if (p) {
+ pg_info->conninfo = G_store(p);
+ G_debug(1, "PG: conninfo = '%s'", pg_info->conninfo);
+ }
+
+ /* schema (default: public) */
+ p = G_find_key_value("schema", key_val);
+ if (p)
+ pg_info->schema_name = G_store(p);
+ else
+ pg_info->schema_name = G_store("public");
+ G_debug(1, "PG: schema_name = '%s'", pg_info->schema_name);
+
+ /* fid column (default: ogc_fid) */
+ p = G_find_key_value("fid", key_val);
+ if (p)
+ pg_info->fid_column = G_store(p);
+ else
+ pg_info->fid_column = G_store("ogc_fid");
+ G_debug(1, "PG: fid_column = '%s'", pg_info->fid_column);
+
+ /* geometry column (default: wkb_geometry) */
+ p = G_find_key_value("geometry_name", key_val);
+ if (p)
+ pg_info->geom_column = G_store(p);
+ else
+ pg_info->geom_column = G_store("wkb_geometry");
+ G_debug(1, "PG: geom_column = '%s'", pg_info->geom_column);
+
+ /* table name */
+ Map->fInfo.pg.table_name = G_store(name);
+ }
+ }
}
else {
/* native */
Modified: grass/trunk/lib/vector/Vlib/open_ogr.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open_ogr.c 2012-03-21 11:05:18 UTC (rev 51125)
+++ grass/trunk/lib/vector/Vlib/open_ogr.c 2012-03-21 11:08:56 UTC (rev 51126)
@@ -54,7 +54,6 @@
OGRDataSourceH Ogr_ds;
OGRLayerH Ogr_layer;
- OGRFeatureDefnH Ogr_featuredefn;
OGRwkbGeometryType Ogr_geom_type;
Ogr_layer = NULL;
@@ -90,9 +89,8 @@
for (i = 0; i < nLayers; i++) {
Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
- Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
- if (strcmp(OGR_FD_GetName(Ogr_featuredefn), ogr_info->layer_name) == 0) {
- Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
+ if (strcmp(OGR_L_GetName(Ogr_layer), ogr_info->layer_name) == 0) {
+ Ogr_geom_type = OGR_L_GetGeomType(Ogr_layer);
layer = i;
break;
}
@@ -180,7 +178,6 @@
OGRSFDriverH Ogr_driver;
OGRDataSourceH Ogr_ds;
OGRLayerH Ogr_layer;
- OGRFeatureDefnH Ogr_featuredefn;
OGRRegisterAll();
@@ -206,8 +203,7 @@
nlayers = OGR_DS_GetLayerCount(Ogr_ds);
for (i = 0; i < nlayers; i++) {
Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
- Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
- if (strcmp(OGR_FD_GetName(Ogr_featuredefn), name) == 0) {
+ if (strcmp(OGR_L_GetName(Ogr_layer), name) == 0) {
if (G_get_overwrite()) {
G_warning(_("OGR layer <%s> already exists and will be overwritten"),
ogr_info->layer_name);
@@ -277,6 +273,7 @@
G_free_key_value(projinfo);
G_free_key_value(projunits);
+ /* determine geometry type */
switch(type) {
case GV_POINT:
Ogr_geom_type = wkbPoint;
@@ -292,6 +289,7 @@
return -1;
}
+ /* check creation options */
Ogr_layer_options = ogr_info->layer_options;
if (Vect_is_3d(Map)) {
if (strcmp(ogr_info->driver_name, "PostgreSQL") == 0) {
@@ -303,6 +301,8 @@
Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "2");
}
}
+
+ /* create new OGR layer */
Ogr_layer = OGR_DS_CreateLayer(ogr_info->ds, ogr_info->layer_name,
Ogr_spatial_ref, Ogr_geom_type, Ogr_layer_options);
CSLDestroy(Ogr_layer_options);
@@ -325,8 +325,8 @@
G_free(Fi);
}
else
- G_warning(_("Database connection not defined. "
- "Unable to write attributes."));
+ G_warning(_("Database connection not defined. "
+ "Unable to write attributes."));
}
if (OGR_L_TestCapability(ogr_info->layer, OLCTransactions))
Modified: grass/trunk/lib/vector/Vlib/open_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open_pg.c 2012-03-21 11:05:18 UTC (rev 51125)
+++ grass/trunk/lib/vector/Vlib/open_pg.c 2012-03-21 11:08:56 UTC (rev 51126)
@@ -23,68 +23,10 @@
#ifdef HAVE_POSTGRES
#include "pg_local_proto.h"
-static char *get_key_column(struct Format_info_pg *pg_info)
-{
- char *key_column;
- char stmt[DB_SQL_MAX];
-
- PGresult *res;
-
- sprintf(stmt,
- "SELECT kcu.column_name "
- "FROM INFORMATION_SCHEMA.TABLES t "
- "LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc "
- "ON tc.table_catalog = t.table_catalog "
- "AND tc.table_schema = t.table_schema "
- "AND tc.table_name = t.table_name "
- "AND tc.constraint_type = 'PRIMARY KEY' "
- "LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu "
- "ON kcu.table_catalog = tc.table_catalog "
- "AND kcu.table_schema = tc.table_schema "
- "AND kcu.table_name = tc.table_name "
- "AND kcu.constraint_name = tc.constraint_name "
- "WHERE t.table_name = '%s'", pg_info->table_name);
-
- res = PQexec(pg_info->conn, stmt);
- if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
- PQntuples(res) != 1) {
- G_warning(_("No key column detected."));
- if (res)
- PQclear(res);
- return NULL;
- }
- key_column = G_store(PQgetvalue(res, 0, 0));
-
- PQclear(res);
-
- return key_column;
-}
-
-static SF_FeatureType ftype_from_string(const char *type)
-{
- SF_FeatureType sf_type;
-
- if (G_strcasecmp(type, "POINT") == 0)
- return SF_POINT;
- else if (G_strcasecmp(type, "LINESTRING") == 0)
- return SF_LINESTRING;
- else if (G_strcasecmp(type, "POLYGON") == 0)
- return SF_POLYGON;
- else if (G_strcasecmp(type, "MULTIPOINT") == 0)
- return SF_MULTIPOINT;
- else if (G_strcasecmp(type, "MULTILINESTRING") == 0)
- return SF_MULTILINESTRING;
- else if (G_strcasecmp(type, "MULTIPOLYGON") == 0)
- return SF_MULTIPOLYGON;
- else if (G_strcasecmp(type, "GEOMETRYCOLLECTION") == 0)
- return SF_GEOMETRYCOLLECTION;
-
- return SF_UNKNOWN;
-
- G_debug(3, "ftype_from_string(): type='%s' -> %d", type, sf_type);
-
- return sf_type;
-}
+static char *get_key_column(struct Format_info_pg *);
+static SF_FeatureType ftype_from_string(const char *);
+static int drop_table(struct Format_info_pg *);
+static int create_table(struct Format_info_pg *, const struct field_info *);
#endif
/*!
@@ -101,16 +43,14 @@
int V1_open_old_pg(struct Map_info *Map, int update)
{
#ifdef HAVE_POSTGRES
- int found, ntables, i;
+ int found;
- dbString stmt;
+ char stmt[DB_SQL_MAX];
PGresult *res;
struct Format_info_pg *pg_info;
- db_init_string(&stmt);
-
pg_info = &(Map->fInfo.pg);
if (!pg_info->conninfo) {
G_warning(_("Connection string not defined"));
@@ -139,54 +79,44 @@
return -1;
}
+ /* if schema not defined, use 'public' */
+ if (!pg_info->schema_name) {
+ pg_info->schema_name = G_store("public");
+ }
+
/* get fid and geometry column */
- db_set_string(&stmt, "SELECT f_table_schema, f_table_name, f_geometry_column,"
- "coord_dimension, srid, type "
- "FROM geometry_columns");
- G_debug(2, "SQL: %s", db_get_string(&stmt));
+ sprintf(stmt, "SELECT f_geometry_column, coord_dimension, srid, type "
+ "FROM geometry_columns WHERE f_table_schema = '%s' AND "
+ "f_table_name = '%s'",
+ pg_info->schema_name, pg_info->table_name);
+ G_debug(2, "SQL: %s", stmt);
- res = PQexec(pg_info->conn, db_get_string(&stmt));
+ res = PQexec(pg_info->conn, stmt);
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
G_fatal_error("%s\n%s", _("No feature tables found in database."),
PQresultErrorMessage(res));
-
- ntables = PQntuples(res);
- G_debug(3, "\tnrows = %d", ntables);
- found = FALSE;
- for (i = 0; i < ntables; i++) {
- if ((pg_info->schema_name && /* schema defined */
- strcmp(PQgetvalue(res, i, 0), pg_info->schema_name) == 0 &&
- strcmp(PQgetvalue(res, i, 1), pg_info->table_name) == 0) ||
- (!pg_info->schema_name && /* schema not defined, get first match */
- strcmp(PQgetvalue(res, i, 1), pg_info->table_name) == 0)) {
- /* schema name */
- if (!pg_info->schema_name) {
- pg_info->schema_name = G_store(PQgetvalue(res, i, 0));
- }
- /* geometry column */
- pg_info->geom_column = G_store(PQgetvalue(res, i, 2));
- G_debug(3, "\t-> table = %s column = %s", pg_info->table_name,
- pg_info->geom_column);
- /* fid column */
- pg_info->fid_column = get_key_column(pg_info);
- /* coordinates dimension */
- pg_info->coor_dim = atoi(PQgetvalue(res, i, 3));
- /* SRS ID */
- pg_info->srid = atoi(PQgetvalue(res, i, 4));
- /* feature type */
- pg_info->feature_type = ftype_from_string(PQgetvalue(res, i, 5));
- found = TRUE;
- break;
- }
+
+ found = PQntuples(res) > 0 ? TRUE : FALSE;
+ if (found) {
+ /* geometry column */
+ pg_info->geom_column = G_store(PQgetvalue(res, 0, 0));
+ G_debug(3, "\t-> table = %s column = %s", pg_info->table_name,
+ pg_info->geom_column);
+ /* fid column */
+ pg_info->fid_column = get_key_column(pg_info);
+ /* coordinates dimension */
+ pg_info->coor_dim = atoi(PQgetvalue(res, 0, 1));
+ /* SRS ID */
+ pg_info->srid = atoi(PQgetvalue(res, 0, 2));
+ /* feature type */
+ pg_info->feature_type = ftype_from_string(PQgetvalue(res, 0, 3));
}
-
+
/* no feature in cache */
pg_info->cache.fid = -1;
PQclear(res);
- db_free_string(&stmt);
-
if (!found) {
G_warning(_("Feature table <%s> not found in 'geometry_columns'"),
pg_info->table_name);
@@ -243,11 +173,386 @@
*/
int V1_open_new_pg(struct Map_info *Map, const char *name, int with_z)
{
- G_debug(1, "V1_open_new_pg(): name = %s with_z = %d", name, with_z);
#ifdef HAVE_POSTGRES
+ char stmt[DB_SQL_MAX];
+
+ struct Format_info_pg *pg_info;
+
+ PGresult *res;
+
+ pg_info = &(Map->fInfo.pg);
+ if (!pg_info->conninfo) {
+ G_warning(_("Connection string not defined"));
+ return -1;
+ }
+
+ if (!pg_info->table_name) {
+ G_warning(_("PostGIS feature table not defined"));
+ return -1;
+ }
+
+ G_debug(1, "V1_open_new_pg(): conninfo='%s' table='%s'", pg_info->conninfo,
+ pg_info->table_name);
+
+ /* connect database */
+ pg_info->conn = PQconnectdb(pg_info->conninfo);
+ G_debug(2, " PQconnectdb(): %s", pg_info->conninfo);
+ if (PQstatus(pg_info->conn) == CONNECTION_BAD)
+ G_fatal_error("%s\n%s", _("Connection ton PostgreSQL database failed."),
+ PQerrorMessage(pg_info->conn));
+
+ /* get DB name */
+ pg_info->db_name = G_store(PQdb(pg_info->conn));
+ if (!pg_info->db_name) {
+ G_warning(_("Unable to get database name"));
+ return -1;
+ }
+
+ /* if schema not defined, use 'public' */
+ if (!pg_info->schema_name) {
+ pg_info->schema_name = G_store("public");
+ }
+
+ /* if fid_column not defined, use 'ogc_fid' */
+ if (!pg_info->fid_column) {
+ pg_info->fid_column = G_store("ogc_fid");
+ }
+
+ /* if geom_column not defined, use 'wkb_geometry' */
+ if (!pg_info->geom_column) {
+ pg_info->geom_column = G_store("wkb_geometry");
+ }
+
+ /* check if feature table already exists */
+ sprintf(stmt, "SELECT * FROM pg_tables "
+ "WHERE schemaname = '%s' AND tablename = '%s'",
+ pg_info->schema_name, pg_info->table_name);
+ G_debug(2, "SQL: %s", stmt);
+
+ res = PQexec(pg_info->conn, stmt);
+ if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
+ G_fatal_error("%s\n%s", _("No feature tables found in database."),
+ PQresultErrorMessage(res));
+
+ if (PQntuples(res) > 0) {
+ /* table found */
+ if (G_get_overwrite()) {
+ G_warning(_("PostGIS layer <%s.%s> already exists and will be overwritten"),
+ pg_info->schema_name, pg_info->table_name);
+ if (drop_table(pg_info) == -1) {
+ G_warning(_("Unable to delete PostGIS layer <%s>"),
+ pg_info->table_name);
+ return -1;
+ }
+ }
+ else {
+ G_warning(_("PostGIS layer <%s> already exists in database '%s'"),
+ pg_info->table_name, pg_info->db_name);
+ return -1;
+ }
+ }
+
+ /* no feature in cache */
+ pg_info->cache.fid = -1;
+
+ /* unknown feature type */
+ pg_info->feature_type = SF_UNKNOWN;
+
+ PQclear(res);
+
return 0;
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
return -1;
#endif
}
+
+/*!
+ \brief Create new PostGIS layer in given database (level 2)
+
+ V1_open_new_pg() is required to be called before this function.
+
+ List of currently supported types:
+ - GV_POINT (SF_POINT)
+ - GV_LINE (SF_LINESTRING)
+ - GV_BOUNDARY (SF_POLYGON)
+ \param[in,out] Map pointer to Map_info structure
+ \param type feature type (GV_POINT, GV_LINE, ...)
+
+ \return 0 success
+ \return -1 error
+*/
+int V2_open_new_pg(struct Map_info *Map, int type)
+{
+#ifdef HAVE_POSTGRES
+ int ndblinks;
+
+ struct Format_info_pg *pg_info;
+ struct field_info *Fi;
+ struct Key_Value *projinfo, *projunits;
+
+ Fi = NULL;
+
+ pg_info = &(Map->fInfo.pg);
+ if (!pg_info->conninfo) {
+ G_warning(_("Connection string not defined"));
+ return -1;
+ }
+
+ if (!pg_info->table_name) {
+ G_warning(_("PostGIS feature table not defined"));
+ return -1;
+ }
+
+ G_debug(1, "V2_open_new_pg(): conninfo='%s' table='%s' -> type = %d",
+ pg_info->conninfo, pg_info->table_name, type);
+
+ /* get spatial reference */
+ projinfo = G_get_projinfo();
+ projunits = G_get_projunits();
+ pg_info->srid = 0; /* TODO */
+ // Ogr_spatial_ref = GPJ_grass_to_osr(projinfo, projunits);
+ G_free_key_value(projinfo);
+ G_free_key_value(projunits);
+
+ /* determine geometry type */
+ switch(type) {
+ case GV_POINT:
+ pg_info->feature_type = SF_POINT;
+ break;
+ case GV_LINE:
+ pg_info->feature_type = SF_LINESTRING;
+ break;
+ case GV_BOUNDARY:
+ pg_info->feature_type = SF_POLYGON;
+ break;
+ default:
+ G_warning(_("Unsupported geometry type (%d)"), type);
+ return -1;
+ }
+
+ /* coordinate dimension */
+ pg_info->coor_dim = Vect_is_3d(Map) ? 3 : 2;
+
+ /* create new PostGIS table */
+ ndblinks = Vect_get_num_dblinks(Map);
+ if (ndblinks > 0) {
+ Fi = Vect_get_dblink(Map, 0);
+ if (Fi) {
+ if (ndblinks > 1)
+ G_warning(_("More layers defined, using driver <%s> and "
+ "database <%s>"), Fi->driver, Fi->database);
+ }
+ else {
+ G_warning(_("Database connection not defined. "
+ "Unable to write attributes."));
+ }
+ }
+
+ if (create_table(pg_info, Fi) == -1) {
+ G_warning(_("Unable to create new PostGIS table"));
+ return -1;
+ }
+
+ if (Fi)
+ G_free(Fi);
+
+ return 0;
+#else
+ G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+ return -1;
+#endif
+}
+
+#ifdef HAVE_POSTGRES
+char *get_key_column(struct Format_info_pg *pg_info)
+{
+ char *key_column;
+ char stmt[DB_SQL_MAX];
+
+ PGresult *res;
+
+ sprintf(stmt,
+ "SELECT kcu.column_name "
+ "FROM INFORMATION_SCHEMA.TABLES t "
+ "LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc "
+ "ON tc.table_catalog = t.table_catalog "
+ "AND tc.table_schema = t.table_schema "
+ "AND tc.table_name = t.table_name "
+ "AND tc.constraint_type = 'PRIMARY KEY' "
+ "LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu "
+ "ON kcu.table_catalog = tc.table_catalog "
+ "AND kcu.table_schema = tc.table_schema "
+ "AND kcu.table_name = tc.table_name "
+ "AND kcu.constraint_name = tc.constraint_name "
+ "WHERE t.table_schema = '%s' AND t.table_name = '%s'",
+ pg_info->schema_name, pg_info->table_name);
+ G_debug(0, "SQL: %s", stmt);
+
+ res = PQexec(pg_info->conn, stmt);
+ if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
+ PQntuples(res) != 1 || strlen(PQgetvalue(res, 0, 0)) < 1) {
+ G_warning(_("No key column detected."));
+ if (res)
+ PQclear(res);
+ return NULL;
+ }
+ key_column = G_store(PQgetvalue(res, 0, 0));
+
+ PQclear(res);
+
+ return key_column;
+}
+
+SF_FeatureType ftype_from_string(const char *type)
+{
+ SF_FeatureType sf_type;
+
+ if (G_strcasecmp(type, "POINT") == 0)
+ return SF_POINT;
+ else if (G_strcasecmp(type, "LINESTRING") == 0)
+ return SF_LINESTRING;
+ else if (G_strcasecmp(type, "POLYGON") == 0)
+ return SF_POLYGON;
+ else if (G_strcasecmp(type, "MULTIPOINT") == 0)
+ return SF_MULTIPOINT;
+ else if (G_strcasecmp(type, "MULTILINESTRING") == 0)
+ return SF_MULTILINESTRING;
+ else if (G_strcasecmp(type, "MULTIPOLYGON") == 0)
+ return SF_MULTIPOLYGON;
+ else if (G_strcasecmp(type, "GEOMETRYCOLLECTION") == 0)
+ return SF_GEOMETRYCOLLECTION;
+
+ return SF_UNKNOWN;
+
+ G_debug(3, "ftype_from_string(): type='%s' -> %d", type, sf_type);
+
+ return sf_type;
+}
+
+int drop_table(struct Format_info_pg *pg_info)
+{
+ char stmt[DB_SQL_MAX];
+
+ sprintf(stmt, "DROP TABLE \"%s\".\"%s\"",
+ pg_info->schema_name, pg_info->table_name);
+ G_debug(2, "SQL: %s", stmt);
+
+ if (execute(pg_info->conn, stmt) == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+int create_table(struct Format_info_pg *pg_info, const struct field_info *Fi)
+{
+ int spatial_index, primary_key;
+ char stmt[DB_SQL_MAX], *geom_type;
+
+ PGresult *result;
+
+ /* by default create spatial index & add primary key */
+ spatial_index = primary_key = TRUE;
+ if (G_find_file2("", "PG", G_mapset())) {
+ FILE *fp;
+ const char *p;
+
+ struct Key_Value *key_val;
+
+ fp = G_fopen_old("", "PG", G_mapset());
+ if (!fp) {
+ G_fatal_error(_("Unable to open PG file"));
+ }
+ key_val = G_fread_key_value(fp);
+ fclose(fp);
+
+ /* spatial index */
+ p = G_find_key_value("spatial_index", key_val);
+ if (p && G_strcasecmp(p, "off") == 0)
+ spatial_index = FALSE;
+ /* primary key */
+ p = G_find_key_value("primary_key", key_val);
+ if (p && G_strcasecmp(p, "off") == 0)
+ primary_key = FALSE;
+ }
+
+ /* begin transaction */
+ if (execute(pg_info->conn, "BEGIN") == -1) {
+ return -1;
+ }
+
+ /* create table */
+ sprintf(stmt, "CREATE TABLE \"%s\".\"%s\" (%s SERIAL)",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->fid_column);
+ G_debug(2, "SQL: %s", stmt);
+ if (execute(pg_info->conn, stmt) == -1) {
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+
+ /* add primary key ? */
+ if (primary_key) {
+ sprintf(stmt, "ALTER TABLE \"%s\".\"%s\" ADD PRIMARY KEY (%s)",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->fid_column);
+ G_debug(2, "SQL: %s", stmt);
+ if (execute(pg_info->conn, stmt) == -1) {
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+ }
+
+ /* determine geometry type (string) */
+ switch(pg_info->feature_type) {
+ case (SF_POINT):
+ geom_type = "POINT";
+ break;
+ case (SF_LINESTRING):
+ geom_type = "LINESTRING";
+ break;
+ case (SF_POLYGON):
+ geom_type = "POLYGON";
+ break;
+ default:
+ G_warning(_("Unsupported feature type %d"), pg_info->feature_type);
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+
+ /* add geometry column */
+ sprintf(stmt, "SELECT AddGeometryColumn('%s', '%s', "
+ "'%s', %d, '%s', %d)",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->geom_column, pg_info->srid,
+ geom_type, pg_info->coor_dim);
+ G_debug(2, "SQL: %s", stmt);
+ result = PQexec(pg_info->conn, stmt);
+
+ if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
+ PQclear(result);
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+
+ /* create index ? */
+ if (spatial_index) {
+ sprintf(stmt, "CREATE INDEX %s_%s_idx ON %s USING GIST (%s)",
+ pg_info->table_name, pg_info->geom_column, pg_info->table_name,
+ pg_info->geom_column);
+ G_debug(2, "SQL: %s", stmt);
+
+ if (execute(pg_info->conn, stmt) == -1) {
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+ }
+
+ /* close transaction */
+ if (execute(pg_info->conn, "COMMIT") == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+#endif
Modified: grass/trunk/lib/vector/Vlib/write.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write.c 2012-03-21 11:05:18 UTC (rev 51125)
+++ grass/trunk/lib/vector/Vlib/write.c 2012-03-21 11:08:56 UTC (rev 51126)
@@ -185,7 +185,7 @@
G_fatal_error(_("Unable to write feature, vector map is not opened"));
if (!(Map->plus.update_cidx)) {
- Map->plus.cidx_up_to_date = 0;
+ Map->plus.cidx_up_to_date = FALSE;
}
offset =
Modified: grass/trunk/lib/vector/Vlib/write_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_pg.c 2012-03-21 11:05:18 UTC (rev 51125)
+++ grass/trunk/lib/vector/Vlib/write_pg.c 2012-03-21 11:08:56 UTC (rev 51126)
@@ -76,13 +76,22 @@
pg_info = &(Map->fInfo.pg);
offset_info = &(pg_info->offset);
- if (!pg_info->conn || !pg_info->table_name) {
+ if (!pg_info->conn) {
G_warning(_("No connection defined"));
return -1;
}
+
+ if (!pg_info->table_name) {
+ G_warning(_("PostGIS feature table not defined"));
+ return -1;
+ }
+
+ if (pg_info->feature_type == SF_UNKNOWN) {
+ /* create PostGIS table if doesn't exist */
+ if (V2_open_new_pg(Map, type) < 0)
+ return -1;
+ }
- /* create PostGIS layer if doesn't exist ? */
-
cat = -1; /* no attributes to be written */
if (cats->n_cats > 0 && Vect_get_num_dblinks(Map) > 0) {
/* check for attributes */
@@ -633,9 +642,10 @@
/* build INSERT statement */
stmt = NULL;
- G_asprintf(&stmt, "INSERT INTO %s (%s, %s) VALUES (%d, '%s'::GEOMETRY)",
- pg_info->table_name, pg_info->fid_column, pg_info->geom_column,
- fid, text_data);
+ G_asprintf(&stmt, "INSERT INTO \"%s\".\"%s\" (%s) VALUES "
+ "('%s'::GEOMETRY)",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->geom_column, text_data);
G_debug(2, "SQL: %s", stmt);
if (execute(pg_info->conn, stmt) == -1) {
More information about the grass-commit
mailing list