~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to lib/vector/Vlib/area_pg.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*!
 
2
   \file lib/vector/Vlib/area_pg.c
 
3
 
 
4
   \brief Vector library - area-related functions (PostGIS Topology)
 
5
 
 
6
   Higher level functions for reading/writing/manipulating vectors.
 
7
 
 
8
   (C) 2013 by the GRASS Development Team
 
9
 
 
10
   This program is free software under the GNU General Public License
 
11
   (>=v2). Read the file COPYING that comes with GRASS for details.
 
12
 
 
13
   \author Martin Landa <landa.martin gmail.com>
 
14
*/
 
15
 
 
16
#include <grass/vector.h>
 
17
 
 
18
#ifdef HAVE_POSTGRES
 
19
#include "pg_local_proto.h"
 
20
 
 
21
static PGresult *build_stmt(const struct Plus_head *, const struct Format_info_pg *, const plus_t *, int);
 
22
 
 
23
/*!
 
24
  \brief Get area boundary points (PostGIS Topology)
 
25
  
 
26
  Used by Vect_build_line_area() and Vect_get_area_points().
 
27
 
 
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
 
32
 
 
33
  \return number of points
 
34
  \return -1 on error
 
35
*/
 
36
int Vect__get_area_points_pg(const struct Map_info *Map, const plus_t *lines, int n_lines,
 
37
                             struct line_pnts *APoints)
 
38
{
 
39
    int i, direction;
 
40
    
 
41
    struct Format_info_pg *pg_info;
 
42
    
 
43
    PGresult *res;
 
44
    
 
45
    pg_info = (struct Format_info_pg *)&(Map->fInfo.pg);
 
46
   
 
47
    Vect_reset_line(APoints);
 
48
 
 
49
    res = build_stmt(&(Map->plus), pg_info, lines, n_lines);
 
50
    if (!res)
 
51
        return -1;
 
52
    
 
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 */
 
59
    }
 
60
    APoints->n_points++;        /* close polygon */
 
61
 
 
62
    PQclear(res);
 
63
    
 
64
    return APoints->n_points;
 
65
}
 
66
 
 
67
PGresult *build_stmt(const struct Plus_head *plus, const struct Format_info_pg *pg_info,
 
68
                     const plus_t *lines, int n_lines)
 
69
{
 
70
    int i, line;
 
71
    size_t stmt_id_size;
 
72
    char *stmt, *stmt_id, buf_id[128];
 
73
 
 
74
    struct P_line *BLine;
 
75
    
 
76
    PGresult *res;
 
77
    
 
78
    stmt = NULL;
 
79
    stmt_id_size = DB_SQL_MAX;
 
80
    stmt_id = (char *) G_malloc(stmt_id_size);
 
81
    stmt_id[0] = '\0';
 
82
 
 
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);
 
87
        }
 
88
        line = abs(lines[i]);
 
89
        BLine = plus->Line[line];
 
90
        if (i > 0)
 
91
            strcat(stmt_id, ",");
 
92
        sprintf(buf_id, "%d", (int) BLine->offset);
 
93
        strcat(stmt_id, buf_id);
 
94
    }
 
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,
 
98
               stmt_id, stmt_id);
 
99
    */
 
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);
 
105
    G_free(stmt_id);
 
106
    
 
107
    G_debug(2, "SQL: %s", stmt);
 
108
    res = PQexec(pg_info->conn, stmt);
 
109
    G_free(stmt);
 
110
 
 
111
    if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
 
112
        PQntuples(res) != n_lines) {
 
113
        if (res)
 
114
            PQclear(res);
 
115
        
 
116
        return NULL;
 
117
    }
 
118
 
 
119
    return res;
 
120
}
 
121
#endif