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