1
2 /***************************************************************************
3 *
4 * MODULE: r.buffer
5 *
6 * AUTHOR(S): Michael Shapiro, US Army Construction Engineering Research Laboratory
7 * James Westervelt, US Army CERL
8 *
9 * PURPOSE: This program creates distance zones from non-zero
10 * cells in a grid layer. Distances are specified in
11 * meters (on the command-line). Window does not have to
12 * have square cells. Works both for planimetric (UTM,
13 * State Plane) and lat-long.
14 *
15 * COPYRIGHT: (c) 2006 by the GRASS Development Team
16 *
17 * This program is free software under the GNU General Public
18 * License (>=v2). Read the file COPYING that comes with GRASS
19 * for details.
20 *
21 **************************************************************************/
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "distance.h"
28 #include "local_proto.h"
29 #include <grass/raster.h>
30 #include <grass/glocale.h>
31
32 struct Distance *distances;
33 int ndist;
34 int wrap_ncols;
35 MAPTYPE *map;
36 struct Cell_head window;
37 int minrow, maxrow, mincol, maxcol;
38 char *pgm_name;
39 double meters_to_grid = 1.0;
40 double ns_to_ew_squared;
41 int count_rows_with_data;
42
main(int argc,char * argv[])43 int main(int argc, char *argv[])
44 {
45 struct Distance *pd;
46 const char *input, *output, *mapset;
47 char **zone_list;
48 double to_meters;
49 const char *units;
50 int offset;
51 int count;
52 int step, nsteps;
53 struct History hist;
54
55 struct GModule *module;
56 struct Option *opt1, *opt2, *opt3, *opt4;
57 struct Flag *flag2;
58 int ZEROFLAG;
59
60 /* initialize GRASS */
61 G_gisinit(argv[0]);
62
63 pgm_name = argv[0];
64
65 module = G_define_module();
66 G_add_keyword(_("raster"));
67 G_add_keyword(_("buffer"));
68 module->description =
69 _("Creates a raster map showing buffer zones "
70 "surrounding cells that contain non-NULL category values.");
71
72 opt1 = G_define_standard_option(G_OPT_R_INPUT);
73
74 opt2 = G_define_standard_option(G_OPT_R_OUTPUT);
75
76 opt3 = G_define_option();
77 opt3->key = "distances";
78 opt3->type = TYPE_DOUBLE;
79 opt3->required = YES;
80 opt3->multiple = YES;
81 opt3->description = _("Distance zone(s)");
82
83 opt4 = G_define_option();
84 opt4->key = "units";
85 opt4->options = "meters,kilometers,feet,miles,nautmiles";
86 opt4->type = TYPE_STRING;
87 opt4->required = NO;
88 opt4->description = _("Units of distance");
89 opt4->answer = "meters";
90
91 flag2 = G_define_flag();
92 flag2->key = 'z';
93 flag2->description =
94 _("Ignore zero (0) data cells instead of NULL cells");
95
96 if (G_parser(argc, argv))
97 exit(EXIT_FAILURE);
98
99 init_grass();
100
101 /* get input, output map names */
102 input = opt1->answer;
103 output = opt2->answer;
104 zone_list = opt3->answers;
105 units = opt4->answer;
106
107 ZEROFLAG = 0; /* default: use NULL for non-data cells */
108 ZEROFLAG = (flag2->answer);
109
110 mapset = G_find_raster2(input, "");
111 if (mapset == NULL)
112 G_fatal_error(_("Raster map <%s> not found"), input);
113
114 /* parse units */
115 if (opt4->answer == NULL)
116 units = "meters";
117
118 if (strcmp(units, "meters") == 0)
119 to_meters = 1.0;
120 else if (strcmp(units, "feet") == 0)
121 to_meters = FEET_TO_METERS;
122 else if (strcmp(units, "kilometers") == 0)
123 to_meters = KILOMETERS_TO_METERS;
124 else if (strcmp(units, "miles") == 0)
125 to_meters = MILES_TO_METERS;
126 else if (strcmp(units, "nautmiles") == 0)
127 to_meters = NAUT_MILES_TO_METERS;
128
129 /* parse distances */
130 if (!(count = parse_distances(zone_list, to_meters)))
131 G_fatal_error(_("Parse distances error"));
132
133
134 /* need to keep track of distance zones - in memory.
135 * process MAX_DIST at a time
136 *
137 * Coding: 0 == not-yet determined, 1 == input cells,
138 * 2 == distance zone #1, 3 == distance zone #2, etc.
139 */
140
141 read_input_map(input, mapset, ZEROFLAG);
142
143 offset = 0;
144
145 nsteps = (count - 1) / MAX_DIST + 1;
146
147 pd = distances;
148 for (step = 1; count > 0; step++) {
149 if (nsteps > 1)
150 G_message(_("Pass %d (of %d)"), step, nsteps);
151 ndist = count;
152 if (ndist > MAX_DIST)
153 ndist = MAX_DIST;
154 if (count_rows_with_data > 0)
155 execute_distance();
156 write_output_map(output, offset);
157 offset += ndist;
158 distances += ndist;
159 count -= ndist;
160 }
161 distances = pd;
162 make_support_files(output, units);
163
164 /* write map history (meta data) */
165 Rast_short_history(output, "raster", &hist);
166 Rast_set_history(&hist, HIST_DATSRC_1, input);
167 Rast_append_format_history(&hist, "Buffer distance%s:", ndist > 1 ? "s" : "");
168 Rast_append_format_history(&hist, " %s %s", opt3->answer, units);
169 Rast_command_history(&hist);
170 Rast_write_history(output, &hist);
171
172
173 exit(EXIT_SUCCESS);
174 }
175