Browse Source

add support for generating horizontal gradient legends, tweak tickbar style

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@60140 15284696-431f-4ddb-bdfa-cd5b030d7da7
Hamish Bowman 11 years ago
parent
commit
ca51406c6c
2 changed files with 112 additions and 54 deletions
  1. 13 9
      ps/ps.map/ps.map.html
  2. 99 45
      ps/ps.map/ps_fclrtbl.c

+ 13 - 9
ps/ps.map/ps.map.html

@@ -239,19 +239,20 @@ For a categorical (CELL) map the color table will create a legend displaying
 the colors for each of a raster map's category values along with its
 the colors for each of a raster map's category values along with its
 associated category label. For a floating point (FCELL or DCELL) map a
 associated category label. For a floating point (FCELL or DCELL) map a
 continuous gradient legend will be created.
 continuous gradient legend will be created.
-<p>If <b>raster</b> is omitted, the colortable defaults to the previously
+<p>
+If <b>raster</b> is omitted, the colortable defaults to the previously
 registered raster layer.
 registered raster layer.
-
+<p>
 The default location for the colortable is immediately below any other
 The default location for the colortable is immediately below any other
 map legend information, starting at the left margin.
 map legend information, starting at the left margin.
 The default text color is black.
 The default text color is black.
-
-Omitting the <b>colortable</b> instruction would result in
-no color table.
-<p>If the colortable is turned off with a &quot;<tt>colortable&nbsp;N</tt>&quot;
-instruction the <b>end</b> command should not be given as the  
+<p>
+Omitting the <b>colortable</b> instruction would result in no color table.
+If the colortable is turned off with a &quot;<tt>colortable&nbsp;N</tt>&quot;
+instruction the <b>end</b> command should not be given as the
 main command will be treated as a single line instruction.
 main command will be treated as a single line instruction.
-<p>See also the <a href="#vlegend">vlegend</a> command for creating vector map
+<p>
+See also the <a href="#vlegend">vlegend</a> command for creating vector map
 legends.
 legends.
 
 
 
 
@@ -266,7 +267,8 @@ raster map layers which have many categories, such as elevation.
 This could result in the printing of an extremely long color table!
 This could result in the printing of an extremely long color table!
 In this situation it is useful to use the <b>discrete N</b> instruction
 In this situation it is useful to use the <b>discrete N</b> instruction
 to force a continuous color gradient legend.
 to force a continuous color gradient legend.
-<p>Be aware that the color table only includes categories which
+<p>
+Be aware that the color table only includes categories which
 have a label. You can use the <em>r.category</em> module to add labels.
 have a label. You can use the <em>r.category</em> module to add labels.
 
 
 
 
@@ -283,6 +285,8 @@ then this label will be displayed.
 
 
 For floating point legends <b>width</b> is width of color
 For floating point legends <b>width</b> is width of color
 band only. <b>height</b> is used only for floating point legend.
 band only. <b>height</b> is used only for floating point legend.
+A horizontal gradient legend can be achieved by setting the legend
+width greater than its height.
 
 
 Adding the <b>tickbar Y</b> instruction will change the tick mark style
 Adding the <b>tickbar Y</b> instruction will change the tick mark style
 so that ticks are drawn across the color table instead of protruding out 
 so that ticks are drawn across the color table instead of protruding out 

+ 99 - 45
ps/ps.map/ps_fclrtbl.c

@@ -25,8 +25,8 @@ int PS_fcolortable(void)
     int i, k;
     int i, k;
     int R, G, B;
     int R, G, B;
     DCELL dmin, dmax, val;
     DCELL dmin, dmax, val;
-    double t, l;		/* legend top, left, right */
-    double x1, x2, y, dy, xu, yu;
+    double t, l;		/* legend top, left */
+    double x1, x2, y1, y2, x, y, dy, xu, yu;
     double width;		/* width of legend in map units */
     double width;		/* width of legend in map units */
     double height;		/* width of legend in map units */
     double height;		/* width of legend in map units */
     double cwidth;		/* width of one color line */
     double cwidth;		/* width of one color line */
@@ -37,7 +37,7 @@ int PS_fcolortable(void)
     struct Colors colors;
     struct Colors colors;
     struct FPRange range;
     struct FPRange range;
     double ex, cur_d, cur_ex;
     double ex, cur_d, cur_ex;
-    int do_color;
+    int do_color, horiz = FALSE;
     double grey_color_val, margin;
     double grey_color_val, margin;
     unsigned int max_label_length = 0;
     unsigned int max_label_length = 0;
     int label_posn, label_xref, label_yref;
     int label_posn, label_xref, label_yref;
@@ -119,14 +119,30 @@ int PS_fcolortable(void)
     width = 72.0 * ct.width;
     width = 72.0 * ct.width;
     height = 72.0 * ct.height;
     height = 72.0 * ct.height;
     cwidth = 0.1;
     cwidth = 0.1;
-    ncols = (int)height / cwidth;
+
+    if (width > height) {
+	horiz = TRUE;
+	ncols = (int)width / cwidth;
+	dy *= 1.4;  /* leave a bit more space so the tick labels don't overlap */
+    }
+    else
+	ncols = (int)height / cwidth;
+
     step = (dmax - dmin) / (ncols - 1);
     step = (dmax - dmin) / (ncols - 1);
-    lwidth = ct.lwidth;
+    lwidth = ct.lwidth;  /* line width */
 
 
     /* Print color band */
     /* Print color band */
-    y = t;
-    x1 = l;
-    x2 = x1 + width;
+    if (horiz) {
+	x = l + width;
+	y1 = t + height;
+	y2 = t;
+    }
+    else {  /* vertical */
+	y = t;
+	x1 = l;
+	x2 = x1 + width;
+    }
+
     fprintf(PS.fp, "%.8f W\n", cwidth);
     fprintf(PS.fp, "%.8f W\n", cwidth);
 
 
     for (i = 0; i < ncols; i++) {
     for (i = 0; i < ncols; i++) {
@@ -144,19 +160,33 @@ int PS_fcolortable(void)
 	}
 	}
 
 
 	fprintf(PS.fp, "NP\n");
 	fprintf(PS.fp, "NP\n");
-	fprintf(PS.fp, "%f %f M\n", x1, y);
-	fprintf(PS.fp, "%f %f LN\n", x2, y);
+	if (horiz) {
+	    fprintf(PS.fp, "%f %f M\n", x, y1);
+	    fprintf(PS.fp, "%f %f LN\n", x, y2);
+	    x -= cwidth;
+	}
+	else {  /* vertical */
+	    fprintf(PS.fp, "%f %f M\n", x1, y);
+	    fprintf(PS.fp, "%f %f LN\n", x2, y);
+	    y -= cwidth;
+	}
 	fprintf(PS.fp, "D\n");
 	fprintf(PS.fp, "D\n");
-	y -= cwidth;
     }
     }
 
 
     /* Frame around */
     /* Frame around */
     fprintf(PS.fp, "NP\n");
     fprintf(PS.fp, "NP\n");
     set_ps_color(&ct.color);
     set_ps_color(&ct.color);
     fprintf(PS.fp, "%.8f W\n", lwidth);
     fprintf(PS.fp, "%.8f W\n", lwidth);
-    fprintf(PS.fp, "%f %f %f %f B\n", x1,
-	    t - (ncols - 1) * cwidth - (cwidth + lwidth) / 2, x2,
-	    t + (cwidth + lwidth) / 2);
+    if (horiz) {
+	fprintf(PS.fp, "%f %f %f %f B\n",
+		l + width + (cwidth + lwidth) / 2, y1,
+		l + width - (ncols - 1) * cwidth - (cwidth + lwidth) / 2, y2);
+    }
+    else {
+	fprintf(PS.fp, "%f %f %f %f B\n", x1,
+		t - (ncols - 1) * cwidth - (cwidth + lwidth) / 2, x2,
+		t + (cwidth + lwidth) / 2);
+    }
     fprintf(PS.fp, "D\n");
     fprintf(PS.fp, "D\n");
 
 
     /* Print labels */
     /* Print labels */
@@ -198,14 +228,25 @@ int PS_fcolortable(void)
     if (val < dmin)
     if (val < dmin)
 	val += step;
 	val += step;
 
 
-    x1 = l + width + 0.1;
-    if (ct.tickbar)		/* switch to draw tic all the way through bar */
-	x2 = x1 - width;
+    if (horiz) {
+	y2 = t - 0.37 * height;
+	if (height > 36)
+	    y2 = t - 0.37 * 36;
+
+	if (ct.tickbar)		/* this is the switch to draw tic all the way through bar */
+	    y1 = t + height;
+	else
+	    y1 = t;
+    }
     else {
     else {
+	x1 = l + width + 0.1;
 	x2 = x1 + 0.37 * width;
 	x2 = x1 + 0.37 * width;
 	if (width > 36)
 	if (width > 36)
 	    x2 = x1 + 0.37 * 36;
 	    x2 = x1 + 0.37 * 36;
-    }    
+
+	if (ct.tickbar)
+	    x1 -= width;
+    }
 
 
     /* do nice label: we need so many decimal places to hold all step decimal digits */
     /* do nice label: we need so many decimal places to hold all step decimal digits */
     if (step > 100) {		/* nice steps do not have > 2 digits, important separate, otherwise */
     if (step > 100) {		/* nice steps do not have > 2 digits, important separate, otherwise */
@@ -221,12 +262,22 @@ int PS_fcolortable(void)
     }
     }
 
 
     fprintf(PS.fp, "%.8f W\n", lwidth);
     fprintf(PS.fp, "%.8f W\n", lwidth);
+
     while (val <= dmax) {
     while (val <= dmax) {
-	/*      y = t - (val - dmin) * height / (dmax - dmin) ;  flip */
-	y = t - (dmax - val) * height / (dmax - dmin);
 	fprintf(PS.fp, "NP\n");
 	fprintf(PS.fp, "NP\n");
-	fprintf(PS.fp, "%f %f M\n", x1, y);
-	fprintf(PS.fp, "%f %f LN\n", x2, y);
+
+	if (horiz) {
+	    x = l + width - (dmax - val) * width / (dmax - dmin);
+	    fprintf(PS.fp, "%f %f M\n", x, y1);
+	    fprintf(PS.fp, "%f %f LN\n", x, y2);
+	}
+	else {
+	    /*  y = t - (val - dmin) * height / (dmax - dmin) ;   *** flip */
+	    y = t - (dmax - val) * height / (dmax - dmin);
+	    fprintf(PS.fp, "%f %f M\n", x1, y);
+	    fprintf(PS.fp, "%f %f LN\n", x2, y);
+	}
+
 	fprintf(PS.fp, "D\n");
 	fprintf(PS.fp, "D\n");
 
 
 	sprintf(buf, "%f", val);
 	sprintf(buf, "%f", val);
@@ -236,16 +287,17 @@ int PS_fcolortable(void)
 	    ch++;
 	    ch++;
 	*ch = '\0';
 	*ch = '\0';
 
 
-	if (ct.tickbar)		/* switch to draw tic all the way through bar */
-	    fprintf(PS.fp, "(%s) %f %f MS\n", buf, x1 + 0.2 * ct.fontsize,
-		    y - 0.35 * ct.fontsize);
+	if(strlen(buf) > max_label_length)
+	    max_label_length = strlen(buf);
+
+	if (horiz)
+	    fprintf(PS.fp, "(%s) %f %f MS\n", buf,
+		    x + 0.2 * ct.fontsize - (strlen(buf) * 0.37 * ct.fontsize),
+		    y2 - 1.15 * ct.fontsize);
 	else
 	else
 	    fprintf(PS.fp, "(%s) %f %f MS\n", buf, x2 + 0.2 * ct.fontsize,
 	    fprintf(PS.fp, "(%s) %f %f MS\n", buf, x2 + 0.2 * ct.fontsize,
 		    y - 0.35 * ct.fontsize);
 		    y - 0.35 * ct.fontsize);
 
 
-	if(strlen(buf) > max_label_length)
-	    max_label_length = strlen(buf);
-
 	val += step;
 	val += step;
     }
     }
 
 
@@ -269,10 +321,14 @@ int PS_fcolortable(void)
 	   `charpath` may overflow the maximum path length). */
 	   `charpath` may overflow the maximum path length). */
 
 
 	/* select label position */
 	/* select label position */
-	label_posn = 3;
+	if (horiz)
+	    label_posn = 5;
+	else
+	    label_posn = 3;
 	/*  1 2
 	/*  1 2
 	      3
 	      3
 	    5 4 */
 	    5 4 */
+
 	switch (label_posn) {
 	switch (label_posn) {
 	case 1:
 	case 1:
 	    /* above the tick numbers */
 	    /* above the tick numbers */
@@ -283,10 +339,7 @@ int PS_fcolortable(void)
 	    break;
 	    break;
 	case 2:
 	case 2:
 	    /* directly above the tick numbers */
 	    /* directly above the tick numbers */
-	    if (ct.tickbar)
-		xu = x1 + 0.2 * ct.fontsize;
-	    else
-		xu = x2 + 0.2 * ct.fontsize;
+	    xu = x2 + 0.2 * ct.fontsize;
 	    yu = t + 0.05*72;
 	    yu = t + 0.05*72;
 	    label_xref = LEFT;
 	    label_xref = LEFT;
 	    label_yref = LOWER;
 	    label_yref = LOWER;
@@ -294,34 +347,35 @@ int PS_fcolortable(void)
 	case 3:
 	case 3:
 	    /* to the right of the tick numbers */
 	    /* to the right of the tick numbers */
 	    xu = 0.15*72 + max_label_length * ct.fontsize * 0.5;
 	    xu = 0.15*72 + max_label_length * ct.fontsize * 0.5;
-	    if (ct.tickbar)
-		xu += x1;
-	    else
-		xu += x2;
+	    xu += x2;
 	    yu = t - height/2;
 	    yu = t - height/2;
 	    label_xref = LEFT;
 	    label_xref = LEFT;
 	    label_yref = CENTER;
 	    label_yref = CENTER;
 	    break;
 	    break;
 	case 4:
 	case 4:
 	    /* directly below the tick numbers */
 	    /* directly below the tick numbers */
-	    if (ct.tickbar)
-		xu = x1 + 0.2 * ct.fontsize;
-	    else
-		xu = x2 + 0.2 * ct.fontsize;
+	    xu = x2 + 0.2 * ct.fontsize;
 	    yu = t - height - 0.05*72;
 	    yu = t - height - 0.05*72;
 	    label_xref = LEFT;
 	    label_xref = LEFT;
 	    label_yref = UPPER;
 	    label_yref = UPPER;
 	    break;
 	    break;
 	case 5:
 	case 5:
 	    /* below the tick numbers */
 	    /* below the tick numbers */
-	    xu = x1;
-	    yu = t - height - 0.05*72;
-	    label_xref = LEFT;
+	    if (horiz) {
+		xu = l + width/2.;
+		yu = y2 - 1.85 * ct.fontsize;
+		label_xref = CENTER;
+	    }
+	    else {
+		xu = x1;
+		yu = t - height - 0.05*72;
+		label_xref = LEFT;
+	    }
 	    label_yref = UPPER;
 	    label_yref = UPPER;
 	    break;
 	    break;
 	}
 	}
 
 
-	text_box_path( xu, yu, label_xref, label_yref, units, 0);
+	text_box_path(xu, yu, label_xref, label_yref, units, 0);
 	fprintf(PS.fp, "TIB\n");
 	fprintf(PS.fp, "TIB\n");
 	set_rgb_color(BLACK);
 	set_rgb_color(BLACK);
     }
     }