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

« back to all changes in this revision

Viewing changes to raster/r.stream.extract/close.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
#include <grass/raster.h>
 
2
#include <grass/glocale.h>
 
3
#include <grass/vector.h>
 
4
#include <grass/dbmi.h>
 
5
#include "local_proto.h"
 
6
 
 
7
int close_streamvect(char *stream_vect)
 
8
{
 
9
    int r, c, r_nbr, c_nbr, done;
 
10
    GW_LARGE_INT i;
 
11
    CELL stream_id, stream_nbr;
 
12
    ASP_FLAG af;
 
13
    int next_node;
 
14
    struct sstack
 
15
    {
 
16
        int stream_id;
 
17
        int next_trib;
 
18
    } *nodestack;
 
19
    int top = 0, stack_step = 1000;
 
20
    int asp_r[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 };
 
21
    int asp_c[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 };
 
22
    struct Map_info Out;
 
23
    static struct line_pnts *Points;
 
24
    struct line_cats *Cats;
 
25
    dbDriver *driver;
 
26
    dbHandle handle;
 
27
    dbString table_name, dbsql, valstr;
 
28
    struct field_info *Fi;
 
29
    char *cat_col_name = "cat", buf[2000];
 
30
    struct Cell_head window;
 
31
    double north_offset, west_offset, ns_res, ew_res;
 
32
    int next_cat;
 
33
 
 
34
    G_message(_("Writing vector map <%s>..."), stream_vect);
 
35
 
 
36
    if (Vect_open_new(&Out, stream_vect, 0) < 0)
 
37
        G_fatal_error(_("Unable to create vector map <%s>"), stream_vect);
 
38
    
 
39
    nodestack = (struct sstack *)G_malloc(stack_step * sizeof(struct sstack));
 
40
 
 
41
    Points = Vect_new_line_struct();
 
42
    Cats = Vect_new_cats_struct();
 
43
 
 
44
    G_get_set_window(&window);
 
45
    ns_res = window.ns_res;
 
46
    ew_res = window.ew_res;
 
47
    north_offset = window.north - 0.5 * ns_res;
 
48
    west_offset = window.west + 0.5 * ew_res;
 
49
 
 
50
    next_cat = n_stream_nodes + 1;
 
51
 
 
52
    for (i = 0; i < n_outlets; i++, next_cat++) {
 
53
        G_percent(i, n_outlets, 2);
 
54
        r = outlets[i].r;
 
55
        c = outlets[i].c;
 
56
        cseg_get(&stream, &stream_id, r, c);
 
57
 
 
58
        if (!stream_id)
 
59
            continue;
 
60
 
 
61
        Vect_reset_line(Points);
 
62
        Vect_reset_cats(Cats);
 
63
 
 
64
        /* outlet */
 
65
        Vect_cat_set(Cats, 1, stream_id);
 
66
        Vect_cat_set(Cats, 2, 2);
 
67
        Vect_append_point(Points, west_offset + c * ew_res,
 
68
                          north_offset - r * ns_res, 0);
 
69
        Vect_write_line(&Out, GV_POINT, Points, Cats);
 
70
 
 
71
        /* add root node to stack */
 
72
        G_debug(3, "add root node");
 
73
        top = 0;
 
74
        nodestack[top].stream_id = stream_id;
 
75
        nodestack[top].next_trib = 0;
 
76
 
 
77
        /* depth first post order traversal */
 
78
        G_debug(3, "traverse");
 
79
        while (top >= 0) {
 
80
 
 
81
            done = 1;
 
82
            stream_id = nodestack[top].stream_id;
 
83
            G_debug(3, "stream_id %d", stream_id);
 
84
            if (nodestack[top].next_trib < stream_node[stream_id].n_trib) {
 
85
                /* add to stack */
 
86
                next_node =
 
87
                    stream_node[stream_id].trib[nodestack[top].next_trib];
 
88
                G_debug(3, "add to stack: next %d, trib %d, n trib %d",
 
89
                        next_node, nodestack[top].next_trib,
 
90
                        stream_node[stream_id].n_trib);
 
91
                nodestack[top].next_trib++;
 
92
                top++;
 
93
                if (top >= stack_step) {
 
94
                    /* need more space */
 
95
                    stack_step += 1000;
 
96
                    nodestack =
 
97
                        (struct sstack *)G_realloc(nodestack,
 
98
                                                   stack_step *
 
99
                                                   sizeof(struct sstack));
 
100
                }
 
101
                nodestack[top].next_trib = 0;
 
102
                nodestack[top].stream_id = next_node;
 
103
                done = 0;
 
104
                G_debug(3, "go further down");
 
105
            }
 
106
            if (done) {
 
107
                G_debug(3, "write stream segment");
 
108
 
 
109
                Vect_reset_line(Points);
 
110
                Vect_reset_cats(Cats);
 
111
 
 
112
                r_nbr = stream_node[stream_id].r;
 
113
                c_nbr = stream_node[stream_id].c;
 
114
 
 
115
                cseg_get(&stream, &stream_nbr, r_nbr, c_nbr);
 
116
                if (stream_nbr <= 0)
 
117
                    G_fatal_error(_("Stream id %d not set, top is %d, parent is %d"),
 
118
                                  stream_id, top, nodestack[top - 1].stream_id);
 
119
 
 
120
                Vect_cat_set(Cats, 1, stream_id);
 
121
                if (stream_node[stream_id].n_trib == 0)
 
122
                    Vect_cat_set(Cats, 2, 0);
 
123
                else
 
124
                    Vect_cat_set(Cats, 2, 1);
 
125
 
 
126
                Vect_append_point(Points, west_offset + c_nbr * ew_res,
 
127
                                  north_offset - r_nbr * ns_res, 0);
 
128
 
 
129
                Vect_write_line(&Out, GV_POINT, Points, Cats);
 
130
 
 
131
                seg_get(&aspflag, (char *)&af, r_nbr, c_nbr);
 
132
                while (af.asp > 0) {
 
133
                    r_nbr = r_nbr + asp_r[(int)af.asp];
 
134
                    c_nbr = c_nbr + asp_c[(int)af.asp];
 
135
                    
 
136
                    cseg_get(&stream, &stream_nbr, r_nbr, c_nbr);
 
137
                    if (stream_nbr <= 0)
 
138
                        G_fatal_error(_("Stream id not set while tracing"));
 
139
 
 
140
                    Vect_append_point(Points, west_offset + c_nbr * ew_res,
 
141
                                      north_offset - r_nbr * ns_res, 0);
 
142
                    if (stream_nbr != stream_id) {
 
143
                        /* first point of parent stream */
 
144
                        break;
 
145
                    }
 
146
                    seg_get(&aspflag, (char *)&af, r_nbr, c_nbr);
 
147
                }
 
148
 
 
149
                Vect_write_line(&Out, GV_LINE, Points, Cats);
 
150
 
 
151
                top--;
 
152
            }
 
153
        }
 
154
    }
 
155
    G_percent(n_outlets, n_outlets, 1); /* finish it */
 
156
 
 
157
    G_message(_("Writing attribute data..."));
 
158
 
 
159
    /* Prepeare strings for use in db_* calls */
 
160
    db_init_string(&dbsql);
 
161
    db_init_string(&valstr);
 
162
    db_init_string(&table_name);
 
163
    db_init_handle(&handle);
 
164
 
 
165
    /* Preparing database for use */
 
166
    /* Create database for new vector map */
 
167
    Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
 
168
    driver = db_start_driver_open_database(Fi->driver,
 
169
                                           Vect_subst_var(Fi->database,
 
170
                                                                  &Out));
 
171
    if (driver == NULL) {
 
172
        G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
 
173
    }
 
174
    db_set_error_handler_driver(driver);
 
175
 
 
176
    G_debug(1, "table: %s", Fi->table);
 
177
    G_debug(1, "driver: %s", Fi->driver);
 
178
    G_debug(1, "database: %s", Fi->database);
 
179
 
 
180
    sprintf(buf,
 
181
            "create table %s (%s integer, stream_type varchar(20), type_code integer)",
 
182
            Fi->table, cat_col_name);
 
183
    db_set_string(&dbsql, buf);
 
184
 
 
185
    if (db_execute_immediate(driver, &dbsql) != DB_OK) {
 
186
        db_close_database(driver);
 
187
        db_shutdown_driver(driver);
 
188
        G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&dbsql));
 
189
    }
 
190
 
 
191
    if (db_create_index2(driver, Fi->table, cat_col_name) != DB_OK)
 
192
        G_warning(_("Unable to create index on table <%s>"), Fi->table);
 
193
 
 
194
    if (db_grant_on_table(driver, Fi->table, DB_PRIV_SELECT,
 
195
                          DB_GROUP | DB_PUBLIC) != DB_OK)
 
196
        G_fatal_error(_("Unable to grant privileges on table <%s>"), Fi->table);
 
197
 
 
198
    db_begin_transaction(driver);
 
199
 
 
200
    /* stream nodes */
 
201
    for (i = 1; i <= n_stream_nodes; i++) {
 
202
 
 
203
        sprintf(buf, "insert into %s values ( %lld, \'%s\', %d )",
 
204
                Fi->table, i,
 
205
                (stream_node[i].n_trib > 0 ? "intermediate" : "start"),
 
206
                (stream_node[i].n_trib > 0));
 
207
 
 
208
        db_set_string(&dbsql, buf);
 
209
 
 
210
        if (db_execute_immediate(driver, &dbsql) != DB_OK) {
 
211
            db_close_database(driver);
 
212
            db_shutdown_driver(driver);
 
213
            G_fatal_error(_("Unable to insert new row: '%s'"),
 
214
                          db_get_string(&dbsql));
 
215
        }
 
216
    }
 
217
 
 
218
    db_commit_transaction(driver);
 
219
    db_close_database_shutdown_driver(driver);
 
220
 
 
221
    Vect_map_add_dblink(&Out, 1, NULL, Fi->table,
 
222
                        cat_col_name, Fi->database, Fi->driver);
 
223
 
 
224
    G_debug(1, "close vector");
 
225
 
 
226
    Vect_hist_command(&Out);
 
227
    Vect_build(&Out);
 
228
    Vect_close(&Out);
 
229
 
 
230
    G_free(nodestack);
 
231
 
 
232
    return 1;
 
233
}
 
234
 
 
235
 
 
236
int close_maps(char *stream_rast, char *stream_vect, char *dir_rast)
 
237
{
 
238
    int stream_fd, dir_fd, r, c, i;
 
239
    CELL *cell_buf1, *cell_buf2;
 
240
    struct History history;
 
241
    CELL stream_id;
 
242
    ASP_FLAG af;
 
243
 
 
244
    /* cheating... */
 
245
    stream_fd = dir_fd = -1;
 
246
    cell_buf1 = cell_buf2 = NULL;
 
247
 
 
248
    G_message(_("Writing output raster maps..."));
 
249
    
 
250
    /* write requested output rasters */
 
251
    if (stream_rast) {
 
252
        stream_fd = Rast_open_new(stream_rast, CELL_TYPE);
 
253
        cell_buf1 = Rast_allocate_c_buf();
 
254
    }
 
255
    if (dir_rast) {
 
256
        dir_fd = Rast_open_new(dir_rast, CELL_TYPE);
 
257
        cell_buf2 = Rast_allocate_c_buf();
 
258
    }
 
259
 
 
260
    for (r = 0; r < nrows; r++) {
 
261
        G_percent(r, nrows, 2);
 
262
        if (stream_rast)
 
263
            Rast_set_c_null_value(cell_buf1, ncols);    /* reset row to all NULL */
 
264
        if (dir_rast)
 
265
            Rast_set_c_null_value(cell_buf2, ncols);    /* reset row to all NULL */
 
266
 
 
267
        for (c = 0; c < ncols; c++) {
 
268
            if (stream_rast) {
 
269
                cseg_get(&stream, &stream_id, r, c);
 
270
                if (stream_id)
 
271
                    cell_buf1[c] = stream_id;
 
272
            }
 
273
            if (dir_rast) {
 
274
                seg_get(&aspflag, (char *)&af, r, c);
 
275
                if (!FLAG_GET(af.flag, NULLFLAG)) {
 
276
                    cell_buf2[c] = af.asp;
 
277
                }
 
278
            }
 
279
            
 
280
        }
 
281
        if (stream_rast)
 
282
            Rast_put_row(stream_fd, cell_buf1, CELL_TYPE);
 
283
        if (dir_rast)
 
284
            Rast_put_row(dir_fd, cell_buf2, CELL_TYPE);
 
285
    }
 
286
    G_percent(nrows, nrows, 2); /* finish it */
 
287
 
 
288
    if (stream_rast) {
 
289
        Rast_close(stream_fd);
 
290
        G_free(cell_buf1);
 
291
        Rast_short_history(stream_rast, "raster", &history);
 
292
        Rast_command_history(&history);
 
293
        Rast_write_history(stream_rast, &history);
 
294
    }
 
295
    if (dir_rast) {
 
296
        struct Colors colors;
 
297
 
 
298
        Rast_close(dir_fd);
 
299
        G_free(cell_buf2);
 
300
 
 
301
        Rast_short_history(dir_rast, "raster", &history);
 
302
        Rast_command_history(&history);
 
303
        Rast_write_history(dir_rast, &history);
 
304
 
 
305
        Rast_init_colors(&colors);
 
306
        Rast_make_aspect_colors(&colors, -8, 8);
 
307
        Rast_write_colors(dir_rast, G_mapset(), &colors);
 
308
    }
 
309
 
 
310
    /* close stream vector */
 
311
    if (stream_vect) {
 
312
        if (close_streamvect(stream_vect) < 0)
 
313
            G_fatal_error(_("Unable to write vector map <%s>"), stream_vect);
 
314
    }
 
315
 
 
316
    /* rearranging desk chairs on the Titanic... */
 
317
    G_free(outlets);
 
318
 
 
319
    /* free stream nodes */
 
320
    for (i = 1; i <= n_stream_nodes; i++) {
 
321
        if (stream_node[i].n_alloc > 0) {
 
322
            G_free(stream_node[i].trib);
 
323
        }
 
324
    }
 
325
    G_free(stream_node);
 
326
 
 
327
    return 1;
 
328
}