[GRASS-SVN] r52004 - grass/trunk/lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jun 7 15:36:39 PDT 2012
Author: martinl
Date: 2012-06-07 15:36:38 -0700 (Thu, 07 Jun 2012)
New Revision: 52004
Modified:
grass/trunk/lib/vector/Vlib/build.c
grass/trunk/lib/vector/Vlib/build_pg.c
grass/trunk/lib/vector/Vlib/open_pg.c
grass/trunk/lib/vector/Vlib/pg_local_proto.h
Log:
vlib/pg: build isles for PostGIS Topology access
Modified: grass/trunk/lib/vector/Vlib/build.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build.c 2012-06-07 19:19:42 UTC (rev 52003)
+++ grass/trunk/lib/vector/Vlib/build.c 2012-06-07 22:36:38 UTC (rev 52004)
@@ -56,15 +56,14 @@
\param iline line id
\param side side (GV_LEFT or GV_RIGHT)
- \return > 0 number of area
- \return < 0 number of isle
+ \return > 0 area id
+ \return < 0 isle id
\return 0 not created (may also already exist)
*/
int Vect_build_line_area(struct Map_info *Map, int iline, int side)
{
int j, area, isle, n_lines, line, direction;
- static int first = 1;
- off_t offset;
+ static int first = TRUE;
struct Plus_head *plus;
struct P_line *BLine;
static struct line_pnts *Points, *APoints;
@@ -79,15 +78,15 @@
if (first) {
Points = Vect_new_line_struct();
APoints = Vect_new_line_struct();
- first = 0;
+ first = FALSE;
}
area = dig_line_get_area(plus, iline, side);
if (area != 0) {
- G_debug(3, " area/isle = %d -> skip", area);
- return 0;
+ G_debug(3, " area/isle = %d -> skip", area);
+ return 0;
}
-
+
n_lines = dig_build_area_with_line(plus, iline, side, &lines);
G_debug(3, " n_lines = %d", n_lines);
if (n_lines < 1) {
@@ -99,9 +98,8 @@
for (j = 0; j < n_lines; j++) {
line = abs(lines[j]);
BLine = plus->Line[line];
- offset = BLine->offset;
G_debug(3, " line[%d] = %d, offset = %lu", j, line,
- (unsigned long)offset);
+ (unsigned long) BLine->offset);
Vect_read_line(Map, Points, NULL, line);
if (lines[j] > 0)
direction = GV_FORWARD;
Modified: grass/trunk/lib/vector/Vlib/build_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_pg.c 2012-06-07 19:19:42 UTC (rev 52003)
+++ grass/trunk/lib/vector/Vlib/build_pg.c 2012-06-07 22:36:38 UTC (rev 52004)
@@ -5,8 +5,6 @@
Higher level functions for reading/writing/manipulating vectors.
- \todo Implement build_topo()
-
Line offset is
- centroids : FID
- other types : index of the first record (which is FID) in offset array.
@@ -108,7 +106,7 @@
#ifdef HAVE_POSTGRES
/*!
- \brief Build based on PostGIS topology
+ \brief Build from PostGIS topology schema
Currently only GV_BUILD_ALL is supported
@@ -120,10 +118,8 @@
*/
int build_topo(struct Map_info *Map, int build)
{
- struct Format_info_pg *pg_info;
struct Plus_head *plus;
- pg_info = &(Map->fInfo.pg);
plus = &(Map->plus);
/* check if upgrade or downgrade */
@@ -140,7 +136,7 @@
}
if (plus->built < GV_BUILD_BASE) {
- if (load_plus(pg_info, plus, FALSE) != 0)
+ if (load_plus(Map, FALSE) != 0)
return 0;
}
Modified: grass/trunk/lib/vector/Vlib/open_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open_pg.c 2012-06-07 19:19:42 UTC (rev 52003)
+++ grass/trunk/lib/vector/Vlib/open_pg.c 2012-06-07 22:36:38 UTC (rev 52004)
@@ -40,9 +40,8 @@
static int check_topo(struct Format_info_pg *, struct Plus_head *);
static int parse_bbox(const char *, struct bound_box *);
static int num_of_records(const struct Format_info_pg *, const char *);
-static int read_p_node(struct Plus_head *, int, int, struct Format_info_pg *);
-static int read_p_line(struct Plus_head *, int, const struct edge_data *);
-static int read_p_area(struct Plus_head *, int, int, struct Format_info_pg *);
+static struct P_node *read_p_node(struct Plus_head *, int, int, struct Format_info_pg *);
+static struct P_line *read_p_line(struct Plus_head *, int, const struct edge_data *);
static int load_plus_head(struct Format_info_pg *, struct Plus_head *);
static void notice_processor(void *, const char *);
#endif
@@ -401,6 +400,8 @@
struct Plus_head *plus;
struct Format_info_pg *pg_info;
+ Map->open = VECT_OPEN_CODE; /* needed by load_plus */
+
plus = &(Map->plus);
pg_info = &(Map->fInfo.pg);
@@ -411,7 +412,7 @@
/* free and init plus structure */
dig_init_plus(plus);
- return load_plus(pg_info, plus, head_only);
+ return load_plus(Map, head_only);
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
return -1;
@@ -956,11 +957,11 @@
\param id node id (table "node")
\param pg_info pointer to Format_info_pg sttucture
- \return 0 on success
- \return -1 on failure
+ \return pointer to new P_node struct
+ \return NULL on error
*/
-int read_p_node(struct Plus_head *plus, int n, int id,
- struct Format_info_pg *pg_info)
+struct P_node *read_p_node(struct Plus_head *plus, int n, int id,
+ struct Format_info_pg *pg_info)
{
int i, cnt;
char stmt[DB_SQL_MAX];
@@ -986,13 +987,13 @@
G_warning(_("Unable to read node %d"), id);
if (res)
PQclear(res);
- return -1;
+ return NULL;
}
cnt = PQntuples(res);
if (cnt == 0) { /* dead ??? */
plus->Node[n] = NULL;
- return 0;
+ return NULL;
}
node = dig_alloc_node();
@@ -1000,7 +1001,7 @@
G_debug(4, "read_p_node(): id = %d, n_lines = %d", id, cnt);
if (dig_node_alloc_line(node, node->n_lines) == -1)
- return -1;
+ return NULL;
/* lines / angles */
for (i = 0; i < node->n_lines; i++) {
@@ -1037,7 +1038,7 @@
G_warning(_("Unable to read node %d"), id);
if (res)
PQclear(res);
- return -1;
+ return NULL;
}
node->x = atof(PQgetvalue(res, 0, 0));
node->y = atof(PQgetvalue(res, 0, 1));
@@ -1049,7 +1050,7 @@
plus->Node[n] = node;
- return 0;
+ return node;
}
/*!
@@ -1067,11 +1068,11 @@
\param data edge data (id, start/end node, left/right face, ...)
\param pg_info pointer to Format_info_pg sttucture
- \return 0 on success
- \return -1 on failure
+ \return pointer to P_line struct
+ \return NULL on error
*/
-int read_p_line(struct Plus_head *plus, int n,
- const struct edge_data *data)
+struct P_line *read_p_line(struct Plus_head *plus, int n,
+ const struct edge_data *data)
{
int tp;
struct P_line *line;
@@ -1091,7 +1092,7 @@
if (tp == 0) { /* dead ??? */
plus->Line[n] = NULL;
- return 0;
+ return NULL;
}
line = dig_alloc_line();
@@ -1121,8 +1122,10 @@
topo->N1 = data->start_node;
topo->N2 = data->end_node;
- topo->left = data->left_face == 0 ? -1 : data->left_face;
- topo->right = data->right_face == 0 ? -1 : data->right_face;
+
+ /* skip left/right area - will be detected when building
+ areas/isles */
+ topo->left = topo->right = 0;
}
/* centroids */
else if (line->type == GV_CENTROID) {
@@ -1135,75 +1138,10 @@
plus->Line[n] = line;
- return 0;
+ return line;
}
/*!
- \brief Read P_area structure
-
- See dig_Rd_P_area() for reference.
-
- \param plus pointer to Plus_head structure
- \param n index (starts at 1)
- \param face_id face id (see 'face' table)
- \param pg_info pointer to Format_info_pg sttucture
-
- \return 0 on success
- \return -1 on failure
-*/
-int read_p_area(struct Plus_head *plus, int n, int face_id, struct Format_info_pg *pg_info)
-{
- int i, cnt;
- char stmt[DB_SQL_MAX];
-
- PGresult *res;
- struct P_area *area;
-
- sprintf(stmt,
- "SELECT edge from ST_GetFaceEdges('%s', %d)",
- pg_info->toposchema_name, face_id);
- G_debug(2, "SQL: %s", stmt);
- res = PQexec(pg_info->conn, stmt);
- if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) {
- G_warning(_("Unable to read face %d"), face_id);
- if (res)
- PQclear(res);
- return -1;
- }
-
- cnt = PQntuples(res);
- if (cnt == 0) { /* dead */
- plus->Area[n] = NULL;
- return 0;
- }
-
- area = dig_alloc_area();
-
- /* boundaries */
- area->n_lines = cnt;
- if (dig_area_alloc_line(area, area->n_lines) == -1)
- return -1;
- area->lines = (plus_t *)G_realloc(area->lines, sizeof(plus_t) * area->n_lines);
- for (i = 0; i < area->n_lines; i++) {
- /* GRASS Topo model: lines in clockwise order
- PosTGIS Topo model: lines in counter clockwise order */
- area->lines[i] = -1 * atoi(PQgetvalue(res, i, 0));
- }
-
- /* isles */
- /* TODO */
-
- /* centroid */
- area->centroid = plus->n_lines - plus->n_clines + i;
-
- plus->Area[n] = area;
-
- PQclear(res);
-
- return 0;
-}
-
-/*!
\brief Read topo (from PostGIS topology schema) header info only
\param[in,out] plus pointer to Plus_head struct
@@ -1256,12 +1194,13 @@
/* + isolated nodes as points
+ centroids */
plus->n_lines = num_of_records(pg_info, stmt);
- /* areas (faces in PostGIS Topology model) */
+ /* areas (faces in PostGIS Topology model)
sprintf(stmt,
"SELECT COUNT(*) FROM \"%s\".face WHERE mbr IS NOT NULL",
pg_info->toposchema_name);
plus->n_areas = num_of_records(pg_info, stmt);
G_debug(3, "Vect_open_topo_pg(): n_areas=%d", plus->n_areas);
+ */
/* TODO: n_isles | n_volumes | n_holes */
/* number of features group by type */
@@ -1314,15 +1253,21 @@
\return 0 on success
\return -1 on error
*/
-int load_plus(struct Format_info_pg *pg_info, struct Plus_head *plus,
- int head_only)
+int load_plus(struct Map_info *Map, int head_only)
{
int i, id, ntuples;
char stmt[DB_SQL_MAX];
struct edge_data line_data;
+ struct Format_info_pg *pg_info;
+ struct Plus_head *plus;
+ struct P_line *Line;
+
PGresult *res;
+ pg_info = &(Map->fInfo.pg);
+ plus = &(Map->plus);
+
if (load_plus_head(pg_info, plus) != 0)
return -1;
@@ -1364,7 +1309,9 @@
G_debug(3, "load_plus(): n_lines = %d", plus->n_lines);
dig_alloc_lines(plus, plus->n_lines);
- /* read PostGIS Topo standalone nodes */
+ /* read PostGIS Topo standalone nodes
+ -> points
+ */
sprintf(stmt,
"SELECT node_id FROM \"%s\".node WHERE node_id NOT IN "
"(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
@@ -1391,7 +1338,10 @@
}
PQclear(res);
- /* read PostGIS Topo edges */
+ /* read PostGIS Topo edges
+ -> lines
+ -> boundaries
+ */
sprintf(stmt,
"SELECT edge_id,start_node,end_node,left_face,right_face "
"FROM \"%s\".edge",
@@ -1414,37 +1364,43 @@
line_data.end_node = atoi(PQgetvalue(res, i, 2));
line_data.left_face = atoi(PQgetvalue(res, i, 3));
line_data.right_face = atoi(PQgetvalue(res, i, 4));
- read_p_line(plus, plus->n_plines + i + 1, &line_data);
+
+ id = plus->n_plines + i + 1; /* points already registered */
+ Line = read_p_line(plus, id, &line_data);
+ if (line_data.left_face != 0 || line_data.right_face != 0) {
+ /* boundary detected -> build area on left and right*/
+
+ int s, side;
+ for (s = 0; s < 2; s++) {
+ if (s == 0)
+ side = GV_LEFT;
+ else
+ side = GV_RIGHT;
+
+ G_debug(3, "Build area for line = %d, side = %d",
+ id, side);
+ Vect_build_line_area(Map, id, side);
+ }
+ }
+ if (Line->type == GV_BOUNDARY) {
+ struct P_topo_b *topo;
+
+ if (line_data.left_face == 0)
+ line_data.left_face = -1;
+ if (line_data.right_face == 0)
+ line_data.right_face = -1;
+
+ topo = (struct P_topo_b *)Line->topo;
+ if (topo->left != line_data.left_face)
+ G_warning(_("Left area detected as %d (should be %d"),
+ topo->left, line_data.left_face);
+ if (topo->right != line_data.right_face)
+ G_warning(_("Right area detected as %d (should be %d"),
+ topo->right, line_data.right_face);
+ }
}
PQclear(res);
- /* read areas (GRASS Topo) */
- sprintf(stmt,
- "SELECT face_id from \"%s\".face WHERE mbr IS NOT NULL",
- pg_info->toposchema_name);
- G_debug(2, "SQL: %s", stmt);
- res = PQexec(pg_info->conn, stmt);
- if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
- PQntuples(res) != plus->n_areas) {
- G_warning(_("Unable to read areas"));
- if (res)
- PQclear(res);
- return -1;
- }
-
- G_debug(3, "load_plus(): n_areas = %d", plus->n_areas);
- dig_alloc_areas(plus, plus->n_areas);
- G_zero(&line_data, sizeof(struct edge_data));
- for (i = 1; i <= plus->n_areas; i++) {
- line_data.id = line_data.left_face = atoi(PQgetvalue(res, i - 1, 0));
- read_p_area(plus, i, line_data.id, pg_info);
- /* add centroids */
- read_p_line(plus, plus->n_lines - plus->n_clines + i, &line_data);
- }
- PQclear(res);
-
- /* read isle (GRASS Topo) */
-
return 0;
}
Modified: grass/trunk/lib/vector/Vlib/pg_local_proto.h
===================================================================
--- grass/trunk/lib/vector/Vlib/pg_local_proto.h 2012-06-07 19:19:42 UTC (rev 52003)
+++ grass/trunk/lib/vector/Vlib/pg_local_proto.h 2012-06-07 22:36:38 UTC (rev 52004)
@@ -53,7 +53,7 @@
struct Format_info_cache *,
struct feat_parts *);
int set_initial_query(struct Format_info_pg *, int);
-int load_plus(struct Format_info_pg *, struct Plus_head *, int);
+int load_plus(struct Map_info *, int);
#endif /* HAVE_POSTGRES */
More information about the grass-commit
mailing list