[GRASS-SVN] r61978 - grass/trunk/lib/vector/Vlib

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Sep 15 11:27:01 PDT 2014


Author: mmetz
Date: 2014-09-15 11:27:01 -0700 (Mon, 15 Sep 2014)
New Revision: 61978

Modified:
   grass/trunk/lib/vector/Vlib/line.c
Log:
Vlib: add Vect_line_geodesic_distance()

Modified: grass/trunk/lib/vector/Vlib/line.c
===================================================================
--- grass/trunk/lib/vector/Vlib/line.c	2014-09-15 15:17:57 UTC (rev 61977)
+++ grass/trunk/lib/vector/Vlib/line.c	2014-09-15 18:27:01 UTC (rev 61978)
@@ -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,141 @@
     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, ttpx, ttpy, ttpz; 
+    double tdist, tspdist, tlpdist = 0, tlpdistseg;
+    double 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,
+						   &ttpx, &ttpy, &ttpz,
+						   NULL, NULL);
+	    new_dist = G_distance(ux, uy, ttpx, ttpy);
+	    if (with_z)
+		new_dist = hypot(new_dist, uz - ttpz);
+
+	    if (new_dist < distance) {
+		distance = new_dist;
+		segment = i + 1;
+		tpx = ttpx;
+		tpy = ttpy;
+		tpz = ttpz;
+	    }
+	}
+
+	/* 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