[GRASS-SVN] r52563 - in grass/trunk: include/defs lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Aug 6 09:16:34 PDT 2012
Author: martinl
Date: 2012-08-06 09:16:34 -0700 (Mon, 06 Aug 2012)
New Revision: 52563
Modified:
grass/trunk/include/defs/vector.h
grass/trunk/lib/vector/Vlib/open.c
grass/trunk/lib/vector/Vlib/open_pg.c
grass/trunk/lib/vector/Vlib/write_pg.c
Log:
vlib: postgis topology support (work in progress)
Vect_write_area_pg() introduced
Modified: grass/trunk/include/defs/vector.h
===================================================================
--- grass/trunk/include/defs/vector.h 2012-08-06 14:30:28 UTC (rev 52562)
+++ grass/trunk/include/defs/vector.h 2012-08-06 16:16:34 UTC (rev 52563)
@@ -548,6 +548,9 @@
const struct line_pnts *, const struct line_cats *);
off_t V2_rewrite_line_sfa(struct Map_info *, int, int, off_t,
const struct line_pnts *, const struct line_cats *);
+off_t V2_write_area_pg(struct Map_info *, const struct line_pnts *,
+ const struct line_cats *,
+ const struct line_pnts **, int);
/* Build topology */
int Vect_build_nat(struct Map_info *, int);
Modified: grass/trunk/lib/vector/Vlib/open.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open.c 2012-08-06 14:30:28 UTC (rev 52562)
+++ grass/trunk/lib/vector/Vlib/open.c 2012-08-06 16:16:34 UTC (rev 52563)
@@ -730,7 +730,7 @@
Map->mapset = G_store(G_mapset());
Map->location = G_store(G_location());
Map->gisdbase = G_store(G_gisdbase());
-
+
/* determine output format */
if (strcmp(G_program_name(), "v.external") != 0)
Map->format = map_format(Map);
@@ -1108,6 +1108,8 @@
/* check for external formats definition */
int map_format(struct Map_info *Map)
{
+ char *def_file;
+
if (G_find_file2("", "OGR", G_mapset())) {
/* OGR */
FILE *fp;
@@ -1117,7 +1119,7 @@
struct Format_info_ogr *ogr_info;
G_debug(2, " using OGR format");
- Map->format = GV_FORMAT_OGR;
+ Map->format = GV_FORMAT_OGR_DIRECT;
fp = G_fopen_old("", "OGR", G_mapset());
if (!fp) {
G_fatal_error(_("Unable to open OGR file"));
@@ -1141,7 +1143,9 @@
ogr_info->layer_name = G_store(Map->name);
}
- if (G_find_file2("", "PG", G_mapset())) {
+
+ def_file = getenv("GRASS_VECTOR_PGFILE");
+ if (G_find_file2("", def_file ? def_file : "PG", G_mapset())) {
/* PostGIS */
if (Map->fInfo.ogr.driver_name) {
G_warning(_("OGR output also detected, using OGR"));
@@ -1155,7 +1159,7 @@
G_debug(2, " using PostGIS format");
Map->format = GV_FORMAT_POSTGIS;
- fp = G_fopen_old("", "PG", G_mapset());
+ fp = G_fopen_old("", def_file ? def_file : "PG", G_mapset());
if (!fp) {
G_fatal_error(_("Unable to open PG file"));
}
@@ -1178,30 +1182,30 @@
pg_info->schema_name = G_store("public");
G_debug(1, "PG: schema_name = '%s'", pg_info->schema_name);
- /* fid column (default: fid) */
+ /* fid column (default: ogc_fid) */
p = G_find_key_value("fid", key_val);
if (p)
pg_info->fid_column = G_store(p);
+ else
#ifdef HAVE_POSTGRES
- else
pg_info->fid_column = G_store(FID_COLUMN);
#endif
G_debug(1, "PG: fid_column = '%s'", pg_info->fid_column);
- /* geometry column (default: geom) */
+ /* geometry column (default: wkb_geometry) */
p = G_find_key_value("geometry_name", key_val);
if (p)
pg_info->geom_column = G_store(p);
+ else
#ifdef HAVE_POSTGRES
- else
pg_info->geom_column = G_store(GEOMETRY_COLUMN);
#endif
G_debug(1, "PG: geom_column = '%s'", pg_info->geom_column);
/* table name */
- pg_info->table_name = G_store(Map->name);
+ Map->fInfo.pg.table_name = G_store(Map->name);
}
}
-
+
return Map->format;
}
Modified: grass/trunk/lib/vector/Vlib/open_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open_pg.c 2012-08-06 14:30:28 UTC (rev 52562)
+++ grass/trunk/lib/vector/Vlib/open_pg.c 2012-08-06 16:16:34 UTC (rev 52563)
@@ -634,19 +634,21 @@
{
int spatial_index, primary_key;
char stmt[DB_SQL_MAX];
- char *geom_type;
+ char *geom_type, *def_file;
PGresult *result;
+ def_file = getenv("GRASS_VECTOR_PGFILE");
+
/* by default create spatial index & add primary key */
spatial_index = primary_key = TRUE;
- if (G_find_file2("", "PG", G_mapset())) {
+ if (G_find_file2("", def_file ? def_file : "PG", G_mapset())) {
FILE *fp;
const char *p;
struct Key_Value *key_val;
- fp = G_fopen_old("", "PG", G_mapset());
+ fp = G_fopen_old("", def_file ? def_file : "PG", G_mapset());
if (!fp) {
G_fatal_error(_("Unable to open PG file"));
}
@@ -862,18 +864,21 @@
{
double tolerance;
char stmt[DB_SQL_MAX];
+ char *def_file;
PGresult *result;
+ def_file = getenv("GRASS_VECTOR_PGFILE");
+
/* read default values from PG file*/
tolerance = 0.;
- if (G_find_file2("", "PG", G_mapset())) {
+ if (G_find_file2("", def_file ? def_file : "PG", G_mapset())) {
FILE *fp;
const char *p;
struct Key_Value *key_val;
- fp = G_fopen_old("", "PG", G_mapset());
+ fp = G_fopen_old("", def_file ? def_file : "PG", G_mapset());
if (!fp) {
G_fatal_error(_("Unable to open PG file"));
}
@@ -899,7 +904,8 @@
}
/* create topology schema */
- G_message(_("Creating topology schema <%s>..."), pg_info->toposchema_name);
+ G_verbose_message(_("Creating topology schema <%s>..."),
+ pg_info->toposchema_name);
sprintf(stmt, "SELECT topology.createtopology('%s', "
"find_srid('%s', '%s', '%s'), %f, '%s')",
pg_info->toposchema_name, pg_info->schema_name,
@@ -915,7 +921,8 @@
}
/* add topo column to the feature table */
- G_message(_("Adding new topology column <%s>..."), pg_info->topogeom_column);
+ G_verbose_message(_("Adding new topology column <%s>..."),
+ pg_info->topogeom_column);
sprintf(stmt, "SELECT topology.AddTopoGeometryColumn('%s', '%s', '%s', "
"'%s', '%s')", pg_info->toposchema_name, pg_info->schema_name,
pg_info->table_name, pg_info->topogeom_column,
Modified: grass/trunk/lib/vector/Vlib/write_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_pg.c 2012-08-06 14:30:28 UTC (rev 52562)
+++ grass/trunk/lib/vector/Vlib/write_pg.c 2012-08-06 16:16:34 UTC (rev 52563)
@@ -31,18 +31,24 @@
#define WKBSRIDFLAG 0x20000000
+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,
+ const struct line_pnts *);
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 *,
+static unsigned char *polygon_to_wkb(int, const struct line_pnts **, int,
int, int *);
static int write_feature(struct Format_info_pg *,
- int, const struct line_pnts *, int,
+ int, const struct line_pnts **, int, int,
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(const struct Format_info_pg *, int, const char *);
+static char *build_topo_stmt(const struct Format_info_pg *, 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 *);
#endif
@@ -69,6 +75,159 @@
const struct line_cats *cats)
{
#ifdef HAVE_POSTGRES
+ if (!Map->fInfo.pg.toposchema_name)
+ return write_line_sf(Map, type, &points, 1, cats);
+ else
+ return write_line_tp(Map, type, points);
+#else
+ G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+ return -1;
+#endif
+}
+
+/*!
+ \brief Rewrites feature at the given offset (level 1) (PostGIS interface)
+
+ \param Map pointer to Map_info structure
+ \param offset feature offset
+ \param type feature type (GV_POINT, GV_LINE, ...)
+ \param points feature geometry
+ \param cats feature categories
+
+ \return feature offset (rewriten feature)
+ \return -1 on error
+ */
+off_t V1_rewrite_line_pg(struct Map_info * Map,
+ int line, int type, off_t offset,
+ const struct line_pnts * points,
+ const struct line_cats * cats)
+{
+ G_debug(3, "V1_rewrite_line_pg(): line=%d type=%d offset=%lu",
+ line, type, offset);
+#ifdef HAVE_POSTGRES
+ if (type != V1_read_line_pg(Map, NULL, NULL, offset)) {
+ G_warning(_("Unable to rewrite feature (incompatible feature types)"));
+ return -1;
+ }
+
+ /* delete old */
+ V1_delete_line_pg(Map, offset);
+
+ return V1_write_line_pg(Map, type, points, cats);
+#else
+ G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+ return -1;
+#endif
+}
+
+/*!
+ \brief Deletes feature at the given offset (level 1)
+
+ \param Map pointer Map_info structure
+ \param offset feature offset
+
+ \return 0 on success
+ \return -1 on error
+ */
+int V1_delete_line_pg(struct Map_info *Map, off_t offset)
+{
+#ifdef HAVE_POSTGRES
+ long fid;
+ char stmt[DB_SQL_MAX];
+
+ struct Format_info_pg *pg_info;
+
+ pg_info = &(Map->fInfo.pg);
+
+ if (!pg_info->conn || !pg_info->table_name) {
+ G_warning(_("No connection defined"));
+ return -1;
+ }
+
+ if (offset >= pg_info->offset.array_num) {
+ G_warning(_("Invalid offset (%d)"), offset);
+ return -1;
+ }
+
+ fid = pg_info->offset.array[offset];
+
+ G_debug(3, "V1_delete_line_pg(), offset = %lu -> fid = %ld",
+ (unsigned long)offset, fid);
+
+ if (!pg_info->inTransaction) {
+ /* start transaction */
+ pg_info->inTransaction = TRUE;
+ if (execute(pg_info->conn, "BEGIN") == -1)
+ return -1;
+ }
+
+ sprintf(stmt, "DELETE FROM %s WHERE %s = %ld",
+ pg_info->table_name, pg_info->fid_column, fid);
+ G_debug(2, "SQL: %s", stmt);
+
+ if (execute(pg_info->conn, stmt) == -1) {
+ G_warning(_("Unable to delete feature"));
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+
+ return 0;
+#else
+ G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+ return -1;
+#endif
+}
+
+/*!
+ \brief Writes area on level 2 (PostGIS interface)
+
+ \param Map pointer to Map_info structure
+ \param type feature type (GV_POINT, GV_LINE, ...)
+ \param points pointer to line_pnts structure (boundary geometry)
+ \param cats pointer to line_cats structure (feature categories)
+ \param ipoints pointer to line_pnts structure (isles geometry)
+ \param nisles number of isles
+
+ \return feature offset into file
+ \return -1 on error
+ */
+off_t V2_write_area_pg(struct Map_info *Map,
+ const struct line_pnts *bpoints,
+ const struct line_cats *cats,
+ const struct line_pnts **ipoints, int nisles)
+{
+#ifdef HAVE_POSTGRES
+ int i;
+ off_t ret;
+ const struct line_pnts **points;
+
+ if (nisles > 0) {
+ points = (const struct line_pnts **) G_calloc(nisles + 1, sizeof(struct line_pnts *));
+ points[0] = bpoints;
+ for (i = 0; i < nisles; i++)
+ points[i + 1] = ipoints[i];
+ }
+ else {
+ points = &bpoints;
+ }
+
+ ret = write_line_sf(Map, GV_BOUNDARY, points, nisles + 1, cats);
+
+ if (nisles > 0)
+ G_free(points);
+
+ return ret;
+#else
+ G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+ return -1;
+#endif
+}
+
+#ifdef HAVE_POSTGRES
+off_t write_line_sf(struct Map_info *Map, int type,
+ const struct line_pnts **points, int nparts,
+ const struct line_cats *cats)
+{
int cat;
off_t offset;
@@ -128,7 +287,7 @@
return -1;
}
}
- else if (type & GV_BOUNDARY) {
+ else if (type & GV_BOUNDARY || type & GV_CENTROID) {
if (sf_type != SF_POLYGON) {
G_warning(_("Feature is not a polygon. Skipping."));
return -1;
@@ -144,24 +303,27 @@
G_warning(_("Unsupported feature type (%d)"), type);
return -1;
}
+
+ G_debug(3, "write_line_sf(): type = %d n_points = %d cat = %d",
+ type, points[0]->n_points, cat);
- G_debug(3, "V1_write_line_pg(): type = %d n_points = %d cat = %d",
- type, points->n_points, cat);
-
if (sf_type == SF_POLYGON || sf_type == SF_POLYGON25D) {
- int npoints;
+ /* skip this check when writing PostGIS topology */
+ int part, npoints;
- npoints = points->n_points - 1;
- if (points->x[0] != points->x[npoints] ||
- points->y[0] != points->y[npoints] ||
- points->z[0] != points->z[npoints]) {
- G_warning(_("Boundary is not closed. Skipping."));
- return -1;
+ for (part = 0; part < nparts; part++) {
+ npoints = points[part]->n_points - 1;
+ if (points[part]->x[0] != points[part]->x[npoints] ||
+ points[part]->y[0] != points[part]->y[npoints] ||
+ points[part]->z[0] != points[part]->z[npoints]) {
+ G_warning(_("Boundary is not closed. Skipping."));
+ return -1;
+ }
}
}
/* write feature's geometry and fid */
- if (-1 == write_feature(pg_info, type, points,
+ if (-1 == write_feature(pg_info, type, points, nparts,
Vect_is_3d(Map) ? WITH_Z : WITHOUT_Z, cat, Fi)) {
execute(pg_info->conn, "ROLLBACK");
return -1;
@@ -182,110 +344,48 @@
/* register first part in offset array */
offset_info->array[offset_info->array_num++] = 0;
}
- G_debug(3, "V1_write_line_pg(): -> offset = %lu offset_num = %d cat = %d",
+ G_debug(3, "write_line_sf(): -> offset = %lu offset_num = %d cat = %d",
(unsigned long)offset, offset_info->array_num, cat);
return offset;
-#else
- G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
- return -1;
-#endif
}
-/*!
- \brief Rewrites feature at the given offset (level 1) (PostGIS interface)
-
- \param Map pointer to Map_info structure
- \param offset feature offset
- \param type feature type (GV_POINT, GV_LINE, ...)
- \param points feature geometry
- \param cats feature categories
-
- \return feature offset (rewriten feature)
- \return -1 on error
- */
-off_t V1_rewrite_line_pg(struct Map_info * Map,
- int line, int type, off_t offset,
- const struct line_pnts * points,
- const struct line_cats * cats)
+off_t write_line_tp(struct Map_info *Map, int type,
+ const struct line_pnts *points)
{
- G_debug(3, "V1_rewrite_line_pg(): line=%d type=%d offset=%lu",
- line, type, offset);
-#ifdef HAVE_POSTGRES
- if (type != V1_read_line_pg(Map, NULL, NULL, offset)) {
- G_warning(_("Unable to rewrite feature (incompatible feature types)"));
- return -1;
- }
-
- /* delete old */
- V1_delete_line_pg(Map, offset);
-
- return V1_write_line_pg(Map, type, points, cats);
-#else
- G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
- return -1;
-#endif
-}
-
-/*!
- \brief Deletes feature at the given offset (level 1)
-
- \param Map pointer Map_info structure
- \param offset feature offset
-
- \return 0 on success
- \return -1 on error
- */
-int V1_delete_line_pg(struct Map_info *Map, off_t offset)
-{
-#ifdef HAVE_POSTGRES
- long fid;
- char stmt[DB_SQL_MAX];
-
struct Format_info_pg *pg_info;
-
+
pg_info = &(Map->fInfo.pg);
- if (!pg_info->conn || !pg_info->table_name) {
+ if (!pg_info->conn) {
G_warning(_("No connection defined"));
return -1;
}
- if (offset >= pg_info->offset.array_num) {
- G_warning(_("Invalid offset (%d)"), offset);
+ if (!pg_info->table_name) {
+ G_warning(_("PostGIS feature table not defined"));
return -1;
}
- fid = pg_info->offset.array[offset];
-
- G_debug(3, "V1_delete_line_pg(), offset = %lu -> fid = %ld",
- (unsigned long)offset, fid);
-
- if (!pg_info->inTransaction) {
- /* start transaction */
- pg_info->inTransaction = TRUE;
- if (execute(pg_info->conn, "BEGIN") == -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;
}
+
+ G_debug(3, "write_line_pg(): type = %d n_points = %d",
+ type, points->n_points);
- sprintf(stmt, "DELETE FROM %s WHERE %s = %ld",
- pg_info->table_name, pg_info->fid_column, fid);
- G_debug(2, "SQL: %s", stmt);
-
- if (execute(pg_info->conn, stmt) == -1) {
- G_warning(_("Unable to delete feature"));
+ /* write feature's geometry and fid */
+ if (-1 == write_feature(pg_info, type, &points, 1,
+ Vect_is_3d(Map) ? WITH_Z : WITHOUT_Z, -1, NULL)) {
execute(pg_info->conn, "ROLLBACK");
return -1;
}
return 0;
-#else
- G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
- return -1;
-#endif
}
-#ifdef HAVE_POSTGRES
/*!
\brief Binary data to HEX
@@ -463,7 +563,8 @@
See OGRPolygon::exportToWkb from GDAL/OGR library
\param byte_order byte order (ENDIAN_LITTLE or ENDIAN_BIG)
- \param points feature geometry
+ \param ipoints list of ring geometries (first is outer ring)
+ \param nrings number of rings
\param with_z WITH_Z for 3D data
\param[out] nsize buffer size
@@ -471,21 +572,26 @@
\return NULL on error
*/
unsigned char *polygon_to_wkb(int byte_order,
- const struct line_pnts *points, int with_z,
- int *nsize)
+ const struct line_pnts** points, int nrings,
+ int with_z, int *nsize)
{
- int i, point_size, nrings;
+ int i, ring, point_size, offset;
unsigned char *wkb_data;
unsigned int sf_type;
- if (points->n_points < 3)
+ /* check data validity */
+ if (nrings < 1)
return NULL;
+ for (ring = 0; ring < nrings; ring++) {
+ if (points[ring]->n_points < 3)
+ return NULL;
+ }
/* allocate buffer */
point_size = 8 * (with_z ? 3 : 2);
- /* one ring only */
- nrings = 1;
- *nsize = 9 + (4 + point_size * points->n_points);
+ *nsize = 9;
+ for (ring = 0; ring < nrings; ring++)
+ *nsize += 4 + point_size * points[ring]->n_points;
wkb_data = G_malloc(*nsize);
G_zero(wkb_data, *nsize);
@@ -517,31 +623,38 @@
memcpy(wkb_data + 5, &nrings, 4);
}
- /* serialize ring */
- memcpy(wkb_data + 9, &(points->n_points), 4);
- for (i = 0; i < points->n_points; i++) {
- memcpy(wkb_data + 9 + 4 + point_size * i, &(points->x[i]), 8);
- memcpy(wkb_data + 9 + 4 + 8 + point_size * i, &(points->y[i]), 8);
-
- if (with_z) {
- memcpy(wkb_data + 9 + 4 + 16 + point_size * i, &(points->z[i]),
- 8);
+ /* serialize rings */
+ offset = 9;
+ for (ring = 0; ring < nrings; ring++) {
+ memcpy(wkb_data + offset, &(points[ring]->n_points), 4);
+ for (i = 0; i < points[ring]->n_points; i++) {
+ memcpy(wkb_data + offset +
+ 4 + point_size * i, &(points[ring]->x[i]), 8);
+ memcpy(wkb_data + offset +
+ 4 + 8 + point_size * i, &(points[ring]->y[i]), 8);
+
+ if (with_z) {
+ memcpy(wkb_data + offset +
+ 4 + 16 + point_size * i, &(points[ring]->z[i]), 8);
+ }
}
- }
-
- /* swap if needed */
- if (byte_order == ENDIAN_BIG) {
- int npoints, nitems;
-
- npoints = SWAP32(points->n_points);
- memcpy(wkb_data + 5, &npoints, 4);
-
- nitems = (with_z ? 3 : 2) * points->n_points;
- for (i = 0; i < nitems; i++) {
- SWAPDOUBLE(wkb_data + 9 + 4 + 8 * i);
+
+ offset += 4 + point_size * points[ring]->n_points;
+
+ /* swap if needed */
+ if (byte_order == ENDIAN_BIG) {
+ int npoints, nitems;
+
+ npoints = SWAP32(points[ring]->n_points);
+ memcpy(wkb_data + 5, &npoints, 4);
+
+ nitems = (with_z ? 3 : 2) * points[ring]->n_points;
+ for (i = 0; i < nitems; i++) {
+ SWAPDOUBLE(wkb_data + offset + 4 + 8 * i);
+ }
}
}
-
+
return wkb_data;
}
@@ -551,6 +664,7 @@
\param pg_info pointer to Format_info_pg struct
\param type feature type (GV_POINT, GV_LINE, ...)
\param points pointer to line_pnts struct
+ \param nparts number of parts (rings for polygon)
\param with_z WITH_Z for 3D data
\param cat category number (-1 for no category)
\param Fi pointer to field_info (attributes to copy, NULL for no attributes)
@@ -558,9 +672,9 @@
\return -1 on error
\retirn 0 on success
*/
-int write_feature(struct Format_info_pg *pg_info,
- int type, const struct line_pnts *points, int with_z,
- int cat, const struct field_info *Fi)
+int write_feature(struct Format_info_pg *pg_info, int type,
+ const struct line_pnts **points, int nparts,
+ int with_z, int cat, const struct field_info *Fi)
{
int byte_order, nbytes, nsize;
unsigned int sf_type;
@@ -583,13 +697,22 @@
/* get wkb data */
nbytes = -1;
wkb_data = NULL;
- if (type == GV_POINT)
- wkb_data = point_to_wkb(byte_order, points, with_z, &nbytes);
+ if (type == GV_POINT || type == GV_CENTROID)
+ wkb_data = point_to_wkb(byte_order, points[0], with_z, &nbytes);
else if (type == GV_LINE)
- wkb_data = linestring_to_wkb(byte_order, points, with_z, &nbytes);
- else if (type == GV_BOUNDARY)
- wkb_data = polygon_to_wkb(byte_order, points, with_z, &nbytes);
-
+ wkb_data = linestring_to_wkb(byte_order, points[0], with_z, &nbytes);
+ else if (type == GV_BOUNDARY) {
+ if (!pg_info->toposchema_name) {
+ /* PostGIS simple feature access */
+ wkb_data = polygon_to_wkb(byte_order, points, nparts,
+ with_z, &nbytes);
+ }
+ else {
+ /* PostGIS topology access */
+ wkb_data = linestring_to_wkb(byte_order, points[0], with_z, &nbytes);
+ }
+ }
+
if (!wkb_data || nbytes < 1) {
G_warning(_("Unsupported feature type %d"), type);
return -1;
@@ -674,7 +797,7 @@
to the feature table */
/* insert feature into topology schema (node or edge) */
- stmt = build_topo_stmt(pg_info, type, text_data);
+ stmt = build_topo_stmt(pg_info, type, NULL, text_data);
id = execute_topo(pg_info->conn, stmt);
if (id == -1) {
/* rollback transaction */
@@ -686,7 +809,6 @@
/* insert topoelement into feature table) */
stmt = build_topogeom_stmt(pg_info, id, type, do_update);
if (execute(pg_info->conn, stmt) == -1) {
- /* rollback transaction */
execute(pg_info->conn, "ROLLBACK");
return -1;
}
@@ -853,22 +975,59 @@
topology schema
\param pg_info so pointer to Format_info_pg
- \param type feature type (GV_POINT, ...)
+ \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(const struct Format_info_pg *pg_info,
- int type, const char *geom_data)
+char *build_topo_stmt(const struct Format_info_pg *pg_info, int type,
+ const struct P_line *Line, const char *geom_data)
{
char *stmt;
stmt = NULL;
- if (type == GV_POINT) {
+ switch(type) {
+ case GV_POINT: {
+#if 0
+ G_asprintf(&stmt, "INSERT INTO \"%s\".node (geom) VALUES ('%s'::GEOMETRY)",
+ pg_info->toposchema_name, geom_data);
+#else
+ G_asprintf(&stmt, "SELECT topology.AddNode('%s', '%s'::GEOMETRY)",
+ pg_info->toposchema_name, geom_data);
+#endif
+ break;
+ }
+ case GV_LINE: {
+ struct P_topo_l *topo;
+
+ topo = (struct P_topo_l *) Line->topo;
+ G_asprintf(&stmt, "INSERT INTO \"%s\".edge_data (geom,"
+ "start_node,end_node,"
+ "next_left_edge,abs_next_left_edge,"
+ "next_right_edge,abs_next_right_edge,"
+ "left_face,right_face) "
+ "VALUES ('%s'::GEOMETRY,%d,%d,0,0,0,0,0,0)",
+ pg_info->toposchema_name, geom_data,
+ topo->N1, topo->N2);
+ break;
+ }
+ case GV_CENTROID: {
+ /* TopoGeo_AddPoint ? */
G_asprintf(&stmt, "SELECT AddNode('%s', '%s'::GEOMETRY)",
- pg_info->toposchema_name, geom_data);
+ pg_info->toposchema_name, geom_data);
+ break;
}
+ case GV_BOUNDARY: {
+ /* TopoGeo_AddLineString ? */
+ G_asprintf(&stmt, "SELECT AddEdge('%s', '%s'::GEOMETRY)",
+ pg_info->toposchema_name, geom_data);
+ break;
+ }
+ default:
+ G_warning(_("Unsupported feature type %d"), Line->type);
+ break;
+ }
return stmt;
}
@@ -897,7 +1056,7 @@
if (type == GV_POINT)
topogeom_type = 1;
- else if (type == GV_LINES)
+ else if (type & GV_LINES)
topogeom_type = 2;
else {
G_warning(_("Unsupported topo geometry type %d"), type);
More information about the grass-commit
mailing list