[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