[GRASS-SVN] r45729 - in grass-addons/display: . d.barb

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Mar 23 03:52:15 EDT 2011


Author: hamish
Date: 2011-03-23 00:52:15 -0700 (Wed, 23 Mar 2011)
New Revision: 45729

Added:
   grass-addons/display/d.barb/
   grass-addons/display/d.barb/Makefile
   grass-addons/display/d.barb/description.html
   grass-addons/display/d.barb/draw.c
   grass-addons/display/d.barb/grid.c
   grass-addons/display/d.barb/legend.c
   grass-addons/display/d.barb/local_proto.h
   grass-addons/display/d.barb/main.c
   grass-addons/display/d.barb/points.c
Log:
+d.barb prototype

Added: grass-addons/display/d.barb/Makefile
===================================================================
--- grass-addons/display/d.barb/Makefile	                        (rev 0)
+++ grass-addons/display/d.barb/Makefile	2011-03-23 07:52:15 UTC (rev 45729)
@@ -0,0 +1,13 @@
+MODULE_TOPDIR = ../..
+
+PGM = d.barb
+
+LIBES     = $(VECTLIB) $(DBMILIB) $(SYMBLIB) $(DISPLAYLIB) $(RASTERLIB) $(GISLIB)
+DEPENDENCIES = $(VECTDEP) $(DBMIDEP) $(SYMBDEP) $(DISPLAYDEP) $(RASTERDEP) $(GISDEP)
+
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/display/d.barb/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass-addons/display/d.barb/description.html
===================================================================
--- grass-addons/display/d.barb/description.html	                        (rev 0)
+++ grass-addons/display/d.barb/description.html	2011-03-23 07:52:15 UTC (rev 45729)
@@ -0,0 +1,82 @@
+<h2>DESCRIPTION</h2>
+
+Draws arrows, straws, or wind barbs.
+Can use either raster or vector input maps, and either u,v velocity
+component or direction and magnitude input data.
+
+
+<h2>NOTES</h2>
+
+Cartesian aspect is measures in degreess CCW from the positive x-axis (east).
+Compass aspect is measures in degreess CW from north.
+<P>
+Rendering is scaled so largest stick covers 20% of the display frame
+for arrows and straws, use the scale parameter to adjust from there.
+<P>
+Wind barbs are all of equal length, but that length may be adjusted
+by the scale parameter.
+<P>
+Wind barbs assume velocity data is given in knots. Actually it
+doesn't care, but effectively maxes out at velo=150.
+<!--
+  units=
+  m/s    m_per_sec
+  km/hr  km_per_hr
+  mi/hr  mi_per_hr
+  knots  knots
+??
+-->
+
+
+<h2>EXAMPLES</h2>
+
+<h4>Eularian field from raster grid</h4>
+<div class="code"><pre>
+d.barb
+</pre></div>
+
+<h4>Sparse staion data from vector maps</h4>
+
+First prepare some dummy data, then plot it.
+<div class="code"><pre>
+# Spearfish dataset
+g.copy vect=bugsites,dummy_map
+v.db.addcol map=dummy_map \
+    columns='direction DOUBLE PRECISION, magnitude DOUBLE PRECISION'
+v.db.update dummy_map column=direction value='cat * 4.0'
+v.db.update dummy_map column=magnitude value='cat / 2.0'
+
+g.region -d
+d.barb input=dummy_map direction=direction magnitude=magnitude aspect=compass
+</pre></div>
+
+
+<h4>Create a legend</h4>
+<div class="code"><pre>
+d.graph << EOF
+ color 230:230:210
+ polygon
+  80 5
+  80 35
+  97 35
+  97 5
+EOF
+
+d.barb legend_velo=5,10,15,20,25 \
+   legend_at=90,30,90,25,90,20,90,15,90,10 \
+   color=black legend_fontsize=20 style=arrow
+</pre></div>
+
+
+
+<h2>SEE ALSO</h2>
+d.rast.arrow
+d.graph
+d.vect
+
+
+<h2>AUTHOR</h2>
+Hamish Bowman
+Dept Marine Science
+University of Otago
+


Property changes on: grass-addons/display/d.barb/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/display/d.barb/draw.c
===================================================================
--- grass-addons/display/d.barb/draw.c	                        (rev 0)
+++ grass-addons/display/d.barb/draw.c	2011-03-23 07:52:15 UTC (rev 45729)
@@ -0,0 +1,361 @@
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/display.h>
+#include <grass/symbol.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+#define PI M_PI
+#define RpD ((2 * M_PI) / 360.) 	/* radians/degree */
+#define D2R(d) (double)(d * RpD)	/* degrees->radians */
+
+
+/* draw a single barb at the given map coordinates */
+void draw_barb(double easting, double northing, double velocity,
+	       double compass_deg, int color, double scale, int style)
+{
+    G_debug(3, "in draw_barb()");
+
+    unknown_(150, 50);
+
+    R_standard_color(color);
+
+    R_move_abs((int)(D_u_to_d_col(easting) + 0.5),
+	       (int)(D_u_to_d_row(northing) + 0.5));
+
+    if (style != TYPE_BARB) {
+	if (velocity == velocity) /* ie not NaN */
+	    arrow_mag(easting, northing, compass_deg, velocity, style);
+	else
+	    arrow_360(easting, northing, compass_deg, TYPE_GRASS, scale, style);
+    }
+    else {
+	/* calc barb parameters */
+
+	/* draw barb bits */
+	draw_circle(easting, northing, 10.0, FALSE);
+	draw_feather(easting, northing, 10.0 /*radius*/, velocity, compass_deg);
+
+//      int i;
+//	for (i=0; i < 360; i+=20)
+//	    draw_feather(easting, northing, 20.0 /*radius*/, velocity, i);
+
+    }
+
+    return;
+}
+
+/* draw an arrow, with only direction */
+void arrow_360(double easting, double northing, double theta, int aspect_type,
+	       double scale, int style)
+{
+    arrow_mag(easting, northing, aspect_type == TYPE_GRASS ? theta : 90 - theta, scale, style);
+    return;
+}
+
+
+/* draw an arrow, with magnitude and direction */
+/* angle is measured in degrees counter-clockwise from east */
+void arrow_mag(double easting, double northing, double theta, double length, int style)
+{
+    double x, y, dx, dy, mid_x, mid_y;
+    double theta_offset;
+    int col, row;
+
+    G_debug(0, "in arrow_mag()");
+
+    //tmp init
+//    col = row = 0;
+col=(int)(D_u_to_d_col(easting) + 0.5);
+row=(int)(D_u_to_d_row(northing) + 0.5);
+G_debug(0, "  col=%d  row=%d", col, row);
+    theta *= -1;		/* display coords use inverse y */
+
+    /* find the display coordinates of the middle of the cell */
+    mid_x = col + (.5);
+    mid_y = row + (.5);
+
+    /* tail */
+    R_move_abs(mid_x, mid_y);
+
+    /* head */
+    x = mid_x + (length * cos(D2R(theta)));
+    y = mid_y + (length * sin(D2R(theta)));
+    R_cont_abs(x, y);
+
+
+    if (style == TYPE_ARROW) {
+	/* fin 1 */
+	theta_offset = theta + 20;
+	dx = mid_x + (0.6 * length * cos(D2R(theta_offset)));
+	dy = mid_y + (0.6 * length * sin(D2R(theta_offset)));
+	R_cont_abs(dx, dy);
+
+	/* fin 2 */
+	R_move_abs(x, y);
+	theta_offset = theta - 20;
+	dx = mid_x + (0.6 * length * cos(D2R(theta_offset)));
+	dy = mid_y + (0.6 * length * sin(D2R(theta_offset)));
+	R_cont_abs(dx, dy);
+    }
+}
+
+
+/* draw a grey '?' if data is non-sensical */
+// FIXME: change x,y to _east,north_ or %x %y of display _frame_
+void unknown_(int x, int y)
+{
+    // ref center,center
+    //    x = D_x + (int)(D_ew * .3);
+    //    y = D_y + (int)(D_ns * .4);
+
+//    int x, y;
+//    x = (int?)D_U_to_d_col(easting);
+//    y = D_u_to_d_row(northing);
+
+    R_standard_color(D_translate_color("grey"));
+    R_move_abs(x, y);
+    R_text_size(8, 8);
+    R_text("?");
+}
+
+/* put a "+" at the percentage of the display frame */
+void mark_the_spot(double perc_x, double perc_y)
+{
+    SYMBOL *Symb;
+    RGBA_Color *line_color, *fill_color;
+    int R,G,B;
+    int Xpx, Ypx;
+    int t, b, l, r;
+    int color;
+
+    line_color = G_malloc(sizeof(RGBA_Color));
+    fill_color = G_malloc(sizeof(RGBA_Color));
+    Symb = S_read( "basic/cross1" );
+
+    G_str_to_color("black", &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;
+//?
+//    R_RGB_color(R, G, B);
+
+    color = G_str_to_color("yellow", &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;
+
+    S_stroke( Symb, 6, 0, 0 );
+
+    D_get_screen_window(&t, &b, &l, &r);
+    Xpx = (int)((perc_x * (r - l) / 100.) + 0.5);
+    Ypx = (int)(((100. - perc_y) * (b - t) / 100.)+0.5);
+
+    D_symbol( Symb, Xpx, Ypx, line_color, fill_color );
+
+    return;
+}
+
+
+/* draws a circle at the map coords given by e,n.
+    radius is in display pixels, fill is boolean */
+/*** change fill to int=0-8 for cloud cover? ***/
+void draw_circle(double easting, double northing, double radius, int fill)
+{
+    int i, n;
+    double x, y, angle, step = 5.;
+    int *xi, *yi;
+
+    G_debug(4, "draw_circle()");
+
+    n = (int)(360 / step) + 1; /* number of vertices */
+
+    xi = G_calloc(n, sizeof(int));
+    yi = G_calloc(n, sizeof(int));
+/*
+    x = (int)round(D_u_to_d_col(easting));
+    y = (int)round(D_u_to_d_row(northing));
+    G_debug(0, "  x=%d  y=%d", (int)x, (int)y);
+
+    R_move_abs(x, y);
+    R_move_rel((int)(radius + 0.5), 0);
+*/
+
+    /* for loop moving around the circle */ 
+    for (i = 0; i <= n; i++) {
+	angle = D2R(step * i);
+	xi[i] = (int)round( D_u_to_d_col(easting) + radius * cos(angle) );
+	yi[i] = (int)round( D_u_to_d_row(northing) + radius * sin(angle) );
+	G_debug(5, "angle=%.2f   xi[%d]=%d  yi[%d]=%d", step*i, i, xi[i], i, yi[i]);
+    }
+
+    /* close it*/
+    xi[n] = xi[0];
+    yi[n] = yi[0];
+
+    if (fill)
+        R_polygon_abs(xi, yi, n);
+    else
+        R_polyline_abs(xi, yi, n);
+
+    G_free(xi);
+    G_free(yi);
+
+    return;
+}
+
+
+/* draws the stem and tail of a wind barb centered at e,n.
+    radius is scaling in display pixels, velocity is assumed as knots,
+    angle is cartesian convention CCW from positive x-axis */
+void draw_feather(double easting, double northing, double radius, double velocity,
+		  double compass_deg)
+{
+    double x, y, dx, dy, angle, rot_angle;
+    double stem_length = 5.;   /* length of tail */
+
+    G_debug(4, "draw_feather()");
+
+    /* barb points to FROM direction */
+    angle = compass_deg - 90;
+    if(angle < 0)
+	angle += 360;
+    else if(angle > 360)
+	angle -= 360;
+
+    rot_angle = angle + 60;
+        if(rot_angle < 0)
+	rot_angle += 360;
+    else if(rot_angle > 360)
+	rot_angle -= 360;
+
+    G_debug(5, "  compass_deg=%.2f   angle=%.2f   rot_angle=%.2f", compass_deg, angle, rot_angle);
+
+//D_line_width(2);
+
+    if (velocity < 5) {
+//	draw_circle(easting, northing, 2.0, TRUE);
+	draw_circle(easting, northing, 3*radius/4, FALSE);
+	return;
+    }
+
+
+//R_RGB_color(255, 0, 0);
+    /* move to head */
+    x = D_u_to_d_col(easting) + radius * cos(D2R(angle));
+    y = D_u_to_d_row(northing) + radius * sin(D2R(angle));
+    R_move_abs((int)round(x), (int)round(y));
+
+    /* draw to tail */
+    dx = D_u_to_d_col(easting) + stem_length * radius * cos(D2R(angle));
+    dy = D_u_to_d_row(northing) + stem_length * radius * sin(D2R(angle));
+    R_cont_abs((int)round(dx), (int)round(dy));
+
+//R_RGB_color(0, 255, 0);
+    /* TODO: simplify following into a loop */
+    if ( velocity >= 10 ) {
+	x = dx + radius*2 * cos(D2R(rot_angle));
+	y = dy + radius*2 * sin(D2R(rot_angle));
+	R_cont_abs((int)round(x), (int)round(y));
+    }
+    else if (velocity >= 5) {
+	x = dx + radius * cos(D2R(rot_angle));
+	y = dy + radius * sin(D2R(rot_angle));
+	R_cont_abs((int)round(x), (int)round(y));
+    }
+    else
+	return;
+
+//R_RGB_color(0, 0, 255);
+    if ( velocity >= 20 ) {
+	dx = D_u_to_d_col(easting) + (stem_length - 0.5) * radius * cos(D2R(angle));
+	dy = D_u_to_d_row(northing) + (stem_length - 0.5) * radius * sin(D2R(angle));
+	R_move_abs((int)round(dx), (int)round(dy));
+	x = dx + radius*2 * cos(D2R(rot_angle));
+	y = dy + radius*2 * sin(D2R(rot_angle));
+	R_cont_abs((int)round(x), (int)round(y));
+    }
+    else if (velocity >= 15) {
+    	dx = D_u_to_d_col(easting) + (stem_length - 0.5) * radius * cos(D2R(angle));
+	dy = D_u_to_d_row(northing) + (stem_length - 0.5) * radius * sin(D2R(angle));
+	R_move_abs((int)round(dx), (int)round(dy));
+	x = dx + radius * cos(D2R(rot_angle));
+	y = dy + radius * sin(D2R(rot_angle));
+	R_cont_abs((int)round(x), (int)round(y));
+    }
+    else
+	return;
+
+//R_RGB_color(0, 255, 255);
+    if ( velocity >= 30 ) {
+	dx = D_u_to_d_col(easting) + (stem_length - 1) * radius * cos(D2R(angle));
+	dy = D_u_to_d_row(northing) + (stem_length - 1) * radius * sin(D2R(angle));
+	R_move_abs((int)round(dx), (int)round(dy));
+	x = dx + radius*2 * cos(D2R(rot_angle));
+	y = dy + radius*2 * sin(D2R(rot_angle));
+	R_cont_abs((int)round(x), (int)round(y));
+    }
+    else if (velocity >= 25) {
+    	dx = D_u_to_d_col(easting) + (stem_length - 1) * radius * cos(D2R(angle));
+	dy = D_u_to_d_row(northing) + (stem_length - 1) * radius * sin(D2R(angle));
+	R_move_abs((int)round(dx), (int)round(dy));
+	x = dx + radius * cos(D2R(rot_angle));
+	y = dy + radius * sin(D2R(rot_angle));
+	R_cont_abs((int)round(x), (int)round(y));
+    }
+    else
+	return;
+
+//R_RGB_color(255, 255, 0);
+    if ( velocity >= 40 ) {
+	dx = D_u_to_d_col(easting) + (stem_length - 1.5) * radius * cos(D2R(angle));
+	dy = D_u_to_d_row(northing) + (stem_length - 1.5) * radius * sin(D2R(angle));
+	R_move_abs((int)round(dx), (int)round(dy));
+	x = dx + radius*2 * cos(D2R(rot_angle));
+	y = dy + radius*2 * sin(D2R(rot_angle));
+	R_cont_abs((int)round(x), (int)round(y));
+    }
+    else if (velocity >= 35) {
+    	dx = D_u_to_d_col(easting) + (stem_length - 1.5) * radius * cos(D2R(angle));
+	dy = D_u_to_d_row(northing) + (stem_length - 1.5) * radius * sin(D2R(angle));
+	R_move_abs((int)round(dx), (int)round(dy));
+	x = dx + radius * cos(D2R(rot_angle));
+	y = dy + radius * sin(D2R(rot_angle));
+	R_cont_abs((int)round(x), (int)round(y));
+    }
+    else
+	return;
+
+//R_RGB_color(255, 0, 255);
+    if ( velocity >= 50 ) {
+	/* beyond 50 kts gets a filled triangle (flag) at the end */
+// inner angle is same as barb lines, outer angle is equal but opposite
+	dx = D_u_to_d_col(easting) + (stem_length - 2) * radius * cos(D2R(angle));
+	dy = D_u_to_d_row(northing) + (stem_length - 2) * radius * sin(D2R(angle));
+	R_move_abs((int)round(dx), (int)round(dy));
+	x = dx + radius*2 * cos(D2R(rot_angle));
+	y = dy + radius*2 * sin(D2R(rot_angle));
+	R_cont_abs((int)round(x), (int)round(y));
+    }
+    else if (velocity >= 45) {
+    	dx = D_u_to_d_col(easting) + (stem_length - 2) * radius * cos(D2R(angle));
+	dy = D_u_to_d_row(northing) + (stem_length - 2) * radius * sin(D2R(angle));
+	R_move_abs((int)round(dx), (int)round(dy));
+	x = dx + radius * cos(D2R(rot_angle));
+	y = dy + radius * sin(D2R(rot_angle));
+	R_cont_abs((int)round(x), (int)round(y));
+    }
+    else
+	return;
+
+// ...
+
+/* beyond 100 kts gets two 50kt flags at the end */
+
+
+
+    return;
+}


Property changes on: grass-addons/display/d.barb/draw.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/display/d.barb/grid.c
===================================================================
--- grass-addons/display/d.barb/grid.c	                        (rev 0)
+++ grass-addons/display/d.barb/grid.c	2011-03-23 07:52:15 UTC (rev 45729)
@@ -0,0 +1,165 @@
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/display.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+
+/* load and plot barbs from data stored in two raster maps */
+void do_barb_grid(char *dir_u_map, char *mag_v_map, int is_component,
+		  int color, int aspect_type, double scale, int skip,
+		  int style)
+{
+    /* from d.rast.arrow */
+    struct FPRange range;
+    double mag_min, mag_max;
+    int dir_u_fd, mag_v_fd;
+    RASTER_MAP_TYPE dir_u_raster_type, mag_v_raster_type;
+    void *dir_u_raster_row, *mag_v_raster_row, *dir_u_ptr, *mag_v_ptr;
+    struct Cell_head window;
+    int nrows, ncols, row, col;
+    int no_arrow;		/* boolean */
+    float aspect_f = -1.0;
+    float length = -1.0;
+
+    G_debug(0, "Doing Eulerian field ...");
+    G_warning("Not working yet -- use d.rast.arrow instead.");
+
+    /* figure out arrow scaling */
+    G_init_fp_range(&range);	/* really needed? */
+    if (G_read_fp_range(mag_v_map, "", &range) != 1)
+	G_fatal_error(_("Problem reading range file"));
+    G_get_fp_range_min_max(&range, &mag_min, &mag_max);
+
+    scale *= 1.5 / fabs(mag_max);
+    G_debug(3, "scaling=%.2f  rast_max=%.2f", scale, mag_max);
+
+    // howto figure for u,v maps where max_mag is not known until combined in render step?
+
+
+    /* open the direction (or u-component) raster map */
+    dir_u_fd = G_open_cell_old(dir_u_map, "");
+    if (dir_u_fd < 0)
+	G_fatal_error(_("Unable to open raster map <%s>"), dir_u_map);
+    dir_u_raster_type = G_get_raster_map_type(dir_u_fd);
+
+    /* open the magnitude (or v-component) raster map */
+    mag_v_fd = G_open_cell_old(mag_v_map, "");
+    if (mag_v_fd < 0)
+	G_fatal_error(_("Unable to open raster map <%s>"), mag_v_map);
+    mag_v_raster_type = G_get_raster_map_type(mag_v_fd);
+
+
+    /* allocate the cell array */
+    dir_u_raster_row = G_allocate_raster_buf(dir_u_raster_type);
+    mag_v_raster_row = G_allocate_raster_buf(mag_v_raster_type);
+
+    /* number of rows and cols in region */
+    G_get_window(&window);
+    nrows = window.rows;
+    ncols = window.cols;
+
+    /* loop through cells, find value, determine direction (n,s,e,w,ne,se,sw,nw),
+       and call appropriate function to draw an arrow on the cell */
+
+    for (row = 0; row < nrows; row++) {
+	G_get_raster_row(dir_u_fd, dir_u_raster_row, row, dir_u_raster_type);
+	dir_u_ptr = dir_u_raster_row;
+
+	// should magnitude be manditory?
+	if (mag_v_map) {
+	    G_get_raster_row(mag_v_fd, mag_v_raster_row, row,
+			     mag_v_raster_type);
+	    mag_v_ptr = mag_v_raster_row;
+	}
+
+	for (col = 0; col < ncols; col++) {
+
+	    if (row % skip != 0)
+		no_arrow = TRUE;
+	    else
+		no_arrow = FALSE;
+
+	    if (col % skip != 0)
+		no_arrow = TRUE;
+
+	    /* find aspect direction based on cell value */
+	    if (dir_u_raster_type == CELL_TYPE)
+		aspect_f = *((CELL *) dir_u_ptr);
+	    else if (dir_u_raster_type == FCELL_TYPE)
+		aspect_f = *((FCELL *) dir_u_ptr);
+	    else if (dir_u_raster_type == DCELL_TYPE)
+		aspect_f = *((DCELL *) dir_u_ptr);
+
+
+	    if (mag_v_raster_type == CELL_TYPE)
+		length = *((CELL *) mag_v_ptr);
+	    else if (mag_v_raster_type == FCELL_TYPE)
+		length = *((FCELL *) mag_v_ptr);
+	    else if (mag_v_raster_type == DCELL_TYPE)
+		length = *((DCELL *) mag_v_ptr);
+
+	    length *= scale;
+
+	    if (G_is_null_value(mag_v_ptr, mag_v_raster_type)) {
+		G_debug(5, "Invalid arrow length [NULL]. Skipping.");
+		no_arrow = TRUE;
+	    }
+	    else if (length <= 0.0) {	/* use fabs() or theta+=180? */
+		G_debug(5, "Illegal arrow length [%.3f]. Skipping.", length);
+		no_arrow = TRUE;
+	    }
+
+	    if (no_arrow) {
+		dir_u_ptr =
+		    G_incr_void_ptr(dir_u_ptr,
+				    G_raster_size(dir_u_raster_type));
+		if (mag_v_map)
+		    mag_v_ptr =
+			G_incr_void_ptr(mag_v_ptr,
+					G_raster_size(mag_v_raster_type));
+		no_arrow = FALSE;
+		continue;
+	    }
+
+
+	   /** Now draw the arrows **/
+
+	    /* case switch for standard GRASS aspect map 
+	       measured in degrees counter-clockwise from east */
+	    R_standard_color(color);
+
+	    if (G_is_null_value(dir_u_ptr, dir_u_raster_type))
+		continue;
+	    else if (aspect_f >= 0.0 && aspect_f <= 360.0) {
+		if (mag_v_map) {
+		    if (aspect_type == TYPE_GRASS)
+			arrow_mag(3.,4., aspect_f, length, style);
+		    else
+			arrow_mag(3.,4., 90 - aspect_f, length, style);
+		}
+		else {
+		    if (aspect_type == TYPE_GRASS) ;	//todo                        arrow_360(aspect_f);
+		    else;	//  arrow_360(90 - aspect_f);
+		}
+	    }
+	    else {
+		R_standard_color(D_parse_color("grey", 0));
+		unknown_(10, 10);
+		R_standard_color(color);
+	    }
+
+
+	    dir_u_ptr =
+		G_incr_void_ptr(dir_u_ptr, G_raster_size(dir_u_raster_type));
+	    mag_v_ptr =
+		G_incr_void_ptr(mag_v_ptr, G_raster_size(mag_v_raster_type));
+	}
+    }
+
+    G_close_cell(dir_u_fd);
+    G_close_cell(mag_v_fd);
+
+    return;
+}


Property changes on: grass-addons/display/d.barb/grid.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/display/d.barb/legend.c
===================================================================
--- grass-addons/display/d.barb/legend.c	                        (rev 0)
+++ grass-addons/display/d.barb/legend.c	2011-03-23 07:52:15 UTC (rev 45729)
@@ -0,0 +1,66 @@
+#include <stdlib.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/display.h>
+#include <grass/raster.h>
+#include "local_proto.h"
+
+void do_legend(char **at_list, char **velo_list, int num_velos,
+	       double key_fontsize, int style, double scale, double peak,
+	       int color)
+{
+    double easting, northing, px, py, velo;
+    int Xpx, Ypx;
+    int t, b, l, r;
+    int i;
+    char buff[1024];
+
+    G_debug(1, "Doing legend ... (%d entries)", num_velos);
+
+    D_get_screen_window(&t, &b, &l, &r);
+
+    for (i = 0; i < num_velos; i++) {
+	px = atof(at_list[i * 2]);
+	py = atof(at_list[i * 2 + 1]);
+	velo = atof(velo_list[i]);
+
+	G_debug(4, "Legend entry: %.15g at [%.2f,%.2f]", velo, px, py);
+
+// frame percent, utm, display pixels, raster array coords.  all -> utm ?
+	/* convert screen percentage to east,north */
+// check if +.5 rounding is really needed
+
+	Xpx = (int)((px * (r - l) / 100.) + 0.5);
+	Ypx = (int)(((100. - py) * (b - t) / 100.)+0.5);
+	easting = D_d_to_u_col(Xpx);
+	northing = D_d_to_u_row(Ypx);
+
+	// actually this could stay in screen pixel coords...
+	//  anyway it should work if out-of-region (borders)
+
+	G_debug(5, "  (aka east=%.2f  north=%2.f)", easting, northing);
+	G_debug(5, "  (aka pixelX=%d  pixelY=%d)", Xpx, Ypx);
+
+
+	R_standard_color(color);
+	sprintf(buff, "%s", velo_list[i]);
+
+	/* Y: center justify: */
+	R_move_abs(Xpx, Ypx + key_fontsize/2);
+
+	/* X: right justify the text + 10px buffer: */
+ 	/* text width is 0.81 of text height? so even though we set width 
+           to txsiz with R_text_size(), we still have to reduce.. hmmm */
+	R_move_rel(-10 - (strlen(buff) * key_fontsize * 0.81), 0);
+	R_text_size(key_fontsize, key_fontsize);
+	R_text(buff);
+
+	/* arrow then starts at the given x-percent, to the right of the text */
+	R_move_abs(Xpx, Ypx + key_fontsize/2);
+	draw_barb(easting, northing, velo, 0.0, color, scale, style);
+
+    }
+
+    return;
+}
+


Property changes on: grass-addons/display/d.barb/legend.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/display/d.barb/local_proto.h
===================================================================
--- grass-addons/display/d.barb/local_proto.h	                        (rev 0)
+++ grass-addons/display/d.barb/local_proto.h	2011-03-23 07:52:15 UTC (rev 45729)
@@ -0,0 +1,33 @@
+//#include <grass/gis.h>
+#include <grass/Vect.h>
+
+/* aspect flavours */
+#define TYPE_GRASS 0
+#define TYPE_COMPASS 1
+
+/* barb flavours */
+#define TYPE_STRAW 0
+#define TYPE_BARB 1
+#define TYPE_ARROW 2
+
+/* grid.c */
+void do_barb_grid(char *, char *, int, int, int, double, int, int);
+
+/* points.c */
+void do_barb_points(char *, int, char *, char *, int, int, int, double, int);
+int count_pts_in_region(struct Map_info *);
+void fill_arrays(struct Map_info *, int, char *, char *, int, double *,
+		 double *, double *, double *);
+double max_magnitude(double *, int);
+
+/* draw.c */
+void draw_barb(double, double, double, double, int, double, int);
+void unknown_(int, int);
+void arrow_mag(double, double, double, double, int);
+void arrow_360(double, double, double, int, double, int);
+void mark_the_spot(double, double);
+void draw_circle(double, double, double, int);
+void draw_feather(double, double, double, double, double);
+
+/* legend.c */
+void do_legend(char **, char **, int, double, int, double, double, int);


Property changes on: grass-addons/display/d.barb/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/display/d.barb/main.c
===================================================================
--- grass-addons/display/d.barb/main.c	                        (rev 0)
+++ grass-addons/display/d.barb/main.c	2011-03-23 07:52:15 UTC (rev 45729)
@@ -0,0 +1,253 @@
+/*
+ * MODULE:      d.barb
+ *
+ * PURPOSE:     Draws wind barbs based on data from raster maps or a vector
+ *              points map with data stored as attributes in database column
+ *
+ * AUTHORS:     Hamish Bowman, Dunedin, New Zealand
+ *              Parts of code derived from d.rast.arrow and d.barscale.
+ *
+ * COPYRIGHT:   (c) 2008-2011 by Hamish Bowman, and The GRASS Development Team
+ *              This program is free software under the GNU General Public
+ *              License (>=v2). Read the file COPYING that comes with GRASS
+ *              for details.
+ */
+
+//#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/display.h>
+#include <grass/raster.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+
+int main(int argc, char *argv[])
+{
+
+    struct GModule *module;
+
+    struct Option *dir_opt, *magn_opt, *u_opt, *v_opt,
+	*color_opt, *type_opt, *skip_opt, *scale_opt,
+	*vinput_opt, *vlayer_opt, *style_opt, *keyat_opt,
+	*keyvelo_opt, *keyfont_opt, *peak_opt;
+
+    int color, aspect_type, skip, vlayer, style;
+    int is_vector, is_component;	/* boolean */
+    double scale, peak, key_fontsize;
+    char dir_u_map[GNAME_MAX], mag_v_map[GNAME_MAX];
+    int i, num_leg_at, num_leg_velo;
+
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("");
+    module->description = _("Draws flow barbs.");
+
+    dir_opt = G_define_standard_option(G_OPT_R_INPUT);
+    dir_opt->key = "direction";
+    dir_opt->description =
+	_("Raster map (or attribute column) containing velocity direction");
+    dir_opt->required = NO;
+    dir_opt->guisection = _("Input");
+
+    magn_opt = G_define_standard_option(G_OPT_R_INPUT);
+    magn_opt->key = "magnitude";
+    magn_opt->description =
+	_("Raster map (or attribute column) containing velocity magnitude");
+    magn_opt->required = NO;
+    magn_opt->guisection = _("Input");
+
+    u_opt = G_define_standard_option(G_OPT_R_INPUT);
+    u_opt->key = "u";
+    u_opt->description =
+	_("Raster map (or attribute column) containing u-component of velocity");
+    u_opt->required = NO;
+    u_opt->guisection = _("Input");
+
+    v_opt = G_define_standard_option(G_OPT_R_INPUT);
+    v_opt->key = "v";
+    v_opt->description =
+	_("Raster map (or attribute column) containing v-component of velocity");
+    v_opt->required = NO;
+    v_opt->guisection = _("Input");
+
+    vinput_opt = G_define_standard_option(G_OPT_V_INPUT);
+    vinput_opt->required = NO;
+    vinput_opt->guisection = _("Input");
+
+    vlayer_opt = G_define_standard_option(G_OPT_V_FIELD);
+    vlayer_opt->guisection = _("Input");
+
+    style_opt = G_define_option();
+    style_opt->key = "style";
+    style_opt->type = TYPE_STRING;
+    style_opt->answer = "arrow";
+    style_opt->options = "arrow,barb,straw";
+    style_opt->description = _("Style");
+
+    color_opt = G_define_standard_option(G_OPT_C_FG);
+
+    skip_opt = G_define_option();
+    skip_opt->key = "skip";
+    skip_opt->type = TYPE_INTEGER;
+    skip_opt->required = NO;
+    skip_opt->answer = "100";
+    skip_opt->description = _("Draw arrow every Nth grid cell");
+    skip_opt->guisection = _("Raster");
+
+    scale_opt = G_define_option();
+    scale_opt->key = "scale";
+    scale_opt->type = TYPE_DOUBLE;
+    scale_opt->required = NO;
+    scale_opt->answer = "1.0";
+    scale_opt->description = _("Scale factor for arrow rendering");
+
+    peak_opt = G_define_option();
+    peak_opt->key = "peak";
+    peak_opt->type = TYPE_DOUBLE;
+    peak_opt->required = NO;
+    peak_opt->description =
+	_("Maximum value for scaling (overrides map's maximum)");
+
+    type_opt = G_define_option();
+    type_opt->key = "aspect_type";
+    type_opt->type = TYPE_STRING;
+    type_opt->required = NO;
+    type_opt->answer = "cartesian";
+    type_opt->options = "cartesian,compass";
+    type_opt->description = _("Direction map aspect type");
+
+
+    /* legend  draw vertical (N facing) barb and exit */
+    keyat_opt = G_define_option();
+    keyat_opt->key = "legend_at";
+    keyat_opt->key_desc = "x,y";
+    keyat_opt->type = TYPE_DOUBLE;
+    keyat_opt->answer = "10.0,10.0";
+    keyat_opt->options = "0-100";
+    keyat_opt->required = NO;
+    keyat_opt->multiple = YES;
+    keyat_opt->label =
+	_("Screen percentage for legend barb ([0,0] is bottom-left)");
+    keyat_opt->description = _("Draws a single barb and exits");
+    keyat_opt->guisection = _("Legend");
+
+    keyvelo_opt = G_define_option();
+    keyvelo_opt->key = "legend_velo";
+    keyvelo_opt->type = TYPE_DOUBLE;
+    keyvelo_opt->required = NO;
+    keyvelo_opt->multiple = YES;
+    keyvelo_opt->description = _("Velocity for legend key arrow");
+    keyvelo_opt->guisection = _("Legend");
+
+    keyfont_opt = G_define_option();
+    keyfont_opt->key = "legend_fontsize";
+    keyfont_opt->type = TYPE_DOUBLE;
+    keyfont_opt->answer = "14";
+    keyfont_opt->description = _("Font size used in legend");
+    keyfont_opt->guisection = _("Legend");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    G_warning("This module is a work in progress. Don't expect it to work.");
+
+    /* check parms */
+    if ((u_opt->answer && (dir_opt->answer || magn_opt->answer)) ||
+	(v_opt->answer && (dir_opt->answer || magn_opt->answer)))
+	G_fatal_error(_("Specify either direction and magnitude or u and v components"));
+
+    if (!(!(dir_opt->answer && magn_opt->answer) ||
+	  !(u_opt->answer && v_opt->answer)))
+	G_fatal_error(_("Specify either direction and magnitude or u and v components"));
+
+    if (u_opt->answer && v_opt->answer) {
+	is_component = TRUE;
+	strncpy(dir_u_map, u_opt->answer, sizeof(dir_u_map) - 1);	/* FIXME: not well null terminated on overflow */
+	strncpy(mag_v_map, v_opt->answer, sizeof(mag_v_map) - 1);
+    }
+    else if (dir_opt->answer && magn_opt->answer) {
+	is_component = FALSE;
+	strncpy(dir_u_map, dir_opt->answer, sizeof(dir_u_map) - 1);
+	strncpy(mag_v_map, magn_opt->answer, sizeof(mag_v_map) - 1);
+    }
+
+    if (vinput_opt->answer)
+	is_vector = TRUE;
+    else
+	is_vector = FALSE;
+
+    scale = atof(scale_opt->answer);
+    skip = atoi(skip_opt->answer);
+    vlayer = atoi(vlayer_opt->answer);
+    if (peak_opt->answer)
+	peak = atof(peak_opt->answer);
+
+    if (strcmp(type_opt->answer, "compass") == 0)
+	aspect_type = TYPE_COMPASS;
+    else
+	aspect_type = TYPE_GRASS;
+
+    if (G_strcasecmp(style_opt->answer, "arrow") == 0)
+	style = TYPE_ARROW;
+    else if (G_strcasecmp(style_opt->answer, "barb") == 0)
+	style = TYPE_BARB;
+    else if (G_strcasecmp(style_opt->answer, "straw") == 0)
+	style = TYPE_STRAW;
+    else
+	G_fatal_error("Invalid style: %s", style_opt->answer);
+
+
+    if (keyvelo_opt->answer) {
+	/* Coords from Command Line */
+	/* Test for number coordinate pairs */
+	for (i = 0; keyat_opt->answers[i]; i += 2)
+	    num_leg_at = i + 2;
+
+	for (i = 0, num_leg_velo = 0; keyvelo_opt->answers[i]; i++)
+	    num_leg_velo++;
+
+	if (num_leg_at != num_leg_velo * 2)
+	    G_fatal_error(_("Unequal number of legend placement and velocity requests (%d vs. %d)"),
+			  num_leg_at, num_leg_velo);
+
+	key_fontsize = atof(keyfont_opt->answer);
+    }
+
+    if (R_open_driver() != 0)
+	G_fatal_error(_("No graphics device selected"));
+
+    /* Parse and select foreground color */
+    color = D_parse_color(color_opt->answer, 0);
+
+
+    /*////// do it ////////// */
+
+    // is D_setup() actually needed?
+    D_setup(0);
+
+    if (keyvelo_opt->answer) {
+
+	do_legend(keyat_opt->answers, keyvelo_opt->answers, num_leg_velo,
+		  key_fontsize, style, scale, peak, color);
+
+	R_close_driver();
+	exit(EXIT_SUCCESS);
+    }
+
+    if (is_vector)
+	do_barb_points(vinput_opt->answer, vlayer,
+		       dir_u_map, mag_v_map, is_component, color,
+		       aspect_type, scale, style);
+    else
+	do_barb_grid(dir_u_map, mag_v_map, is_component, color,
+		     aspect_type, scale, skip, style);
+
+
+    D_add_to_list(G_recreate_command());
+    R_close_driver();
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/display/d.barb/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/display/d.barb/points.c
===================================================================
--- grass-addons/display/d.barb/points.c	                        (rev 0)
+++ grass-addons/display/d.barb/points.c	2011-03-23 07:52:15 UTC (rev 45729)
@@ -0,0 +1,282 @@
+#include <float.h>
+#include <grass/gis.h>
+//#include <grass/Vect.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+
+/* load and plot barbs from data stored in a vector map's attribute table */
+void do_barb_points(char *vinput_name, int vlayer, char *dir_u_col,
+		    char *mag_v_col, int is_component, int color,
+		    int aspect_type, double scale, int style)
+{
+
+    struct Map_info vMap;
+    char *mapset;
+    int num_pts;
+    double *coord_x, *coord_y, *magn, *dirn;
+    int i;
+    double peak = -DBL_MAX, scale_fact;
+
+//? needed?    static struct line_pnts *Points;
+//    /* Create and initialize struct's where to store points/lines and categories */
+//    Points = Vect_new_line_struct();
+//    Cats = Vect_new_cats_struct();
+
+    magn = NULL; /* init in case it isn't used */
+
+    G_debug(0, "Doing sparse points ...");
+
+    if ((mapset = G_find_vector2(vinput_name, "")) == NULL)
+        G_fatal_error(_("Vector map <%s> not found"), vinput_name);
+
+    /* Predetermine level at which a map will be opened for reading */
+    if (Vect_set_open_level(2))
+        G_fatal_error(_("Unable to set predetermined vector open level"));
+
+    /* Open existing vector for reading lib/vector/Vlib/open.c */
+    if (1 > Vect_open_old(&vMap, vinput_name, mapset))
+	G_fatal_error(_("Unable to open vector map <%s>"), vinput_name);
+
+    G_debug(0, "<%s> is open", vinput_name);
+
+    /* we need to scan through and find the greatest value in of the
+	magnitude within the current region and scale from that. hence
+	the following complexity ... */
+    num_pts = count_pts_in_region(&vMap);
+    G_debug(0, "  %d points found in region", num_pts);
+
+    coord_x = G_calloc(num_pts + 1, sizeof(double));
+    coord_y = G_calloc(num_pts + 1, sizeof(double));
+    dirn = G_calloc(num_pts + 1, sizeof(double));
+    if(mag_v_col)
+	magn = G_calloc(num_pts + 1, sizeof(double));
+    else
+	magn = NULL;
+
+    fill_arrays(&vMap, vlayer, dir_u_col, mag_v_col, is_component,
+		coord_x, coord_y, dirn, magn);
+
+    if (aspect_type == TYPE_GRASS) {
+	for (i=0; i < num_pts; i++) {
+//	    G_debug(0, "in=%.1f  out=%.1f", dirn[i], 90-dirn[i] < 0 ? 360+90-dirn[i] : 90-dirn[i]);
+	    dirn[i] = 90 - dirn[i];
+	    if (dirn[i] < 0)
+		dirn[i] += 360;
+	}
+    }
+
+    peak = max_magnitude(magn, num_pts);
+
+// to figure out:
+//   also pass u,v columns and calc dir,mag prior to filling dirn,magn arrays
+
+
+    /* somehow check, load attributes            see d.vect  */
+
+
+/*
+       if(is_component) {
+       read u attrib;
+       read v attrib;
+       dir= ...calc;
+       velo= ...calc;
+       }
+       else {
+       read dir attrib;
+       read velo attrib;
+       }
+
+       if (aspect_type == TYPE_COMPASS)
+       dir = 90 - dir;
+*/
+
+    peak = 1.;    // TODO: window width * 0.20 
+    scale_fact = (peak ) * scale;
+
+    for (i=0; i < num_pts; i++) {
+	draw_barb(coord_x[i], coord_y[i], magn[i] * scale_fact, dirn[i],
+		  color, scale, style);
+    }
+
+   Vect_close(&vMap);
+
+    return;
+}
+
+/* counts point features in the current region box */
+int count_pts_in_region(struct Map_info *Map)
+{
+    int count = 0, nlines, ltype;
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+    struct Cell_head window;
+
+    G_debug(0, "count_pts_in_region()");
+    G_get_window(&window);
+    G_debug(0, "  n=%.2f s=%.2f e=%.2f w=%.2f", window.north, window.south,
+    	    window.east, window.west);
+
+    /* Create and initialize struct's where to store points/lines and categories */
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    nlines = Vect_get_num_lines(Map);
+    G_debug(0, "  %d features found in map", nlines);
+
+    Vect_rewind(Map);
+
+    while (1) {
+        ltype = Vect_read_next_line(Map, Points, Cats);
+        switch (ltype) {
+        case -1:
+            G_fatal_error(_("Can't read vector map"));
+        case -2:                /* EOF */
+            return count;
+        }
+
+	if(! (ltype & GV_POINTS))
+	    continue;
+
+	if (Points->x[0] > window.east || Points->x[0] < window.west ||
+	    Points->y[0] > window.north || Points->y[0] < window.south)
+	    continue;
+
+	count++;
+    }
+
+    return -1; /* shouldn't get here */
+}
+
+
+/* populates arrays */
+/* rather redundant WRT count_pts_in_region() ... */
+void fill_arrays(struct Map_info *Map, int layer, char *dir_u, char *mag_v,
+		int is_uv, double *Xs, double *Ys, double *Dirs, double *Mags)
+{
+    int i, ltype, nrec;
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+    struct Cell_head window;
+    struct field_info *fi = NULL;
+    dbDriver *driver = NULL;
+    dbCatValArray cvarr_dir_u, cvarr_mag_v;
+    dbCatVal *cv_dir_u = NULL, *cv_mag_v = NULL;
+
+    G_debug(0, "fill_arrays()");
+
+    G_get_window(&window);
+
+
+    fi = Vect_get_field(Map, (layer > 0 ? layer : 1));
+    if (fi == NULL) {
+	G_fatal_error(_("Database connection not defined for layer %d"),
+		      (layer > 0 ? layer : 1));
+    }
+
+    driver = db_start_driver_open_database(fi->driver, fi->database);
+    if (driver == NULL) {
+	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
+		      fi->database, fi->driver);
+    }
+
+    /* Create and initialize struct's where to store points/lines and categories */
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    db_CatValArray_init(&cvarr_dir_u);
+    if(Mags)
+	db_CatValArray_init(&cvarr_mag_v);
+
+
+    nrec = db_select_CatValArray(driver, fi->table, fi->key,
+				 dir_u, NULL, &cvarr_dir_u);
+    G_debug(0, "nrec (%s) = %d", dir_u, nrec);
+
+    if (cvarr_dir_u.ctype != DB_C_TYPE_INT && cvarr_dir_u.ctype != DB_C_TYPE_DOUBLE)
+	G_fatal_error(_("Direction/u column (%s) is not a numeric."),  dir_u);
+
+    if (nrec < 0)
+	G_fatal_error(_("Cannot select data (%s) from table"), dir_u);
+    G_debug(0, "%d records selected from table", nrec);
+
+    if(Mags) {
+	nrec = db_select_CatValArray(driver, fi->table, fi->key,
+	    			     mag_v, NULL, &cvarr_mag_v);
+	G_debug(0, "nrec (%s) = %d", mag_v, nrec);
+
+	if (cvarr_mag_v.ctype != DB_C_TYPE_INT && cvarr_mag_v.ctype != DB_C_TYPE_DOUBLE)
+	    G_fatal_error(_("Magnitude/v column (%s) is not a numeric."),  mag_v);
+
+	if (nrec < 0)
+	    G_fatal_error(_("Cannot select data (%s) from table"), mag_v);
+	G_debug(0, "%d records selected from table", nrec);
+    }
+
+    Vect_rewind(Map);
+    i = 0;
+
+    while (1) {
+        ltype = Vect_read_next_line(Map, Points, Cats);
+        switch (ltype) {
+        case -1:
+	    db_close_database_shutdown_driver(driver);
+            G_fatal_error(_("Can't read vector map"));
+        case -2:                /* EOF */
+	    db_close_database_shutdown_driver(driver);
+            return;
+        }
+
+	if(! (ltype & GV_POINTS))
+	    continue;
+
+	if (Points->x[0] > window.east || Points->x[0] < window.west ||
+	    Points->y[0] > window.north || Points->y[0] < window.south)
+	    continue;
+
+	Xs[i] = Points->x[0];
+	Ys[i] = Points->y[0];
+	G_debug(5, "  Xs[%d] = %.2f  Ys[%d] = %.2f  cat = %d",  i, Xs[i],
+		i, Ys[i], Cats->cat[0]);
+
+	/* Read rotation from db */
+	if (db_CatValArray_get_value(&cvarr_dir_u, Cats->cat[0], &cv_dir_u) != DB_OK)
+	   Dirs[i] = 0.0/0.0; /* NaN */
+	else
+	    Dirs[i] = cvarr_dir_u.ctype == DB_C_TYPE_INT ?
+		 (double)cv_dir_u->val.i : cv_dir_u->val.d;
+
+
+	/* Read magnitude from db */
+	if(Mags) {
+	    if (db_CatValArray_get_value(&cvarr_mag_v, Cats->cat[0], &cv_mag_v) != DB_OK)
+		Mags[i] = 0.0/0.0; /* NaN */
+	    else
+		Mags[i] = cvarr_mag_v.ctype == DB_C_TYPE_INT ?
+			(double)cv_mag_v->val.i : cv_mag_v->val.d;
+
+	    if(Mags[i] < 0) /* magnitude is scalar and can only be positive */
+		Mags[i] = 0;
+	}
+	G_debug(5, "    Dirs[%d] = %.2f  Mags[%d] = %.2f",  i, Dirs[i],
+		i, Mags[i]);
+	i++;
+    }
+
+    db_close_database_shutdown_driver(driver);
+    return; /* shouldn't get here */
+}
+
+
+/* scan for biggest value in magnitude array */
+double max_magnitude(double *magn, int n)
+{
+    double maxmag = -DBL_MAX;
+    int i;
+    for(i = 0; i < n; i++) {
+	if(magn[i] > maxmag)
+	    maxmag = magn[i];
+    }
+    return maxmag;
+}


Property changes on: grass-addons/display/d.barb/points.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native



More information about the grass-commit mailing list