1 /*
2  ****************************************************************************
3  *
4  * MODULE:       d.rast.num
5  * AUTHOR(S):    Raghavan Srinivasan, Agricultural Engineering, Purdue University
6  * PURPOSE:      Print numbers of category for raster cells
7  * COPYRIGHT:    (C) 2000, 2012 by the GRASS Development Team
8  *
9  *               This program is free software under the GNU General Public
10  *               License (>=v2). Read the file COPYING that comes with GRASS
11  *               for details.
12  *
13  *****************************************************************************/
14 
15 /* updated by Andreas Lange, andreas.lange@rhein-main.de
16  * for text color support.
17  * updated 2004 my MN for FP support
18  */
19 
20 /*
21  *   Raghavan Srinivasan, Agricultural Engineering, Purdue University
22  *   srin@ecn.purdue.edu  March 1991
23  *
24  *   d.rast.num
25  *
26  *   Usage:  d.rast.num
27  *
28  *   This program used Dgrid's sources as a beginning. Purpose of Dnumber
29  *   is to read the cell layer displayed on the graphics monitor and number
30  *   them, if the cell value is other than 0 in an acending order.
31  *   d.rast.num draws a number on the graphic display
32  *   of each cell, so the cell number could be identified when using hydrologic
33  *   models such AGNPS which uses the cell number for all its correspondance.
34  *
35  */
36 
37 #include <stdlib.h>
38 #include <string.h>
39 #include <math.h>
40 #include <grass/gis.h>
41 #include <grass/raster.h>
42 #include <grass/display.h>
43 #include <grass/colors.h>
44 #include <grass/glocale.h>
45 
46 int draw_number(int, int, double, int, RASTER_MAP_TYPE);
47 
48 static double D_ew, D_ns;
49 
main(int argc,char ** argv)50 int main(int argc, char **argv)
51 {
52     DCELL *cell;
53     char *map_name;
54     int fixed_color, grid_color;
55     int R, G, B;
56     int layer_fd;
57     int nrows, ncols, row, col;
58     int digits;
59     struct Cell_head window;
60     struct Colors colors;
61     struct GModule *module;
62     struct _opt {
63 	struct Option *map, *grid_color, *text_color, *prec,
64 	    *font, *path, *charset;
65     } opt;
66     struct _flg {
67 	struct Flag *text_color, *align;
68     } flg;
69     RASTER_MAP_TYPE map_type, inmap_type;
70     double t, b, l, r;
71     char *tmpstr1, *tmpstr2;
72 
73     /* Initialize the GIS calls */
74     G_gisinit(argv[0]);
75 
76     module = G_define_module();
77     G_add_keyword(_("display"));
78     G_add_keyword(_("map annotations"));
79     G_add_keyword(_("raster"));
80     module->description =
81 	_("Overlays cell category values on a raster map "
82 	  "displayed in the active graphics frame.");
83 
84     opt.map = G_define_standard_option(G_OPT_R_MAP);
85 
86     opt.text_color = G_define_standard_option(G_OPT_C);
87     opt.text_color->key = "text_color";
88     opt.text_color->label = _("Text color");
89     opt.text_color->guisection = _("Colors");
90 
91     opt.grid_color = G_define_standard_option(G_OPT_CN);
92     opt.grid_color->key = "grid_color";
93     opt.grid_color->answer = "gray";
94     opt.grid_color->label = _("Grid color");
95     opt.grid_color->guisection = _("Colors");
96 
97     opt.prec = G_define_option();
98     opt.prec->key = "precision";
99     opt.prec->type = TYPE_INTEGER;
100     opt.prec->required = NO;
101     opt.prec->answer = "1";
102     opt.prec->options = "0,1,2,3,4,5,6,7,8,9";
103     opt.prec->description =
104 	_("Number of significant digits (floating point only)");
105 
106     flg.align = G_define_flag();
107     flg.align->key = 'a';
108     flg.align->description = _("Align grids with raster cells");
109 
110     flg.text_color = G_define_flag();
111     flg.text_color->key = 'f';
112     flg.text_color->description = _("Get text color from cell color value");
113     flg.text_color->guisection = _("Colors");
114 
115     opt.font = G_define_option();
116     opt.font->key = "font";
117     opt.font->type = TYPE_STRING;
118     opt.font->required = NO;
119     opt.font->description = _("Font name");
120     opt.font->guisection = _("Font settings");
121 
122     opt.path = G_define_standard_option(G_OPT_F_INPUT);
123     opt.path->key = "path";
124     opt.path->required = NO;
125     opt.path->description = _("Path to font file");
126     opt.path->gisprompt = "old_file,font,file";
127     opt.path->guisection = _("Font settings");
128 
129     opt.charset = G_define_option();
130     opt.charset->key = "charset";
131     opt.charset->type = TYPE_STRING;
132     opt.charset->required = NO;
133     opt.charset->description =
134 	_("Text encoding (only applicable to TrueType fonts)");
135     opt.charset->guisection = _("Font settings");
136 
137     /* Check command line */
138     if (G_parser(argc, argv))
139 	exit(EXIT_FAILURE);
140 
141     map_name = opt.map->answer;
142 
143     if (strcmp("none", opt.grid_color->answer) == 0)
144 	grid_color = -1;
145     else
146 	grid_color = D_translate_color(opt.grid_color->answer);
147 
148     if (flg.text_color->answer)
149 	fixed_color = 0;
150     else
151 	fixed_color = 1;
152 
153     /* Read in the map window associated with window */
154 
155     G_get_window(&window);
156 
157     if (flg.align->answer) {
158 	struct Cell_head wind;
159 
160 	Rast_get_cellhd(map_name, "", &wind);
161 
162 	/* expand window extent by one wind resolution */
163 	wind.west += wind.ew_res * ((int)((window.west - wind.west) / wind.ew_res) - (window.west < wind.west));
164 	wind.east += wind.ew_res * ((int)((window.east - wind.east) / wind.ew_res) + (window.east > wind.east));
165 	wind.south += wind.ns_res * ((int)((window.south - wind.south) / wind.ns_res) - (window.south < wind.south));
166 	wind.north += wind.ns_res * ((int)((window.north - wind.north) / wind.ns_res) + (window.north > wind.north));
167 
168 	wind.rows = (wind.north - wind.south) / wind.ns_res;
169 	wind.cols = (wind.east - wind.west) / wind.ew_res;
170 
171 	Rast_set_window(&wind);
172 
173 	nrows = wind.rows;
174 	ncols = wind.cols;
175 
176 	t = (wind.north - window.north) * nrows / (wind.north - wind.south);
177 	b = t + (window.north - window.south) * nrows / (wind.north - wind.south);
178 	l = (window.west - wind.west) * ncols / (wind.east - wind.west);
179 	r = l + (window.east - window.west) * ncols / (wind.east - wind.west);
180     } else {
181         nrows = window.rows;
182         ncols = window.cols;
183 
184 	t = 0;
185 	b = nrows;
186 	l = 0;
187 	r = ncols;
188     }
189 
190     layer_fd = Rast_open_old(map_name, "");
191 
192     /* determine the inputmap type (CELL/FCELL/DCELL) */
193     inmap_type = Rast_get_map_type(layer_fd);
194     map_type = DCELL_TYPE;
195 
196     /* number of rows and cols in window */
197 
198     if ((nrows > 75) || (ncols > 75)) {
199         G_asprintf(&tmpstr1, n_("%d row", "%d rows", nrows), nrows);
200         G_asprintf(&tmpstr2, n_("%d col", "%d cols", ncols), ncols);
201         /* GTC %s will be replaced by strings "X rows" and "Y cols" */
202         G_warning(_("Current region size: %s X %s\n"
203 		    "Your current region setting may be too large. "
204 		    "Cells displayed on your graphics window may be too "
205 		    "small for cell category number to be visible."),
206 		    tmpstr1, tmpstr2);
207         G_free(tmpstr1);
208         G_free(tmpstr2);
209 
210     }
211     if ((nrows > 200) || (ncols > 200)) {
212 	G_fatal_error(_("Aborting (region larger then 200 rows X 200 cols is not allowed)"));
213     }
214 
215     /* Setup driver and check important information */
216 
217     D_open_driver();
218 
219     if (opt.font->answer)
220 	D_font(opt.font->answer);
221     else if (opt.path->answer)
222 	D_font(opt.path->answer);
223 
224     if (opt.charset->answer)
225 	D_encoding(opt.charset->answer);
226 
227     D_setup2(0, 0, t, b, l, r);
228 
229     D_ns = fabs(D_get_u_to_d_yconv());
230     D_ew = fabs(D_get_u_to_d_xconv());
231 
232     /*set the number of significant digits */
233     sscanf(opt.prec->answer, "%i", &digits);
234 
235     if (grid_color > 0) {	/* ie not "none" */
236 	/* Set grid color */
237 	D_use_color(grid_color);
238 
239 	/* Draw vertical grids */
240 	for (col = 0; col <= ncols; col++)
241 	    D_line_abs(col, 0, col, nrows);
242 
243 	/* Draw horizontal grids */
244 	for (row = 0; row <= nrows; row++)
245 	    D_line_abs(0, row, ncols, row);
246     }
247 
248     /* allocate the cell array */
249     cell = Rast_allocate_buf(map_type);
250 
251     /* read the color table in the color structures of the displayed map */
252     if (Rast_read_colors(map_name, "", &colors) == -1)
253 	G_fatal_error(_("Color file for <%s> not available"), map_name);
254 
255     /* fixed text color */
256     if (fixed_color == 1)
257 	D_use_color(D_translate_color(opt.text_color->answer));
258 
259     /* loop through cells, find value, and draw text for value */
260     for (row = 0; row < nrows; row++) {
261 	Rast_get_row(layer_fd, cell, row, map_type);
262 
263 	for (col = 0; col < ncols; col++) {
264 
265 	    if (fixed_color == 0) {
266 		Rast_get_color(&cell[col], &R, &G, &B, &colors, map_type);
267 		D_RGB_color(R, G, B);
268 	    }
269 
270 	    draw_number(row, col, cell[col], digits, inmap_type);
271 	}
272     }
273 
274     Rast_close(layer_fd);
275 
276     D_save_command(G_recreate_command());
277     D_close_driver();
278 
279     exit(EXIT_SUCCESS);
280 }
281 
282 /* --- end of main --- */
283 
284 
draw_number(int row,int col,double number,int prec,RASTER_MAP_TYPE map_type)285 int draw_number(int row, int col, double number, int prec, RASTER_MAP_TYPE map_type)
286 {
287     int len;
288     double text_size, rite;
289     double tt, tb, tl, tr;
290     char no[32];
291     double dots_per_line, factor = 0.8;
292     DCELL dcell = number;
293     CELL cell = (int)number;
294     double dx;
295 
296     /* maybe ugly, but works */
297     if (map_type == CELL_TYPE) {
298 	if (!Rast_is_c_null_value(&cell))
299 	    sprintf(no, "%d", (int)number);
300 	else
301 	    sprintf(no, "Null");
302     }
303     else {
304 	if (!Rast_is_d_null_value(&dcell))
305 	    sprintf(no, "%.*f", prec, number);
306 	else
307 	    sprintf(no, "Null");
308     }
309     len = strlen(no);
310 
311     dots_per_line = factor * D_ns;
312     text_size = factor * dots_per_line;
313     rite = text_size * len;
314 
315     while (rite > D_ew) {
316 	factor = factor - 0.01;
317 	text_size = factor * dots_per_line;
318 	rite = text_size * len;
319     }
320 
321     D_text_size(text_size, text_size);
322 
323     D_pos_abs(col, row + 0.7);
324     D_get_text_box(no, &tt, &tb, &tl, &tr);
325 
326     dx = (tr + tl) / 2 - (col + 0.5);
327     D_pos_abs(col - dx, row + 0.7);
328     D_text(no);
329 
330     return 0;
331 }
332