main.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /****************************************************************************
  2. *
  3. * MODULE: d.northarrow
  4. *
  5. * AUTHOR(S): Hamish Bowman, Dunedin, NZ <hamish_b yahoo.com>
  6. *
  7. * PURPOSE: Displays a north arrow on graphics monitor
  8. *
  9. * COPYRIGHT: (C) 2013 by the GRASS Development Team
  10. *
  11. * This program is free software under the GNU General Public
  12. * License (>=v2). Read the file COPYING that comes with GRASS
  13. * for details.
  14. *
  15. *****************************************************************************/
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <unistd.h>
  19. #include <string.h>
  20. #include <math.h>
  21. #include <grass/gis.h>
  22. #include <grass/display.h>
  23. #include <grass/glocale.h>
  24. #include "options.h"
  25. int fg_color, bg_color, text_color;
  26. //int do_background = TRUE;
  27. int main(int argc, char **argv)
  28. {
  29. struct GModule *module;
  30. struct Option *bg_color_opt, *fg_color_opt, *coords, *n_arrow, *fsize,
  31. *width_opt, *rotation_opt, *lbl_opt, *text_color_opt;
  32. struct Flag *no_text, *rotate_text, *rads;
  33. double east, north;
  34. double rotation;
  35. double fontsize, line_width;
  36. int rot_with_text;
  37. /* Initialize the GIS calls */
  38. G_gisinit(argv[0]);
  39. module = G_define_module();
  40. G_add_keyword(_("display"));
  41. G_add_keyword(_("cartography"));
  42. module->description =
  43. _("Displays a north arrow on the graphics monitor.");
  44. n_arrow = G_define_option();
  45. n_arrow->key = "style";
  46. n_arrow->description = _("North arrow style");
  47. n_arrow->options =
  48. "1a,1b,2,3,4,5,6,7a,7b,8a,8b,9,fancy_compass,basic_compass,arrow1,arrow2,arrow3,star";
  49. G_asprintf((char **)&(n_arrow->descriptions),
  50. "1a;%s;" "1b;%s;" "2;%s;" "3;%s;" "4;%s;" "5;%s;" "6;%s;"
  51. "7a;%s;" "7b;%s;" "8a;%s;" "8b;%s;" "9;%s;" "fancy_compass;%s;"
  52. "basic_compass;%s;" "arrow1;%s;" "arrow2;%s;" "arrow3;%s;"
  53. "star;%s;",
  54. _("Two color arrowhead"),
  55. _("Two color arrowhead with circle"),
  56. _("Narrow with blending N"), _("Long with small arrowhead"),
  57. _("Inverted narrow inside a circle"),
  58. _("Triangle and N inside a circle"),
  59. _("Arrowhead and N inside a circle"),
  60. _("Tall half convex arrowhead"),
  61. _("Tall half concave arrowhead"), _("Thin arrow in a circle"),
  62. _("Fat arrow in a circle"), _("One color arrowhead"),
  63. _("Fancy compass"), _("Basic compass"), _("Simple arrow"),
  64. _("Thin arrow"), _("Fat arrow"), _("4-point star"));
  65. n_arrow->answer = "1a";
  66. n_arrow->guisection = _("Style");
  67. n_arrow->gisprompt = "old,northarrow,northarrow";
  68. coords = G_define_option();
  69. coords->key = "at";
  70. coords->key_desc = "x,y";
  71. coords->type = TYPE_DOUBLE;
  72. coords->answer = "85.0,15.0";
  73. coords->options = "0-100";
  74. coords->label =
  75. _("Screen coordinates of the rectangle's top-left corner");
  76. coords->description = _("(0,0) is lower-left of the display frame");
  77. rotation_opt = G_define_option();
  78. rotation_opt->key = "rotation";
  79. rotation_opt->type = TYPE_DOUBLE;
  80. rotation_opt->required = NO;
  81. rotation_opt->answer = "0";
  82. rotation_opt->description =
  83. _("Rotation angle in degrees (counter-clockwise)");
  84. lbl_opt = G_define_option();
  85. lbl_opt->key = "label";
  86. lbl_opt->required = NO;
  87. lbl_opt->answer = "N";
  88. lbl_opt->description =
  89. _("Displayed letter on the top of arrow");
  90. lbl_opt->guisection = _("Text");
  91. fg_color_opt = G_define_standard_option(G_OPT_CN);
  92. fg_color_opt->label = _("Line color");
  93. fg_color_opt->guisection = _("Colors");
  94. bg_color_opt = G_define_standard_option(G_OPT_CN);
  95. bg_color_opt->key = "fill_color";
  96. bg_color_opt->label = _("Fill color");
  97. bg_color_opt->guisection = _("Colors");
  98. text_color_opt = G_define_standard_option(G_OPT_C);
  99. text_color_opt->key = "text_color";
  100. text_color_opt->label = _("Text color");
  101. text_color_opt->answer = NULL;
  102. text_color_opt->guisection = _("Colors");
  103. width_opt = G_define_option();
  104. width_opt->key = "width";
  105. width_opt->type = TYPE_DOUBLE;
  106. width_opt->answer = "0";
  107. width_opt->description = _("Line width");
  108. fsize = G_define_option();
  109. fsize->key = "fontsize";
  110. fsize->type = TYPE_DOUBLE;
  111. fsize->required = NO;
  112. fsize->answer = "14";
  113. fsize->options = "1-360";
  114. fsize->description = _("Font size");
  115. fsize->guisection = _("Text");
  116. no_text = G_define_flag();
  117. no_text->key = 't';
  118. no_text->description = _("Draw the symbol without text");
  119. no_text->guisection = _("Text");
  120. rotate_text = G_define_flag();
  121. rotate_text->key = 'w';
  122. rotate_text->description = _("Do not rotate text with symbol");
  123. rotate_text->guisection = _("Text");
  124. rads = G_define_flag();
  125. rads->key = 'r';
  126. rads->description = _("Use radians instead of degrees for rotation");
  127. /* TODO:
  128. - add a -n flag to rotate to match true north instead of grid north.
  129. Similar to 'g.region -n' but use the at=x,y coord for the convergence
  130. angle calc. (assuming that's the center of the icon)
  131. */
  132. if (G_parser(argc, argv))
  133. exit(EXIT_FAILURE);
  134. sscanf(coords->answers[0], "%lf", &east);
  135. sscanf(coords->answers[1], "%lf", &north);
  136. fontsize = atof(fsize->answer);
  137. if (no_text->answer)
  138. fontsize = -1;
  139. rot_with_text = 0;
  140. if (!rotate_text->answer)
  141. rot_with_text = 1;
  142. /* Convert to radians */
  143. rotation = atof(rotation_opt->answer);
  144. if (!rads->answer)
  145. rotation *= M_PI / 180.0;
  146. rotation = fmod(rotation, 2.0 * M_PI);
  147. if (rotation < 0.0)
  148. rotation += 2.0 * M_PI;
  149. /* Parse and select foreground color */
  150. fg_color = D_parse_color(fg_color_opt->answer, 1);
  151. /* Parse and select background color */
  152. bg_color = D_parse_color(bg_color_opt->answer, 1);
  153. /* Parse and select text color */
  154. if (text_color_opt->answer)
  155. text_color = D_parse_color(text_color_opt->answer, 0);
  156. else if (strcmp(fg_color_opt->answer, "none") != 0)
  157. text_color = D_parse_color(fg_color_opt->answer, 1);
  158. else if (strcmp(bg_color_opt->answer, "none") != 0)
  159. text_color = D_parse_color(bg_color_opt->answer, 1);
  160. else
  161. text_color = 0;
  162. line_width = atof(width_opt->answer);
  163. if (line_width < 0)
  164. line_width = 0;
  165. else if (line_width > 72)
  166. line_width = 72;
  167. D_open_driver();
  168. draw_n_arrow(east, north, rotation, lbl_opt->answer, rot_with_text,
  169. fontsize, n_arrow->answer, line_width);
  170. D_save_command(G_recreate_command());
  171. D_close_driver();
  172. exit(EXIT_SUCCESS);
  173. }