[GRASS-SVN] r68502 - grass/trunk/display/d.northarrow
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue May 24 10:43:27 PDT 2016
Author: annakrat
Date: 2016-05-24 10:43:27 -0700 (Tue, 24 May 2016)
New Revision: 68502
Modified:
grass/trunk/display/d.northarrow/draw_n_arrow.c
grass/trunk/display/d.northarrow/main.c
grass/trunk/display/d.northarrow/options.h
Log:
d.northarrow: improvements - rotate by angle, change label, rotate label, add other existing symbols - see #3019, #3018, #3031, author Adam Laza
Modified: grass/trunk/display/d.northarrow/draw_n_arrow.c
===================================================================
--- grass/trunk/display/d.northarrow/draw_n_arrow.c 2016-05-24 17:16:11 UTC (rev 68501)
+++ grass/trunk/display/d.northarrow/draw_n_arrow.c 2016-05-24 17:43:27 UTC (rev 68502)
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <string.h>
+#include <math.h>
#include <grass/gis.h>
#include <grass/display.h>
#include <grass/symbol.h>
@@ -11,12 +12,13 @@
#include <grass/glocale.h>
#include "options.h"
-int draw_n_arrow(double east, double north, double fontsize,
- char *n_arrow_num, double line_width)
+int draw_n_arrow(double east, double north, double rotation, char *lbl,
+ int rot_with_text, double fontsize, char *n_arrow_num,
+ double line_width)
{
double x_pos, y_pos;
double t, b, l, r;
- double tt, tb, tl, tr; /* text box*/
+ double tt, tb, tl, tr; /* text box */
SYMBOL *Symb;
RGBA_Color *line_color, *fill_color;
@@ -28,7 +30,7 @@
/* Establish text size */
if (fontsize > 0)
- D_text_size(fontsize, fontsize);
+ D_text_size(fontsize, fontsize);
D_setup_unity(0);
D_get_src(&t, &b, &l, &r);
@@ -37,48 +39,74 @@
y_pos = (100. - north) * (b - t) / 100.;
if (line_width > 0)
- D_line_width(line_width);
+ D_line_width(line_width);
if (fontsize > 0) {
- /* draw the "N" */
- D_get_text_box("N", &tt, &tb, &tl, &tr);
- D_use_color(fg_color);
+ /* draw the label (default "N") */
+ if (rot_with_text)
+ D_text_rotation(rotation * 180.0 / M_PI);
+ D_get_text_box(lbl, &tt, &tb, &tl, &tr);
+ D_use_color(fg_color);
- /* positions manually tuned */
- switch (n_arrow_num[0]) {
- case '1':
- D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 45);
- D_text("N");
- break;
- case '3':
- D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 60);
- D_text("N");
- break;
- case '4':
- D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 45);
- D_text("N");
- break;
- case '7':
- D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 70);
- D_text("N");
- break;
- case '9':
- case 'f':
- D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 55);
- D_text("N");
- break;
- case 'b':
- D_pos_abs(x_pos - (tr + tl) / 2, y_pos - 48.5);
- D_text("N");
- break;
- case '2':
- case '5':
- case '6':
- case '8':
- break;
- default:
- G_fatal_error(_("Could not parse symbol"));
- }
+ /* positions manually tuned */
+ switch (n_arrow_num[0]) {
+ case '1':
+ D_pos_abs(x_pos - sin(rotation) * 50 - (tr + tl) / 2,
+ y_pos - cos(rotation) * 50 - (tb + tt) / 2);
+ D_text(lbl);
+ break;
+ case '3':
+ D_pos_abs(x_pos - sin(rotation) * 60 - (tr + tl) / 2,
+ y_pos - cos(rotation) * 60 - (tb + tt) / 2);
+ D_text(lbl);
+ break;
+ case '4':
+ D_pos_abs(x_pos - sin(rotation) * 45 - (tr + tl) / 2,
+ y_pos - cos(rotation) * 45 - (tb + tt) / 2);
+ D_text(lbl);
+ break;
+ case '7':
+ D_pos_abs(x_pos - sin(rotation) * 70 - (tr + tl) / 2,
+ y_pos - cos(rotation) * 70 - (tb + tt) / 2);
+ D_text(lbl);
+ break;
+ case '8':
+ D_pos_abs(x_pos - sin(rotation) * 60 - (tr + tl) / 2,
+ y_pos - cos(rotation) * 60 - (tb + tt) / 2);
+ D_text(lbl);
+ break;
+ case '9':
+ D_pos_abs(x_pos - sin(rotation) * 55 - (tr + tl) / 2,
+ y_pos - cos(rotation) * 55 - (tb + tt) / 2);
+ D_text(lbl);
+ break;
+ case 'f':
+ D_pos_abs(x_pos - sin(rotation) * 55 - (tr + tl) / 2,
+ y_pos - cos(rotation) * 55 - (tb + tt) / 2);
+ D_text(lbl);
+ break;
+ case 'b':
+ D_pos_abs(x_pos - sin(rotation) * 48.5 - (tr + tl) / 2,
+ y_pos - cos(rotation) * 48.5 - (tb + tt) / 2);
+ D_text(lbl);
+ break;
+ case 'a':
+ D_pos_abs(x_pos - sin(rotation) * 50 - (tr + tl) / 2,
+ y_pos - cos(rotation) * 50 - (tb + tt) / 2);
+ D_text(lbl);
+ break;
+ case 's':
+ D_pos_abs(x_pos - sin(rotation) * 50 - (tr + tl) / 2,
+ y_pos - cos(rotation) * 50 - (tb + tt) / 2);
+ D_text(lbl);
+ break;
+ case '2':
+ case '5':
+ case '6':
+ break;
+ default:
+ G_fatal_error(_("Could not parse symbol"));
+ }
}
/* display the north arrow symbol */
@@ -86,82 +114,99 @@
fill_color = G_malloc(sizeof(RGBA_Color));
if (D_color_number_to_RGB(fg_color, &R, &G, &B) == 0)
- /* fall back to black on failure */
- G_str_to_color(DEFAULT_FG_COLOR, &R, &G, &B);
+ /* fall back to black on failure */
+ G_str_to_color(DEFAULT_FG_COLOR, &R, &G, &B);
line_color->r = (unsigned char)R;
line_color->g = (unsigned char)G;
line_color->b = (unsigned char)B;
line_color->a = RGBA_COLOR_OPAQUE;
if (D_color_number_to_RGB(bg_color, &R, &G, &B) == 0)
- /* fall back to black on failure */
- G_str_to_color(DEFAULT_FG_COLOR, &R, &G, &B);
+ /* fall back to black on failure */
+ G_str_to_color(DEFAULT_FG_COLOR, &R, &G, &B);
fill_color->r = (unsigned char)R;
fill_color->g = (unsigned char)G;
fill_color->b = (unsigned char)B;
fill_color->a = RGBA_COLOR_OPAQUE;
if (n_arrow_num[0] == '2' || n_arrow_num[0] == '9')
- fill_color->a = RGBA_COLOR_TRANSPARENT;
+ fill_color->a = RGBA_COLOR_TRANSPARENT;
/* sizes manually tuned */
switch (n_arrow_num[0]) {
case '1':
- symbol_size = 35.;
- break;
+ symbol_size = 35.;
+ break;
case '2':
- symbol_size = 19.;
- break;
+ symbol_size = 19.;
+ break;
case '3':
- symbol_size = 20.;
- break;
+ symbol_size = 20.;
+ break;
case '4':
- symbol_size = 15.;
- break;
+ symbol_size = 15.;
+ break;
case '5':
case '6':
- symbol_size = 14.;
- break;
+ symbol_size = 14.;
+ break;
case '7':
- symbol_size = 23.;
- break;
+ symbol_size = 23.;
+ break;
case '8':
case '9':
- symbol_size = 17.;
- break;
+ symbol_size = 17.;
+ break;
case 'b':
- symbol_size = 80.;
- break;
+ symbol_size = 80.;
+ break;
case 'f':
- symbol_size = 100.;
- break;
+ symbol_size = 100.;
+ break;
+ case 'a':
+ if (n_arrow_num[5] == '2')
+ symbol_size = 53.;
+ else
+ symbol_size = 70.;
+ break;
+ case 's':
+ symbol_size = 80.;
+ break;
default:
- G_fatal_error(_("Could not parse symbol"));
+ G_fatal_error(_("Could not parse symbol"));
}
x0 = D_d_to_u_col(x_pos);
y0 = D_d_to_u_row(y_pos);
if (n_arrow_num[0] == 'b')
- strcpy(icon, "n_arrows/basic_compass");
+ strcpy(icon, "n_arrows/basic_compass");
else if (n_arrow_num[0] == 'f')
- strcpy(icon, "n_arrows/fancy_compass");
+ strcpy(icon, "n_arrows/fancy_compass");
+ else if (n_arrow_num[0] == 'a' && n_arrow_num[5] == '1')
+ strcpy(icon, "basic/arrow1");
+ else if (n_arrow_num[0] == 'a' && n_arrow_num[5] == '2')
+ strcpy(icon, "basic/arrow2");
+ else if (n_arrow_num[0] == 'a' && n_arrow_num[5] == '3')
+ strcpy(icon, "basic/arrow3");
+ else if (n_arrow_num[0] == 's')
+ strcpy(icon, "extra/4pt_star");
else {
- strcpy(icon, "n_arrows/n_arrow");
- strncat(icon, n_arrow_num, 32);
+ strcpy(icon, "n_arrows/n_arrow");
+ strncat(icon, n_arrow_num, 32);
}
Symb = S_read(icon);
- if(!Symb)
- G_fatal_error(_("Could not read symbol \"%s\""), icon);
+ if (!Symb)
+ G_fatal_error(_("Could not read symbol \"%s\""), icon);
- S_stroke(Symb, symbol_size, 0.0, 0);
+ S_stroke(Symb, symbol_size, rotation * (180 / M_PI), 0);
D_symbol(Symb, x0, y0, line_color, fill_color);
if (line_width > 0)
- D_line_width(0);
+ D_line_width(0);
G_free(Symb);
G_free(line_color);
Modified: grass/trunk/display/d.northarrow/main.c
===================================================================
--- grass/trunk/display/d.northarrow/main.c 2016-05-24 17:16:11 UTC (rev 68501)
+++ grass/trunk/display/d.northarrow/main.c 2016-05-24 17:43:27 UTC (rev 68502)
@@ -1,3 +1,4 @@
+
/****************************************************************************
*
* MODULE: d.northarrow
@@ -18,6 +19,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <math.h>
#include <grass/gis.h>
#include <grass/display.h>
#include <grass/glocale.h>
@@ -30,10 +32,12 @@
{
struct GModule *module;
struct Option *bg_color_opt, *fg_color_opt, *coords, *n_arrow, *fsize,
- *width_opt;
- struct Flag *no_text;
+ *width_opt, *rotation_opt, *lbl_opt;
+ struct Flag *no_text, *rotate_text, *rads;
double east, north;
+ double rotation;
double fontsize, line_width;
+ int rot_with_text;
/* Initialize the GIS calls */
G_gisinit(argv[0]);
@@ -41,45 +45,34 @@
module = G_define_module();
G_add_keyword(_("display"));
G_add_keyword(_("cartography"));
- module->description = _("Displays a north arrow on the graphics monitor.");
+ module->description =
+ _("Displays a north arrow on the graphics monitor.");
n_arrow = G_define_option();
n_arrow->key = "style";
n_arrow->description = _("North arrow style");
- n_arrow->options = "1a,1b,2,3,4,5,6,7a,7b,8a,8b,9,fancy_compass,basic_compass";
- G_asprintf((char **) &(n_arrow->descriptions),
- "1a;%s;"
- "1b;%s;"
- "2;%s;"
- "3;%s;"
- "4;%s;"
- "5;%s;"
- "6;%s;"
- "7a;%s;"
- "7b;%s;"
- "8a;%s;"
- "8b;%s;"
- "9;%s;"
- "fancy_compass;%s;"
- "basic_compass;%s;",
+ n_arrow->options =
+ "1a,1b,2,3,4,5,6,7a,7b,8a,8b,9,fancy_compass,basic_compass,arrow1,arrow2,arrow3,star";
+ G_asprintf((char **)&(n_arrow->descriptions),
+ "1a;%s;" "1b;%s;" "2;%s;" "3;%s;" "4;%s;" "5;%s;" "6;%s;"
+ "7a;%s;" "7b;%s;" "8a;%s;" "8b;%s;" "9;%s;" "fancy_compass;%s;"
+ "basic_compass;%s;" "arrow1;%s;" "arrow2;%s;" "arrow3;%s;"
+ "star;%s;",
_("Two color arrowhead"),
_("Two color arrowhead with circle"),
- _("Narrow with blending N"),
- _("Long with small arrowhead"),
+ _("Narrow with blending N"), _("Long with small arrowhead"),
_("Inverted narrow inside a circle"),
_("Triangle and N inside a circle"),
_("Arrowhead and N inside a circle"),
_("Tall half convex arrowhead"),
- _("Tall half concave arrowhead"),
- _("Thin arrow in a circle"),
- _("Fat arrow in a circle"),
- _("One color arrowhead"),
- _("Fancy compass"),
- _("Basic compass"));
+ _("Tall half concave arrowhead"), _("Thin arrow in a circle"),
+ _("Fat arrow in a circle"), _("One color arrowhead"),
+ _("Fancy compass"), _("Basic compass"), _("Simple arrow"),
+ _("Thin arrow"), _("Fat arrow"), _("4-point star"));
n_arrow->answer = "1a";
n_arrow->guisection = _("Style");
n_arrow->gisprompt = "old,northarrow,northarrow";
-
+
coords = G_define_option();
coords->key = "at";
coords->key_desc = "x,y";
@@ -87,9 +80,25 @@
coords->answer = "85.0,15.0";
coords->options = "0-100";
coords->label =
- _("Screen coordinates of the rectangle's top-left corner");
+ _("Screen coordinates of the rectangle's top-left corner");
coords->description = _("(0,0) is lower-left of the display frame");
+ rotation_opt = G_define_option();
+ rotation_opt->key = "rotation";
+ rotation_opt->type = TYPE_DOUBLE;
+ rotation_opt->required = NO;
+ rotation_opt->answer = "0";
+ rotation_opt->description =
+ _("Rotation angle in degrees (counter-clockwise)");
+
+ lbl_opt = G_define_option();
+ lbl_opt->key = "label";
+ lbl_opt->required = NO;
+ lbl_opt->answer = "N";
+ lbl_opt->description =
+ _("Displayed letter on the top of arrow");
+ lbl_opt->guisection = _("Text");
+
fg_color_opt = G_define_standard_option(G_OPT_C);
fg_color_opt->label = _("Line color");
fg_color_opt->guisection = _("Colors");
@@ -114,39 +123,57 @@
fsize->options = "1-360";
fsize->description = _("Font size");
fsize->guisection = _("Text");
-
+
no_text = G_define_flag();
no_text->key = 't';
no_text->description = _("Draw the symbol without text");
no_text->guisection = _("Text");
-/* TODO:
- - add rotation= option to rotate the north arrow by an arbitrary amount.
- do a bit of trig to figure out where to put the "N" (and rotate it too).
- - add a -n flag to rotate to match true north instead of grid north.
+ rotate_text = G_define_flag();
+ rotate_text->key = 'w';
+ rotate_text->description = _("Do not rotate text with symbol");
+ rotate_text->guisection = _("Text");
+
+ rads = G_define_flag();
+ rads->key = 'r';
+ rads->description = _("Use radians instead of degrees for rotation");
+
+ /* TODO:
+ - add a -n flag to rotate to match true north instead of grid north.
Similar to 'g.region -n' but use the at=x,y coord for the convergence
angle calc. (assuming that's the center of the icon)
- */
+ */
if (G_parser(argc, argv))
- exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
-
sscanf(coords->answers[0], "%lf", &east);
sscanf(coords->answers[1], "%lf", &north);
fontsize = atof(fsize->answer);
if (no_text->answer)
- fontsize = -1;
+ fontsize = -1;
+ rot_with_text = 0;
+ if (!rotate_text->answer)
+ rot_with_text = 1;
+
+ /* Convert to radians */
+ rotation = atof(rotation_opt->answer);
+ if (!rads->answer)
+ rotation *= M_PI / 180.0;
+ rotation = fmod(rotation, 2.0 * M_PI);
+ if (rotation < 0.0)
+ rotation += 2.0 * M_PI;
+
/* Parse and select foreground color */
fg_color = D_parse_color(fg_color_opt->answer, 0);
/* Parse and select background color */
bg_color = D_parse_color(bg_color_opt->answer, 1);
if (bg_color == 0)
- do_background = FALSE;
+ do_background = FALSE;
line_width = atof(width_opt->answer);
if (line_width < 0)
@@ -154,12 +181,12 @@
else if (line_width > 72)
line_width = 72;
-
D_open_driver();
D_setup(0);
- draw_n_arrow(east, north, fontsize, n_arrow->answer, line_width);
+ draw_n_arrow(east, north, rotation, lbl_opt->answer, rot_with_text,
+ fontsize, n_arrow->answer, line_width);
D_save_command(G_recreate_command());
D_close_driver();
Modified: grass/trunk/display/d.northarrow/options.h
===================================================================
--- grass/trunk/display/d.northarrow/options.h 2016-05-24 17:16:11 UTC (rev 68501)
+++ grass/trunk/display/d.northarrow/options.h 2016-05-24 17:43:27 UTC (rev 68502)
@@ -5,4 +5,4 @@
extern int do_background;
/* draw_n_arrow.c */
-int draw_n_arrow(double, double, double, char *, double);
+int draw_n_arrow(double, double, double, char *, int, double, char *, double);
More information about the grass-commit
mailing list