[GRASS-SVN] r62894 - grass/branches/releasebranch_7_0/vector/v.mkgrid

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Nov 24 12:53:44 PST 2014


Author: mmetz
Date: 2014-11-24 12:53:44 -0800 (Mon, 24 Nov 2014)
New Revision: 62894

Added:
   grass/branches/releasebranch_7_0/vector/v.mkgrid/hexgrid.c
Modified:
   grass/branches/releasebranch_7_0/vector/v.mkgrid/grid_structs.h
   grass/branches/releasebranch_7_0/vector/v.mkgrid/local_proto.h
   grass/branches/releasebranch_7_0/vector/v.mkgrid/main.c
   grass/branches/releasebranch_7_0/vector/v.mkgrid/rotate.c
   grass/branches/releasebranch_7_0/vector/v.mkgrid/v.mkgrid.html
   grass/branches/releasebranch_7_0/vector/v.mkgrid/write_grid.c
Log:
v.mkgrid: simplify user interface, optimze rotation, add hexagon creation

Modified: grass/branches/releasebranch_7_0/vector/v.mkgrid/grid_structs.h
===================================================================
--- grass/branches/releasebranch_7_0/vector/v.mkgrid/grid_structs.h	2014-11-24 17:22:45 UTC (rev 62893)
+++ grass/branches/releasebranch_7_0/vector/v.mkgrid/grid_structs.h	2014-11-24 20:53:44 UTC (rev 62894)
@@ -4,9 +4,12 @@
     int num_cols;
     int num_vect_rows;
     int num_vect_cols;
-    double length;		/*  distance to shift to the east  */
-    double width;		/*  distance to shift to the north  */
-    double origin_x;		/*  lower left point of grid  */
-    double origin_y;
+    double width;		/* grid cell width (EW res) */
+    double height;		/* grid cell height (NS res) */
+    double north, south, east, west;
+    double xo, yo;		/* grid origin = center */
     double angle;
+    /* hexagon */
+    double rrad, crad;
+    double rstep, cstep;
 };

Added: grass/branches/releasebranch_7_0/vector/v.mkgrid/hexgrid.c
===================================================================
--- grass/branches/releasebranch_7_0/vector/v.mkgrid/hexgrid.c	                        (rev 0)
+++ grass/branches/releasebranch_7_0/vector/v.mkgrid/hexgrid.c	2014-11-24 20:53:44 UTC (rev 62894)
@@ -0,0 +1,271 @@
+#include <stdio.h>
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+#include "grid_structs.h"
+#include "local_proto.h"
+
+static int write_line(struct grid_description *grid_info, 
+                      struct Map_info *Map, struct line_pnts *Points, 
+                      struct line_cats *Cats, int *cat, int type,
+	              double x1, double y1, double x2, double y2,
+	              int nbreaks)
+{
+    int i;
+    double x, y;
+    double dx, dy;
+
+    Vect_reset_line(Points);
+    Vect_reset_cats(Cats);
+
+    dx = x2 - x1;
+    dy = y2 - y1;
+
+    x = x1;
+    y = y1;
+    rotate(&x, &y, grid_info->xo, grid_info->yo, grid_info->angle);
+    Vect_append_point(Points, x, y, 0);
+
+    for (i = 1; i < nbreaks; i++) {
+	x = x1 + dx * i / nbreaks;
+	y = y1 + dy * i / nbreaks;
+	rotate(&x, &y, grid_info->xo, grid_info->yo, grid_info->angle);
+	Vect_append_point(Points, x, y, 0);
+    }
+
+    x = x2;
+    y = y2;
+    rotate(&x, &y, grid_info->xo, grid_info->yo, grid_info->angle);
+    Vect_append_point(Points, x, y, 0);
+
+    if (type == GV_LINE) {
+	Vect_cat_set(Cats, 1, *cat);
+	(*cat)++;
+    }
+
+    Vect_write_line(Map, type, Points, Cats);
+
+    return 0;
+}
+
+int hexgrid(struct grid_description *grid_info, struct Map_info *Map,
+               int nbreaks, int otype)
+{
+    int row, col, rows, cols;
+    double x1, y1, x2, y2;
+    double north, east;
+    double angle;
+    int ptype, ltype;
+    int cat;
+
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    rows = grid_info->num_vect_rows;
+    cols = grid_info->num_vect_cols;
+    angle = grid_info->angle;
+
+    ptype = (otype & GV_POINTS);
+    ltype = (otype & GV_LINES);
+
+    nbreaks++;
+
+    if ((otype & GV_POINTS)) {
+	if (ptype != GV_POINT && ptype != GV_CENTROID)
+	    G_fatal_error("Wrong point type");
+    }
+    if ((otype & GV_LINES)) {
+	if (ltype != GV_LINE && ltype != GV_BOUNDARY)
+	    G_fatal_error("Wrong line type");
+    }
+    cat = 1;
+
+    G_message(_("Writing out hexagon grid..."));
+    for (row = 0; row < rows; row++) {
+
+	G_percent(row, rows, 9);
+	north = grid_info->north - grid_info->rstep * (row + 1);
+
+	if (row & 1) {
+	    if (otype & GV_POINTS) {
+		for (col = 1; col < cols; col += 2) {
+		    east = grid_info->west + grid_info->cstep * col + grid_info->crad;
+		    x1 = east;
+		    y1 = north;
+
+		    Vect_reset_cats(Cats);
+		    Vect_cat_set(Cats, 1, cat);
+		    cat++;
+		    Vect_reset_line(Points);
+		    rotate(&x1, &y1, grid_info->xo, grid_info->yo, angle);
+		    Vect_append_point(Points, x1, y1, 0);
+		    Vect_write_line(Map, ptype, Points, Cats);
+		}
+	    }
+	    /* close last col */
+	    col = cols - 1;
+	    if ((col & 1) && (otype & GV_LINES)) {
+
+		x1 = grid_info->west + grid_info->cstep * (col + 1);
+		y1 = grid_info->north - grid_info->rstep * row;
+		x2 = grid_info->west + grid_info->cstep * (col + 1) + grid_info->crad * 0.5;
+		y2 = grid_info->north - grid_info->rstep * (row + 1);
+
+		write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			   x1, y1, x2, y2, nbreaks);
+
+		x1 = x2;
+		y1 = y2;
+		x2 = grid_info->west + grid_info->cstep * (col + 1);
+		y2 = grid_info->north - grid_info->rstep * (row + 2);
+
+		write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			   x1, y1, x2, y2, nbreaks);
+	    }
+	}
+	else {
+	    for (col = 0; col < cols; col += 2) {
+		east = grid_info->west + grid_info->cstep * col + grid_info->crad;
+
+		if (otype & GV_POINTS) {
+		    Vect_reset_cats(Cats);
+		    Vect_cat_set(Cats, 1, cat);
+		    cat++;
+		    Vect_reset_line(Points);
+		    x1 = east;
+		    y1 = north;
+		    rotate(&x1, &y1, grid_info->xo, grid_info->yo, angle);
+		    Vect_append_point(Points, x1, y1, 0);
+		    Vect_write_line(Map, ptype, Points, Cats);
+		}
+		if (otype & GV_LINES) {
+		    /* draw hexagon without bottom */
+		    x1 = grid_info->west + grid_info->cstep * col + grid_info->crad * 0.5;
+		    y1 = grid_info->north - grid_info->rstep * (row + 2);
+		    x2 = grid_info->west + grid_info->cstep * col;
+		    y2 = grid_info->north - grid_info->rstep * (row + 1);
+
+		    write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			       x1, y1, x2, y2, nbreaks);
+
+		    x1 = x2;
+		    y1 = y2;
+		    x2 = grid_info->west + grid_info->cstep * col + grid_info->crad * 0.5;
+		    y2 = grid_info->north - grid_info->rstep * row;
+
+		    write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			       x1, y1, x2, y2, nbreaks);
+
+		    x1 = x2;
+		    y1 = y2;
+		    x2 = grid_info->west + grid_info->cstep * (col + 1);
+
+		    write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			       x1, y1, x2, y2, nbreaks);
+
+		    x1 = x2;
+		    y1 = y2;
+		    x2 = grid_info->west + grid_info->cstep * (col + 1) + grid_info->crad * 0.5;
+		    y2 = grid_info->north - grid_info->rstep * (row + 1);
+
+		    write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			       x1, y1, x2, y2, nbreaks);
+
+		    x1 = x2;
+		    y1 = y2;
+		    x2 = grid_info->west + grid_info->cstep * (col + 1);
+		    y2 = grid_info->north - grid_info->rstep * (row + 2);
+
+		    write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			       x1, y1, x2, y2, nbreaks);
+		}
+		/* next to left */
+		if ((otype & GV_LINES) && col < cols - 1) {
+
+		    x1 = grid_info->west + grid_info->cstep * (col + 1) + grid_info->crad * 0.5;
+		    y1 = north;
+		    x2 = grid_info->west + grid_info->cstep * (col + 2);
+		    y2 = y1;
+
+		    write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			       x1, y1, x2, y2, nbreaks);
+		}
+	    }
+	}
+    }
+    /* close last row */
+    if (otype & GV_LINES) {
+	if ((row - 1) & 1) {
+	    for (col = 1; col < cols; col += 2) {
+
+		/* close even rows */
+		x1 = grid_info->west + grid_info->cstep * (col - 1) + grid_info->crad * 0.5;
+		y1 = grid_info->north - grid_info->rstep * row;
+		x2 = grid_info->west + col * grid_info->cstep;
+		y2 = y1;
+
+		write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			   x1, y1, x2, y2, nbreaks);
+
+		x1 = grid_info->west + grid_info->cstep * col;
+		y1 = grid_info->north - grid_info->rstep * row;
+		x2 = grid_info->west + grid_info->cstep * col + grid_info->crad * 0.5;
+		y2 = grid_info->north - grid_info->rstep * (row + 1);
+
+		write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			   x1, y1, x2, y2, nbreaks);
+
+		x1 = x2;
+		y1 = y2;
+		x2 = grid_info->west + grid_info->cstep * (col + 1);
+
+		write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			   x1, y1, x2, y2, nbreaks);
+
+		if (col < cols - 1) {
+		    x1 = x2;
+		    y1 = y2;
+		    x2 = grid_info->west + grid_info->cstep * (col + 1) + grid_info->crad * 0.5;
+		    y2 = grid_info->north - grid_info->rstep * row;
+
+		    write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			       x1, y1, x2, y2, nbreaks);
+		}
+	    }
+	    /* close last col */
+	    col = cols - 1;
+	    if (!(col & 1)) {
+		/* close even rows */
+		x1 = grid_info->west + grid_info->cstep * col + grid_info->crad * 0.5;
+		y1 = grid_info->north - grid_info->rstep * row;
+		x2 = grid_info->west + grid_info->cstep * (col + 1);
+		y2 = y1;
+
+		write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			   x1, y1, x2, y2, nbreaks);
+	    }
+	}
+	else {
+	    y1 = grid_info->north - (row + 1) * grid_info->rstep;
+	    y2 = y1;
+	    for (col = 0; col < cols; col += 2) {
+
+		x1 = grid_info->west + grid_info->cstep * col + grid_info->crad * 0.5;
+		x2 = grid_info->west + grid_info->cstep * (col + 1);
+
+		write_line(grid_info, Map, Points, Cats, &cat, ltype,
+			   x1, y1, x2, y2, nbreaks);
+	    }
+	}
+    }
+
+    G_percent(row, rows, 4);
+
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_cats_struct(Cats);
+
+    return (cat);
+}


Property changes on: grass/branches/releasebranch_7_0/vector/v.mkgrid/hexgrid.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Modified: grass/branches/releasebranch_7_0/vector/v.mkgrid/local_proto.h
===================================================================
--- grass/branches/releasebranch_7_0/vector/v.mkgrid/local_proto.h	2014-11-24 17:22:45 UTC (rev 62893)
+++ grass/branches/releasebranch_7_0/vector/v.mkgrid/local_proto.h	2014-11-24 20:53:44 UTC (rev 62894)
@@ -1,7 +1,10 @@
 /* rotate.c */
+void set_angle(double);
 void rotate(double *, double *, double, double, double);
 
 /* write_grid.c */
 int write_grid(struct grid_description *, struct Map_info *, int, int);
-int write_vect(double, double, double, double, struct Map_info *,
-	       struct line_pnts *, int);
+
+/* hexgrid.c */
+int hexgrid(struct grid_description *, struct Map_info *, int, int);
+

Modified: grass/branches/releasebranch_7_0/vector/v.mkgrid/main.c
===================================================================
--- grass/branches/releasebranch_7_0/vector/v.mkgrid/main.c	2014-11-24 17:22:45 UTC (rev 62893)
+++ grass/branches/releasebranch_7_0/vector/v.mkgrid/main.c	2014-11-24 20:53:44 UTC (rev 62894)
@@ -6,9 +6,10 @@
  *               Upgrade to 5.7 Radim Blazek 10/2004
  *               Hamish Bowman <hamish_b yahoo.com>,
  *               Jachym Cepicky <jachym les-ejk.cz>, Markus Neteler <neteler itc.it>
- *               Ivan Shevlakov: points support -p                
- *               Luca Delucchi: lines support -l
- * PURPOSE:      
+ *               Ivan Shevlakov: points support -p
+ *               Luca Delucchi: lines support -l, vertical breaks
+ *               Markus Metz: rewrite, hexagon creation 
+ * PURPOSE:
  * COPYRIGHT:    (C) 1999-2014 by the GRASS Development Team
  *
  *               This program is free software under the GNU General
@@ -47,10 +48,11 @@
     struct grid_description grid_info;
     struct Cell_head window;
     struct Map_info Map;
-    struct Option *vectname, *grid, *coord, *box, *angle, *position_opt, *breaks;
+    struct Option *vectname, *grid, *coord, *box, *angle, *position_opt,
+                  *breaks, *type_opt;
     struct GModule *module;
-    struct Flag *points_fl, *line_fl;
-    int points_p, line_p, output_type;
+    struct Flag *hex_flag, *hs_flag;
+    int otype, ptype, ltype;
     char *desc;
 
     struct line_pnts *Points;
@@ -67,9 +69,7 @@
     module = G_define_module();
     G_add_keyword(_("vector"));
     G_add_keyword(_("geometry"));
-    G_add_keyword(_("grid"));
-    G_add_keyword(_("point pattern"));
-    module->description = _("Creates a vector map of a user-defined grid of area, lines or points.");
+    module->description = _("Creates a vector map of a user-defined grid.");
 
     vectname = G_define_standard_option(G_OPT_V_OUTPUT);
     vectname->key = "map";
@@ -127,31 +127,46 @@
     breaks->type = TYPE_INTEGER;
     breaks->required = NO;
     breaks->description =
-	_("Number of horizontal vertex points per grid cell");
+	_("Number of vertex points per grid cell");
     breaks->options = "0-60";
     breaks->answer = "3";
 
-    points_fl = G_define_flag();
-    points_fl->key = 'p';
-    points_fl->description =
-	_("Create grid of points instead of areas and centroids");
+    type_opt = G_define_standard_option(G_OPT_V_TYPE);
+    type_opt->options = "point,line,area";
+    type_opt->answer = "area";
+    type_opt->multiple = NO;
+    type_opt->description = _("Output feature type");
 
-    line_fl = G_define_flag();
-    line_fl->key = 'l';
-    line_fl->description =
-	_("Create grid as lines, instead of areas");
+    hex_flag = G_define_flag();
+    hex_flag->key = 'h';
+    hex_flag->description =
+	_("Create hexagons (default: rectangles)");
 
+    hs_flag = G_define_flag();
+    hs_flag->key = 's';
+    hs_flag->description =
+	_("Enforce symmetric hexagons");
+
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
-    line_p = line_fl->answer;
-    if (line_p) {
-	output_type = GV_LINE;
-    } else {
-	output_type = GV_BOUNDARY;
+    otype = 0;
+    switch (type_opt->answer[0]) {
+    case 'p':
+	otype |= GV_POINT;
+	break;
+    case 'l':
+	otype |= GV_LINE;
+	break;
+    case 'a':
+	otype |= GV_CENTROID;
+	otype |= GV_BOUNDARY;
+	break;
     }
 
-    points_p = points_fl->answer;
+    ptype = (otype & GV_POINTS);
+    ltype = (otype & GV_LINES);
+    
 
     /* get the current window  */
     G_get_window(&window);
@@ -167,6 +182,7 @@
     grid_info.num_cols = atoi(grid->answers[1]);
 
     grid_info.angle = M_PI / 180 * atof(angle->answer);
+    set_angle(grid_info.angle);
 
     nbreaks = atoi(breaks->answer);
 
@@ -178,17 +194,16 @@
 	if (box->answer)
 	    G_fatal_error(_("'box' and 'position=region' are exclusive options"));
 
-	if (grid_info.angle != 0.0)
-	    G_fatal_error(_("'angle' and 'position=region' are exclusive options"));
+	grid_info.west = window.west;
+	grid_info.south = window.south;
+	grid_info.east = window.east;
+	grid_info.north = window.north;
 
-	grid_info.origin_x = window.west;
-	grid_info.origin_y = window.south;
+	grid_info.width = (window.east - window.west) / grid_info.num_cols;
+	grid_info.height = (window.north - window.south) / grid_info.num_rows;
 
-	grid_info.length = (window.east - window.west) / grid_info.num_cols;
-	grid_info.width = (window.north - window.south) / grid_info.num_rows;
-
-	G_debug(2, "x = %e y = %e l = %e w = %e", grid_info.origin_x,
-		grid_info.origin_y, grid_info.length, grid_info.width);
+	G_debug(2, "x = %e y = %e w = %e h = %e", grid_info.west,
+		grid_info.south, grid_info.width, grid_info.height);
     }
     else {
 	if (!coord->answer)
@@ -198,32 +213,25 @@
 	    G_fatal_error(_("'box' option missing"));
 
 	if (!G_scan_easting
-	    (coord->answers[0], &(grid_info.origin_x), window.proj))
-	    G_fatal_error(_("Invalid easting"));;
+	    (coord->answers[0], &(grid_info.west), window.proj))
+	    G_fatal_error(_("Invalid easting"));
 	if (!G_scan_northing
-	    (coord->answers[1], &(grid_info.origin_y), window.proj))
-	    G_fatal_error(_("Invalid northing"));;
+	    (coord->answers[1], &(grid_info.south), window.proj))
+	    G_fatal_error(_("Invalid northing"));
 
 	if (!G_scan_resolution
-	    (box->answers[0], &(grid_info.length), window.proj))
-	    G_fatal_error(_("Invalid distance"));;
+	    (box->answers[0], &(grid_info.width), window.proj))
+	    G_fatal_error(_("Invalid width"));
 	if (!G_scan_resolution
-	    (box->answers[1], &(grid_info.width), window.proj))
-	    G_fatal_error(_("Invalid distance"));;
+	    (box->answers[1], &(grid_info.height), window.proj))
+	    G_fatal_error(_("Invalid height"));
 
+	grid_info.east = grid_info.west + grid_info.width * grid_info.num_cols;
+	grid_info.north = grid_info.south + grid_info.height * grid_info.num_rows;
     }
+    grid_info.xo = (grid_info.east + grid_info.west) / 2.0;
+    grid_info.yo = (grid_info.north + grid_info.south) / 2.0;
 
-    /*
-     * vector rows are the actual number of rows of vectors to make up the
-     * entire grid.   ditto for cols.
-     */
-    grid_info.num_vect_rows = grid_info.num_rows + 1;
-    grid_info.num_vect_cols = grid_info.num_cols + 1;
-
-    Points = Vect_new_line_struct();
-    Cats = Vect_new_cats_struct();
-    db_init_string(&sql);
-
     /* Open output map */
     if (0 > Vect_open_new(&Map, dig_file, 0)) {
 	G_fatal_error(_("Unable to create vector map <%s>"), dig_file);
@@ -243,92 +251,175 @@
 	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
 		      Fi->database, Fi->driver);
     db_set_error_handler_driver(Driver);
+    db_init_string(&sql);
 
-    if (grid_info.num_rows < 27 && grid_info.num_cols < 27) {
-	sprintf(buf,
-		"create table %s ( cat integer, row integer, col integer, "
-		"rown varchar(1), coln varchar(1))", Fi->table);
+    if (hex_flag->answer) {
+
+	grid_info.num_vect_rows = 2 * grid_info.num_rows + 1;
+	grid_info.num_vect_cols = grid_info.num_cols;
+
+	/* figure out hexagon radius */
+	grid_info.rstep = (grid_info.north - grid_info.south) /
+	                  (grid_info.num_rows * 2);
+	grid_info.rrad = grid_info.rstep * 2 / sqrt(3.0);
+
+	grid_info.cstep = (grid_info.east - grid_info.west) / 
+	                  (grid_info.num_cols + 1.0 / 3.0);
+	grid_info.crad = grid_info.cstep / 1.5;
+
+	if (hs_flag->answer) {
+	    if (grid_info.rrad > grid_info.crad) {
+		grid_info.rrad = grid_info.crad;
+		grid_info.rstep = grid_info.rrad * sqrt(3.0) / 2.0;
+	    }
+	    else if (grid_info.crad > grid_info.rrad) {
+		grid_info.crad = grid_info.rrad;
+		grid_info.cstep = grid_info.crad * 1.5;
+	    }
+	}
+
+	grid_info.num_vect_rows = (grid_info.north - grid_info.south) / 
+	     grid_info.rstep - 0.5;
+	grid_info.num_vect_cols = (grid_info.east - grid_info.west -
+	     grid_info.crad * 0.5) / grid_info.cstep;
+
+	if (grid_info.east - grid_info.west < 3.5 * grid_info.crad) {
+	    G_fatal_error(_("Please use a higher resolution or a larger region"));
+	}
+	if (grid_info.north - grid_info.south < 3 * grid_info.rstep) {
+	    G_fatal_error(_("Please use a higher resolution or a larger region"));
+	}
+
+	sprintf(buf, "create table %s ( %s integer)", Fi->table, Fi->key);
+
+	db_set_string(&sql, buf);
+
+	G_debug(1, "SQL: %s", db_get_string(&sql));
+
+	if (db_execute_immediate(Driver, &sql) != DB_OK) {
+	    G_fatal_error(_("Unable to create table: %s"), db_get_string(&sql));
+	}
+
+	if (db_create_index2(Driver, Fi->table, Fi->key) != DB_OK)
+	    G_warning(_("Unable to create index"));
+
+	if (db_grant_on_table
+	    (Driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
+	    G_fatal_error(_("Unable to grant privileges on table <%s>"),
+			  Fi->table);
+
+	attCount = hexgrid(&grid_info, &Map, nbreaks, otype);
+
+	db_begin_transaction(Driver);
+
+	for (i = 1; i <= attCount; ++i) {
+
+	    sprintf(buf, "insert into %s values ( %d )", Fi->table, i);
+	    if (db_set_string(&sql, buf) != DB_OK)
+		G_fatal_error(_("Unable to fill attribute table"));
+
+	    G_debug(3, "SQL: %s", db_get_string(&sql));
+	    if (db_execute_immediate(Driver, &sql) != DB_OK) {
+		G_fatal_error(_("Unable to insert new record: %s"),
+			      db_get_string(&sql));
+	    }
+	}
     }
     else {
-	sprintf(buf,
-		"create table %s ( cat integer, row integer, col integer)",
-		Fi->table);
-    }
-    db_set_string(&sql, buf);
+	/*
+	 * vector rows are the actual number of rows of vectors to make up the
+	 * entire grid.   ditto for cols.
+	 */
+	grid_info.num_vect_rows = grid_info.num_rows + 1;
+	grid_info.num_vect_cols = grid_info.num_cols + 1;
 
-    G_debug(1, "SQL: %s", db_get_string(&sql));
+	Points = Vect_new_line_struct();
+	Cats = Vect_new_cats_struct();
 
-    if (db_execute_immediate(Driver, &sql) != DB_OK) {
-	G_fatal_error(_("Unable to create table: %s"), db_get_string(&sql));
-    }
+	if (grid_info.num_rows < 27 && grid_info.num_cols < 27) {
+	    sprintf(buf,
+		    "create table %s ( cat integer, row integer, col integer, "
+		    "rown varchar(1), coln varchar(1))", Fi->table);
+	}
+	else {
+	    sprintf(buf,
+		    "create table %s ( cat integer, row integer, col integer)",
+		    Fi->table);
+	}
+	db_set_string(&sql, buf);
 
-    if (db_create_index2(Driver, Fi->table, Fi->key) != DB_OK)
-	G_warning(_("Unable to create index"));
+	G_debug(1, "SQL: %s", db_get_string(&sql));
 
-    if (db_grant_on_table
-	(Driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
-	G_fatal_error(_("Unable to grant privileges on table <%s>"),
-		      Fi->table);
+	if (db_execute_immediate(Driver, &sql) != DB_OK) {
+	    G_fatal_error(_("Unable to create table: %s"), db_get_string(&sql));
+	}
 
-    if (!points_p) {
-	/* create areas */
-	write_grid(&grid_info, &Map, nbreaks, output_type);
-    }
+	if (db_create_index2(Driver, Fi->table, Fi->key) != DB_OK)
+	    G_warning(_("Unable to create index"));
 
-    /* Create a grid of label points at the centres of the grid cells */
-    G_verbose_message(_("Creating centroids..."));
+	if (db_grant_on_table
+	    (Driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
+	    G_fatal_error(_("Unable to grant privileges on table <%s>"),
+			  Fi->table);
 
-    /* Write out centroids and attributes */
-    /* If the output id is lines it skips to add centroids and attributes
-       TODO decide what to write in the attribute table
-     */
-    if (!line_p) {
-      db_begin_transaction(Driver);
-      attCount = 0;
-      for (i = 0; i < grid_info.num_rows; ++i) {
-	  for (j = 0; j < grid_info.num_cols; ++j) {
-	      double x, y;
-	      const int point_type = points_p ? GV_POINT : GV_CENTROID;
+	if (ltype) {
+	    /* create areas */
+	    write_grid(&grid_info, &Map, nbreaks, ltype);
+	}
 
-	      x = grid_info.origin_x + (0.5 + j) * grid_info.length;
-	      y = grid_info.origin_y + (0.5 + i) * grid_info.width;
+	/* Create a grid of label points at the centres of the grid cells */
+	G_verbose_message(_("Creating centroids..."));
 
-	      rotate(&x, &y, grid_info.origin_x, grid_info.origin_y,
-		    grid_info.angle);
+	/* Write out centroids and attributes */
+	/* If the output id is lines it skips to add centroids and attributes
+	   TODO decide what to write in the attribute table
+	 */
+	if (ptype) {
+            db_begin_transaction(Driver);
+	    attCount = 0;
+	    for (i = 0; i < grid_info.num_rows; ++i) {
+	        for (j = 0; j < grid_info.num_cols; ++j) {
+		    double x, y;
 
-	      Vect_reset_line(Points);
-	      Vect_reset_cats(Cats);
+		    x = grid_info.west + (0.5 + j) * grid_info.width;
+		    y = grid_info.south + (0.5 + i) * grid_info.height;
 
-	      Vect_append_point(Points, x, y, 0.0);
-	      Vect_cat_set(Cats, 1, attCount + 1);
-	      Vect_write_line(&Map, point_type, Points, Cats);
+		    rotate(&x, &y, grid_info.xo, grid_info.yo,
+			   grid_info.angle);
 
-	      sprintf(buf, "insert into %s values ", Fi->table);
-	      if (db_set_string(&sql, buf) != DB_OK)
-		  G_fatal_error(_("Unable to fill attribute table"));
+		    Vect_reset_line(Points);
+		    Vect_reset_cats(Cats);
 
-	      if (grid_info.num_rows < 27 && grid_info.num_cols < 27) {
-		  sprintf(buf,
-			  "( %d, %d, %d, '%c', '%c' )",
-			  attCount + 1, grid_info.num_rows - i,
-			  j + 1, 'A' + grid_info.num_rows - i - 1, 'A' + j);
-	      }
-	      else {
-		  sprintf(buf, "( %d, %d, %d )",
-			  attCount + 1, i + 1, j + 1);
-	      }
-	      if (db_append_string(&sql, buf) != DB_OK)
-		      G_fatal_error(_("Unable to fill attribute table"));
+		    Vect_append_point(Points, x, y, 0.0);
+		    Vect_cat_set(Cats, 1, attCount + 1);
+		    Vect_write_line(&Map, ptype, Points, Cats);
 
-	      G_debug(3, "SQL: %s", db_get_string(&sql));
+		    sprintf(buf, "insert into %s values ", Fi->table);
+		    if (db_set_string(&sql, buf) != DB_OK)
+		        G_fatal_error(_("Unable to fill attribute table"));
 
-	      if (db_execute_immediate(Driver, &sql) != DB_OK) {
-		  G_fatal_error(_("Unable to insert new record: %s"),
-			      db_get_string(&sql));
-	      }
-	      attCount++;
-	  }
-      }
+		    if (grid_info.num_rows < 27 && grid_info.num_cols < 27) {
+		        sprintf(buf, "( %d, %d, %d, '%c', '%c' )",
+			      attCount + 1, grid_info.num_rows - i,
+			      j + 1, 'A' + grid_info.num_rows - i - 1, 'A' + j);
+		    }
+		    else {
+		        sprintf(buf, "( %d, %d, %d )",
+			        attCount + 1, i + 1, j + 1);
+		    }
+		    if (db_append_string(&sql, buf) != DB_OK)
+		        G_fatal_error(_("Unable to fill attribute table"));
+
+		    G_debug(3, "SQL: %s", db_get_string(&sql));
+
+		    if (db_execute_immediate(Driver, &sql) != DB_OK) {
+		        G_fatal_error(_("Unable to insert new record: %s"),
+				  db_get_string(&sql));
+		    }
+		    attCount++;
+	        }
+	    }
+	}
     }
     db_commit_transaction(Driver);
 

Modified: grass/branches/releasebranch_7_0/vector/v.mkgrid/rotate.c
===================================================================
--- grass/branches/releasebranch_7_0/vector/v.mkgrid/rotate.c	2014-11-24 17:22:45 UTC (rev 62893)
+++ grass/branches/releasebranch_7_0/vector/v.mkgrid/rotate.c	2014-11-24 20:53:44 UTC (rev 62894)
@@ -1,16 +1,31 @@
-#include<math.h>
+#include <math.h>
+
+static double sa = 0.0;
+static double ca = 1.0;
+
+void set_angle(double angle)
+{
+    if (angle != 0) {
+	sa = sin(angle);
+	ca = cos(angle);
+    }
+}
+
 /* rotates x and y about the origin (xo,yo) by angle radians */
 void rotate(double *x, double *y, double xo, double yo, double angle)
 {
     double tmpx, tmpy;
 
+    if (angle == 0)
+	return;
+
     /* first translate */
     tmpx = *x - xo;
     tmpy = *y - yo;
 
     /* now rotate */
-    *x = tmpx * cos(angle) - tmpy * sin(angle);
-    *y = tmpx * sin(angle) + tmpy * cos(angle);
+    *x = tmpx * ca - tmpy * sa;
+    *y = tmpx * sa + tmpy * ca;
 
     /* now translate back */
     *x += xo;

Modified: grass/branches/releasebranch_7_0/vector/v.mkgrid/v.mkgrid.html
===================================================================
--- grass/branches/releasebranch_7_0/vector/v.mkgrid/v.mkgrid.html	2014-11-24 17:22:45 UTC (rev 62893)
+++ grass/branches/releasebranch_7_0/vector/v.mkgrid/v.mkgrid.html	2014-11-24 20:53:44 UTC (rev 62894)
@@ -1,24 +1,34 @@
 <h2>DESCRIPTION</h2>
 
-<em>v.mkgrid</em> will create a vector map representation of a regular coordinate grid.
-Both point and area vector grids can be created.
+<em>v.mkgrid</em> creates a vector map representation of a regular 
+coordinate grid. Point, line, and area vector grids can be created.
 
 
 <h2>NOTES</h2>
 
-Grid points created with the <b>-p</b> flag will be placed at the
-<i>center</i> of each grid cell, not at the grid line nodes.
-
+Grid points created with the <b>type=point</b> option will be placed at 
+the <i>center</i> of each grid cell, like centroids with the default 
+<b>type=area</b> option. 
 <p>
-This is NOT to be used to generate a vector map of USGS quadrangles,
-because USGS quads are not exact rectangles.
+Grid lines created with the <b>type=line</b> option will be identical to 
+the edges of each grid cell area, like boundaries with the default 
+<b>type=area</b> option. 
+<p>
+The resultant grid can be rotated around the origin (center of the 
+grid) with the <b>angle</b> option.
+<p>
+Optionally hexagons can be created with the <b>-h</b> flag. Hexagons 
+are by default asymmetric. Symmetric hexagons can be created with the 
+<b>-s</b> flag.
+<p>
+This module is NOT to be used to generate a vector map of USGS 
+quadrangles, because USGS quads are not exact rectangles.
 
 
 <h2>EXAMPLES</h2>
 
-<h3>Creating a global grid in a latitude-longitude</h3>
+1) Create a grid in a latitude-longitude location (WGS84):
 
-To be run in a latitude-longitude location (WGS84)
 <div class="code"><pre>
 # use g.region to easily calculate rows and column for 'grid':
 g.region n=90 s=-90 w=-180 e=180 res=10 -p
@@ -40,70 +50,29 @@
 v.mkgrid map=grid_10deg grid=18,36
 </pre></div>
 
-<h3>Creating a grid in a metric projection</h3>
-
-Creating a 4x3 grid, cells 20km a side, with lower left corner at 2716500,6447000:
-
+<p>
+2) Make a 4x3 grid, cells 20km a side, with lower left corner at 2716500,6447000:
 <div class="code"><pre>
 v.mkgrid map=coro_grid grid=4,3 position=coor coor=2716500,6447000 box=20000,20000
 </pre></div>
 
-<h3>Creating a positioned grid in a latitude-longitude</h3>
-
-Creating a 10x12 lat/lon grid, cells 2 arc-min a side, with lower left corner
+<p>
+3) Make a 10x12 lat/lon grid, cells 2 arc-min a side, with lower left corner
 at 167deg 52min east, 47deg 6min south. For use with e.g. QGIS you can then
 pull this grid into a projected location with <em>v.proj</em> before
-exporting as a Shapefile with <em>v.out.ogr</em> (within GRASS GIS you could
+exporting as a Shapefile with <em>v.out.ogr</em> (within GRASS you could
 just use <em>d.grid -w</em> from the projected location for the same effect):
 
 <div class="code"><pre>
 v.mkgrid map=p2min_grid grid=10,12 position=coor coor=167:52E,47:06S box=0:02,0:02
 </pre></div>
 
-<h3>Creating a simple point pattern</h3>
 
-North Carolina sample dataset example, creating a 1km spaced point grid
-based on the current region extent defined by the "elevation" map:
-
-<div class="code"><pre>
-g.region rast=elevation -p
-# we use the row/column/resolution information to determine the grid= values:
-v.mkgrid -p map=pointpattern grid=13,15 position=region breaks=1
-</pre></div>
-<p>
-
-<h3>Creating a regular point pattern</h3>
-
-North Carolina sample dataset example, creating a regular spaced point grid
-based on the current region extent defined by the "elevation" map, using
-a two-step approach:
-
-<div class="code"><pre>
-# create first set of points, covering extent of "elevation" raster map
-g.region rast=elevation -p
-v.mkgrid -p map=pointpattern1 grid=13,15 position=region breaks=1
-
-# shift grid by half point distance (map units)
-g.region n=n+500 w=w+500 e=e+500 s=s+500 -p
-
-# create second set of points
-v.mkgrid -p map=pointpattern2 grid=13,15 position=region breaks=1
-
-# merge into final point pattern
-v.patch input=pointpattern1,pointpattern2 output=pointpattern3
-</pre></div>
-
-<center>
-<img src="v_mkgrid_ppattern.png"><br>
-Different point patterns for sampling design
-</center>
-
 <h2>SEE ALSO</h2>
 
 <em>
-<a href="d.grid.html">d.grid</a>,
-<a href="v.in.region.html">v.in.region</a>,
-<a href="v.patch.html">v.patch</a>
+<a href="v.patch.html">v.patch</a>,
+<a href="d.grid.html">d.grid</a>
 </em>
 
 <h2>AUTHORS</h2>

Modified: grass/branches/releasebranch_7_0/vector/v.mkgrid/write_grid.c
===================================================================
--- grass/branches/releasebranch_7_0/vector/v.mkgrid/write_grid.c	2014-11-24 17:22:45 UTC (rev 62893)
+++ grass/branches/releasebranch_7_0/vector/v.mkgrid/write_grid.c	2014-11-24 20:53:44 UTC (rev 62894)
@@ -5,15 +5,41 @@
 #include "grid_structs.h"
 #include "local_proto.h"
 
+static double xarray[10];
+static double yarray[10];
+
+#define  NUM_POINTS  2
+
+int write_vect(double x1, double y1, double x2, double y2,
+	       struct Map_info *Map, struct line_pnts *Points, int out_type)
+{
+    static struct line_cats *Cats = NULL;
+
+    if (!Cats) {
+	Cats = Vect_new_cats_struct();
+    }
+
+    xarray[0] = x1;
+    xarray[1] = x2;
+    yarray[0] = y1;
+    yarray[1] = y2;
+
+    if (0 > Vect_copy_xyz_to_pnts(Points, xarray, yarray, NULL, NUM_POINTS))
+	G_fatal_error(_("Out of memory"));
+    Vect_write_line(Map, out_type, Points, Cats);
+
+    return 0;
+}
+
 int write_grid(struct grid_description *grid_info, struct Map_info *Map, int nbreaks, int out_type)
 {
 
     int i, k, j;
     int rows, cols;
     int num_v_rows, num_v_cols;
-    double x, y, x_len;
+    double x, y, x_len, y_len;
     double sx, sy;
-    double width, length;
+    double width, height;
     double next_x, next_y;
     double snext_x, snext_y;
     double angle, dum;
@@ -27,7 +53,7 @@
     rows = grid_info->num_rows;
     cols = grid_info->num_cols;
     width = grid_info->width;
-    length = grid_info->length;
+    height = grid_info->height;
     angle = grid_info->angle;
 
     /*
@@ -35,16 +61,16 @@
      * to make sure that each section of the grid
      * line is less than half way around the globe
      */
-     x_len = length / (1. * nbreaks + 1);
+     x_len = width / (1. * nbreaks + 1);
+     y_len = height / (1. * nbreaks + 1);
 
     /* write out all the vector lengths (x vectors) of the entire grid  */
     G_verbose_message(_("Writing out vector rows..."));
-
-    y = grid_info->origin_y;
+    y = grid_info->south;
     for (i = 0; i < num_v_rows; ++i) {
 	double startx;
 
-	startx = grid_info->origin_x;
+	startx = grid_info->west;
 	G_percent(i, num_v_rows, 2);
 
 	for (k = 0; k < cols; k++) {
@@ -54,55 +80,63 @@
 		if (j < nbreaks)
 		    next_x = x + x_len;
 		else
-		    next_x = startx + length;
+		    next_x = startx + width;
 
 		sx = x;
 		sy = y;
 		snext_x = next_x;
 		dum = y;
 
-		rotate(&x, &y, grid_info->origin_x, grid_info->origin_y,
+		rotate(&x, &y, grid_info->xo, grid_info->yo,
 		       angle);
-		rotate(&next_x, &dum, grid_info->origin_x,
-		       grid_info->origin_y, angle);
+		rotate(&next_x, &dum, grid_info->xo, grid_info->yo, 
+		       angle);
 		write_vect(x, y, next_x, dum, Map, Points, out_type);
 
 		y = sy;
 		x = next_x = snext_x;
                 j++;
 	    } while (j <= nbreaks);
-	    startx += length;
+	    startx += width;
 	}
-	y += width;
+	y += height;
     }
 
     /* write out all the vector widths (y vectors) of the entire grid  */
     G_verbose_message(_("Writing out vector columns..."));
-    x = grid_info->origin_x;
-    for (k = 0; k < num_v_cols; ++k) {
-	y = grid_info->origin_y;
-	G_percent(k, num_v_cols, 2);
+    x = grid_info->west;
+    for (i = 0; i < num_v_cols; ++i) {
+        double starty;
+	starty = grid_info->south;
+	G_percent(i, num_v_cols, 2);
 
-	i = 0;
-        do {
-	    next_y = y + width;
+	for (k = 0; k < rows; k++) {
+	  y = starty;
+	  j = 0;
+	  do {
+	      if (j < nbreaks)
+		  next_y = y + y_len;
+	      else
+		  next_y = starty + height;
 
-	    sx = x;
-	    sy = y;
-	    snext_y = next_y;
-	    dum = x;
-	    rotate(&x, &y, grid_info->origin_x, grid_info->origin_y, angle);
-	    rotate(&dum, &next_y, grid_info->origin_x, grid_info->origin_y,
-		   angle);
+	      sx = x;
+	      sy = y;
+	      snext_y = next_y;
+	      dum = x;
+	      rotate(&x, &y, grid_info->xo, grid_info->yo, angle);
+	      rotate(&dum, &next_y, grid_info->xo, grid_info->yo,
+		    angle);
 
-	    write_vect(x, y, dum, next_y, Map, Points, out_type);
+	      write_vect(x, y, dum, next_y, Map, Points, out_type);
 
-	    x = sx;
-	    y = next_y = snext_y;
-            i++;
-	} while (i < rows);
-	/* To get exactly the same coordinates as above, x+=length is wrong */
-	x += length;
+	      x = sx;
+	      y = next_y = snext_y;
+	      j++;
+	  } while (j <= nbreaks);
+	  /* To get exactly the same coordinates as above, y+=width is wrong */
+	  starty += height;
+	}
+	x += width;
     }
 
     /* new with Vlib */
@@ -110,29 +144,3 @@
 
     return (0);
 }
-
-static double xarray[10];
-static double yarray[10];
-
-#define  NUM_POINTS  2
-
-int write_vect(double x1, double y1, double x2, double y2,
-	       struct Map_info *Map, struct line_pnts *Points, int out_type)
-{
-    static struct line_cats *Cats = NULL;
-
-    if (!Cats) {
-	Cats = Vect_new_cats_struct();
-    }
-
-    xarray[0] = x1;
-    xarray[1] = x2;
-    yarray[0] = y1;
-    yarray[1] = y2;
-
-    if (0 > Vect_copy_xyz_to_pnts(Points, xarray, yarray, NULL, NUM_POINTS))
-	G_fatal_error(_("Out of memory"));
-    Vect_write_line(Map, out_type, Points, Cats);
-
-    return 0;
-}



More information about the grass-commit mailing list