2
\file lib/vector/Vlib/area_pg.c
4
\brief Vector library - area-related functions (PostGIS Topology)
6
Higher level functions for reading/writing/manipulating vectors.
8
(C) 2013 by the GRASS Development Team
10
This program is free software under the GNU General Public License
11
(>=v2). Read the file COPYING that comes with GRASS for details.
13
\author Martin Landa <landa.martin gmail.com>
16
#include <grass/vector.h>
19
#include "pg_local_proto.h"
21
static PGresult *build_stmt(const struct Plus_head *, const struct Format_info_pg *, const plus_t *, int);
24
\brief Get area boundary points (PostGIS Topology)
26
Used by Vect_build_line_area() and Vect_get_area_points().
28
\param Map pointer to Map_info struct
29
\param lines array of boundary lines
30
\param n_lines number of lines in array
31
\param[out] APoints pointer to output line_pnts struct
33
\return number of points
36
int Vect__get_area_points_pg(const struct Map_info *Map, const plus_t *lines, int n_lines,
37
struct line_pnts *APoints)
41
struct Format_info_pg *pg_info;
45
pg_info = (struct Format_info_pg *)&(Map->fInfo.pg);
47
Vect_reset_line(APoints);
49
res = build_stmt(&(Map->plus), pg_info, lines, n_lines);
53
for (i = 0; i < n_lines; i++) {
54
Vect__cache_feature_pg(PQgetvalue(res, i, 0), FALSE, FALSE,
55
&(pg_info->cache), NULL); /* do caching in readable way */
56
direction = lines[i] > 0 ? GV_FORWARD : GV_BACKWARD;
57
Vect_append_points(APoints, pg_info->cache.lines[0], direction);
58
APoints->n_points--; /* skip last point, avoids duplicates */
60
APoints->n_points++; /* close polygon */
64
return APoints->n_points;
67
PGresult *build_stmt(const struct Plus_head *plus, const struct Format_info_pg *pg_info,
68
const plus_t *lines, int n_lines)
72
char *stmt, *stmt_id, buf_id[128];
79
stmt_id_size = DB_SQL_MAX;
80
stmt_id = (char *) G_malloc(stmt_id_size);
83
for (i = 0; i < n_lines; i++) {
84
if (strlen(stmt_id) + 100 > stmt_id_size) {
85
stmt_id_size = strlen(stmt_id) + DB_SQL_MAX;
86
stmt_id = (char *) G_realloc(stmt_id, stmt_id_size);
89
BLine = plus->Line[line];
92
sprintf(buf_id, "%d", (int) BLine->offset);
93
strcat(stmt_id, buf_id);
95
/* Not really working - why?
96
G_asprintf(&stmt, "SELECT geom FROM \"%s\".edge_data WHERE edge_id IN (%s) "
97
"ORDER BY POSITION(edge_id::text in '%s')", pg_info->toposchema_name,
100
G_asprintf(&stmt, "SELECT geom FROM \"%s\".edge_data AS t "
101
"JOIN (SELECT id, row_number() over() AS id_sorter FROM "
102
"(SELECT UNNEST(ARRAY[%s]) AS id) AS y) x ON "
103
"t.edge_id in (%s) AND x.id = t.edge_id "
104
"ORDER BY x.id_sorter", pg_info->toposchema_name, stmt_id, stmt_id);
107
G_debug(2, "SQL: %s", stmt);
108
res = PQexec(pg_info->conn, stmt);
111
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
112
PQntuples(res) != n_lines) {