[GRASS-CVS] martinl: grass6/vector/v.distance description.html, 1.11, 1.12 main.c, 1.44, 1.45

grass at intevation.de grass at intevation.de
Thu Dec 6 09:15:17 EST 2007


Author: martinl

Update of /grassrepository/grass6/vector/v.distance
In directory doto:/tmp/cvs-serv7728

Modified Files:
	description.html main.c 
Log Message:
Matrix-like output for -a flag

Index: description.html
===================================================================
RCS file: /grassrepository/grass6/vector/v.distance/description.html,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- description.html	30 Mar 2006 11:40:14 -0000	1.11
+++ description.html	6 Dec 2007 14:15:14 -0000	1.12
@@ -1,76 +1,87 @@
 <H2>DESCRIPTION</H2>
 
-<EM>v.distance</EM>
-finds features from one vector (from=) feature to another vector (to=) nearest feature.
-Various information about relation (distance, ...) may be uploaded to attribute
-table attached to first vector map or printed to 'stdout'.
-A new vector map may be created where lines connecting nearest points on features are written.
-<P>
-
+<EM>v.distance</EM> finds the nearest element in vector map
+(<B>to</B>) for elements in vector map (<B>from</B>). Various
+information about relation (distance, category, etc.) may be uploaded
+to attribute table attached to first vector map or printed to
+'stdout'.  A new vector map may be created where lines connecting
+nearest points on features are written.
 
 <h2>EXAMPLES</H2>
 
-1) Find <B>nearest lines</B> in vector map <B>ln</B> for points from vector map
-<B>pnt</B> within the given threshold and write related line categories to
-column <B>linecat</B> in attribute table attached to vector map <B>pnt</B>:
-<br>
+<H3>Find nearest lines</H3>
+
+Find <EM>nearest lines</EM> in vector map <B>ln</B> for points from
+vector map <B>pnt</B> within the given threshold and write related
+line categories to column <B>linecat</B> in attribute table attached
+to vector map <B>pnt</B>:
+
 <div class="code"><pre>
 v.distance from=pnt to=ln upload=cat column=linecat
 </pre></div>
 
-<p>
-2) For each point from vector map <B>pnt</B> find <B>nearest area</B> from map
-<B>ar</B> within the given threshold and write the related area categories
-to column <B>areacat</B> in attribute table attached to vector map
-<B>pnt</B>. In case a point falls into a polygon area, the distance is zero:
-<br>
+<H3>Find nearest area</H3>
+
+For each point from vector map <B>pnt</B> find <EM>nearest area</EM>
+from map <B>ar</B> within the given threshold and write the related
+area categories to column <B>areacat</B> in attribute table attached
+to vector map <B>pnt</B>. In case a point falls into a polygon area,
+the distance is zero:
+
 <div class="code"><pre>
 v.distance from=pnt to=ar upload=cat column=areacat
 </pre></div>
 
-<p>
-3) Create a new vector map which contains <B>lines connecting nearest
-features</B> of maps <B>pnt</B> and map <B>ln</B>. The resulting vector map
-can be used for example to connect points to a network as needed for
-network analysis:
-<br>
+<H3>Create a new vector map</H3>
+
+Create a new vector map which contains <EM>lines connecting nearest
+features</EM> of maps <B>pnt</B> and map <B>ln</B>. The resulting
+vector map can be used for example to connect points to a network as
+needed for network analysis:
+
 <div class="code"><pre>
 v.distance -p from=pnt to=ln out=connections upload=dist column=dist
 </pre></div>
 
-<p>
-4) Query information from selected point(s). v.distance takes points from 
-   vector as input instead of stdin. First new vector map with query points, 
-   has to be created, then the map can be analysed:
+<H3>Query information</H3>
+
+Query information from selected point(s). <EM>v.distance</EM> takes
+points from vector map as input instead of stdin. First new vector map
+with query points, has to be created, then the map can be analysed:
 <br>   
-Create query map (if not present):<br>
+
+Create query map (if not present):
+
 <div class="code"><pre>
 echo "123456|654321|1" | v.in.ascii output=pnt
 </pre></div>
-<br>
-Find nearest features:<br>
+
+Find nearest features:
+
 <div class="code"><pre>
 v.distance from=pnt to=map_to_query upload=cat col=somecol -p
 </pre></div>
 
-<p>
-5) Point-in-polygon: Find <B>area</B> from vector map <B>ar</B> for each point 
-from vector map <B>pnt</B> in which the individual point falls into and write
-the related area categories to column <B>areacat</B> into attribute table 
-attached to vector map <B>pnt</B>:
-<br>
+<H3>Point-in-polygon</H3>
+
+Find <EM>area</EM> from vector map <B>ar</B> for each point from
+vector map <B>pnt</B> in which the individual point falls into and
+write the related area categories to column <B>areacat</B> into
+attribute table attached to vector map <B>pnt</B>:
+
 <div class="code"><pre>
 v.distance from=pnt to=ar dmax=0 upload=cat column=areacat
 </pre></div>
 
-<p>
-6) Univariate statistics on results: Create a vector map containing connecting
-lines and investigate mean distance to targets.<br>
-An alternative solution is to use the <tt>v.distance upload=dist</tt> option 
-to upload distances into the <i>bugs</i> vector directly, then run v.univar 
-on that. Also note you can  upload two columns at a time.<BR>
-e.g. <tt>v.distance upload=cat,dist column=nearest_id,dist_to_nr</tt>
-<br>
+<H3>Univariate statistics on results</H3>
+
+Create a vector map containing connecting lines and investigate mean
+distance to targets. An alternative solution is to use
+the <tt>v.distance upload=dist</tt> option to upload distances into
+the <i>bugs</i> vector directly, then run v.univar on that. Also note
+you can upload two columns at a time, e.g. <tt>v.distance
+upload=cat,dist column=nearest_id,dist_to_nr</tt>.
+
 <div class="code"><pre>
 # create working copy
 g.copy vect=bugsites,bugs
@@ -93,12 +104,23 @@
 v.univar vdistance_vectors column=length
 </pre></div>
 
+<H3>Print distance matrix</H3>
+
+<div class="code"><pre>
+v.distance -pa from=archsites to=archsites upload=dist col=dist
+</pre></div>
+
+Note: Matrix-like output is enabled only for flag <EM>-a</EM> and one
+given upload option.
 
 <H2>NOTES</H2>
-If a nearest feature does not have a category, column is updated to <B>null</B>.
-This is true also for areas, which means for example, that if point is in island
-(area WITHOUT category), v.distance does not search for nearest area WITH category,
-island is identified as nearest and category updated to null.
+
+If a nearest feature does not have a category, column is updated
+to <B>null</B>.  This is true also for areas, which means for example,
+that if point is in island (area WITHOUT
+category), <EM>v.distance</EM> does not search for nearest area WITH
+category, island is identified as nearest and category updated to
+null.
 <p>
 The upload <B>column</B>(s) must already exist. Create one with <em>v.db.addcol</em>.
 
@@ -113,11 +135,9 @@
 
 <H2>AUTHOR</H2>
 
-Janne Soimasuo 1994, Finland<br>
-University of Joensuu, Faculty of Forestry, Finland
-<p>
-5.0 cmd line coordinates support: Markus Neteler, ITC-irst, Trento, Italy<BR>
-<p>
-5.1 update Radim Blazek, ITC-irst, Trento, Italy
+Janne Soimasuo 1994, University of Joensuu, Faculty of Forestry, Finland<BR>
+Cmd line coordinates support: Markus Neteler, ITC-irst, Trento, Italy<BR>
+Updated for 5.1: Radim Blazek, ITC-irst, Trento, Italy<BR>
+Martix-like output by Martin Landa, FBK-irst, Trento, Italy
 
 <p><i>Last changed: $Date$</i>

Index: main.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.distance/main.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- main.c	5 Dec 2007 13:56:34 -0000	1.44
+++ main.c	6 Dec 2007 14:15:14 -0000	1.45
@@ -46,29 +46,31 @@
 /* Structure where are stored infos about nearest feature for each category */
 typedef struct {
     int    from_cat;     /* category (from) */
-    int    count;    /* number of features already found */ 
-    int    to_cat;  /* category (to) */
-    double from_x, from_y, from_z, to_x, to_y, to_z;    /* coordinates of nearest point */
-    double from_along, to_along;    /* distance along a linear feature to the nearest point */
-    double to_angle; /* angle of linear feature in nearest point */
-    double dist;  /* distance to nearest feature */
+    int    count;        /* number of features already found */ 
+    int    to_cat;       /* category (to) */
+    double from_x, from_y, from_z, to_x, to_y, to_z; /* coordinates of nearest point */
+    double from_along, to_along; /* distance along a linear feature to the nearest point */
+    double to_angle;     /* angle of linear feature in nearest point */
+    double dist;         /* distance to nearest feature */
 } NEAR;
 
 /* Upload and column store */
 typedef struct {
-    int  upload;   /* code */
+    int  upload;    /* code */
     char *column;   /* column name */
 } UPLOAD;
 
 
-static int cmp_near ( const void *, const void *);
-static int cmp_exist ( const void *, const void *);
-
+static int cmp_near(const void *, const void *);
+static int cmp_near_to(const void *, const void *);
+static int cmp_exist(const void *, const void *);
+static int print_upload(NEAR *, UPLOAD *, int, dbCatValArray *, dbCatVal *);
 
 int main (int argc, char *argv[])
 {
     int    i, j;
-    int    all = 0; /* calculate from each to each within the threshold */
+    int    print_as_matrix; /* only for all */
+    int    all;             /* calculate from each to each within the threshold */
     char   *mapset;
     struct GModule *module;
     struct Option *from_opt, *to_opt, *from_type_opt, *to_type_opt, *from_field_opt, *to_field_opt;
@@ -81,7 +83,7 @@
     struct line_pnts *FPoints, *TPoints;
     struct line_cats *FCats, *TCats;
     NEAR   *Near, *near;
-    int    anear; /* allocated space, used only for all */
+    int    anear;   /* allocated space, used only for all */
     UPLOAD *Upload; /* zero terminated */
     int ftype, fcat, tcat, count;
     int nfrom, nto, nfcats, fline, tline, tseg, tarea, area, isle, nisles;
@@ -97,6 +99,8 @@
     dbCatValArray cvarr;
     dbColumn *column;
 
+    all    = 0;
+    print_as_matrix = 0;
     column = NULL;
 
     G_gisinit (argv[0]);
@@ -104,9 +108,7 @@
     module = G_define_module();
     module->keywords = _("vector, database, attribute table");
     module->description =
-	_("Finds the nearest element in vector 'to' for elements in vector 'from'. "
-	  "Various information about this relation may be uploaded to the "
-	  "attribute table of input vector 'from' or printed to stdout.");
+      _("Finds the nearest element in vector map 'to' for elements in vector map 'from'.");
 
     from_opt = G_define_standard_option(G_OPT_V_INPUT);
     from_opt->key         = "from" ;
@@ -145,7 +147,8 @@
     out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
     out_opt->key         = "output";
     out_opt->required    = NO;
-    out_opt->description = _("Name for output vector map containing lines connecting nearest elements");
+    out_opt->description = _("Name for output vector map containing lines "
+			     "connecting nearest elements");
     
     max_opt = G_define_option();
     max_opt->key = "dmax";
@@ -217,10 +220,18 @@
     
     max = atof (max_opt->answer);
 
+    if ( all_flag->answer )
+	all = 1;
+
     /* Read upload and column options */
     /* count */
     i = 0;
-    while (upload_opt->answers[i]) i++;
+    while (upload_opt->answers[i])
+	i++;
+    if (strcmp(from_opt->answer, to_opt->answer) == 0 &&
+	all && !table_opt->answer && i == 1)
+	print_as_matrix = 1;
+
     /* alloc */
     Upload = (UPLOAD *) G_calloc ( i+1, sizeof (UPLOAD) );
     /* read upload */
@@ -267,8 +278,6 @@
     if ( Upload[i].upload != END ) 
 	G_fatal_error(_("Not enough column names"));
 
-    if ( all_flag->answer ) all = 1;
-
     /* Open 'from' vector */
     if ((mapset = G_find_vector2 (from_opt->answer, "")) == NULL )
 	G_fatal_error(_("Vector map <%s> not found"), from_opt->answer);
@@ -718,7 +727,8 @@
         if ( db_execute_immediate (driver, &stmt) != DB_OK )
 	    G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&stmt));
 
-	if (db_grant_on_table (driver, table_opt->answer, DB_PRIV_SELECT, DB_GROUP|DB_PUBLIC ) != DB_OK )
+	if (db_grant_on_table (driver, table_opt->answer, DB_PRIV_SELECT,
+			       DB_GROUP|DB_PUBLIC ) != DB_OK )
 	    G_fatal_error(_("Unable to grant privileges on table <%s>"), table_opt->answer);
 		
     } else if (!all) { /* read existing cats from table */
@@ -727,8 +737,13 @@
     }
     update_ok = update_err = update_exist = update_notexist = update_dupl = update_notfound = 0;
 
-    if ( !all ) count = nfcats;
-    
+    if ( !all ) {
+	count = nfcats;
+    }
+    else if (print_as_matrix) {
+	qsort( (void *)Near, count, sizeof(NEAR), cmp_near_to);
+    }
+
     if ( driver ) 
         db_begin_transaction ( driver );
 
@@ -773,73 +788,34 @@
 	}
 	
 	if ( print_flag->answer || (all && !table_opt->answer) ) { /* print only */
-	    fprintf(stdout, "%d", Near[i].from_cat );
-	    j = 0;
-	    while ( Upload[j].upload != END ) {
-		if (  Near[i].count == 0 ) { /* no nearest found */
-		    fprintf(stdout, "|null" );
-		} else { 
-		    switch ( Upload[j].upload ) {
-			case CAT:
-			    if ( Near[i].to_cat >= 0 ) 
-			        fprintf(stdout, "|%d", Near[i].to_cat );
-			    else 
-			        fprintf(stdout, "|null" );
-
-			    break;
-			case DIST:
-			    fprintf(stdout, "|%f", Near[i].dist );
-			    break;
-			case FROM_X:
-			    fprintf(stdout, "|%f", Near[i].from_x );
-			    break;
-			case FROM_Y:
-			    fprintf(stdout, "|%f", Near[i].from_y );
-			    break;
-			case TO_X:
-			    fprintf(stdout, "|%f", Near[i].to_x );
-			    break;
-			case TO_Y:
-			    fprintf(stdout, "|%f", Near[i].to_y );
-			    break;
-			case FROM_ALONG:
-			    fprintf(stdout, "|%f", Near[i].from_along );
-			    break;
-			case TO_ALONG:
-			    fprintf(stdout, "|%f", Near[i].to_along );
-			    break;
-			case TO_ANGLE:
-			    fprintf(stdout, "|%f", Near[i].to_angle );
-			    break;
-			case TO_ATTR:
-			    if ( catval	) {
-				switch (cvarr.ctype) {
-				    case DB_C_TYPE_INT:
-			            	fprintf(stdout, "|%d", catval->val.i );
-				    	break;
-
-				    case DB_C_TYPE_DOUBLE:
-			            	fprintf(stdout, "|%.15e", catval->val.d );
-				    	break;
-
-				    case DB_C_TYPE_STRING:
-			            	fprintf(stdout, "|%s", db_get_string(catval->val.s) );
-				    	break;
-
-				    case DB_C_TYPE_DATETIME:
-					/* TODO: formating datetime */
-			            	fprintf(stdout, "|" );
-				    	break;
-				}
-			    } else {        
-				fprintf(stdout, "|null" );
-			    }
-			    break;
+	    /*
+	      input and output is the same &&
+	      calculate distances &&
+	      only one upload option given ->
+	      print as a matrix
+	    */
+	    if (print_as_matrix) {
+		if (i == 0) {
+		    for (j = 0; j < nfrom; j++) {
+			if (j == 0)
+			    fprintf(stdout, " ");
+			fprintf(stdout, "|%d", Near[j].to_cat);
 		    }
+		    fprintf(stdout, "\n");
+		}
+		if (i % nfrom == 0) {
+		    fprintf(stdout, "%d", Near[i].from_cat);
+		    for (j = 0; j < nfrom; j++) {
+			print_upload(Near, Upload, i + j, &cvarr, catval);
+		    }
+		    fprintf(stdout, "\n");
 		}
-		j++;
 	    }
-	    fprintf(stdout, "\n" );
+	    else {
+		fprintf(stdout, "%d", Near[i].from_cat );
+		print_upload(Near, Upload, i, &cvarr, catval);
+		fprintf(stdout, "\n" );
+	    }
 	} else if ( all )  { /* insert new record */
 	    sprintf (buf1, "insert into %s values ( %d ", table_opt->answer, Near[i].from_cat);
 	    db_set_string (&stmt, buf1);
@@ -915,7 +891,8 @@
 	    }
 	} else { /* update table */
             /* check if exists in table */
-	    cex = (int *) bsearch((void *) &(Near[i].from_cat), catexist, ncatexist, sizeof(int), cmp_exist);
+	    cex = (int *) bsearch((void *) &(Near[i].from_cat), catexist, ncatexist,
+				  sizeof(int), cmp_exist);
 	    if ( cex == NULL ){ /* cat does not exist in DB */
 		update_notexist++;
 		continue;
@@ -1021,11 +998,11 @@
 	db_free_string (&stmt);
 
 	/* print stats */
-	if ( all ) {
+	if ( all && table_opt->answer) {
 	    G_message(_("%d distances calculated"), count);
 	    G_message(_("%d records inserted"), update_ok);
 	    G_message(_("%d insert errors"), update_err);
-	} else {
+	} else if (!all) {
 	    G_message(_("%d categories read from the map"), nfcats);
 	    G_message(_("%d categories exist in the table"), ncatexist);
 	    G_message(_("%d categories read from the map exist in the table"), update_exist);
@@ -1063,6 +1040,25 @@
     return 0;
 }
 
+static int cmp_near_to (const void *pa, const void *pb) {
+    NEAR *p1 = (NEAR *) pa;
+    NEAR *p2 = (NEAR *) pb;
+
+    if(p1->from_cat < p2->from_cat)
+	return -1;
+
+    if(p1->from_cat > p2->from_cat)
+	return 1;
+
+    if(p1->to_cat < p2->to_cat)
+	return -1;
+
+    if(p1->to_cat > p2->to_cat)
+	return 1;
+
+    return 0;
+}
+
 
 static int cmp_exist ( const void *pa, const void *pb)
 {
@@ -1071,5 +1067,81 @@
 
     if( *p1 < *p2 ) return -1;
     if( *p1 > *p2) return 1;
+    return 0;
+}
+
+/*
+  print out upload values 
+*/
+static int print_upload(NEAR *Near, UPLOAD *Upload, int i,
+			dbCatValArray *cvarr, dbCatVal *catval)
+{
+    int j;
+
+    j = 0;
+    while ( Upload[j].upload != END ) {
+	if (  Near[i].count == 0 ) { /* no nearest found */
+	    fprintf(stdout, "|null" );
+	} else { 
+	    switch ( Upload[j].upload ) {
+	    case CAT:
+		if ( Near[i].to_cat >= 0 ) 
+		    fprintf(stdout, "|%d", Near[i].to_cat );
+		else 
+		    fprintf(stdout, "|null" );
+		break;
+	    case DIST:
+		fprintf(stdout, "|%f", Near[i].dist );
+		break;
+	    case FROM_X:
+		fprintf(stdout, "|%f", Near[i].from_x );
+		break;
+	    case FROM_Y:
+		fprintf(stdout, "|%f", Near[i].from_y );
+		break;
+	    case TO_X:
+		fprintf(stdout, "|%f", Near[i].to_x );
+		break;
+	    case TO_Y:
+		fprintf(stdout, "|%f", Near[i].to_y );
+		break;
+	    case FROM_ALONG:
+		fprintf(stdout, "|%f", Near[i].from_along );
+		break;
+	    case TO_ALONG:
+		fprintf(stdout, "|%f", Near[i].to_along );
+			    break;
+	    case TO_ANGLE:
+		fprintf(stdout, "|%f", Near[i].to_angle );
+		break;
+	    case TO_ATTR:
+		if ( catval	) {
+		    switch (cvarr->ctype) {
+		    case DB_C_TYPE_INT:
+			fprintf(stdout, "|%d", catval->val.i );
+			break;
+			
+		    case DB_C_TYPE_DOUBLE:
+			fprintf(stdout, "|%.15e", catval->val.d );
+			break;
+			
+		    case DB_C_TYPE_STRING:
+			fprintf(stdout, "|%s", db_get_string(catval->val.s) );
+			break;
+			
+		    case DB_C_TYPE_DATETIME:
+			/* TODO: formating datetime */
+			fprintf(stdout, "|" );
+			break;
+		    }
+			    } else {        
+		    fprintf(stdout, "|null" );
+		}
+		break;
+	    }
+	}
+	j++;
+    }
+
     return 0;
 }




More information about the grass-commit mailing list