[GRASS-SVN] r56352 - grass/trunk/lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue May 21 08:36:10 PDT 2013
Author: martinl
Date: 2013-05-21 08:36:09 -0700 (Tue, 21 May 2013)
New Revision: 56352
Added:
grass/trunk/lib/vector/Vlib/area_pg.c
Modified:
grass/trunk/lib/vector/Vlib/area.c
grass/trunk/lib/vector/Vlib/build.c
grass/trunk/lib/vector/Vlib/build_nat.c
grass/trunk/lib/vector/Vlib/build_pg.c
grass/trunk/lib/vector/Vlib/local_proto.h
grass/trunk/lib/vector/Vlib/pg_local_proto.h
Log:
vlib(pg): speed up Vect_get_area|isle_points() for PostGIS Topology
access (work in progress)
Modified: grass/trunk/lib/vector/Vlib/area.c
===================================================================
--- grass/trunk/lib/vector/Vlib/area.c 2013-05-21 15:25:30 UTC (rev 56351)
+++ grass/trunk/lib/vector/Vlib/area.c 2013-05-21 15:36:09 UTC (rev 56352)
@@ -5,7 +5,7 @@
Higher level functions for reading/writing/manipulating vectors.
- (C) 2001-2009, 2011-2012 by the GRASS Development Team
+ (C) 2001-2009, 2011-2013 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
@@ -41,14 +41,14 @@
struct P_area *Area;
G_debug(3, "Vect_get_area_points(): area = %d", area);
- BPoints->n_points = 0;
+ Vect_reset_line(BPoints);
Plus = &(Map->plus);
Area = Plus->Area[area];
if (Area == NULL) { /* dead area */
G_warning(_("Attempt to read points of nonexistent area"));
- return -1; /* error , because we should not read dead areas */
+ return -1; /* error, because we should not read dead areas */
}
G_debug(3, " n_lines = %d", Area->n_lines);
@@ -66,49 +66,35 @@
\return -1 on error
*/
int Vect_get_isle_points(const struct Map_info *Map,
- int isle, struct line_pnts *BPoints)
+ int isle, struct line_pnts *BPoints)
{
- int i, line, aline, dir;
const struct Plus_head *Plus;
struct P_isle *Isle;
- static int first_time = 1;
- static struct line_pnts *Points;
G_debug(3, "Vect_get_isle_points(): isle = %d", isle);
- BPoints->n_points = 0;
+ Vect_reset_line(BPoints);
Plus = &(Map->plus);
Isle = Plus->Isle[isle];
-
- if (first_time == 1) {
- Points = Vect_new_line_struct();
- first_time = 0;
+
+ if (Isle == NULL) { /* dead isle */
+ G_warning(_("Attempt to read points of nonexistent isle"));
+ return -1; /* error, because we should not read dead isles */
}
G_debug(3, " n_lines = %d", Isle->n_lines);
- for (i = 0; i < Isle->n_lines; i++) {
- line = Isle->lines[i];
- aline = abs(line);
- G_debug(3, " append line(%d) = %d", i, line);
- if (0 > Vect_read_line(Map, Points, NULL, aline)) {
- G_fatal_error(_("Unable to read line %d"), aline);
- }
-
- G_debug(3, " line n_points = %d", Points->n_points);
-
- if (line > 0)
- dir = GV_FORWARD;
- else
- dir = GV_BACKWARD;
-
- Vect_append_points(BPoints, Points, dir);
- if (i != (Isle->n_lines - 1)) /* all but not last */
- BPoints->n_points--;
- G_debug(3, " isle n_points = %d", BPoints->n_points);
+ if (Map->format == GV_FORMAT_POSTGIS &&
+ Map->fInfo.pg.toposchema_name) {
+#ifdef HAVE_POSTGRES
+ /* PostGIS Topology */
+ return Vect__get_area_points_pg(Map, Isle->lines, Isle->n_lines, BPoints);
+#else
+ G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+#endif
}
-
- return (BPoints->n_points);
+ /* native format */
+ return Vect__get_area_points_nat(Map, Isle->lines, Isle->n_lines, BPoints);
}
/*!
@@ -452,6 +438,20 @@
return -1;
}
+/*!
+ \brief Get area boundary points (internal use only)
+
+ For PostGIS Topology calls Vect__get_area_points_pg() otherwise
+ Vect__get_area_points_nat(),
+
+ \param Map pointer to Map_info struct
+ \param lines array of boundary lines
+ \param n_lines number of lines in array
+ \param[out] APoints pointer to output line_pnts struct
+
+ \return number of points
+ \return -1 on error
+*/
int Vect__get_area_points(const struct Map_info *Map, const plus_t *lines, int n_lines,
struct line_pnts *BPoints)
{
@@ -467,3 +467,44 @@
/* native format */
return Vect__get_area_points_nat(Map, lines, n_lines, BPoints);
}
+
+
+/*!
+ \brief Get area boundary points (native format)
+
+ Used by Vect_build_line_area() and Vect_get_area_points().
+
+ \param Map pointer to Map_info struct
+ \param lines array of boundary lines
+ \param n_lines number of lines in array
+ \param[out] APoints pointer to output line_pnts struct
+
+ \return number of points
+ \return -1 on error
+*/
+int Vect__get_area_points_nat(const struct Map_info *Map, const plus_t *lines, int n_lines,
+ struct line_pnts *BPoints)
+{
+ int i, line, aline, dir;
+ static struct line_pnts *Points;
+
+ if (!Points)
+ Points = Vect_new_line_struct();
+
+ Vect_reset_line(BPoints);
+ for (i = 0; i < n_lines; i++) {
+ line = lines[i];
+ aline = abs(line);
+ G_debug(5, " append line(%d) = %d", i, line);
+
+ if (0 > Vect_read_line(Map, Points, NULL, aline))
+ return -1;
+
+ dir = line > 0 ? GV_FORWARD : GV_BACKWARD;
+ Vect_append_points(BPoints, Points, dir);
+ BPoints->n_points--; /* skip last point, avoids duplicates */
+ }
+ BPoints->n_points++; /* close polygon */
+
+ return BPoints->n_points;
+}
Added: grass/trunk/lib/vector/Vlib/area_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/area_pg.c (rev 0)
+++ grass/trunk/lib/vector/Vlib/area_pg.c 2013-05-21 15:36:09 UTC (rev 56352)
@@ -0,0 +1,114 @@
+/*!
+ \file lib/vector/Vlib/area_pg.c
+
+ \brief Vector library - area-related functions (PostGIS Topology)
+
+ Higher level functions for reading/writing/manipulating vectors.
+
+ (C) 2013 by the GRASS Development Team
+
+ This program is free software under the GNU General Public License
+ (>=v2). Read the file COPYING that comes with GRASS for details.
+
+ \author Martin Landa <landa.martin gmail.com>
+*/
+
+#include <grass/vector.h>
+
+#ifdef HAVE_POSTGRES
+#include "pg_local_proto.h"
+
+static PGresult *build_stmt(const struct Plus_head *, const struct Format_info_pg *, const plus_t *, int);
+
+/*!
+ \brief Get area boundary points (PostGIS Topology)
+
+ Used by Vect_build_line_area() and Vect_get_area_points().
+
+ \param Map pointer to Map_info struct
+ \param lines array of boundary lines
+ \param n_lines number of lines in array
+ \param[out] APoints pointer to output line_pnts struct
+
+ \return number of points
+ \return -1 on error
+*/
+int Vect__get_area_points_pg(const struct Map_info *Map, const plus_t *lines, int n_lines,
+ struct line_pnts *APoints)
+{
+ int i, direction;
+
+ struct Format_info_pg *pg_info;
+
+ PGresult *res;
+
+ pg_info = (struct Format_info_pg *)&(Map->fInfo.pg);
+
+ Vect_reset_line(APoints);
+
+ res = build_stmt(&(Map->plus), pg_info, lines, n_lines);
+ if (!res)
+ return -1;
+
+ for (i = 0; i < n_lines; i++) {
+ Vect__cache_feature_pg(PQgetvalue(res, i, 0), FALSE, FALSE,
+ &(pg_info->cache), NULL); /* do caching in readable way */
+ direction = lines[i] > 0 ? GV_FORWARD : GV_BACKWARD;
+ Vect_append_points(APoints, pg_info->cache.lines[0], direction);
+ APoints->n_points--; /* skip last point, avoids duplicates */
+ }
+ APoints->n_points++; /* close polygon */
+
+ PQclear(res);
+
+ return APoints->n_points;
+}
+
+PGresult *build_stmt(const struct Plus_head *plus, const struct Format_info_pg *pg_info,
+ const plus_t *lines, int n_lines)
+{
+ int i, line;
+ size_t stmt_id_size;
+ char *stmt, *stmt_id, buf_id[128];
+
+ struct P_line *BLine;
+
+ PGresult *res;
+
+ stmt = NULL;
+ stmt_id_size = DB_SQL_MAX;
+ stmt_id = (char *) G_malloc(stmt_id_size);
+ stmt_id[0] = '\0';
+
+ for (i = 0; i < n_lines; i++) {
+ if (strlen(stmt_id) + 100 > stmt_id_size) {
+ stmt_id_size = strlen(stmt_id) + DB_SQL_MAX;
+ stmt_id = (char *) G_realloc(stmt_id, stmt_id_size);
+ }
+ line = abs(lines[i]);
+ BLine = plus->Line[line];
+ if (i > 0)
+ strcat(stmt_id, ",");
+ sprintf(buf_id, "%d", (int) BLine->offset);
+ strcat(stmt_id, buf_id);
+ }
+ G_asprintf(&stmt, "SELECT geom FROM \"%s\".edge_data WHERE edge_id IN (%s) "
+ "ORDER BY POSITION(edge_id::text in '%s')", pg_info->toposchema_name,
+ stmt_id, stmt_id);
+ G_free(stmt_id);
+
+ G_debug(2, "SQL: %s", stmt);
+ res = PQexec(pg_info->conn, stmt);
+ G_free(stmt);
+
+ if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
+ PQntuples(res) != n_lines) {
+ if (res)
+ PQclear(res);
+
+ return NULL;
+ }
+
+ return res;
+}
+#endif
Property changes on: grass/trunk/lib/vector/Vlib/area_pg.c
___________________________________________________________________
Added: svn:mime-type
+ text/x-csrc
Added: svn:eol-style
+ native
Modified: grass/trunk/lib/vector/Vlib/build.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build.c 2013-05-21 15:25:30 UTC (rev 56351)
+++ grass/trunk/lib/vector/Vlib/build.c 2013-05-21 15:36:09 UTC (rev 56352)
@@ -128,7 +128,6 @@
/* add area structure to plus */
area = dig_add_area(plus, n_lines, lines, &box);
if (area == -1) { /* error */
- Vect_close(Map);
G_fatal_error(_("Unable to add area (map closed, topo saved)"));
}
G_debug(3, " -> area %d", area);
@@ -137,7 +136,6 @@
else if (area_size < 0) { /* CCW: island */
isle = dig_add_isle(plus, n_lines, lines, &box);
if (isle == -1) { /* error */
- Vect_close(Map);
G_fatal_error(_("Unable to add isle (map closed, topo saved)"));
}
G_debug(3, " -> isle %d", isle);
Modified: grass/trunk/lib/vector/Vlib/build_nat.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_nat.c 2013-05-21 15:25:30 UTC (rev 56351)
+++ grass/trunk/lib/vector/Vlib/build_nat.c 2013-05-21 15:36:09 UTC (rev 56352)
@@ -61,8 +61,8 @@
Cats = Vect_new_cats_struct();
if (plus->built < GV_BUILD_BASE) {
- int npoints, c;
-
+ int npoints, c;
+
/*
* We shall go through all primitives in coor file and add
* new node for each end point to nodes structure if the node
@@ -233,47 +233,3 @@
return 1;
}
-
-/*!
- \brief Get area boundary points (native format)
-
- Used by Vect_build_line_area().
-
- \param Map pointer to Map_info struct
- \param lines array of boundary lines
- \param n_lines number of lines in array
- \param[out] APoints pointer to output line_pnts struct
-
- \return number of points
- \return -1 on error
-*/
-int Vect__get_area_points_nat(struct Map_info *Map, plus_t *lines, int n_lines,
- struct line_pnts *APoints)
-{
- int j, line, direction;
- struct Plus_head *plus;
- struct P_line *BLine;
-
- plus = &(Map->plus);
-
- if (!Points)
- Points = Vect_new_line_struct();
-
- Vect_reset_line(APoints);
- for (j = 0; j < n_lines; j++) {
- line = abs(lines[j]);
- BLine = plus->Line[line];
- G_debug(5, " line[%d] = %d, offset = %lu", j, line,
- (unsigned long) BLine->offset);
- if (0 > Vect_read_line(Map, Points, NULL, line))
- return -1;
-
- direction = lines[j] > 0 ? GV_FORWARD : GV_BACKWARD;
- Vect_append_points(APoints, Points, direction);
- APoints->n_points--; /* skip last point, avoids duplicates */
- }
- APoints->n_points++; /* close polygon */
-
- return APoints->n_points;
-}
-
Modified: grass/trunk/lib/vector/Vlib/build_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_pg.c 2013-05-21 15:25:30 UTC (rev 56351)
+++ grass/trunk/lib/vector/Vlib/build_pg.c 2013-05-21 15:36:09 UTC (rev 56352)
@@ -476,82 +476,4 @@
return has_topo;
}
-
-/*!
- \brief Get area boundary points (PostGIS Topology)
-
- Used by Vect_build_line_area().
-
- \param Map pointer to Map_info struct
- \param lines array of boundary lines
- \param n_lines number of lines in array
- \param[out] APoints pointer to output line_pnts struct
-
- \return number of points
- \return -1 on error
-*/
-int Vect__get_area_points_pg(const struct Map_info *Map, const plus_t *lines, int n_lines,
- struct line_pnts *APoints)
-{
-
- int i, line, direction;
- size_t stmt_id_size;
- char *stmt, *stmt_id, buf_id[128];
-
- const struct Plus_head *plus;
- struct Format_info_pg *pg_info;
- struct P_line *BLine;
-
- PGresult *res;
-
- plus = &(Map->plus);
- pg_info = (struct Format_info_pg *)&(Map->fInfo.pg);
-
- stmt = NULL;
- stmt_id_size = DB_SQL_MAX;
- stmt_id = (char *) G_malloc(stmt_id_size);
- stmt_id[0] = '\0';
-
- Vect_reset_line(APoints);
-
- for (i = 0; i < n_lines; i++) {
- if (strlen(stmt_id) + 100 > stmt_id_size) {
- stmt_id_size = strlen(stmt_id) + DB_SQL_MAX;
- stmt_id = (char *) G_realloc(stmt_id, stmt_id_size);
- }
- line = abs(lines[i]);
- BLine = plus->Line[line];
- if (i > 0)
- strcat(stmt_id, ",");
- sprintf(buf_id, "%d", (int) BLine->offset);
- strcat(stmt_id, buf_id);
- }
- G_asprintf(&stmt, "SELECT geom FROM \"%s\".edge_data WHERE edge_id IN (%s) "
- "ORDER BY POSITION(edge_id::text in '%s')", pg_info->toposchema_name,
- stmt_id, stmt_id);
- G_free(stmt_id);
-
- G_debug(2, "SQL: %s", stmt);
- res = PQexec(pg_info->conn, stmt);
- G_free(stmt);
-
- if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
- PQntuples(res) != n_lines) {
- if (res)
- PQclear(res);
-
- return -1;
- }
-
- for (i = 0; i < n_lines; i++) {
- Vect__cache_feature_pg(PQgetvalue(res, i, 0), FALSE, FALSE,
- &(pg_info->cache), NULL); /* do caching in readable way */
- direction = lines[i] > 0 ? GV_FORWARD : GV_BACKWARD;
- Vect_append_points(APoints, pg_info->cache.lines[0], direction);
- APoints->n_points--; /* skip last point, avoids duplicates */
- }
- APoints->n_points++; /* close polygon */
-
- return APoints->n_points;
-}
#endif
Modified: grass/trunk/lib/vector/Vlib/local_proto.h
===================================================================
--- grass/trunk/lib/vector/Vlib/local_proto.h 2013-05-21 15:25:30 UTC (rev 56351)
+++ grass/trunk/lib/vector/Vlib/local_proto.h 2013-05-21 15:36:09 UTC (rev 56352)
@@ -8,8 +8,6 @@
/* area.c */
int Vect__get_area_points(const struct Map_info *, const plus_t *, int, struct line_pnts *);
-
-/* build_nat.c */
int Vect__get_area_points_nat(const struct Map_info *, const plus_t *, int, struct line_pnts *);
/* map.c */
Modified: grass/trunk/lib/vector/Vlib/pg_local_proto.h
===================================================================
--- grass/trunk/lib/vector/Vlib/pg_local_proto.h 2013-05-21 15:25:30 UTC (rev 56351)
+++ grass/trunk/lib/vector/Vlib/pg_local_proto.h 2013-05-21 15:36:09 UTC (rev 56352)
@@ -53,7 +53,7 @@
int *idx; /* index in cache where to start */
};
-/* build_pg.c */
+/* area_pg.c */
int Vect__get_area_points_pg(const struct Map_info *, const plus_t *, int, struct line_pnts *);
/* read_pg.c */
More information about the grass-commit
mailing list