2
/****************************************************************************
5
* AUTHOR(S): Jianping Xu 1995: WIldfire SPread Simulation, WiSpS (original contributor)
6
* Markus Neteler <neteler itc.it>
7
* Roberto Flor <flor itc.it>, Brad Douglas <rez touchofmadness.com>,
8
* Glynn Clements <glynn gclements.plus.com>, Jachym Cepicky <jachym les-ejk.cz>
9
* PURPOSE: This is the main program for tracing out the shortest path(s)
10
* based on the raster map showing back path cells from which the
11
* cumulative costs were determined.
12
* COPYRIGHT: (C) 2000-2006 by the GRASS Development Team
14
* This program is free software under the GNU General Public
15
* License (>=v2). Read the file COPYING that comes with GRASS
18
*****************************************************************************/
20
/**********************************************************************/
22
/* This is the main program for tracing out the shortest path(s) */
23
/* based on the raster map showing back path cells from which the */
24
/* cumulative costs were determined. */
27
/**********************************************************************/
34
#include <grass/segment.h>
35
#include <grass/gis.h>
38
#include <grass/glocale.h>
39
#include "local_proto.h"
44
SEGMENT in_row_seg, in_col_seg, out_seg;
47
int main(int argc, char **argv)
54
backrow_fd, backcol_fd, path_fd, in_row_fd, in_col_fd, out_fd;
59
*backcol_mapset, *in_row_file, *in_col_file, *out_file;
61
POINT *PRES_PT, *PRESENT_PT, *OLD_PT;
62
struct Cell_head window;
64
struct Option *opt1, *opt2, *opt3, *opt4;
66
struct GModule *module;
71
module = G_define_module();
72
module->keywords = _("raster, fire");
74
_("Recursively traces the least cost path backwards to "
75
"cells from which the cumulative cost was determined.");
77
opt1 = G_define_option();
78
opt1->key = "x_input";
79
opt1->type = TYPE_STRING;
81
opt1->gisprompt = "old,cell,raster";
83
_("Name of raster map containing back-path easting information");
85
opt2 = G_define_option();
86
opt2->key = "y_input";
87
opt2->type = TYPE_STRING;
89
opt2->gisprompt = "old,cell,raster";
91
_("Name of raster map containing back-path northing information");
93
opt3 = G_define_option();
94
opt3->key = "coordinate";
95
opt3->type = TYPE_STRING;
97
opt3->key_desc = "x,y";
99
_("The map E and N grid coordinates of starting points");
101
opt4 = G_define_option();
102
opt4->key = "output";
103
opt4->type = TYPE_STRING;
104
opt4->required = YES;
105
opt4->gisprompt = "new,cell,raster";
106
opt4->description = _("Name of spread path raster map");
108
flag1 = G_define_flag();
110
flag1->description = _("Run verbosely");
112
/* Do command line parsing */
113
if (G_parser(argc, argv))
116
current_mapset = G_mapset();
117
in_row_file = G_tempfile();
118
in_col_file = G_tempfile();
119
out_file = G_tempfile();
121
/* Get database window parameters */
122
if (G_get_window(&window) < 0)
123
G_fatal_error("can't read current window parameters");
125
verbose = flag1->answer;
127
/* Check if backrow layer exists in data base */
130
strcpy(backrow_layer, opt2->answer);
131
strcpy(backcol_layer, opt1->answer);
133
backrow_mapset = G_find_cell(backrow_layer, search_mapset);
134
backcol_mapset = G_find_cell(backcol_layer, search_mapset);
136
if (backrow_mapset == NULL)
137
G_fatal_error("%s - not found", backrow_layer);
139
if (backcol_mapset == NULL)
140
G_fatal_error("%s - not found", backcol_layer);
144
strcpy(path_layer, opt4->answer);
146
path_mapset = G_find_cell(path_layer, search_mapset);
148
/* find number of rows and cols in window */
149
nrows = G_window_rows();
150
ncols = G_window_cols();
152
cell = G_allocate_cell_buf();
154
/* Open back cell layers for reading */
155
backrow_fd = G_open_cell_old(backrow_layer, backrow_mapset);
157
G_fatal_error("%s - can't open raster map", backrow_layer);
159
backcol_fd = G_open_cell_old(backcol_layer, backcol_mapset);
161
G_fatal_error("%s - can't open raster map", backcol_layer);
163
/* Parameters for map submatrices */
166
srows = nrows / 4 + 1;
167
scols = ncols / 4 + 1;
171
("\nReading the input map -%s- and -%s- and creating some temporary files...",
172
backrow_layer, backcol_layer);
174
/* Create segmented files for back cell and output layers */
175
in_row_fd = creat(in_row_file, 0666);
176
segment_format(in_row_fd, nrows, ncols, srows, scols, len);
178
in_col_fd = creat(in_col_file, 0666);
179
segment_format(in_col_fd, nrows, ncols, srows, scols, len);
182
out_fd = creat(out_file, 0666);
183
segment_format(out_fd, nrows, ncols, srows, scols, len);
186
/* Open initialize and segment all files */
187
in_row_fd = open(in_row_file, 2);
188
segment_init(&in_row_seg, in_row_fd, 4);
189
in_col_fd = open(in_col_file, 2);
190
segment_init(&in_col_seg, in_col_fd, 4);
192
out_fd = open(out_file, 2);
193
segment_init(&out_seg, out_fd, 4);
195
/* Write the back cell layers in the segmented files, and
196
* Change UTM coordinates to ROWs and COLUMNs */
197
for (row = 0; row < nrows; row++) {
198
if (G_get_map_row(backrow_fd, cell, row) < 0)
199
G_fatal_error("unable to get map row %d", row);
201
for (col = 0; col < ncols; col++)
204
(window.north - cell[col]) / window.ns_res /* - 0.5 */ ;
207
segment_put_row(&in_row_seg, cell, row);
208
if (G_get_map_row(backcol_fd, cell, row) < 0)
209
G_fatal_error("unable to get map row %d", row);
211
for (col = 0; col < ncols; col++)
214
(cell[col] - window.west) / window.ew_res /* - 0.5 */ ;
215
segment_put_row(&in_col_seg, cell, row);
218
/* Convert easting and northing from the command line to row and col */
220
for (n = 0; opt3->answers[n] != NULL; n += 2) {
221
G_scan_easting(opt3->answers[n], &east, G_projection());
222
G_scan_northing(opt3->answers[n + 1], &north, G_projection());
223
row = (window.north - north) / window.ns_res;
224
col = (east - window.west) / window.ew_res;
225
/* ignore pt outside window */
226
if (east < window.west || east > window.east ||
227
north < window.south || north > window.north) {
228
G_warning("Ignoring point outside window: ");
229
G_warning(" %.4f,%.4f", east, north);
233
value = (char *)&backrow;
234
segment_get(&in_row_seg, value, row, col);
235
/* ignore pt in no-data area */
237
G_warning("Ignoring point in NO-DATA area :");
238
G_warning(" %.4f,%.4f", east, north);
241
value = (char *)&backcol;
242
segment_get(&in_col_seg, value, row, col);
244
insert(&PRESENT_PT, row, col, backrow, backcol);
248
/* Set flag according to input */
249
if (path_mapset != NULL) {
250
if (head_start_pt == NULL)
251
/*output layer exists and start pts are not given on cmd line */
254
/* output layer exists and starting pts are given on cmd line */
259
flag = 3; /* output layer does not previously exist */
262
/* Check if specified output layer name is legal */
264
if (G_legal_filename(path_layer) < 0)
265
G_fatal_error("%s - illegal name", path_layer);
268
/* If the output layer containing the starting positions */
269
/* create a linked list of of them */
271
path_fd = G_open_cell_old(path_layer, path_mapset);
273
G_fatal_error("%s -can't open raster map", path_layer);
275
/* Search for the marked starting pts and make list */
276
for (row = 0; row < nrows; row++) {
277
if (G_get_map_row(path_fd, cell, row) < 0)
278
G_fatal_error("unable to get map row %d", row);
280
for (col = 0; col < ncols; col++) {
282
value = (char *)&backrow;
283
segment_get(&in_row_seg, value, row, col);
284
/* ignore pt in no-data area */
286
G_warning("Ignoring point in NO-DATA area:");
287
G_warning(" %.4f,%.4f\n",
288
window.west + window.ew_res * (col + 0.5),
289
window.north - window.ns_res * (row + 0.5));
292
value = (char *)&backcol;
293
segment_get(&in_col_seg, value, row, col);
294
insert(&PRESENT_PT, row, col, backrow, backcol);
296
} /* loop over cols */
297
} /* loop over rows */
299
G_close_cell(path_fd);
302
/* loop over the starting points to find the least cost paths */
304
G_message("\nFinding the least cost paths ...");
306
PRES_PT = head_start_pt;
307
while (PRES_PT != NULL) {
308
path_finder(PRES_PT->row, PRES_PT->col, PRES_PT->backrow,
316
/* Write pending updates by segment_put() to outputmap */
317
segment_flush(&out_seg);
320
G_message("\nWriting the output map -%s-...", path_layer);
322
path_fd = G_open_cell_new(path_layer);
323
for (row = 0; row < nrows; row++) {
324
segment_get_row(&out_seg, cell, row);
325
if (G_put_raster_row(path_fd, cell, CELL_TYPE) < 0)
326
G_fatal_error("unable to write map row %d", row);
330
G_message("finished.");
332
segment_release(&in_row_seg); /* release memory */
333
segment_release(&in_col_seg);
334
segment_release(&out_seg);
336
close(in_row_fd); /* close all files */
340
G_close_cell(path_fd);
341
G_close_cell(backrow_fd);
342
G_close_cell(backcol_fd);
344
unlink(in_row_file); /* remove submatrix files */