| 1 | /*
|
|---|
| 2 | ****************************************************************************
|
|---|
| 3 | *
|
|---|
| 4 | * MODULE: d.rast.arrow
|
|---|
| 5 | * AUTHOR(S): Chris Rewerts, Agricultural Engineering, Purdue University
|
|---|
| 6 | * PURPOSE: Draw arrows on slope/aspect maps.
|
|---|
| 7 | * COPYRIGHT: (C) 2000, 2010 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 | /* some minor cleanup done by Andreas Lange, andreas.lange@rhein-main.de
|
|---|
| 16 | * Update to handle NULLs and floating point aspect maps: Hamish Bowman, Aug 2004
|
|---|
| 17 | * Update for 360 degree arrows and magnitude scaling: Hamish Bowman, Oct 2005
|
|---|
| 18 | * Align grids with raster cells: Huidae Cho, Apr 2009
|
|---|
| 19 | * Drainage aspect type: Huidae Cho, Sep 2015
|
|---|
| 20 | */
|
|---|
| 21 |
|
|---|
| 22 | /*
|
|---|
| 23 | * Chris Rewerts, Agricultural Engineering, Purdue University
|
|---|
| 24 | * rewerts@ecn.purdue.edu March 1991
|
|---|
| 25 | *
|
|---|
| 26 | * d.rast.arrow
|
|---|
| 27 | *
|
|---|
| 28 | * Usage: d.rast.arrow
|
|---|
| 29 | *
|
|---|
| 30 | * This program used Dgrid's sources as a beginning. Purpose of Darrow
|
|---|
| 31 | * is to read an aspect layer produced by slope.aspect or by the
|
|---|
| 32 | * programs created for the ANSWERS or AGNPS Hydrology Toolbox
|
|---|
| 33 | * endeavors. d.rast.arrow draws an arrow on the graphic display
|
|---|
| 34 | * of each cell, so that the flow pattern computed as an aspect
|
|---|
| 35 | * layer can be easily seen. Other symbols ("?", "X") may be drawn
|
|---|
| 36 | * as needed.
|
|---|
| 37 | */
|
|---|
| 38 |
|
|---|
| 39 | #include <stdlib.h>
|
|---|
| 40 | #include <string.h>
|
|---|
| 41 | #include <math.h>
|
|---|
| 42 | #include <grass/gis.h>
|
|---|
| 43 | #include <grass/raster.h>
|
|---|
| 44 | #include <grass/display.h>
|
|---|
| 45 | #include <grass/colors.h>
|
|---|
| 46 | #include <grass/glocale.h>
|
|---|
| 47 |
|
|---|
| 48 | # define RpD ((2 * M_PI) / 360.) /* radians/degree */
|
|---|
| 49 | # define D2R(d) (double)(d * RpD) /* degrees->radians */
|
|---|
| 50 |
|
|---|
| 51 | static void arrow_mag(double, double);
|
|---|
| 52 | static void arrow_360(double);
|
|---|
| 53 | static void arrow_se(void);
|
|---|
| 54 | static void arrow_ne(void);
|
|---|
| 55 | static void arrow_nw(void);
|
|---|
| 56 | static void arrow_sw(void);
|
|---|
| 57 | static void arrow_e(void);
|
|---|
| 58 | static void arrow_w(void);
|
|---|
| 59 | static void arrow_s(void);
|
|---|
| 60 | static void arrow_n(void);
|
|---|
| 61 | static void draw_x(void);
|
|---|
| 62 | static void unknown_(void);
|
|---|
| 63 |
|
|---|
| 64 | static char *layer_name;
|
|---|
| 65 | static int map_type, arrow_color, grid_color, x_color, unknown_color;
|
|---|
| 66 | static int row, col;
|
|---|
| 67 |
|
|---|
| 68 | int main(int argc, char **argv)
|
|---|
| 69 | {
|
|---|
| 70 | struct Cell_head window;
|
|---|
| 71 | RASTER_MAP_TYPE raster_type, mag_raster_type = -1;
|
|---|
| 72 | int layer_fd;
|
|---|
| 73 | void *raster_row, *ptr;
|
|---|
| 74 | int nrows, ncols;
|
|---|
| 75 | int aspect_c = -1;
|
|---|
| 76 | float aspect_f = -1.0;
|
|---|
| 77 |
|
|---|
| 78 | double scale;
|
|---|
| 79 | int skip, no_arrow;
|
|---|
| 80 | char *mag_map = NULL;
|
|---|
| 81 | void *mag_raster_row = NULL, *mag_ptr = NULL;
|
|---|
| 82 | double length = -1;
|
|---|
| 83 | int mag_fd = -1;
|
|---|
| 84 | struct FPRange range;
|
|---|
| 85 | double mag_min, mag_max;
|
|---|
| 86 |
|
|---|
| 87 | struct GModule *module;
|
|---|
| 88 | struct Option *opt1, *opt2, *opt3, *opt4, *opt5,
|
|---|
| 89 | *opt6, *opt7, *opt8, *opt9;
|
|---|
| 90 | struct Flag *align;
|
|---|
| 91 |
|
|---|
| 92 | double t, b, l, r;
|
|---|
| 93 |
|
|---|
| 94 | G_gisinit(argv[0]);
|
|---|
| 95 |
|
|---|
| 96 | module = G_define_module();
|
|---|
| 97 | G_add_keyword(_("display"));
|
|---|
| 98 | G_add_keyword(_("map annotations"));
|
|---|
| 99 | G_add_keyword(_("raster"));
|
|---|
| 100 | module->description =
|
|---|
| 101 | _("Draws arrows representing cell aspect direction "
|
|---|
| 102 | "for a raster map containing aspect data.");
|
|---|
| 103 |
|
|---|
| 104 | opt1 = G_define_standard_option(G_OPT_R_MAP);
|
|---|
| 105 | opt1->description = _("Name of raster aspect map to be displayed");
|
|---|
| 106 |
|
|---|
| 107 | opt2 = G_define_option();
|
|---|
| 108 | opt2->key = "type";
|
|---|
| 109 | opt2->type = TYPE_STRING;
|
|---|
| 110 | opt2->required = NO;
|
|---|
| 111 | opt2->answer = "grass";
|
|---|
| 112 | opt2->options = "grass,compass,drainage,agnps,answers";
|
|---|
| 113 | opt2->description = _("Type of existing raster aspect map");
|
|---|
| 114 |
|
|---|
| 115 | opt3 = G_define_standard_option(G_OPT_C);
|
|---|
| 116 | opt3->key = "color";
|
|---|
| 117 | opt3->answer = "green";
|
|---|
| 118 | opt3->label = _("Color for drawing arrows");
|
|---|
| 119 | opt3->guisection = _("Colors");
|
|---|
| 120 |
|
|---|
| 121 | opt4 = G_define_standard_option(G_OPT_CN);
|
|---|
| 122 | opt4->key = "grid_color";
|
|---|
| 123 | opt4->answer = "gray";
|
|---|
| 124 | opt4->label = _("Color for drawing drawing grid");
|
|---|
| 125 | opt4->guisection = _("Colors");
|
|---|
| 126 |
|
|---|
| 127 | opt5 = G_define_standard_option(G_OPT_CN);
|
|---|
| 128 | opt5->key = "null_color";
|
|---|
| 129 | opt5->answer = DEFAULT_FG_COLOR;
|
|---|
| 130 | opt5->label = _("Color for drawing null values (X symbol)");
|
|---|
| 131 | opt5->guisection = _("Colors");
|
|---|
| 132 |
|
|---|
| 133 | opt6 = G_define_standard_option(G_OPT_CN);
|
|---|
| 134 | opt6->key = "unknown_color";
|
|---|
| 135 | opt6->answer = "red";
|
|---|
| 136 | opt6->label = _("Color for showing unknown information (? symbol)");
|
|---|
| 137 | opt6->guisection = _("Colors");
|
|---|
| 138 |
|
|---|
| 139 | opt9 = G_define_option();
|
|---|
| 140 | opt9->key = "skip";
|
|---|
| 141 | opt9->type = TYPE_INTEGER;
|
|---|
| 142 | opt9->required = NO;
|
|---|
| 143 | opt9->answer = "1";
|
|---|
| 144 | opt9->description = _("Draw arrow every Nth grid cell");
|
|---|
| 145 |
|
|---|
| 146 | opt7 = G_define_option();
|
|---|
| 147 | opt7->key = "magnitude_map";
|
|---|
| 148 | opt7->type = TYPE_STRING;
|
|---|
| 149 | opt7->required = NO;
|
|---|
| 150 | opt7->multiple = NO;
|
|---|
| 151 | opt7->gisprompt = "old,cell,raster";
|
|---|
| 152 | opt7->description =
|
|---|
| 153 | _("Raster map containing values used for arrow length");
|
|---|
| 154 |
|
|---|
| 155 | opt8 = G_define_option();
|
|---|
| 156 | opt8->key = "scale";
|
|---|
| 157 | opt8->type = TYPE_DOUBLE;
|
|---|
| 158 | opt8->required = NO;
|
|---|
| 159 | opt8->answer = "1.0";
|
|---|
| 160 | opt8->description = _("Scale factor for arrows (magnitude map)");
|
|---|
| 161 |
|
|---|
| 162 | align = G_define_flag();
|
|---|
| 163 | align->key = 'a';
|
|---|
| 164 | align->description = _("Align grids with raster cells");
|
|---|
| 165 |
|
|---|
| 166 |
|
|---|
| 167 | /* Check command line */
|
|---|
| 168 | if (G_parser(argc, argv))
|
|---|
| 169 | exit(EXIT_FAILURE);
|
|---|
| 170 |
|
|---|
| 171 |
|
|---|
| 172 | layer_name = opt1->answer;
|
|---|
| 173 |
|
|---|
| 174 | arrow_color = D_translate_color(opt3->answer);
|
|---|
| 175 |
|
|---|
| 176 | /* Convert none (transparent) to -1 which in this module means
|
|---|
| 177 | that we will not draw things having this color (-1).
|
|---|
| 178 | We don't do that for arrow because we always want them.
|
|---|
| 179 | (This is specified by the gisprompt ('type') of the options.)
|
|---|
| 180 | */
|
|---|
| 181 | if (strcmp("none", opt4->answer) == 0)
|
|---|
| 182 | grid_color = -1;
|
|---|
| 183 | else
|
|---|
| 184 | grid_color = D_translate_color(opt4->answer);
|
|---|
| 185 |
|
|---|
| 186 | if (strcmp("none", opt5->answer) == 0)
|
|---|
| 187 | x_color = -1;
|
|---|
| 188 | else
|
|---|
| 189 | x_color = D_translate_color(opt5->answer);
|
|---|
| 190 |
|
|---|
| 191 | if (strcmp("none", opt6->answer) == 0)
|
|---|
| 192 | unknown_color = -1;
|
|---|
| 193 | else
|
|---|
| 194 | unknown_color = D_translate_color(opt6->answer);
|
|---|
| 195 |
|
|---|
| 196 | if (strcmp("grass", opt2->answer) == 0)
|
|---|
| 197 | map_type = 1;
|
|---|
| 198 | else if (strcmp("agnps", opt2->answer) == 0)
|
|---|
| 199 | map_type = 2;
|
|---|
| 200 | else if (strcmp("answers", opt2->answer) == 0)
|
|---|
| 201 | map_type = 3;
|
|---|
| 202 | else if (strcmp("compass", opt2->answer) == 0)
|
|---|
| 203 | map_type = 4;
|
|---|
| 204 | else if (strcmp("drainage", opt2->answer) == 0)
|
|---|
| 205 | map_type = 5;
|
|---|
| 206 |
|
|---|
| 207 |
|
|---|
| 208 | scale = atof(opt8->answer);
|
|---|
| 209 | if (scale <= 0.0)
|
|---|
| 210 | G_fatal_error(_("Illegal value for scale factor"));
|
|---|
| 211 |
|
|---|
| 212 | skip = atoi(opt9->answer);
|
|---|
| 213 | if (skip <= 0)
|
|---|
| 214 | G_fatal_error(_("Illegal value for skip factor"));
|
|---|
| 215 |
|
|---|
| 216 |
|
|---|
| 217 | if (opt7->answer) {
|
|---|
| 218 | if (map_type != 1 && map_type != 4)
|
|---|
| 219 | G_fatal_error(_("Magnitude is only supported for GRASS and compass aspect maps."));
|
|---|
| 220 |
|
|---|
| 221 | mag_map = opt7->answer;
|
|---|
| 222 | }
|
|---|
| 223 | else if (scale != 1.0)
|
|---|
| 224 | G_warning(_("Scale option requires magnitude_map"));
|
|---|
| 225 |
|
|---|
| 226 |
|
|---|
| 227 | /* Setup driver and check important information */
|
|---|
| 228 | D_open_driver();
|
|---|
| 229 |
|
|---|
| 230 | D_setup(0);
|
|---|
| 231 |
|
|---|
| 232 | /* Read in the map window associated with window */
|
|---|
| 233 | G_get_window(&window);
|
|---|
| 234 |
|
|---|
| 235 | if (align->answer) {
|
|---|
| 236 | struct Cell_head wind;
|
|---|
| 237 |
|
|---|
| 238 | Rast_get_cellhd(layer_name, "", &wind);
|
|---|
| 239 |
|
|---|
| 240 | /* expand window extent by one wind resolution */
|
|---|
| 241 | wind.west += wind.ew_res * ((int)((window.west - wind.west) / wind.ew_res) - (window.west < wind.west));
|
|---|
| 242 | wind.east += wind.ew_res * ((int)((window.east - wind.east) / wind.ew_res) + (window.east > wind.east));
|
|---|
| 243 | wind.south += wind.ns_res * ((int)((window.south - wind.south) / wind.ns_res) - (window.south < wind.south));
|
|---|
| 244 | wind.north += wind.ns_res * ((int)((window.north - wind.north) / wind.ns_res) + (window.north > wind.north));
|
|---|
| 245 |
|
|---|
| 246 | wind.rows = (wind.north - wind.south) / wind.ns_res;
|
|---|
| 247 | wind.cols = (wind.east - wind.west) / wind.ew_res;
|
|---|
| 248 |
|
|---|
| 249 | Rast_set_window(&wind);
|
|---|
| 250 |
|
|---|
| 251 | nrows = wind.rows;
|
|---|
| 252 | ncols = wind.cols;
|
|---|
| 253 |
|
|---|
| 254 | t = (wind.north - window.north) * nrows / (wind.north - wind.south);
|
|---|
| 255 | b = t + (window.north - window.south) * nrows / (wind.north - wind.south);
|
|---|
| 256 | l = (window.west - wind.west) * ncols / (wind.east - wind.west);
|
|---|
| 257 | r = l + (window.east - window.west) * ncols / (wind.east - wind.west);
|
|---|
| 258 | } else {
|
|---|
| 259 | nrows = window.rows;
|
|---|
| 260 | ncols = window.cols;
|
|---|
| 261 |
|
|---|
| 262 | t = 0;
|
|---|
| 263 | b = nrows;
|
|---|
| 264 | l = 0;
|
|---|
| 265 | r = ncols;
|
|---|
| 266 | }
|
|---|
| 267 |
|
|---|
| 268 | D_set_src(t, b, l, r);
|
|---|
| 269 | D_update_conversions();
|
|---|
| 270 |
|
|---|
| 271 | /* figure out arrow scaling if using a magnitude map */
|
|---|
| 272 | if (opt7->answer) {
|
|---|
| 273 | Rast_init_fp_range(&range); /* really needed? */
|
|---|
| 274 | if (Rast_read_fp_range(mag_map, "", &range) != 1)
|
|---|
| 275 | G_fatal_error(_("Problem reading range file"));
|
|---|
| 276 | Rast_get_fp_range_min_max(&range, &mag_min, &mag_max);
|
|---|
| 277 |
|
|---|
| 278 | scale *= 1.5 / fabs(mag_max);
|
|---|
| 279 | G_debug(3, "scaling=%.2f rast_max=%.2f", scale, mag_max);
|
|---|
| 280 | }
|
|---|
| 281 |
|
|---|
| 282 | if (grid_color > 0) { /* ie not "none" */
|
|---|
| 283 | /* Set color */
|
|---|
| 284 | D_use_color(grid_color);
|
|---|
| 285 |
|
|---|
| 286 | /* Draw vertical grids */
|
|---|
| 287 | for (col = 0; col < ncols; col++)
|
|---|
| 288 | D_line_abs(col, 0, col, nrows);
|
|---|
| 289 |
|
|---|
| 290 | /* Draw horizontal grids */
|
|---|
| 291 | for (row = 0; row < nrows; row++)
|
|---|
| 292 | D_line_abs(0, row, ncols, row);
|
|---|
| 293 | }
|
|---|
| 294 |
|
|---|
| 295 | /* open the raster map */
|
|---|
| 296 | layer_fd = Rast_open_old(layer_name, "");
|
|---|
| 297 |
|
|---|
| 298 | raster_type = Rast_get_map_type(layer_fd);
|
|---|
| 299 |
|
|---|
| 300 | /* allocate the cell array */
|
|---|
| 301 | raster_row = Rast_allocate_buf(raster_type);
|
|---|
| 302 |
|
|---|
| 303 |
|
|---|
| 304 | if (opt7->answer) {
|
|---|
| 305 | /* open the magnitude raster map */
|
|---|
| 306 | mag_fd = Rast_open_old(mag_map, "");
|
|---|
| 307 |
|
|---|
| 308 | mag_raster_type = Rast_get_map_type(mag_fd);
|
|---|
| 309 |
|
|---|
| 310 | /* allocate the cell array */
|
|---|
| 311 | mag_raster_row = Rast_allocate_buf(mag_raster_type);
|
|---|
| 312 | }
|
|---|
| 313 |
|
|---|
| 314 |
|
|---|
| 315 | /* loop through cells, find value, determine direction (n,s,e,w,ne,se,sw,nw),
|
|---|
| 316 | and call appropriate function to draw an arrow on the cell */
|
|---|
| 317 |
|
|---|
| 318 | for (row = 0; row < nrows; row++) {
|
|---|
| 319 | Rast_get_row(layer_fd, raster_row, row, raster_type);
|
|---|
| 320 | ptr = raster_row;
|
|---|
| 321 |
|
|---|
| 322 | if (opt7->answer) {
|
|---|
| 323 | Rast_get_row(mag_fd, mag_raster_row, row, mag_raster_type);
|
|---|
| 324 | mag_ptr = mag_raster_row;
|
|---|
| 325 | }
|
|---|
| 326 |
|
|---|
| 327 | for (col = 0; col < ncols; col++) {
|
|---|
| 328 |
|
|---|
| 329 | if (row % skip != 0)
|
|---|
| 330 | no_arrow = TRUE;
|
|---|
| 331 | else
|
|---|
| 332 | no_arrow = FALSE;
|
|---|
| 333 |
|
|---|
| 334 | if (col % skip != 0)
|
|---|
| 335 | no_arrow = TRUE;
|
|---|
| 336 |
|
|---|
| 337 | /* find aspect direction based on cell value */
|
|---|
| 338 | if (raster_type == CELL_TYPE)
|
|---|
| 339 | aspect_f = *((CELL *) ptr);
|
|---|
| 340 | else if (raster_type == FCELL_TYPE)
|
|---|
| 341 | aspect_f = *((FCELL *) ptr);
|
|---|
| 342 | else if (raster_type == DCELL_TYPE)
|
|---|
| 343 | aspect_f = *((DCELL *) ptr);
|
|---|
| 344 |
|
|---|
| 345 |
|
|---|
| 346 | if (opt7->answer) {
|
|---|
| 347 |
|
|---|
| 348 | if (mag_raster_type == CELL_TYPE)
|
|---|
| 349 | length = *((CELL *) mag_ptr);
|
|---|
| 350 | else if (mag_raster_type == FCELL_TYPE)
|
|---|
| 351 | length = *((FCELL *) mag_ptr);
|
|---|
| 352 | else if (mag_raster_type == DCELL_TYPE)
|
|---|
| 353 | length = *((DCELL *) mag_ptr);
|
|---|
| 354 |
|
|---|
| 355 | length *= scale;
|
|---|
| 356 |
|
|---|
| 357 | if (Rast_is_null_value(mag_ptr, mag_raster_type)) {
|
|---|
| 358 | G_debug(5, "Invalid arrow length [NULL]. Skipping.");
|
|---|
| 359 | no_arrow = TRUE;
|
|---|
| 360 | }
|
|---|
| 361 | else if (length <= 0.0) { /* use fabs() or theta+=180? */
|
|---|
| 362 | G_debug(5, "Illegal arrow length [%.3f]. Skipping.",
|
|---|
| 363 | length);
|
|---|
| 364 | no_arrow = TRUE;
|
|---|
| 365 | }
|
|---|
| 366 | }
|
|---|
| 367 |
|
|---|
| 368 | if (no_arrow) {
|
|---|
| 369 | ptr = G_incr_void_ptr(ptr, Rast_cell_size(raster_type));
|
|---|
| 370 | if (opt7->answer)
|
|---|
| 371 | mag_ptr =
|
|---|
| 372 | G_incr_void_ptr(mag_ptr,
|
|---|
| 373 | Rast_cell_size(mag_raster_type));
|
|---|
| 374 | no_arrow = FALSE;
|
|---|
| 375 | continue;
|
|---|
| 376 | }
|
|---|
| 377 |
|
|---|
| 378 | /* treat AGNPS and ANSWERS data like old zero-as-null CELL */
|
|---|
| 379 | /* TODO: update models */
|
|---|
| 380 | if (map_type == 2 || map_type == 3 || map_type == 5) {
|
|---|
| 381 | if (Rast_is_null_value(ptr, raster_type))
|
|---|
| 382 | aspect_c = 0;
|
|---|
| 383 | else
|
|---|
| 384 | aspect_c = (int)(aspect_f + 0.5);
|
|---|
| 385 | }
|
|---|
| 386 |
|
|---|
| 387 |
|
|---|
| 388 | /** Now draw the arrows **/
|
|---|
| 389 |
|
|---|
| 390 | /* case switch for standard GRASS aspect map
|
|---|
| 391 | measured in degrees counter-clockwise from east */
|
|---|
| 392 | if (map_type == 1) {
|
|---|
| 393 | D_use_color(arrow_color);
|
|---|
| 394 |
|
|---|
| 395 | if (Rast_is_null_value(ptr, raster_type)) {
|
|---|
| 396 | /* don't draw anything if x_color is none (transparent) */
|
|---|
| 397 | if (x_color > 0) {
|
|---|
| 398 | D_use_color(x_color);
|
|---|
| 399 | draw_x();
|
|---|
| 400 | D_use_color(arrow_color);
|
|---|
| 401 | }
|
|---|
| 402 | }
|
|---|
| 403 | else if (aspect_f >= 0.0 && aspect_f <= 360.0) {
|
|---|
| 404 | if (opt7->answer)
|
|---|
| 405 | arrow_mag(aspect_f, length);
|
|---|
| 406 | else
|
|---|
| 407 | arrow_360(aspect_f);
|
|---|
| 408 | }
|
|---|
| 409 | else if (unknown_color > 0) {
|
|---|
| 410 | /* don't draw if unknown_color is none (transparent) */
|
|---|
| 411 | D_use_color(unknown_color);
|
|---|
| 412 | unknown_();
|
|---|
| 413 | D_use_color(arrow_color);
|
|---|
| 414 | }
|
|---|
| 415 | }
|
|---|
| 416 |
|
|---|
| 417 |
|
|---|
| 418 | /* case switch for AGNPS type aspect map */
|
|---|
| 419 | else if (map_type == 2) {
|
|---|
| 420 | D_use_color(arrow_color);
|
|---|
| 421 | switch (aspect_c) {
|
|---|
| 422 | case 0:
|
|---|
| 423 | /* only draw if x_color is not none (transparent) */
|
|---|
| 424 | if (x_color > 0) {
|
|---|
| 425 | D_use_color(x_color);
|
|---|
| 426 | draw_x();
|
|---|
| 427 | D_use_color(arrow_color);
|
|---|
| 428 | }
|
|---|
| 429 | break;
|
|---|
| 430 | case 1:
|
|---|
| 431 | arrow_n();
|
|---|
| 432 | break;
|
|---|
| 433 | case 2:
|
|---|
| 434 | arrow_ne();
|
|---|
| 435 | break;
|
|---|
| 436 | case 3:
|
|---|
| 437 | arrow_e();
|
|---|
| 438 | break;
|
|---|
| 439 | case 4:
|
|---|
| 440 | arrow_se();
|
|---|
| 441 | break;
|
|---|
| 442 | case 5:
|
|---|
| 443 | arrow_s();
|
|---|
| 444 | break;
|
|---|
| 445 | case 6:
|
|---|
| 446 | arrow_sw();
|
|---|
| 447 | break;
|
|---|
| 448 | case 7:
|
|---|
| 449 | arrow_w();
|
|---|
| 450 | break;
|
|---|
| 451 | case 8:
|
|---|
| 452 | arrow_nw();
|
|---|
| 453 | break;
|
|---|
| 454 | default:
|
|---|
| 455 | /* only draw if unknown_color is not none */
|
|---|
| 456 | if (unknown_color > 0) {
|
|---|
| 457 | D_use_color(unknown_color);
|
|---|
| 458 | unknown_();
|
|---|
| 459 | D_use_color(arrow_color);
|
|---|
| 460 | }
|
|---|
| 461 | break;
|
|---|
| 462 | }
|
|---|
| 463 | }
|
|---|
| 464 |
|
|---|
| 465 |
|
|---|
| 466 | /* case switch for ANSWERS type aspect map */
|
|---|
| 467 | else if (map_type == 3) {
|
|---|
| 468 | D_use_color(arrow_color);
|
|---|
| 469 | if (aspect_c >= 15 && aspect_c <= 360) /* start at zero? */
|
|---|
| 470 | arrow_360((double)aspect_c);
|
|---|
| 471 | else if (aspect_c == 400) {
|
|---|
| 472 | if (unknown_color > 0) {
|
|---|
| 473 | /* only draw if unknown_color is not none */
|
|---|
| 474 | D_use_color(unknown_color);
|
|---|
| 475 | unknown_();
|
|---|
| 476 | D_use_color(arrow_color);
|
|---|
| 477 | }
|
|---|
| 478 | }
|
|---|
| 479 | else if (x_color > 0) {
|
|---|
| 480 | /* only draw if x_color is not none (transparent) */
|
|---|
| 481 | D_use_color(x_color);
|
|---|
| 482 | draw_x();
|
|---|
| 483 | D_use_color(arrow_color);
|
|---|
| 484 | }
|
|---|
| 485 | }
|
|---|
| 486 |
|
|---|
| 487 | /* case switch for compass type aspect map
|
|---|
| 488 | measured in degrees clockwise from north */
|
|---|
| 489 | else if (map_type == 4) {
|
|---|
| 490 | D_use_color(arrow_color);
|
|---|
| 491 |
|
|---|
| 492 | if (Rast_is_null_value(ptr, raster_type)) {
|
|---|
| 493 | if (x_color > 0) {
|
|---|
| 494 | /* only draw if x_color is not none */
|
|---|
| 495 | D_use_color(x_color);
|
|---|
| 496 | draw_x();
|
|---|
| 497 | D_use_color(arrow_color);
|
|---|
| 498 | }
|
|---|
| 499 | }
|
|---|
| 500 | else if (aspect_f >= 0.0 && aspect_f <= 360.0) {
|
|---|
| 501 | if (opt7->answer)
|
|---|
| 502 | arrow_mag(90 - aspect_f, length);
|
|---|
| 503 | else
|
|---|
| 504 | arrow_360(90 - aspect_f);
|
|---|
| 505 | }
|
|---|
| 506 | else if (unknown_color > 0) {
|
|---|
| 507 | /* only draw if unknown_color is not none */
|
|---|
| 508 | D_use_color(unknown_color);
|
|---|
| 509 | unknown_();
|
|---|
| 510 | D_use_color(arrow_color);
|
|---|
| 511 | }
|
|---|
| 512 | }
|
|---|
| 513 |
|
|---|
| 514 | /* case switch for r.watershed drainage type aspect map */
|
|---|
| 515 | else if (map_type == 5) {
|
|---|
| 516 | D_use_color(arrow_color);
|
|---|
| 517 | switch (aspect_c >= 0 ? aspect_c : -aspect_c) {
|
|---|
| 518 | case 0:
|
|---|
| 519 | /* only draw if x_color is not none (transparent) */
|
|---|
| 520 | if (x_color > 0) {
|
|---|
| 521 | D_use_color(x_color);
|
|---|
| 522 | draw_x();
|
|---|
| 523 | D_use_color(arrow_color);
|
|---|
| 524 | }
|
|---|
| 525 | break;
|
|---|
| 526 | case 1:
|
|---|
| 527 | arrow_ne();
|
|---|
| 528 | break;
|
|---|
| 529 | case 2:
|
|---|
| 530 | arrow_n();
|
|---|
| 531 | break;
|
|---|
| 532 | case 3:
|
|---|
| 533 | arrow_nw();
|
|---|
| 534 | break;
|
|---|
| 535 | case 4:
|
|---|
| 536 | arrow_w();
|
|---|
| 537 | break;
|
|---|
| 538 | case 5:
|
|---|
| 539 | arrow_sw();
|
|---|
| 540 | break;
|
|---|
| 541 | case 6:
|
|---|
| 542 | arrow_s();
|
|---|
| 543 | break;
|
|---|
| 544 | case 7:
|
|---|
| 545 | arrow_se();
|
|---|
| 546 | break;
|
|---|
| 547 | case 8:
|
|---|
| 548 | arrow_e();
|
|---|
| 549 | break;
|
|---|
| 550 | default:
|
|---|
| 551 | /* only draw if unknown_color is not none */
|
|---|
| 552 | if (unknown_color > 0) {
|
|---|
| 553 | D_use_color(unknown_color);
|
|---|
| 554 | unknown_();
|
|---|
| 555 | D_use_color(arrow_color);
|
|---|
| 556 | }
|
|---|
| 557 | break;
|
|---|
| 558 | }
|
|---|
| 559 | }
|
|---|
| 560 |
|
|---|
| 561 | ptr = G_incr_void_ptr(ptr, Rast_cell_size(raster_type));
|
|---|
| 562 | if (opt7->answer)
|
|---|
| 563 | mag_ptr =
|
|---|
| 564 | G_incr_void_ptr(mag_ptr, Rast_cell_size(mag_raster_type));
|
|---|
| 565 | }
|
|---|
| 566 | }
|
|---|
| 567 |
|
|---|
| 568 | Rast_close(layer_fd);
|
|---|
| 569 | if (opt7->answer)
|
|---|
| 570 | Rast_close(mag_fd);
|
|---|
| 571 |
|
|---|
| 572 | D_save_command(G_recreate_command());
|
|---|
| 573 | D_close_driver();
|
|---|
| 574 |
|
|---|
| 575 | exit(EXIT_SUCCESS);
|
|---|
| 576 | }
|
|---|
| 577 |
|
|---|
| 578 | /* --- end of main --- */
|
|---|
| 579 |
|
|---|
| 580 | /*---------------------------------------------------------------*/
|
|---|
| 581 |
|
|---|
| 582 |
|
|---|
| 583 | static void arrow_mag(double theta, double length)
|
|---|
| 584 | { /* angle is measured in degrees counter-clockwise from east */
|
|---|
| 585 | double x, y, dx, dy, mid_x, mid_y;
|
|---|
| 586 | double theta_offset;
|
|---|
| 587 |
|
|---|
| 588 | theta *= -1; /* display coords use inverse y */
|
|---|
| 589 |
|
|---|
| 590 | /* find the display coordinates of the middle of the cell */
|
|---|
| 591 | mid_x = col + (.5);
|
|---|
| 592 | mid_y = row + (.5);
|
|---|
| 593 |
|
|---|
| 594 | D_begin();
|
|---|
| 595 |
|
|---|
| 596 | /* tail */
|
|---|
| 597 | D_move_abs(mid_x, mid_y);
|
|---|
| 598 |
|
|---|
| 599 | /* head */
|
|---|
| 600 | x = mid_x + (length * cos(D2R(theta)));
|
|---|
| 601 | y = mid_y + (length * sin(D2R(theta)));
|
|---|
| 602 | D_cont_abs(x, y);
|
|---|
| 603 |
|
|---|
| 604 | /* fin 1 */
|
|---|
| 605 | theta_offset = theta + 20;
|
|---|
| 606 | dx = mid_x + (0.6 * length * cos(D2R(theta_offset)));
|
|---|
| 607 | dy = mid_y + (0.6 * length * sin(D2R(theta_offset)));
|
|---|
| 608 | D_cont_abs(dx, dy);
|
|---|
| 609 |
|
|---|
| 610 | /* fin 2 */
|
|---|
| 611 | D_move_abs(x, y);
|
|---|
| 612 | theta_offset = theta - 20;
|
|---|
| 613 | dx = mid_x + (0.6 * length * cos(D2R(theta_offset)));
|
|---|
| 614 | dy = mid_y + (0.6 * length * sin(D2R(theta_offset)));
|
|---|
| 615 | D_cont_abs(dx, dy);
|
|---|
| 616 |
|
|---|
| 617 | D_end();
|
|---|
| 618 | D_stroke();
|
|---|
| 619 | }
|
|---|
| 620 |
|
|---|
| 621 |
|
|---|
| 622 | static void arrow_360(double theta)
|
|---|
| 623 | { /* angle is measured in degrees counter-clockwise from east */
|
|---|
| 624 | double x, y, dx, dy, mid_x, mid_y;
|
|---|
| 625 | double max_radius, theta_offset;
|
|---|
| 626 |
|
|---|
| 627 | theta *= -1; /* display coords use inverse y */
|
|---|
| 628 | max_radius = 0.8 / 2;
|
|---|
| 629 |
|
|---|
| 630 | /* find the display coordinates of the middle of the cell */
|
|---|
| 631 | mid_x = col + (0.5);
|
|---|
| 632 | mid_y = row + (0.5);
|
|---|
| 633 |
|
|---|
| 634 | D_begin();
|
|---|
| 635 |
|
|---|
| 636 | /* head */
|
|---|
| 637 | x = mid_x + (max_radius * cos(D2R(theta)));
|
|---|
| 638 | y = mid_y + (max_radius * sin(D2R(theta)));
|
|---|
| 639 | D_move_abs(x, y);
|
|---|
| 640 |
|
|---|
| 641 | /* tail */
|
|---|
| 642 | dx = -2 * (max_radius * cos(D2R(theta)));
|
|---|
| 643 | dy = -2 * (max_radius * sin(D2R(theta)));
|
|---|
| 644 | D_cont_rel(dx, dy);
|
|---|
| 645 |
|
|---|
| 646 | /* fin 1 */
|
|---|
| 647 | D_move_abs(x, y);
|
|---|
| 648 | theta_offset = theta + 90;
|
|---|
| 649 | dx = mid_x + (0.5 * max_radius * cos(D2R(theta_offset)));
|
|---|
| 650 | dy = mid_y + (0.5 * max_radius * sin(D2R(theta_offset)));
|
|---|
| 651 | D_cont_abs(dx, dy);
|
|---|
| 652 |
|
|---|
| 653 | /* fin 2 */
|
|---|
| 654 | D_move_abs(x, y);
|
|---|
| 655 | theta_offset = theta - 90;
|
|---|
| 656 | dx = mid_x + (0.5 * max_radius * cos(D2R(theta_offset)));
|
|---|
| 657 | dy = mid_y + (0.5 * max_radius * sin(D2R(theta_offset)));
|
|---|
| 658 | D_cont_abs(dx, dy);
|
|---|
| 659 |
|
|---|
| 660 | D_end();
|
|---|
| 661 | D_stroke();
|
|---|
| 662 | }
|
|---|
| 663 |
|
|---|
| 664 | static void arrow_se(void)
|
|---|
| 665 | {
|
|---|
| 666 | double x = col + (.8);
|
|---|
| 667 | double y = row + (.8);
|
|---|
| 668 | D_begin();
|
|---|
| 669 | D_move_abs(x, y);
|
|---|
| 670 | D_cont_rel(((-.6)), (((-.6))));
|
|---|
| 671 | D_move_abs(x, y);
|
|---|
| 672 | D_cont_rel(0, ((-.4)));
|
|---|
| 673 | D_move_abs(x, y);
|
|---|
| 674 | D_cont_rel(((-.4)), 0);
|
|---|
| 675 | D_end();
|
|---|
| 676 | D_stroke();
|
|---|
| 677 | }
|
|---|
| 678 |
|
|---|
| 679 | static void arrow_ne(void)
|
|---|
| 680 | {
|
|---|
| 681 | double x = col + (.8);
|
|---|
| 682 | double y = row + (.2);
|
|---|
| 683 | D_begin();
|
|---|
| 684 | D_move_abs(x, y);
|
|---|
| 685 | D_cont_rel(((-.6)), (((.6))));
|
|---|
| 686 | D_move_abs(x, y);
|
|---|
| 687 | D_cont_rel(0, ((.4)));
|
|---|
| 688 | D_move_abs(x, y);
|
|---|
| 689 | D_cont_rel(((-.4)), 0);
|
|---|
| 690 | D_end();
|
|---|
| 691 | D_stroke();
|
|---|
| 692 | }
|
|---|
| 693 |
|
|---|
| 694 | static void arrow_nw(void)
|
|---|
| 695 | {
|
|---|
| 696 | double x = col + (.2);
|
|---|
| 697 | double y = row + (.2);
|
|---|
| 698 | D_begin();
|
|---|
| 699 | D_move_abs(x, y);
|
|---|
| 700 | D_cont_rel(((.6)), (((.6))));
|
|---|
| 701 | D_move_abs(x, y);
|
|---|
| 702 | D_cont_rel(0, ((.4)));
|
|---|
| 703 | D_move_abs(x, y);
|
|---|
| 704 | D_cont_rel(((.4)), 0);
|
|---|
| 705 | D_end();
|
|---|
| 706 | D_stroke();
|
|---|
| 707 | }
|
|---|
| 708 |
|
|---|
| 709 | static void arrow_sw(void)
|
|---|
| 710 | {
|
|---|
| 711 | double x = col + (.2);
|
|---|
| 712 | double y = row + (.8);
|
|---|
| 713 | D_begin();
|
|---|
| 714 | D_move_abs(x, y);
|
|---|
| 715 | D_cont_rel(((.6)), (((-.6))));
|
|---|
| 716 | D_move_abs(x, y);
|
|---|
| 717 | D_cont_rel(0, ((-.4)));
|
|---|
| 718 | D_move_abs(x, y);
|
|---|
| 719 | D_cont_rel(((.4)), 0);
|
|---|
| 720 | D_end();
|
|---|
| 721 | D_stroke();
|
|---|
| 722 | }
|
|---|
| 723 |
|
|---|
| 724 | static void arrow_e(void)
|
|---|
| 725 | {
|
|---|
| 726 | double x = col + (.9);
|
|---|
| 727 | double y = row + (.5);
|
|---|
| 728 | D_begin();
|
|---|
| 729 | D_move_abs(x, y);
|
|---|
| 730 | D_cont_rel(((-.8)), 0);
|
|---|
| 731 | D_move_abs(x, y);
|
|---|
| 732 | D_cont_rel(((-.3)), ((-.3)));
|
|---|
| 733 | D_move_abs(x, y);
|
|---|
| 734 | D_cont_rel(((-.3)), ((.3)));
|
|---|
| 735 | D_end();
|
|---|
| 736 | D_stroke();
|
|---|
| 737 | }
|
|---|
| 738 |
|
|---|
| 739 | static void arrow_w(void)
|
|---|
| 740 | {
|
|---|
| 741 | double x = col + (.1);
|
|---|
| 742 | double y = row + (.5);
|
|---|
| 743 | D_begin();
|
|---|
| 744 | D_move_abs(x, y);
|
|---|
| 745 | D_cont_rel(((.8)), 0);
|
|---|
| 746 | D_move_abs(x, y);
|
|---|
| 747 | D_cont_rel(((.3)), ((-.3)));
|
|---|
| 748 | D_move_abs(x, y);
|
|---|
| 749 | D_cont_rel(((.3)), ((.3)));
|
|---|
| 750 | D_end();
|
|---|
| 751 | D_stroke();
|
|---|
| 752 | }
|
|---|
| 753 |
|
|---|
| 754 | static void arrow_s(void)
|
|---|
| 755 | {
|
|---|
| 756 | double x = col + (.5);
|
|---|
| 757 | double y = row + (.9);
|
|---|
| 758 | D_begin();
|
|---|
| 759 | D_move_abs(x, y);
|
|---|
| 760 | D_cont_rel(0, ((-.8)));
|
|---|
| 761 | D_move_abs(x, y);
|
|---|
| 762 | D_cont_rel(((.3)), ((-.3)));
|
|---|
| 763 | D_move_abs(x, y);
|
|---|
| 764 | D_cont_rel(((-.3)), ((-.3)));
|
|---|
| 765 | D_end();
|
|---|
| 766 | D_stroke();
|
|---|
| 767 | }
|
|---|
| 768 |
|
|---|
| 769 | static void arrow_n(void)
|
|---|
| 770 | {
|
|---|
| 771 | double x = col + (.5);
|
|---|
| 772 | double y = row + (.1);
|
|---|
| 773 | D_begin();
|
|---|
| 774 | D_move_abs(x, y);
|
|---|
| 775 | D_cont_rel(0, ((.8)));
|
|---|
| 776 | D_move_abs(x, y);
|
|---|
| 777 | D_cont_rel(((.3)), ((.3)));
|
|---|
| 778 | D_move_abs(x, y);
|
|---|
| 779 | D_cont_rel(((-.3)), ((.3)));
|
|---|
| 780 | D_end();
|
|---|
| 781 | D_stroke();
|
|---|
| 782 | }
|
|---|
| 783 |
|
|---|
| 784 | static void draw_x(void)
|
|---|
| 785 | {
|
|---|
| 786 | double x = col;
|
|---|
| 787 | double y = row;
|
|---|
| 788 | D_begin();
|
|---|
| 789 | D_move_abs(x, y);
|
|---|
| 790 | D_cont_rel(1, 1);
|
|---|
| 791 | y = row + 1;
|
|---|
| 792 | D_move_abs(x, y);
|
|---|
| 793 | D_cont_rel(1, (-1));
|
|---|
| 794 | D_end();
|
|---|
| 795 | D_stroke();
|
|---|
| 796 | }
|
|---|
| 797 |
|
|---|
| 798 | static void unknown_(void)
|
|---|
| 799 | {
|
|---|
| 800 | double x = col + (.3);
|
|---|
| 801 | double y = row + (.4);
|
|---|
| 802 |
|
|---|
| 803 | D_begin();
|
|---|
| 804 | D_move_abs(x, y);
|
|---|
| 805 | D_cont_rel(0, ((-.15)));
|
|---|
| 806 | D_cont_rel(((.1)), ((-.1)));
|
|---|
| 807 | D_cont_rel(((.2)), 0);
|
|---|
| 808 | D_cont_rel(((.1)), ((.1)));
|
|---|
| 809 | D_cont_rel(0, ((.2)));
|
|---|
| 810 | D_cont_rel(((-.1)), ((.1)));
|
|---|
| 811 | D_cont_rel(((-.1)), 0);
|
|---|
| 812 | D_cont_rel(0, ((.25)));
|
|---|
| 813 | D_move_rel(0, ((.1)));
|
|---|
| 814 | D_cont_rel(0, ((.1)));
|
|---|
| 815 | D_end();
|
|---|
| 816 | D_stroke();
|
|---|
| 817 | }
|
|---|