浏览代码

marisn: v.to.db add azimuth option (forwardport from develbranch_6, https://trac.osgeo.org/grass/changeset/36528)

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@36599 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Neteler 16 年之前
父节点
当前提交
266b318f2f
共有 7 个文件被更改,包括 68 次插入12 次删除
  1. 4 0
      vector/v.to.db/global.h
  2. 13 1
      vector/v.to.db/lines.c
  3. 15 5
      vector/v.to.db/parse.c
  4. 6 0
      vector/v.to.db/report.c
  5. 15 1
      vector/v.to.db/units.c
  6. 2 0
      vector/v.to.db/update.c
  7. 13 5
      vector/v.to.db/v.to.db.html

+ 4 - 0
vector/v.to.db/global.h

@@ -68,12 +68,16 @@ extern struct vstat vstat;
 
 
 #define O_SINUOUS       14	/* sinuousity of a line (length / <distance between end points>) */
 #define O_SINUOUS       14	/* sinuousity of a line (length / <distance between end points>) */
 
 
+#define O_AZIMUTH	15	/* line azimuth */
+
 #define U_ACRES		1
 #define U_ACRES		1
 #define U_HECTARES	2
 #define U_HECTARES	2
 #define U_KILOMETERS	3
 #define U_KILOMETERS	3
 #define U_METERS	4
 #define U_METERS	4
 #define U_MILES		5
 #define U_MILES		5
 #define U_FEET		6
 #define U_FEET		6
+#define U_RADIANS	7
+#define U_DEGREES	8
 
 
 /* areas.c */
 /* areas.c */
 int read_areas(struct Map_info *);
 int read_areas(struct Map_info *);

+ 13 - 1
vector/v.to.db/lines.c

@@ -62,7 +62,7 @@ int read_lines(struct Map_info *Map)
     register int line_num;
     register int line_num;
     struct line_pnts *Points, *EndPoints;
     struct line_pnts *Points, *EndPoints;
     struct line_cats *Cats, *LCats, *RCats;
     struct line_cats *Cats, *LCats, *RCats;
-    double len, slope, dist;
+    double len, slope, dist, dx, dy, azimuth;
 
 
     /* Initialize the Point struct */
     /* Initialize the Point struct */
     Points = Vect_new_line_struct();
     Points = Vect_new_line_struct();
@@ -192,6 +192,18 @@ int read_lines(struct Map_info *Map)
 		    EndPoints = Vect_new_line_struct();
 		    EndPoints = Vect_new_line_struct();
 		    Values[idx].d1 = len / dist;
 		    Values[idx].d1 = len / dist;
 		}
 		}
+		else if (options.option == O_AZIMUTH && (type & GV_LINES)) {
+			/* Calculate azimuth between line start and end points in degrees */
+			dx = (Points->x[Points->n_points - 1] - Points->x[0]);
+			dy = (Points->y[Points->n_points - 1] - Points->y[0]);
+			/* If line is closed... */
+			if (dx == 0.0 && dy == 0.0) azimuth = -1;
+			else {
+				azimuth = atan2(dx,dy);
+				if (azimuth < 0) azimuth = azimuth + 2*M_PI;
+			}
+			Values[idx].d1 = azimuth;
+		}
 
 
 		found = 1;
 		found = 1;
 	    }
 	    }

+ 15 - 5
vector/v.to.db/parse.c

@@ -52,7 +52,7 @@ int parse_command_line(int argc, char *argv[])
     parms.option->required = YES;
     parms.option->required = YES;
     parms.option->multiple = NO;
     parms.option->multiple = NO;
     parms.option->options =
     parms.option->options =
-	"cat,area,compact,fd,perimeter,length,count,coor,start,end,sides,query,slope,sinuous";
+	"cat,area,compact,fd,perimeter,length,count,coor,start,end,sides,query,slope,sinuous,azimuth";
     parms.option->description = _("Value to upload");
     parms.option->description = _("Value to upload");
     parms.option->descriptions =
     parms.option->descriptions =
 	"cat;insert new row for each category if doesn't exist yet;"
 	"cat;insert new row for each category if doesn't exist yet;"
@@ -72,7 +72,8 @@ int parse_command_line(int argc, char *argv[])
 	"query;result of a database query for all records of the geometry"
 	"query;result of a database query for all records of the geometry"
 	"(or geometries) from table specified by 'qlayer' option;"
 	"(or geometries) from table specified by 'qlayer' option;"
 	"slope;slope steepness of vector line or boundary;"
 	"slope;slope steepness of vector line or boundary;"
-	"sinuous;line sinuousity, calculated as line length / distance between end points;";
+	"sinuous;line sinuousity, calculated as line length / distance between end points;"
+	"azimuth;line azimuth, calculated as angle between North direction and endnode direction at startnode";
 
 
     parms.units = G_define_option();
     parms.units = G_define_option();
     parms.units->key = "units";
     parms.units->key = "units";
@@ -80,10 +81,10 @@ int parse_command_line(int argc, char *argv[])
     parms.units->required = NO;
     parms.units->required = NO;
     parms.units->multiple = NO;
     parms.units->multiple = NO;
     parms.units->options =
     parms.units->options =
-	"mi,miles,f,feet,me,meters,k,kilometers,a,acres,h,hectares";
+	"mi,miles,f,feet,me,meters,k,kilometers,a,acres,h,hectares,r,radians,d,degrees";
     parms.units->label = _("Units");
     parms.units->label = _("Units");
     parms.units->description =
     parms.units->description =
-	_("mi(les),f(eet),me(ters),k(ilometers),a(cres),h(ectares)");
+	_("mi(les),f(eet),me(ters),k(ilometers),a(cres),h(ectares),r(adians),d(egrees)");
 
 
     parms.col = G_define_standard_option(G_OPT_DB_COLUMNS);
     parms.col = G_define_standard_option(G_OPT_DB_COLUMNS);
 
 
@@ -140,7 +141,7 @@ int parse_command_line(int argc, char *argv[])
     }
     }
 
 
     if (!options.print) {
     if (!options.print) {
-	if (options.option == O_AREA || options.option == O_LENGTH || options.option == O_COUNT || options.option == O_QUERY || options.option == O_COMPACT || options.option == O_FD || options.option == O_PERIMETER || options.option == O_SLOPE || options.option == O_SINUOUS) {	/* one column required */
+	if (options.option == O_AREA || options.option == O_LENGTH || options.option == O_COUNT || options.option == O_QUERY || options.option == O_COMPACT || options.option == O_FD || options.option == O_PERIMETER || options.option == O_SLOPE || options.option == O_SINUOUS || options.option == O_AZIMUTH) {	/* one column required */
 	    if (ncols != 1) {
 	    if (ncols != 1) {
 		G_fatal_error(_("This option requires one column"));
 		G_fatal_error(_("This option requires one column"));
 	    }
 	    }
@@ -167,6 +168,9 @@ int parse_command_line(int argc, char *argv[])
 
 
     if (options.option == O_SINUOUS && !(options.type | GV_LINES))
     if (options.option == O_SINUOUS && !(options.type | GV_LINES))
 	G_fatal_error(_("The 'sinuous' option makes sense only for lines"));
 	G_fatal_error(_("The 'sinuous' option makes sense only for lines"));
+    
+    if (options.option == O_AZIMUTH && !(options.type | GV_LINES))
+	G_fatal_error(_("The 'azimuth' option makes sense only for lines"));
 
 
 
 
     return 0;
     return 0;
@@ -188,6 +192,10 @@ int parse_units(char *s)
 	x = U_ACRES;
 	x = U_ACRES;
     else if (match(s, "hectares", 1))
     else if (match(s, "hectares", 1))
 	x = U_HECTARES;
 	x = U_HECTARES;
+    else if (match(s, "radians", 1))
+	x = U_RADIANS;
+    else if (match(s, "degrees", 1))
+	x = U_DEGREES;
 
 
     return x;
     return x;
 }
 }
@@ -224,6 +232,8 @@ int parse_option(char *s)
 	x = O_SLOPE;
 	x = O_SLOPE;
     else if (strcmp(s, "sinuous") == 0)
     else if (strcmp(s, "sinuous") == 0)
 	x = O_SINUOUS;
 	x = O_SINUOUS;
+    else if (strcmp(s, "azimuth") == 0)
+	x = O_AZIMUTH;
 
 
     return x;
     return x;
 }
 }

+ 6 - 0
vector/v.to.db/report.c

@@ -164,6 +164,12 @@ int report(void)
 	    }
 	    }
 	}
 	}
 	break;
 	break;
+    case O_AZIMUTH:
+	if (G_verbose() > G_verbose_min())
+	    fprintf(stdout, "cat|azimuth\n");
+	for (i = 0; i < vstat.rcat; i++)
+		fprintf(stdout, "%d|%.15g\n", Values[i].cat, Values[i].d1);
+	break;
     }
     }
 
 
     return 0;
     return 0;

+ 15 - 1
vector/v.to.db/units.c

@@ -3,7 +3,7 @@
 
 
 int conv_units()
 int conv_units()
 {
 {
-    int i;
+    int i, rad = 0;
     double f = 1.0, sq_f = 1.0;
     double f = 1.0, sq_f = 1.0;
 
 
     switch (options.units) {
     switch (options.units) {
@@ -34,6 +34,12 @@ int conv_units()
 	f = 3.28083989501312;	/*  1 / (0.0254 * 12)    */
 	f = 3.28083989501312;	/*  1 / (0.0254 * 12)    */
 	sq_f = 10.7639104167097;	/*  1 / (0.0254 * 12)^2  */
 	sq_f = 10.7639104167097;	/*  1 / (0.0254 * 12)^2  */
 	break;
 	break;
+    case U_RADIANS:
+	rad = 1;
+	break;
+    case U_DEGREES:
+	rad = 0;
+	break;
     }
     }
 
 
     switch (options.option) {
     switch (options.option) {
@@ -46,6 +52,14 @@ int conv_units()
 	for (i = 0; i < vstat.rcat; i++)
 	for (i = 0; i < vstat.rcat; i++)
 	    Values[i].d1 *= sq_f;
 	    Values[i].d1 *= sq_f;
 	break;
 	break;
+    case O_AZIMUTH:
+	    if (rad == 0) {
+		    for (i = 0; i < vstat.rcat; i++) {
+			    if (Values[i].d1 > 0)
+				   Values[i].d1 = Values[i].d1*(180/M_PI);
+		    }
+	    }
+	break;
 
 
     }
     }
 
 

+ 2 - 0
vector/v.to.db/update.c

@@ -67,6 +67,7 @@ int update(struct Map_info *Map)
     case O_PERIMETER:
     case O_PERIMETER:
     case O_SLOPE:
     case O_SLOPE:
     case O_SINUOUS:
     case O_SINUOUS:
+    case O_AZIMUTH:
 	sprintf(buf1, "update %s set %s =", Fi->table, options.col[0]);
 	sprintf(buf1, "update %s set %s =", Fi->table, options.col[0]);
 	break;
 	break;
     case O_COOR:
     case O_COOR:
@@ -102,6 +103,7 @@ int update(struct Map_info *Map)
 	case O_PERIMETER:
 	case O_PERIMETER:
 	case O_SLOPE:
 	case O_SLOPE:
 	case O_SINUOUS:
 	case O_SINUOUS:
+	case O_AZIMUTH:
 	    sprintf(buf2, "%s %f where %s = %d", buf1, Values[i].d1, Fi->key,
 	    sprintf(buf2, "%s %f where %s = %d", buf1, Values[i].d1, Fi->key,
 		    Values[i].cat);
 		    Values[i].cat);
 	    break;
 	    break;

+ 13 - 5
vector/v.to.db/v.to.db.html

@@ -4,7 +4,8 @@
 table, or prints them (or the SQL queries used to obtain them) in a
 table, or prints them (or the SQL queries used to obtain them) in a
 form of a human-readable report. For uploaded/printed category values
 form of a human-readable report. For uploaded/printed category values
 '-1' is used for 'no category' and 'null'/'-' if category cannot be
 '-1' is used for 'no category' and 'null'/'-' if category cannot be
-found or multiple categories were found.
+found or multiple categories were found. For line azimuths '-1' is used
+for closed lines (start equals end).
 
 
 <H2>NOTES</H2>
 <H2>NOTES</H2>
 The units <em>miles</em>, <em>feet</em>, <em>meters</em> and
 The units <em>miles</em>, <em>feet</em>, <em>meters</em> and
@@ -20,20 +21,27 @@ distance between the vertices is used.
 When using <em>option=coor</em> on a vector area map, 
 When using <em>option=coor</em> on a vector area map, 
 only coordinates of centroids with unique category will be reported.
 only coordinates of centroids with unique category will be reported.
 <p>
 <p>
+Line azimuth is calculaded as angle from the North direction to the line endnode
+direction at the line statnode. By default it's reported in decimal degrees (0-360, CW) but
+it also may be repored in radians with <em>unit=radians</em>. Azimuth value
+<b>-1</b> is used to report closed line with it's startnode and endnode being in
+same place. Azimuth values make sense only if every vector line has only one
+entry in database (unique CAT value).
+<p>
 If the module is apparently slow <em>and</em> the map attributes are
 If the module is apparently slow <em>and</em> the map attributes are
 stored in an external DBMS such as PostgreSQL, it is highly recommended
 stored in an external DBMS such as PostgreSQL, it is highly recommended
 to create an index on the key (category) column.
 to create an index on the key (category) column.
 <p>
 <p>
 Uploading the vector map attributes to a database requires a table attached to
 Uploading the vector map attributes to a database requires a table attached to
 a given input vector <em>layer</em>. The <b>print only</b> (<b>-p</b>) mode
 a given input vector <em>layer</em>. The <b>print only</b> (<b>-p</b>) mode
-doesn't require a table. Use <em><a href=db.execute.html>db.execute</a></em>
-or <em><a href=v.db.addtable.html>v.db.addtable</a></em> to create a table if
+doesn't require a table. Use <em><a href="db.execute.html">db.execute</a></em>
+or <em><a href="v.db.addtable.html">v.db.addtable</a></em> to create a table if
 needed.
 needed.
 <p>
 <p>
 Updating the table has to be done column-wise. The <em>column</em> must be
 Updating the table has to be done column-wise. The <em>column</em> must be
 present in the table, except when using the <b>print only</b> (<b>-p</b>)
 present in the table, except when using the <b>print only</b> (<b>-p</b>)
-mode. Use <em><a href=db.execute.html>db.execute</a></em> or
-<em><a href=v.db.addcol.html>v.db.addcol</a></em> to add new columns if
+mode. Use <em><a href="db.execute.html">db.execute</a></em> or
+<em><a href="v.db.addcol.html">v.db.addcol</a></em> to add new columns if
 needed.
 needed.
 
 
 <H2>EXAMPLES</H2>
 <H2>EXAMPLES</H2>