[GRASS-SVN] r64035 - grass/branches/releasebranch_7_0/lib/vector/Vlib

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Jan 9 12:12:09 PST 2015


Author: mmetz
Date: 2015-01-09 12:12:09 -0800 (Fri, 09 Jan 2015)
New Revision: 64035

Modified:
   grass/branches/releasebranch_7_0/lib/vector/Vlib/ascii.c
   grass/branches/releasebranch_7_0/lib/vector/Vlib/line.c
Log:
Vlib: sync ascii export to trunk

Modified: grass/branches/releasebranch_7_0/lib/vector/Vlib/ascii.c
===================================================================
--- grass/branches/releasebranch_7_0/lib/vector/Vlib/ascii.c	2015-01-09 20:08:02 UTC (rev 64034)
+++ grass/branches/releasebranch_7_0/lib/vector/Vlib/ascii.c	2015-01-09 20:12:09 UTC (rev 64035)
@@ -339,7 +339,7 @@
 		     int field, const struct cat_list *Clist, const char* where,
 		     const char **column_names, int header)
 {
-    int ltype, ctype, i, cat, n_lines, line, left, right, found;
+    int ltype, ctype, i, cat, line, left, right, found;
     double *xptr, *yptr, *zptr, x, y;
     static struct line_pnts *Points;
     struct line_cats *Cats, *ACats;
@@ -388,7 +388,7 @@
     /* get the region */
     G_get_window(&window);
 
-    count = n_lines = ncats = 0;
+    count = ncats = 0;
     xstring = ystring = zstring = NULL;
     cats = NULL;
     
@@ -423,17 +423,18 @@
 	    const char *col_name;
             int len_all = 0;
             
+	    db_set_string(&dbstring, Fi->table);
+	    if (db_describe_table(driver, &dbstring, &Table) != DB_OK) {
+		G_warning(_("Unable to describe table <%s>"), Fi->table);
+		return -1;
+	    }
+	    
+	    ncols = db_get_table_number_of_columns(Table);
+	    columns = (char **) G_malloc((ncols + 1) * sizeof(char *));
+
             if (column_names[0] && strcmp(column_names[0], "*") == 0) {
                 
                 /* all columns */
-                db_set_string(&dbstring, Fi->table);
-                if (db_describe_table(driver, &dbstring, &Table) != DB_OK) {
-                    G_warning(_("Unable to describe table <%s>"), Fi->table);
-                    return -1;
-                }
-                
-                ncols = db_get_table_number_of_columns(Table);
-                columns = (char **) G_malloc(ncols * sizeof(char *));
                 icol = 0;
                 for (i = 0; i < ncols; i++) {
                     col_name = db_get_column_name(db_get_table_column(Table, i));
@@ -442,26 +443,46 @@
 			columns[icol++] = G_store(col_name);
                 }
                 columns[icol] = NULL;
-                
-                db_zero_string(&dbstring);
-                db_free_table(Table);
-                Table = NULL;
             }
             else {
-		ncols = 0;
-		while (column_names[ncols])
-		    ncols++;
+		int j;
 
-                columns = (char **) G_malloc((ncols + 1) * sizeof(char *));
 		icol = 0;
-                for (i = 0; i < ncols; i++) {
-                    col_name = column_names[i];
+		i = 0;
+		while (column_names[i]) {
 		    /* key column skipped */
-                    if (strcmp(Fi->key, col_name) != 0)
-			columns[icol++] = G_store(col_name);
+                    if (strcmp(Fi->key, column_names[i]) != 0) {
+			found = 0;
+			for (j = 0; j < ncols; j++) {
+			    col_name = db_get_column_name(db_get_table_column(Table, j));
+			    if (strcmp(col_name, column_names[i]) == 0) {
+				columns[icol++] = G_store(col_name);
+				found = 1;
+				break;
+			    }
+			}
+			if (!found) {
+			    G_warning(_("Column <%s> does not exist"),
+				      column_names[i]);
+			    G_important_message(_("Available columns:"));
+			    for (j = 0; j < ncols; j++) {
+				col_name = db_get_column_name(db_get_table_column(Table, j));
+				G_important_message("%s", col_name);
+			    }
+			    G_warning(_("Export cancelled"));
+			    db_close_database(driver);
+			    db_shutdown_driver(driver);
+			    return -1;
+			}
+		    }
+		    i++;
                 }
                 columns[icol] = NULL;
             }
+
+	    db_zero_string(&dbstring);
+	    db_free_table(Table);
+	    Table = NULL;
             
 	    if (columns[0]) {
 		/* selected columns only */
@@ -503,6 +524,29 @@
 	}
     }
 
+    if (format == GV_ASCII_FORMAT_POINT && header) {
+
+	/* print header */
+	if (Map->head.with_z)
+	    fprintf(ascii, "east%snorth%sheight%scat", fs, fs, fs);
+	else
+	    fprintf(ascii, "east%snorth%scat", fs, fs);
+	if (columns) {
+	    for (i = 0; columns[i]; i++) {
+		if (db_select_value
+		    (driver, Fi->table, Fi->key, cat,
+		     columns[i], &value) < 0)
+		    G_fatal_error(_("Unable to select record from table <%s> (key %s, column %s)"),
+				  Fi->table, Fi->key, columns[i]);
+		if (columns[i])
+		    fprintf(ascii, "%s%s", fs, columns[i]);
+		else
+		    fprintf(ascii, "%s", columns[i]); /* can not happen */
+	    }
+	}
+	fprintf(ascii, "\n");
+    }
+
     Points = Vect_new_line_struct();
     Cats = Vect_new_cats_struct();
     ACats = Vect_new_cats_struct();
@@ -514,7 +558,7 @@
 
     Vect_rewind(Map);
 
-    n_skipped = line = 0;
+    count = n_skipped = line = 0;
     while (TRUE) {
 	ltype = Vect_read_next_line(Map, Points, Cats);
 	if (ltype == -1 ) {      /* failure */
@@ -637,30 +681,6 @@
 
 	    Vect_field_cat_get(Cats, field, fcats);
 
-	    /* print header */
-	    if (header && count < 1) {
-		count++;
-		if (Map->head.with_z)
-		    fprintf(ascii, "east%snorth%sheight%scat", fs, fs, fs);
-		else
-		    fprintf(ascii, "east%snorth%scat", fs, fs);
-		if (columns) {
-		    for (i = 0; columns[i]; i++) {
-			if (db_select_value
-			    (driver, Fi->table, Fi->key, cat,
-			     columns[i], &value) < 0)
-			    G_fatal_error(_("Unable to select record from table <%s> (key %s, column %s)"),
-					  Fi->table, Fi->key, columns[i]);
-			if (columns[i])
-			    fprintf(ascii, "%s%s", fs, columns[i]);
-			else
-			    fprintf(ascii, "%s", columns[i]); /* can not happen */
-		    }
-		}
-		fprintf(ascii, "\n");
-
-	    }
-
 	    if (Map->head.with_z && ver == 5) {
 		if (region_flag) {
 		    if ((window.top < Points->z[0]) ||
@@ -676,7 +696,6 @@
 		fprintf(ascii, "%s%s%s", xstring, fs, ystring);
 	    }
 
-	    
 	    if (fcats->n_values > 0 && cat > -1) {
 		if (fcats->n_values > 1) {
 		    G_warning(_("Feature has more categories. Only one category (%d) "
@@ -815,11 +834,12 @@
 		continue;
 	    /* Well-Known Text */
 	    Vect_sfa_line_astext(Points, ltype, Vect_is_3d(Map), dp, ascii);
+	    count++;
 	}
 	else {
 	    G_fatal_error(_("Unknown format"));
 	}
-	n_lines++;
+	count++;
     }
 
     if (format == GV_ASCII_FORMAT_WKT) {
@@ -860,6 +880,8 @@
 		Vect_sfa_line_astext(Points, GV_BOUNDARY, 0, dp, ascii); /* boundary is always 2D */
 	    }
 	    fprintf(ascii, ")\n");
+	    
+	    count++;
 	}
     }
 
@@ -871,7 +893,7 @@
     Vect_destroy_cats_struct(Cats);
     Vect_destroy_cats_struct(ACats);
     
-    return n_lines;
+    return count;
 }
 
 int srch(const void *pa, const void *pb)

Modified: grass/branches/releasebranch_7_0/lib/vector/Vlib/line.c
===================================================================
--- grass/branches/releasebranch_7_0/lib/vector/Vlib/line.c	2015-01-09 20:08:02 UTC (rev 64034)
+++ grass/branches/releasebranch_7_0/lib/vector/Vlib/line.c	2015-01-09 20:12:09 UTC (rev 64035)
@@ -630,7 +630,7 @@
 }
 
 /*!
-  \brief Calculate line distance.
+  \brief Calculate distance of point to line.
   
   Sets (if not null):
    - px, py - point on line,
@@ -750,7 +750,147 @@
     return (segment);
 }
 
+/*!
+  \brief Calculate geodesic distance of point to line in meters.
+  
+  Sets (if not null):
+   - px, py - point on line,
+   - dist   - distance to line,
+   - spdist - distance to point on line from segment beginning,
+   - sldist - distance to point on line form line beginning along line
 
+  \param points pointer to line_pnts structure
+  \param ux,uy,uz point coordinates
+  \param with_z flag if to use z coordinate (3D calculation)
+  \param[out] px,py,pz point on line
+  \param[out] dist distance to line,
+  \param[out] spdist distance of point from segment beginning
+  \param[out] lpdist distance of point from line
+
+  \return nearest segment (first is 1)
+ */
+int Vect_line_geodesic_distance(const struct line_pnts *points,
+		       double ux, double uy, double uz,
+		       int with_z,
+		       double *px, double *py, double *pz,
+		       double *dist, double *spdist, double *lpdist)
+{
+    int i;
+    double distance;
+    double new_dist;
+    double tpx, tpy, tpz, tdist, tspdist, tlpdist = 0, tlpdistseg;
+    double dx, dy, dz;
+    int n_points;
+    int segment;
+
+    G_begin_distance_calculations();
+
+    n_points = points->n_points;
+
+    if (n_points == 1) {
+	distance = G_distance(ux, uy, points->x[0], points->y[0]);
+	if (with_z)
+	    distance = hypot(distance, uz - points->z[0]);
+
+	tpx = points->x[0];
+	tpy = points->y[0];
+	tpz = points->z[0];
+	tdist = distance;
+	tspdist = 0;
+	tlpdist = 0;
+	segment = 0;
+
+    }
+    else {
+
+	distance =
+	    dig_distance2_point_to_line(ux, uy, uz, points->x[0],
+					points->y[0], points->z[0],
+					points->x[1], points->y[1],
+					points->z[1], with_z, 
+					&tpx, &tpy, &tpz,
+					NULL, NULL);
+
+	distance = G_distance(ux, uy, tpx, tpy);
+	if (with_z)
+	    distance = hypot(distance, uz - tpz);
+
+	segment = 1;
+
+	for (i = 1; i < n_points - 1; i++) {
+	    new_dist = dig_distance2_point_to_line(ux, uy, uz,
+						   points->x[i], points->y[i],
+						   points->z[i],
+						   points->x[i + 1],
+						   points->y[i + 1],
+						   points->z[i + 1], with_z,
+						   &tpx, &tpy, &tpz,
+						   NULL, NULL);
+	    new_dist = G_distance(ux, uy, tpx, tpy);
+	    if (with_z)
+		new_dist = hypot(new_dist, uz - tpz);
+
+	    if (new_dist < distance) {
+		distance = new_dist;
+		segment = i + 1;
+	    }
+	}
+
+	/* we have segment and now we can recalculate other values (speed) */
+	new_dist = dig_distance2_point_to_line(ux, uy, uz,
+					       points->x[segment - 1],
+					       points->y[segment - 1],
+					       points->z[segment - 1],
+					       points->x[segment],
+					       points->y[segment],
+					       points->z[segment], with_z,
+					       &tpx, &tpy, &tpz, &tspdist,
+					       NULL);
+
+	/* calculate distance from beginning of segment */
+	tspdist = G_distance(points->x[segment - 1], points->y[segment - 1],
+			     tpx, tpy);
+	if (with_z) {
+	    dz = points->z[segment - 1] - tpz;
+	    tspdist += hypot(tspdist, dz);
+	}
+
+	/* calculate distance from beginning of line */
+	if (lpdist) {
+	    tlpdist = 0;
+	    for (i = 0; i < segment - 1; i++) {
+		tlpdistseg = G_distance(points->x[i], points->y[i],
+		                        points->x[i + 1], points->y[i + 1]);
+
+		if (with_z) {
+		    dz = points->z[i + 1] - points->z[i];
+		    tlpdistseg += hypot(tlpdistseg, dz);
+		}
+
+		tlpdist += tlpdistseg;
+	    }
+	    tlpdist += tspdist;
+	}
+	tdist = distance;
+    }
+
+    if (px)
+	*px = tpx;
+    if (py)
+	*py = tpy;
+    if (pz && with_z)
+	*pz = tpz;
+    if (dist)
+	*dist = tdist;
+    if (spdist)
+	*spdist = tspdist;
+    if (lpdist)
+	*lpdist = tlpdist;
+
+    return (segment);
+}
+
+
 /*!
   \brief Calculate distance of 2 points
   



More information about the grass-commit mailing list