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"
7
int close_streamvect(char *stream_vect)
9
int r, c, r_nbr, c_nbr, done;
11
CELL stream_id, stream_nbr;
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 };
23
static struct line_pnts *Points;
24
struct line_cats *Cats;
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;
34
G_message(_("Writing vector map <%s>..."), stream_vect);
36
if (Vect_open_new(&Out, stream_vect, 0) < 0)
37
G_fatal_error(_("Unable to create vector map <%s>"), stream_vect);
39
nodestack = (struct sstack *)G_malloc(stack_step * sizeof(struct sstack));
41
Points = Vect_new_line_struct();
42
Cats = Vect_new_cats_struct();
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;
50
next_cat = n_stream_nodes + 1;
52
for (i = 0; i < n_outlets; i++, next_cat++) {
53
G_percent(i, n_outlets, 2);
56
cseg_get(&stream, &stream_id, r, c);
61
Vect_reset_line(Points);
62
Vect_reset_cats(Cats);
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);
71
/* add root node to stack */
72
G_debug(3, "add root node");
74
nodestack[top].stream_id = stream_id;
75
nodestack[top].next_trib = 0;
77
/* depth first post order traversal */
78
G_debug(3, "traverse");
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) {
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++;
93
if (top >= stack_step) {
97
(struct sstack *)G_realloc(nodestack,
99
sizeof(struct sstack));
101
nodestack[top].next_trib = 0;
102
nodestack[top].stream_id = next_node;
104
G_debug(3, "go further down");
107
G_debug(3, "write stream segment");
109
Vect_reset_line(Points);
110
Vect_reset_cats(Cats);
112
r_nbr = stream_node[stream_id].r;
113
c_nbr = stream_node[stream_id].c;
115
cseg_get(&stream, &stream_nbr, r_nbr, c_nbr);
117
G_fatal_error(_("Stream id %d not set, top is %d, parent is %d"),
118
stream_id, top, nodestack[top - 1].stream_id);
120
Vect_cat_set(Cats, 1, stream_id);
121
if (stream_node[stream_id].n_trib == 0)
122
Vect_cat_set(Cats, 2, 0);
124
Vect_cat_set(Cats, 2, 1);
126
Vect_append_point(Points, west_offset + c_nbr * ew_res,
127
north_offset - r_nbr * ns_res, 0);
129
Vect_write_line(&Out, GV_POINT, Points, Cats);
131
seg_get(&aspflag, (char *)&af, r_nbr, c_nbr);
133
r_nbr = r_nbr + asp_r[(int)af.asp];
134
c_nbr = c_nbr + asp_c[(int)af.asp];
136
cseg_get(&stream, &stream_nbr, r_nbr, c_nbr);
138
G_fatal_error(_("Stream id not set while tracing"));
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 */
146
seg_get(&aspflag, (char *)&af, r_nbr, c_nbr);
149
Vect_write_line(&Out, GV_LINE, Points, Cats);
155
G_percent(n_outlets, n_outlets, 1); /* finish it */
157
G_message(_("Writing attribute data..."));
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);
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,
171
if (driver == NULL) {
172
G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
174
db_set_error_handler_driver(driver);
176
G_debug(1, "table: %s", Fi->table);
177
G_debug(1, "driver: %s", Fi->driver);
178
G_debug(1, "database: %s", Fi->database);
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);
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));
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);
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);
198
db_begin_transaction(driver);
201
for (i = 1; i <= n_stream_nodes; i++) {
203
sprintf(buf, "insert into %s values ( %lld, \'%s\', %d )",
205
(stream_node[i].n_trib > 0 ? "intermediate" : "start"),
206
(stream_node[i].n_trib > 0));
208
db_set_string(&dbsql, buf);
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));
218
db_commit_transaction(driver);
219
db_close_database_shutdown_driver(driver);
221
Vect_map_add_dblink(&Out, 1, NULL, Fi->table,
222
cat_col_name, Fi->database, Fi->driver);
224
G_debug(1, "close vector");
226
Vect_hist_command(&Out);
236
int close_maps(char *stream_rast, char *stream_vect, char *dir_rast)
238
int stream_fd, dir_fd, r, c, i;
239
CELL *cell_buf1, *cell_buf2;
240
struct History history;
245
stream_fd = dir_fd = -1;
246
cell_buf1 = cell_buf2 = NULL;
248
G_message(_("Writing output raster maps..."));
250
/* write requested output rasters */
252
stream_fd = Rast_open_new(stream_rast, CELL_TYPE);
253
cell_buf1 = Rast_allocate_c_buf();
256
dir_fd = Rast_open_new(dir_rast, CELL_TYPE);
257
cell_buf2 = Rast_allocate_c_buf();
260
for (r = 0; r < nrows; r++) {
261
G_percent(r, nrows, 2);
263
Rast_set_c_null_value(cell_buf1, ncols); /* reset row to all NULL */
265
Rast_set_c_null_value(cell_buf2, ncols); /* reset row to all NULL */
267
for (c = 0; c < ncols; c++) {
269
cseg_get(&stream, &stream_id, r, c);
271
cell_buf1[c] = stream_id;
274
seg_get(&aspflag, (char *)&af, r, c);
275
if (!FLAG_GET(af.flag, NULLFLAG)) {
276
cell_buf2[c] = af.asp;
282
Rast_put_row(stream_fd, cell_buf1, CELL_TYPE);
284
Rast_put_row(dir_fd, cell_buf2, CELL_TYPE);
286
G_percent(nrows, nrows, 2); /* finish it */
289
Rast_close(stream_fd);
291
Rast_short_history(stream_rast, "raster", &history);
292
Rast_command_history(&history);
293
Rast_write_history(stream_rast, &history);
296
struct Colors colors;
301
Rast_short_history(dir_rast, "raster", &history);
302
Rast_command_history(&history);
303
Rast_write_history(dir_rast, &history);
305
Rast_init_colors(&colors);
306
Rast_make_aspect_colors(&colors, -8, 8);
307
Rast_write_colors(dir_rast, G_mapset(), &colors);
310
/* close stream vector */
312
if (close_streamvect(stream_vect) < 0)
313
G_fatal_error(_("Unable to write vector map <%s>"), stream_vect);
316
/* rearranging desk chairs on the Titanic... */
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);