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