1
2 /****************************************************************************
3 *
4 * MODULE: r.circle
5 *
6 * AUTHOR(S): Bill Brown - CERL (Jan, 1993)
7 * Markus Neteler
8 *
9 * PURPOSE: Creates a raster map containing concentric rings
10 * around a given point.
11 *
12 * COPYRIGHT: (C) 2006-2008 by the GRASS Development Team
13 *
14 * This program is free software under the GNU General Public
15 * License (>=v2). Read the file COPYING that comes with GRASS
16 * for details.
17 *
18 ***************************************************************************/
19
20 #include <stdlib.h>
21 #include <strings.h>
22 #include <math.h>
23 #include <grass/gis.h>
24 #include <grass/raster.h>
25 #include <grass/glocale.h>
26
27 static double distance(double *, double *, double, double, int);
28
29 #ifndef HUGE_VAL
30 #define HUGE_VAL 1.7976931348623157e+308
31 #endif
32
33
main(int argc,char * argv[])34 int main(int argc, char *argv[])
35 {
36
37 struct GModule *module;
38 struct Option *coord, *out_file, *min, *max, *mult;
39 struct Flag *flag;
40 int *int_buf;
41 struct Cell_head w;
42 struct History history;
43 int cellfile;
44 double east, north, pt[2], cur[2], row, col, fmult;
45 double fmin, fmax;
46 int binary;
47
48 G_gisinit(argv[0]);
49
50 module = G_define_module();
51 G_add_keyword(_("raster"));
52 G_add_keyword(_("buffer"));
53 G_add_keyword(_("geometry"));
54 G_add_keyword(_("circle"));
55 module->description =
56 _("Creates a raster map containing concentric "
57 "rings around a given point.");
58
59 out_file = G_define_standard_option(G_OPT_R_OUTPUT);
60
61 coord = G_define_standard_option(G_OPT_M_COORDS);
62 coord->required = YES;
63 coord->description = _("The coordinate of the center (east,north)");
64
65 min = G_define_option();
66 min->key = "min";
67 min->type = TYPE_DOUBLE;
68 min->required = NO;
69 min->description = _("Minimum radius for ring/circle map (in meters)");
70
71 max = G_define_option();
72 max->key = "max";
73 max->type = TYPE_DOUBLE;
74 max->required = NO;
75 max->description = _("Maximum radius for ring/circle map (in meters)");
76
77 mult = G_define_option();
78 mult->key = "multiplier";
79 mult->type = TYPE_DOUBLE;
80 mult->required = NO;
81 mult->description = _("Data value multiplier");
82
83 flag = G_define_flag();
84 flag->key = 'b';
85 flag->description = _("Generate binary raster map");
86
87 if (G_parser(argc, argv))
88 exit(EXIT_FAILURE);
89
90 G_scan_easting(coord->answers[0], &east, G_projection());
91 G_scan_northing(coord->answers[1], &north, G_projection());
92 pt[0] = east;
93 pt[1] = north;
94
95 fmult = 1.0;
96
97 if (min->answer)
98 sscanf(min->answer, "%lf", &fmin);
99 else
100 fmin = 0;
101
102 if (max->answer)
103 sscanf(max->answer, "%lf", &fmax);
104 else
105 fmax = HUGE_VAL;
106
107 if (fmin > fmax)
108 G_fatal_error(_("Please specify a radius in which min < max"));
109
110 if (mult->answer)
111 if (1 != sscanf(mult->answer, "%lf", &fmult))
112 fmult = 1.0;
113
114 /* nonsense test */
115 if (flag->answer && (!min->answer && !max->answer))
116 G_fatal_error(_("Please specify min and/or max radius when "
117 "using the binary flag"));
118
119 if (flag->answer)
120 binary = 1; /* generate binary pattern only, useful for MASK */
121 else
122 binary = 0;
123
124 G_get_set_window(&w);
125
126 cellfile = Rast_open_c_new(out_file->answer);
127
128 int_buf = (int *)G_malloc(w.cols * sizeof(int));
129 {
130 int c;
131
132 for (row = 0; row < w.rows; row++) {
133 G_percent(row, w.rows, 2);
134 cur[1] = Rast_row_to_northing(row + 0.5, &w);
135 for (col = 0; col < w.cols; col++) {
136 c = col;
137 cur[0] = Rast_col_to_easting(col + 0.5, &w);
138 int_buf[c] =
139 (int)(distance(pt, cur, fmin, fmax, binary) * fmult);
140 if (int_buf[c] == 0)
141 Rast_set_null_value(&int_buf[c], 1, CELL_TYPE);
142 }
143 Rast_put_row(cellfile, int_buf, CELL_TYPE);
144
145 }
146 }
147 G_free(int_buf);
148 Rast_close(cellfile);
149 Rast_short_history(out_file->answer, "raster", &history);
150 Rast_command_history(&history);
151 Rast_write_history(out_file->answer, &history);
152
153 G_done_msg(_("Raster map <%s> created."),
154 out_file->answer);
155
156 return (EXIT_SUCCESS);
157 }
158
159
160
161 /*******************************************************************/
162
distance(double from[2],double to[2],double min,double max,int binary)163 static double distance(double from[2], double to[2], double min, double max,
164 int binary)
165 {
166 static int first = 1;
167 double dist;
168
169 if (first) {
170 first = 0;
171 G_begin_distance_calculations();
172 }
173
174 dist = G_distance(from[0], from[1], to[0], to[1]);
175
176 if ((dist >= min) && (dist <= max))
177 if (!binary)
178 return dist;
179 else
180 return 1;
181 else
182 return 0; /* should be NULL ? */
183 }
184
185 /**********************************************************************/
186