[GRASS-SVN] r58246 - in grass/trunk: include/vect lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Nov 17 09:59:58 PST 2013
Author: martinl
Date: 2013-11-17 09:59:57 -0800 (Sun, 17 Nov 2013)
New Revision: 58246
Modified:
grass/trunk/include/vect/dig_structs.h
grass/trunk/lib/vector/Vlib/open_pg.c
grass/trunk/lib/vector/Vlib/read_pg.c
Log:
vlib/pg: fix reading categories from PostGIS Topology (work in progress)
Modified: grass/trunk/include/vect/dig_structs.h
===================================================================
--- grass/trunk/include/vect/dig_structs.h 2013-11-17 17:58:14 UTC (rev 58245)
+++ grass/trunk/include/vect/dig_structs.h 2013-11-17 17:59:57 UTC (rev 58246)
@@ -474,6 +474,10 @@
*/
int *lines_types;
/*!
+ \brief List of line cats (used only for PostGIS Topology access)
+ */
+ int *lines_cats;
+ /*!
\brief Number of allocated lines in cache
*/
int lines_alloc;
Modified: grass/trunk/lib/vector/Vlib/open_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open_pg.c 2013-11-17 17:58:14 UTC (rev 58245)
+++ grass/trunk/lib/vector/Vlib/open_pg.c 2013-11-17 17:59:57 UTC (rev 58246)
@@ -1231,7 +1231,7 @@
pg_info->toposchema_name);
else
sprintf(stmt, "SELECT node.node_id,geom,lines,angles FROM \"%s\".node AS node "
- "join \"%s\".%s AS node_grass ON node.node_id = node_grass.node_id "
+ "JOIN \"%s\".%s AS node_grass ON node.node_id = node_grass.node_id "
"ORDER BY node_id", pg_info->toposchema_name, pg_info->toposchema_name,
TOPO_TABLE_NODE);
G_debug(2, "SQL: %s", stmt);
Modified: grass/trunk/lib/vector/Vlib/read_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/read_pg.c 2013-11-17 17:58:14 UTC (rev 58245)
+++ grass/trunk/lib/vector/Vlib/read_pg.c 2013-11-17 17:59:57 UTC (rev 58246)
@@ -116,8 +116,12 @@
struct P_line *Line;
struct bound_box lbox, mbox;
+ struct Format_info_pg *pg_info;
+
G_debug(3, "V2_read_next_line_pg()");
+ pg_info = &(Map->fInfo.pg);
+
if (Map->constraint.region_flag)
Vect_get_constraint_box(Map, &mbox);
@@ -142,8 +146,9 @@
}
}
- if (Line->type == GV_CENTROID) {
- G_debug(4, "Centroid");
+ if (!pg_info->toposchema_name &&
+ Line->type == GV_CENTROID) {
+ G_debug(4, "Determine centroid for simple features");
if (line_p != NULL) {
int i, found;
@@ -263,7 +268,7 @@
get_feature(pg_info, fid, -1);
if (pg_info->cache.sf_type == SF_NONE) {
- G_warning(_("Feature %d without geometry skipped"), fid);
+ G_warning(_("Feature %ld without geometry skipped"), fid);
return -1;
}
@@ -338,15 +343,8 @@
if (!line_p && !line_c)
return Line->type;
- if (line_c) {
- Vect_reset_cats(line_c);
- Vect_cat_set(line_c, 1, (int) Line->offset);
- }
-
- if (!line_p)
- return Line->type;
-
- Vect_reset_line(line_p);
+ if (line_p)
+ Vect_reset_line(line_p);
if (Line->type == GV_CENTROID && !pg_info->toposchema_name) {
/* simple features access: get centroid from sidx */
return get_centroid(Map, line, line_p);
@@ -368,9 +366,22 @@
}
if (0 > (int)pg_info->cache.sf_type) /* -1 || - 2 */
return -1;
+
+ if (line_c) {
+ int cat;
+
+ Vect_reset_cats(line_c);
+ if (!pg_info->toposchema_name) /* simple features access */
+ cat = (int) Line->offset;
+ else /* PostGIS Topology (cats are cached) */
+ cat = pg_info->cache.lines_cats[0];
+ if (cat != -1)
+ Vect_cat_set(line_c, 1, cat);
+ }
+
+ if (line_p)
+ Vect_append_points(line_p, pg_info->cache.lines[0], GV_FORWARD);
- Vect_append_points(line_p, pg_info->cache.lines[0], GV_FORWARD);
-
return Line->type;
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -422,7 +433,7 @@
sf_type = get_feature(pg_info, -1, -1);
if (sf_type == SF_NONE) {
- G_warning(_("Feature %d without geometry skipped"), pg_info->cache.fid);
+ G_warning(_("Feature %ld without geometry skipped"), pg_info->cache.fid);
return -1;
}
@@ -467,8 +478,15 @@
if (line_p)
Vect_append_points(line_p, iline, GV_FORWARD);
- if (line_c)
- Vect_cat_set(line_c, 1, (int)pg_info->cache.fid);
+ if (line_c) {
+ int cat;
+ if (!pg_info->toposchema_name) /* simple features access */
+ cat = (int)pg_info->cache.fid;
+ else /* PostGIS Topology (cats are cached) */
+ cat = pg_info->cache.lines_cats[pg_info->cache.lines_next];
+ if (cat != -1)
+ Vect_cat_set(line_c, 1, cat);
+ }
pg_info->cache.lines_next++;
@@ -597,10 +615,19 @@
FALSE, force_type,
&(pg_info->cache), NULL);
+ /* cache also categories (only for PostGIS Topology) */
+ if (pg_info->toposchema_name) {
+ if (!PQgetisnull(pg_info->res, pg_info->next_line, 3))
+ pg_info->cache.lines_cats[pg_info->cache.lines_next] =
+ atoi(PQgetvalue(pg_info->res, pg_info->next_line, 3));
+ else
+ pg_info->cache.lines_cats[pg_info->cache.lines_next] = -1; /* no cat */
+ }
+
/* set feature id */
if (fid < 0) {
pg_info->cache.fid =
- atoi(PQgetvalue(pg_info->res, pg_info->next_line, 1));
+ atoi(PQgetvalue(pg_info->res, pg_info->next_line, 1));
pg_info->next_line++;
}
else {
@@ -1154,26 +1181,31 @@
/* TODO: optimize SQL statement (for points/centroids) */
sprintf(stmt,
"DECLARE %s CURSOR FOR "
- "SELECT geom,fid,type FROM ("
- "SELECT node_id AS fid,geom, %d AS type FROM \"%s\".node WHERE "
- "containing_face IS NULL AND node_id NOT IN "
- "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
- "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
- "\"%s\".edge GROUP BY end_node) AS foo) UNION ALL SELECT "
- "node_id AS fid,geom, %d AS type FROM \"%s\".node WHERE "
- "containing_face IS NOT NULL AND node_id NOT IN "
- "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
- "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
- "\"%s\".edge GROUP BY end_node) AS foo) "
- "UNION ALL SELECT edge_id AS fid, geom, %d AS type FROM \"%s\".edge WHERE "
- "left_face = 0 AND right_face = 0 UNION ALL SELECT edge_id AS fid, geom, %d AS type FROM "
- "\"%s\".edge WHERE left_face != 0 OR right_face != 0 ) AS foo ORDER BY type,fid",
- pg_info->cursor_name, GV_POINT,
- pg_info->toposchema_name, pg_info->toposchema_name, pg_info->toposchema_name,
- GV_CENTROID, pg_info->toposchema_name, pg_info->toposchema_name, pg_info->toposchema_name,
- GV_LINE, pg_info->toposchema_name, GV_BOUNDARY, pg_info->toposchema_name);
+ "SELECT geom,id,type,fid FROM ("
+ "SELECT tt.node_id AS id,tt.geom, %d AS type, ft.fid AS fid FROM \"%s\".node AS tt "
+ "LEFT JOIN \"%s\" AS ft ON (%s).type = 1 AND (%s).id = node_id "
+ "WHERE containing_face IS NULL AND node_id NOT IN "
+ "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge GROUP BY start_node UNION ALL "
+ "SELECT end_node AS node FROM \"%s\".edge GROUP BY end_node) AS foo) UNION ALL "
+ "SELECT tt.node_id AS id,tt.geom, %d AS type, ft.fid AS fid FROM \"%s\".node AS tt "
+ "LEFT JOIN \"%s\" AS ft ON (%s).type = 3 AND (%s).id = containing_face "
+ "WHERE containing_face IS NOT NULL AND node_id NOT IN "
+ "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge GROUP BY start_node UNION ALL "
+ "SELECT end_node AS node FROM \"%s\".edge GROUP BY end_node) AS foo) UNION ALL "
+ "SELECT tt.edge_id AS id, tt.geom, %d AS type, ft.fid AS fid FROM \"%s\".edge AS tt "
+ "LEFT JOIN \"%s\" AS ft ON (%s).type = 2 AND (%s).id = edge_id "
+ "WHERE left_face = 0 AND right_face = 0 UNION ALL "
+ "SELECT tt.edge_id AS id, tt.geom, %d AS type, ft.fid AS fid FROM \"%s\".edge AS tt "
+ "LEFT JOIN \"%s\" AS ft ON (%s).type = 2 AND (%s).id = edge_id "
+ "WHERE left_face != 0 OR right_face != 0 ) AS foo ORDER BY type,id",
+ pg_info->cursor_name,
+ GV_POINT, pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column, pg_info->topogeom_column,
+ pg_info->toposchema_name, pg_info->toposchema_name,
+ GV_CENTROID, pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column, pg_info->topogeom_column,
+ pg_info->toposchema_name, pg_info->toposchema_name,
+ GV_LINE, pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column, pg_info->topogeom_column,
+ GV_BOUNDARY, pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column, pg_info->topogeom_column);
}
-
if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
Vect__execute_pg(pg_info->conn, "ROLLBACK");
return -1;
@@ -1333,13 +1365,19 @@
if (type & GV_POINTS) {
sprintf(stmt,
- "SELECT geom,containing_face FROM \"%s\".node WHERE node_id = %d",
- pg_info->toposchema_name, fid);
+ "SELECT tt.geom,tt.containing_face,ft.fid FROM \"%s\".node AS tt "
+ "LEFT JOIN \"%s\" AS ft ON (%s).type = 1 and (%s).id = edge_id "
+ "WHERE node_id = %d",
+ pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column,
+ pg_info->topogeom_column, fid);
}
else {
sprintf(stmt,
- "SELECT geom,left_face,right_face FROM \"%s\".edge WHERE edge_id = %d",
- pg_info->toposchema_name, fid);
+ "SELECT tt.geom,tt.left_face,tt.right_face,ft.fid FROM \"%s\".edge AS tt "
+ "LEFT JOIN \"%s\" AS ft ON (%s).type = 2 and (%s).id = edge_id "
+ "WHERE edge_id = %d",
+ pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column,
+ pg_info->topogeom_column, fid);
}
}
G_debug(3, "SQL: %s", stmt);
@@ -1440,16 +1478,20 @@
sizeof(struct line_pnts *));
cache->lines_types = (int *)G_realloc(cache->lines_types,
cache->lines_alloc * sizeof(int));
+ cache->lines_cats = (int *)G_realloc(cache->lines_cats,
+ cache->lines_alloc * sizeof(int));
if (cache->lines_alloc > 1) {
for (i = cache->lines_alloc - num; i < cache->lines_alloc; i++) {
cache->lines[i] = Vect_new_line_struct();
cache->lines_types[i] = -1;
+ cache->lines_cats[i] = -1;
}
}
else {
cache->lines[0] = Vect_new_line_struct();
cache->lines_types[0] = -1;
+ cache->lines_cats[0] = -1;
}
}
More information about the grass-commit
mailing list