[GRASS-SVN] r53979 - in grass/trunk: include/vect lib/vector/Vlib vector/v.out.postgis
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Nov 23 04:42:35 PST 2012
Author: martinl
Date: 2012-11-23 04:42:35 -0800 (Fri, 23 Nov 2012)
New Revision: 53979
Modified:
grass/trunk/include/vect/dig_structs.h
grass/trunk/lib/vector/Vlib/build_pg.c
grass/trunk/lib/vector/Vlib/open_pg.c
grass/trunk/lib/vector/Vlib/write_pg.c
grass/trunk/vector/v.out.postgis/main.c
Log:
vlib (PostGIS topo access): full support for lines (work in progress)
Modified: grass/trunk/include/vect/dig_structs.h
===================================================================
--- grass/trunk/include/vect/dig_structs.h 2012-11-23 12:03:32 UTC (rev 53978)
+++ grass/trunk/include/vect/dig_structs.h 2012-11-23 12:42:35 UTC (rev 53979)
@@ -666,9 +666,10 @@
*/
char *topogeom_column;
/*!
- \brief Topology schema name
+ \brief Topology schema name and id
*/
char *toposchema_name;
+ int toposchema_id;
};
/*!
Modified: grass/trunk/lib/vector/Vlib/build_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_pg.c 2012-11-23 12:03:32 UTC (rev 53978)
+++ grass/trunk/lib/vector/Vlib/build_pg.c 2012-11-23 12:42:35 UTC (rev 53979)
@@ -24,6 +24,7 @@
#include "pg_local_proto.h"
static int build_topo(struct Map_info *, int);
+static int build_topogeom_stmt(const struct Format_info_pg *, int, int, char *);
#endif
/*!
@@ -118,9 +119,14 @@
*/
int build_topo(struct Map_info *Map, int build)
{
+ int i, type;
+ char stmt[DB_SQL_MAX];
+
struct Plus_head *plus;
+ struct Format_info_pg *pg_info;
plus = &(Map->plus);
+ pg_info = &(Map->fInfo.pg);
/* check if upgrade or downgrade */
if (build < plus->built) {
@@ -130,6 +136,7 @@
}
if (build != GV_BUILD_ALL) {
+ /* TODO: implement all build levels */
G_warning(_("Only %s is supported for PostGIS topology"),
"GV_BUILD_ALL");
return 0;
@@ -142,12 +149,93 @@
}
*/
- /* build GRASS-like topology from PostGIS topological
- primitives */
- if (Vect_build_nat(Map, build) != 1)
+ /* update TopoGeometry based on GRASS-like topology */
+ if (build < GV_BUILD_BASE)
+ return 1; /* nothing to print */
+
+ if (plus->built < GV_BUILD_BASE) {
+ Vect_build_nat(Map, build);
+ }
+
+ i = 0;
+ Vect_rewind(Map);
+ if (Vect__execute_pg(pg_info->conn, "BEGIN"))
return 0;
- /* update PostGIS topology based on GRASS-like topology */
+ G_message(_("Updating TopoGeometry data..."));
+ while (TRUE) {
+ type = Vect_read_next_line(Map, NULL, NULL);
+ if (type == -1) {
+ G_warning(_("Unable to read vector map"));
+ return 0;
+ }
+ else if (type == -2) {
+ break;
+ }
+ G_progress(++i, 1e3);
+
+ /* update topogeometry elements in feature table */
+ if (type == GV_POINT || type == GV_LINE) {
+ if (build_topogeom_stmt(pg_info, i, type, stmt) &&
+ Vect__execute_pg(pg_info->conn, stmt) == -1) {
+ Vect__execute_pg(pg_info->conn, "ROLLBACK");
+ return 0;
+ }
+ }
+ }
+ G_progress(1, 1);
+
+ if (Vect__execute_pg(pg_info->conn, "COMMIT") == -1)
+ return 0;
+
return 1;
}
+
+/*!
+ \brief Build UPDATE statement for topo geometry element stored in
+ feature table
+
+ \param pg_info so pointer to Format_info_pg
+ \param type feature type (GV_POINT, ...)
+ \param id topology element id
+ \param[out] stmt string buffer
+
+ \return 1 on success
+ \return 0 on failure
+*/
+int build_topogeom_stmt(const struct Format_info_pg *pg_info,
+ int id, int type, char *stmt)
+{
+ int topogeom_type;
+
+ if (type == GV_POINT)
+ topogeom_type = 1;
+ else if (type & GV_LINES)
+ topogeom_type = 2;
+ else {
+ G_warning(_("Unsupported topo geometry type %d"), type);
+ return 0;
+ }
+
+ /* it's quite slow...
+
+ sprintf(stmt, "UPDATE \"%s\".\"%s\" SET %s = "
+ "topology.CreateTopoGeom('%s', %d, 1,"
+ "'{{%d, %d}}'::topology.topoelementarray) "
+ "WHERE %s = %d",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->topogeom_column, pg_info->toposchema_name,
+ topogeom_type, id, topogeom_type,
+ pg_info->fid_column, id);
+ */
+
+ sprintf(stmt, "UPDATE \"%s\".\"%s\" SET %s = "
+ "'(%d, 1, %d, %d)'::topology.TopoGeometry "
+ "WHERE %s = %d",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->topogeom_column, pg_info->toposchema_id,
+ id, topogeom_type, pg_info->fid_column, id);
+
+ return 1;
+}
#endif
Modified: grass/trunk/lib/vector/Vlib/open_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open_pg.c 2012-11-23 12:03:32 UTC (rev 53978)
+++ grass/trunk/lib/vector/Vlib/open_pg.c 2012-11-23 12:42:35 UTC (rev 53979)
@@ -162,22 +162,39 @@
{
#ifdef HAVE_POSTGRES
struct Format_info_pg *pg_info;
-
+
+ PGresult *res;
+
G_debug(3, "V2_open_old_pg(): name = %s mapset = %s", Map->name,
Map->mapset);
pg_info = &(Map->fInfo.pg);
- if (pg_info->toposchema_name)
- /* no fidx file needed for PostGIS topology access */
- return 0;
-
- if (Vect_open_fidx(Map, &(pg_info->offset)) != 0) {
- G_warning(_("Unable to open feature index file for vector map <%s>"),
- Vect_get_full_name(Map));
- G_zero(&(pg_info->offset), sizeof(struct Format_info_offset));
+ if (pg_info->toposchema_name) {
+ char stmt[DB_SQL_MAX];
+
+ /* get topo schema id */
+ sprintf(stmt, "SELECT id FROM topology.topology WHERE name = '%s'",
+ pg_info->toposchema_name);
+ res = PQexec(pg_info->conn, stmt);
+ if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) {
+ G_warning("%s\n%s", _("Topology schema not found."),
+ PQresultErrorMessage(res));
+ if (res)
+ PQclear(res);
+ return -1;
+ }
+ pg_info->toposchema_id = atoi(PQgetvalue(res, 0, 0));
+ PQclear(res);
}
-
+ else {
+ /* fidx file needed only for simple features access */
+ if (Vect_open_fidx(Map, &(pg_info->offset)) != 0) {
+ G_warning(_("Unable to open feature index file for vector map <%s>"),
+ Vect_get_full_name(Map));
+ G_zero(&(pg_info->offset), sizeof(struct Format_info_offset));
+ }
+ }
return 0;
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -918,7 +935,9 @@
Vect__execute_pg(pg_info->conn, "ROLLBACK");
return -1;
}
-
+ /* store toposchema id */
+ pg_info->toposchema_id = atoi(PQgetvalue(result, 0, 0));
+
/* add topo column to the feature table */
G_verbose_message(_("Adding new topology column <%s>..."),
pg_info->topogeom_column);
@@ -985,7 +1004,7 @@
/* check if topology layer/schema exists */
sprintf(stmt,
- "SELECT t.name,t.hasz,l.feature_column FROM topology.layer "
+ "SELECT t.id,t.name,t.hasz,l.feature_column FROM topology.layer "
"AS l JOIN topology.topology AS t ON l.topology_id = t.id "
"WHERE schema_name = '%s' AND table_name = '%s'",
pg_info->schema_name, pg_info->table_name);
@@ -1002,14 +1021,15 @@
return 1;
}
- pg_info->toposchema_name = G_store(PQgetvalue(res, 0, 0));
- pg_info->topogeom_column = G_store(PQgetvalue(res, 0, 2));
+ pg_info->toposchema_id = atoi(PQgetvalue(res, 0, 0));
+ pg_info->toposchema_name = G_store(PQgetvalue(res, 0, 1));
+ pg_info->topogeom_column = G_store(PQgetvalue(res, 0, 3));
G_debug(1, "PostGIS topology detected: schema = %s column = %s",
pg_info->toposchema_name, pg_info->topogeom_column);
/* check for 3D */
- if (strcmp(PQgetvalue(res, 0, 1), "t") == 0)
+ if (strcmp(PQgetvalue(res, 0, 2), "t") == 0)
plus->with_z = WITH_Z;
PQclear(res);
Modified: grass/trunk/lib/vector/Vlib/write_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_pg.c 2012-11-23 12:03:32 UTC (rev 53978)
+++ grass/trunk/lib/vector/Vlib/write_pg.c 2012-11-23 12:42:35 UTC (rev 53979)
@@ -33,27 +33,33 @@
#define WKBSRIDFLAG 0x20000000
+/*! Use SQL statements from PostGIS Topology extension (this options
+ is quite slow. By default are used simple SQL statements (INSERT, UPDATE)
+*/
+#define USE_TOPO_STMT 0
+
static off_t write_line_sf(struct Map_info *, int,
const struct line_pnts **, int,
const struct line_cats *);
static off_t write_line_tp(struct Map_info *, int, int,
- const struct line_pnts *);
+ const struct line_pnts *,
+ const struct line_cats *);
static char *binary_to_hex(int, const unsigned char *);
static unsigned char *point_to_wkb(int, const struct line_pnts *, int, int *);
static unsigned char *linestring_to_wkb(int, const struct line_pnts *,
int, int *);
static unsigned char *polygon_to_wkb(int, const struct line_pnts **, int,
int, int *);
-static int write_feature(struct Format_info_pg *,
+static int write_feature(struct Map_info *,
int, const struct line_pnts **, int, int,
const struct P_line *,
int, const struct field_info *);
static char *build_insert_stmt(const struct Format_info_pg *, const char *,
int, const struct field_info *);
-static char *build_topo_stmt(struct Format_info_pg *, int,
+static char *build_topo_stmt(struct Map_info *, int,
const struct P_line *, const char *);
-static char *build_topogeom_stmt(const struct Format_info_pg *, int, int, int);
static int execute_topo(PGconn *, const char *);
+static int update_next_line(struct Map_info*, int, int, int*, int *);
#endif
/*!
@@ -120,10 +126,14 @@
pg_info = &(Map->fInfo.pg);
- if (!pg_info->toposchema_name) /* pseudo-topology */
+ if (!pg_info->toposchema_name) { /* pseudo-topology */
return V2_write_line_sfa(Map, type, points, cats);
- else /* PostGIS topology */
- return write_line_tp(Map, type, FALSE, points);
+ }
+ else { /* PostGIS topology */
+ if (Map->plus.built < GV_BUILD_BASE)
+ Map->plus.built = GV_BUILD_BASE;
+ return write_line_tp(Map, type, FALSE, points, cats);
+ }
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
return -1;
@@ -242,7 +252,7 @@
if (!pg_info->toposchema_name)
return -1; /* PostGIS Topology required */
- return write_line_tp(Map, GV_POINT, TRUE, points);
+ return write_line_tp(Map, GV_POINT, TRUE, points, NULL);
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
return -1;
@@ -333,7 +343,7 @@
return -1;
}
- Fi = NULL; /* no attributes to be written */
+ Fi = NULL; /* no attributes to be written */
cat = -1;
if (cats->n_cats > 0 && Vect_get_num_dblinks(Map) > 0) {
/* check for attributes */
@@ -400,7 +410,7 @@
}
/* write feature's geometry and fid */
- if (-1 == write_feature(pg_info, type, points, nparts,
+ if (-1 == write_feature(Map, type, points, nparts,
Vect_is_3d(Map) ? WITH_Z : WITHOUT_Z, NULL, cat, Fi)) {
Vect__execute_pg(pg_info->conn, "ROLLBACK");
return -1;
@@ -439,8 +449,12 @@
\return -1 on error
*/
off_t write_line_tp(struct Map_info *Map, int type, int is_node,
- const struct line_pnts *points)
+ const struct line_pnts *points,
+ const struct line_cats *cats)
{
+ int cat;
+
+ struct field_info *Fi;
struct Format_info_pg *pg_info;
struct Plus_head *plus;
struct P_line *Line;
@@ -477,6 +491,26 @@
G_debug(3, "write_line_pg(): type = %d n_points = %d",
type, points->n_points);
+ Fi = NULL; /* no attributes to be written */
+ cat = -1;
+ if (cats && cats->n_cats > 0) {
+ if (Vect_get_num_dblinks(Map) > 0) {
+ /* check for attributes */
+ Fi = Vect_get_dblink(Map, 0);
+ if (Fi) {
+ if (!Vect_cat_get(cats, Fi->number, &cat))
+ G_warning(_("No category defined for layer %d"), Fi->number);
+ if (cats->n_cats > 1) {
+ G_warning(_("Feature has more categories, using "
+ "category %d (from layer %d)"),
+ cat, cats->field[0]);
+ }
+ }
+ }
+ /* assume layer=1 */
+ Vect_cat_get(cats, 1, &cat);
+ }
+
/* update topology before writing feature */
Line = NULL;
if (is_node) {
@@ -499,9 +533,9 @@
}
/* write feature geometry and fid */
- if (-1 == write_feature(pg_info, type, &points, 1,
+ if (-1 == write_feature(Map, type, &points, 1,
Vect_is_3d(Map) ? WITH_Z : WITHOUT_Z, Line,
- -1, NULL)) {
+ cat, Fi)) {
Vect__execute_pg(pg_info->conn, "ROLLBACK");
return -1;
}
@@ -784,7 +818,7 @@
/*!
\brief Insert feature into table
- \param pg_info pointer to Format_info_pg struct
+ \param Map pointer to Map_info structure
\param type feature type (GV_POINT, GV_LINE, ...)
\param points pointer to line_pnts struct
\param nparts number of parts (rings for polygon)
@@ -795,7 +829,7 @@
\return -1 on error
\retirn 0 on success
*/
-int write_feature(struct Format_info_pg *pg_info, int type,
+int write_feature(struct Map_info *Map, int type,
const struct line_pnts **points, int nparts, int with_z,
const struct P_line *Line,
int cat, const struct field_info *Fi)
@@ -805,6 +839,10 @@
unsigned char *wkb_data;
char *stmt, *text_data, *text_data_p, *hex_data;
+ struct Format_info_pg *pg_info;
+
+ pg_info = &(Map->fInfo.pg);
+
if (with_z && pg_info->coor_dim != 3) {
G_warning(_("Trying to insert 3D data into feature table "
"which store 2D data only"));
@@ -916,22 +954,17 @@
/* write feature in PostGIS topology schema if enabled */
if (pg_info->toposchema_name) {
/* insert feature into topology schema (node or edge) */
- stmt = build_topo_stmt(pg_info, type, Line, text_data);
+ stmt = build_topo_stmt(Map, type, Line, text_data);
+#if USE_TOPO_STMT
+ if (stmt && execute_topo(pg_info->conn, stmt) == -1) {
+#else
if (stmt && Vect__execute_pg(pg_info->conn, stmt) == -1) {
+#endif
/* rollback transaction */
Vect__execute_pg(pg_info->conn, "ROLLBACK");
return -1;
}
G_free(stmt);
-
- /* insert topoelement into feature table
- stmt = build_topogeom_stmt(pg_info, id, type, do_update);
- if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
- Vect__execute_pg(pg_info->conn, "ROLLBACK");
- return -1;
- }
- G_free(stmt);
- */
}
G_free(wkb_data);
@@ -941,9 +974,13 @@
}
/*!
- \brief Build INSERT statement to insert new feature to the table
+ \brief Build INSERT statement to add new feature to the feature
+ table
+ Note: Allocated string should be freed.
+
\param pg_info pointer to Format_info_pg structure
+ \param geom_data geometry data
\param cat category number (or -1 for no category)
\param Fi pointer to field_info structure (NULL for no attributes)
@@ -956,7 +993,7 @@
char *stmt, buf[DB_SQL_MAX];
stmt = NULL;
- if (Fi && cat > -1) {
+ if (Fi && cat > -1) { /* write attributes (simple features and topology elements) */
int col, ncol, more;
int sqltype, ctype;
char buf_val[DB_SQL_MAX], buf_tmp[DB_SQL_MAX];
@@ -1075,17 +1112,21 @@
}
}
}
- else if (pg_info->toposchema_name)
- return NULL; /* don't write simple feature element */
-
- if (!stmt) {
- /* no attributes */
- G_asprintf(&stmt, "INSERT INTO \"%s\".\"%s\" (%s) VALUES "
- "('%s'::GEOMETRY)",
- pg_info->schema_name, pg_info->table_name,
- pg_info->geom_column, geom_data);
+ else {
+ if (!pg_info->toposchema_name) {
+ /* no attributes (simple features access) */
+ G_asprintf(&stmt, "INSERT INTO \"%s\".\"%s\" (%s) VALUES "
+ "('%s'::GEOMETRY)",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->geom_column, geom_data);
+ }
+ else if (cat > 0)
+ /* no attributes (topology elements) */
+ G_asprintf(&stmt, "INSERT INTO \"%s\".\"%s\" (%s) VALUES (NULL)",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->geom_column);
}
-
+
return stmt;
}
@@ -1093,44 +1134,85 @@
\brief Build SELECT statement to insert new element into PostGIS
topology schema
- \param pg_info so pointer to Format_info_pg
+ \param Map pointer to Map_info struct
\param Line pointer to P_line struct (topo)
\param geom_data geometry in wkb
\return pointer to allocated string buffer with SQL statement
\return NULL on error
*/
-char *build_topo_stmt(struct Format_info_pg *pg_info, int type,
+char *build_topo_stmt(struct Map_info *Map, int type,
const struct P_line *Line, const char *geom_data)
{
char *stmt;
+ struct Format_info_pg *pg_info;
+
+ pg_info = &(Map->fInfo.pg);
stmt = NULL;
switch(type) {
case GV_POINT: {
-#if 1
- G_asprintf(&stmt, "INSERT INTO \"%s\".node (geom) VALUES ('%s'::GEOMETRY)",
+#if USE_TOPO_STMT
+ G_asprintf(&stmt, "SELECT topology.AddNode('%s', '%s'::GEOMETRY)",
pg_info->toposchema_name, geom_data);
#else
- G_asprintf(&stmt, "SELECT topology.AddNode('%s', '%s'::GEOMETRY)",
+ G_asprintf(&stmt, "INSERT INTO \"%s\".node (geom) VALUES ('%s'::GEOMETRY)",
pg_info->toposchema_name, geom_data);
#endif
break;
}
case GV_LINE: {
+ int line;
+ int n1, n2;
+ int nle, nre; /* next left | right edge */
+
+ /*
+ * isolated lines
+ next left edge: -fid
+ next right edge: fid
+
+ * connected lines
+ next left edge: next line or -fid
+ next right edge: next line or fid
+ */
if (!Line) {
G_warning(_("Topology not available. Unable to insert new edge."));
return NULL;
}
struct P_topo_l *topo = (struct P_topo_l *) Line->topo;
+
+#if USE_TOPO_STMT
+ G_asprintf(&stmt, "SELECT topology.AddEdge('%s', '%s'::GEOMETRY)",
+ pg_info->toposchema_name, geom_data);
+#else
+ line = Vect_get_num_lines(Map);
+ /* get number of lines for each node */
+ n1 = Vect_get_node_n_lines(Map, topo->N1);
+ n2 = Vect_get_node_n_lines(Map, topo->N2);
+
+ /* assuming isolated lines */
+ nle = -line;
+ nre = line;
+
+ /* check for line connection */
+ if (n1 > 1) {
+ update_next_line(Map, n1, line, &nle, &nre);
+ }
+ if (n2 > 1) {
+ update_next_line(Map, n2, -line, &nle, &nre);
+ }
+
+ G_debug(3, "build_topo_stmt(): line=%d type=line nle=%d nre=%d", line, nle, nre);
+
G_asprintf(&stmt, "INSERT INTO \"%s\".edge_data (geom, start_node, end_node, "
- "next_left_edge, next_right_edge, abs_next_left_edge, abs_next_right_edge, "
+ "next_left_edge, abs_next_left_edge, next_right_edge, abs_next_right_edge, "
"left_face, right_face) "
- "VALUES ('%s'::GEOMETRY, %d, %d, %d, %d, %d, %d, %d, %d)",
- pg_info->toposchema_name, geom_data, topo->N1, topo->N2, 0, 0, 0, 0, 0, 0);
-
+ "VALUES ('%s'::GEOMETRY, %d, %d, %d, %d, %d, %d, 0, 0)",
+ pg_info->toposchema_name, geom_data, topo->N1, topo->N2, nle, abs(nle),
+ nre, abs(nre));
+#endif
break;
}
case GV_CENTROID: {
@@ -1154,57 +1236,6 @@
}
/*!
- \brief Build INSERT / UPDATE statement to insert topo geometry
- object into feature table
-
- Allocated string should be freed by G_free()
-
- \param pg_info so pointer to Format_info_pg
- \param type feature type (GV_POINT, ...)
- \param id topology element id
- \param do_update TRUE for UPDATE otherwise build SELECT statement
-
- \return pointer to allocated string buffer with SQL statement
- \return NULL on error
-*/
-char *build_topogeom_stmt(const struct Format_info_pg *pg_info,
- int id, int type, int do_update)
-{
- int topogeom_type;
- char *stmt;
-
- stmt = NULL;
-
- if (type == GV_POINT)
- topogeom_type = 1;
- else if (type & GV_LINES)
- topogeom_type = 2;
- else {
- G_warning(_("Unsupported topo geometry type %d"), type);
- return NULL;
- }
-
- if (!do_update)
- G_asprintf(&stmt, "INSERT INTO \"%s\".\"%s\" (%s) VALUES "
- "(topology.CreateTopoGeom('%s', 1, %d, "
- "'{{%d, %d}}'::topology.topoelementarray))",
- pg_info->schema_name, pg_info->table_name,
- pg_info->topogeom_column, pg_info->toposchema_name,
- topogeom_type, id, topogeom_type);
- else
- G_asprintf(&stmt, "UPDATE \"%s\".\"%s\" SET %s = "
- "topology.CreateTopoGeom('%s', 1, %d, "
- "'{{%d, %d}}'::topology.topoelementarray) "
- "WHERE %s = %d",
- pg_info->schema_name, pg_info->table_name,
- pg_info->topogeom_column, pg_info->toposchema_name,
- topogeom_type, id, topogeom_type,
- pg_info->fid_column, id);
-
- return stmt;
-}
-
-/*!
\brief Execute SQL topo select statement
\param conn pointer to PGconn
@@ -1235,5 +1266,72 @@
return ret;
}
-
+
+/*!
+ \brief Find next line (topo only)
+
+ \param Map pointer to Map_info struct
+ \param nlines number of lines
+ \param line current line (negative for backward direction - ie. end node)
+ \param[out] left left line
+ \param[out] right right line
+ \return line id (left or right)
+
+ \return 0 on success
+ \return -1 on failure
+*/
+int update_next_line(struct Map_info* Map, int nlines, int line,
+ int *left, int *right)
+{
+ int next_line;
+ char stmt[DB_SQL_MAX];
+
+ struct Format_info_pg *pg_info;
+
+ pg_info = &(Map->fInfo.pg);
+
+ /* update left line side */
+ next_line = dig_angle_next_line(&(Map->plus), line,
+ line < 0 ? GV_LEFT : GV_RIGHT, GV_LINE, NULL);
+ if (line > 0)
+ *right = next_line;
+ else
+ *left = next_line;
+ sprintf(stmt, "UPDATE \"%s\".edge_data SET next_left_edge = %d, "
+ "abs_next_left_edge = %d WHERE edge_id = %d",
+ pg_info->toposchema_name, line, abs(line), abs(next_line));
+ G_debug(4, "build_topo_stmt(): line=%d nle=%d | line=%d nle=%d",
+ line, next_line, abs(next_line), line);
+
+ if(Vect__execute_pg(pg_info->conn, stmt) == -1) {
+ /* rollback transaction */
+ Vect__execute_pg(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+
+ if (nlines > 2) {
+ /* update right line side */
+ next_line = dig_angle_next_line(&(Map->plus), line,
+ line < 0 ? GV_RIGHT : GV_LEFT, GV_LINE, NULL);
+ if (line > 0)
+ *right = next_line;
+ else
+ *left = next_line;
+ G_debug(4, "line=%d nre=%d", line, next_line);
+ /*
+ sprintf(stmt, "UPDATE \"%s\".edge_data SET next_right_edge = %d, "
+ "abs_next_right_edge = %d WHERE edge_id = %d",
+ pg_info->toposchema_name, line, abs(line), abs(next_line));
+ G_debug(0, "build_topo_stmt(): line=%d nre=%d", abs(next_line), line);
+
+ if(Vect__execute_pg(pg_info->conn, stmt) == -1) {
+ Vect__execute_pg(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+ */
+ }
+
+ return 0;
+}
+
#endif
Modified: grass/trunk/vector/v.out.postgis/main.c
===================================================================
--- grass/trunk/vector/v.out.postgis/main.c 2012-11-23 12:03:32 UTC (rev 53978)
+++ grass/trunk/vector/v.out.postgis/main.c 2012-11-23 12:42:35 UTC (rev 53979)
@@ -121,6 +121,9 @@
if (Vect_copy_map_lines_field(&In, field, &Out) != 0)
G_fatal_error(_("Copying features failed"));
+ if (flags.topo->answer)
+ Vect_build_partial(&Out, GV_BUILD_NONE); /* build from scratch */
+
Vect_close(&In);
if (Vect_build(&Out) != 1)
More information about the grass-commit
mailing list