21 #include <grass/gis.h>
22 #include <grass/Vect.h>
23 #include <grass/glocale.h>
62 G_fatal_error(
"Vect_new_line_struct(): %s", _(
"Out of memory"));
71 p = (
struct line_pnts *)
malloc(
sizeof(
struct line_pnts));
75 p->alloc_points = p->n_points = 0;
78 p->x = p->y = p->z =
NULL;
93 if (p->alloc_points) {
123 for (i = 0; i <
n; i++) {
130 Points->n_points =
n;
150 Points->n_points = 0;
175 n = Points->n_points;
180 return ++(Points->n_points);
199 if (index < 0 || index > Points->n_points - 1)
201 _(
"Index out of range in"));
207 for (n = Points->n_points; n > index; n--) {
208 Points->x[
n] = Points->x[n - 1];
209 Points->y[
n] = Points->y[n - 1];
210 Points->z[
n] = Points->z[n - 1];
213 Points->x[index] = x;
214 Points->y[index] =
y;
215 Points->z[index] = z;
216 return ++(Points->n_points);
231 if (index < 0 || index > Points->n_points - 1)
233 _(
"Index out of range in"));
235 if (Points->n_points == 0)
239 for (n = index; n < Points->n_points - 1; n++) {
240 Points->x[
n] = Points->x[n + 1];
241 Points->y[
n] = Points->y[n + 1];
242 Points->z[
n] = Points->z[n + 1];
245 return --(Points->n_points);
259 if (Points->n_points > 0) {
261 for (i = 1; i < Points->n_points; i++) {
262 if (Points->x[i] != Points->x[j - 1] ||
263 Points->y[i] != Points->y[j - 1]
264 || Points->z[i] != Points->z[j - 1]) {
265 Points->x[j] = Points->x[i];
266 Points->y[j] = Points->y[i];
267 Points->z[j] = Points->z[i];
271 Points->n_points = j;
274 return (Points->n_points);
291 if (ret < Points->n_points)
292 Points->n_points = ret;
294 return (Points->n_points);
317 on = Points->n_points;
318 an = APoints->n_points;
325 if (direction == GV_FORWARD) {
326 for (i = 0; i < an; i++) {
327 Points->x[on + i] = APoints->x[i];
328 Points->y[on + i] = APoints->y[i];
329 Points->z[on + i] = APoints->z[i];
333 for (i = 0; i < an; i++) {
334 Points->x[on + i] = APoints->x[an - i - 1];
335 Points->y[on + i] = APoints->y[an - i - 1];
336 Points->z[on + i] = APoints->z[an - i - 1];
340 Points->n_points =
n;
364 for (i = 0; i < *
n; i++) {
369 *n = Points->n_points;
372 return (Points->n_points);
394 double *x,
double *
y,
double *z,
double *angle,
398 double dist = 0, length;
399 double xp = 0, yp = 0, zp = 0, dx = 0, dy = 0, dz = 0, dxy =
402 G_debug(3,
"Vect_point_on_line(): distance = %f", distance);
403 if ((distance < 0) || (Points->n_points < 2))
408 G_debug(3,
" length = %f", length);
409 if (distance < 0 || distance > length) {
410 G_debug(3,
" -> outside line");
414 np = Points->n_points;
420 dx = Points->x[1] - Points->x[0];
421 dy = Points->y[1] - Points->y[0];
422 dz = Points->z[1] - Points->z[0];
426 else if (distance == length) {
428 xp = Points->x[np - 1];
429 yp = Points->y[np - 1];
430 zp = Points->z[np - 1];
431 dx = Points->x[np - 1] - Points->x[np - 2];
432 dy = Points->y[np - 1] - Points->y[np - 2];
433 dz = Points->z[np - 1] - Points->z[np - 2];
438 for (j = 0; j < Points->n_points - 1; j++) {
441 dx = Points->x[j + 1] - Points->x[j];
442 dy = Points->y[j + 1] - Points->y[j];
443 dz = Points->z[j + 1] - Points->z[j];
445 dxyz = hypot(dxy, dz);
448 if (dist >= distance) {
449 rest = distance - dist + dxyz;
452 xp = Points->x[j] + k * dx;
453 yp = Points->y[j] + k * dy;
454 zp = Points->z[j] + k * dz;
470 *angle = atan2(dy, dx);
474 *slope = atan2(dz, dxy);
498 struct line_pnts *OutPoints)
502 double x1, y1, z1, x2, y2, z2;
504 G_debug(3,
"Vect_line_segment(): start = %f, end = %f, n_points = %d",
505 start, end, InPoints->n_points);
526 G_debug(3,
" -> seg1 = %d seg2 = %d", seg1, seg2);
528 if (seg1 == 0 || seg2 == 0) {
529 G_warning(_(
"Segment outside line, no segment created"));
535 for (i = seg1; i < seg2; i++) {
558 double dx, dy, dz, len = 0;
560 if (Points->n_points < 2)
563 for (j = 0; j < Points->n_points - 1; j++) {
564 dx = Points->x[j + 1] - Points->x[j];
565 dy = Points->y[j + 1] - Points->y[j];
566 dz = Points->z[j + 1] - Points->z[j];
567 len += hypot(hypot(dx, dy), dz);
586 double dx, dy, dz, dxy, len = 0;
590 if (Points->n_points < 2)
593 for (j = 0; j < Points->n_points - 1; j++) {
597 Points->x[j + 1], Points->y[j + 1]);
599 dx = Points->x[j + 1] - Points->x[j];
600 dy = Points->y[j + 1] - Points->y[j];
604 dz = Points->z[j + 1] - Points->z[j];
605 len += hypot(dxy, dz);
632 double ux,
double uy,
double uz,
634 double *px,
double *py,
double *pz,
635 double *dist,
double *spdist,
double *lpdist)
638 register double distance;
639 register double new_dist;
640 double tpx, tpy, tpz, tdist, tspdist, tlpdist = 0;
642 register int n_points;
645 n_points = points->n_points;
650 points->y[0], points->z[0],
651 points->x[0], points->y[0],
657 tdist = sqrt(distance);
667 points->y[0], points->z[0],
668 points->x[1], points->y[1],
673 for (i = 1; i < n_points - 1; i++) {
675 points->x[i], points->y[i],
679 points->z[i + 1], with_z,
682 if (new_dist < distance) {
690 points->x[segment - 1],
691 points->y[segment - 1],
692 points->z[segment - 1],
695 points->z[segment], with_z,
696 &tpx, &tpy, &tpz, &tspdist,
702 for (i = 0; i < segment - 1; i++) {
703 dx = points->x[i + 1] - points->x[i];
704 dy = points->y[i + 1] - points->y[i];
706 dz = points->z[i + 1] - points->z[i];
710 tlpdist += hypot(hypot(dx, dy), dz);
714 tdist = sqrt(distance);
746 double x2,
double y2,
double z2,
757 return hypot(hypot(dx, dy), dz);
759 return hypot(dx, dy);
789 np = (
int)Points->n_points / 2;
791 for (i = 0; i < np; i++) {
792 j = Points->n_points - i - 1;
796 Points->x[i] = Points->x[j];
797 Points->y[i] = Points->y[j];
798 Points->z[i] = Points->z[j];
818 static struct line_cats *cats =
NULL;
826 G_debug(3,
"Vect_get_line_cat: display line %d, ltype %d, cat %d", line,
void G_free(void *buf)
Free allocated memory.
int Vect_line_box(struct line_pnts *Points, BOUND_BOX *Box)
Get bounding box of line.
int G_begin_distance_calculations(void)
Begin distance calculations.
int dig_line_box(struct line_pnts *Points, BOUND_BOX *Box)
float Box[8][3]
Vertices for box.
struct line_pnts * Vect_new_line_struct()
Creates and initializes a struct line_pnts.
int Vect_line_prune_thresh(struct line_pnts *Points, double threshold)
Remove points in threshold.
int Vect_append_points(struct line_pnts *Points, struct line_pnts *APoints, int direction)
Appends points to the end of a line.
int Vect_reset_line(struct line_pnts *Points)
Reset line.
double dig_distance2_point_to_line(double x, double y, double z, double x1, double y1, double z1, double x2, double y2, double z2, int with_z, double *px, double *py, double *pz, double *pdist, int *status)
int Vect_append_point(struct line_pnts *Points, double x, double y, double z)
Appends one point to the end of a line.
int Vect_copy_xyz_to_pnts(struct line_pnts *Points, double *x, double *y, double *z, int n)
Copy points from array to line structure.
int Vect_copy_pnts_to_xyz(struct line_pnts *Points, double *x, double *y, double *z, int *n)
Copy points from line structure to array.
void Vect_line_reverse(struct line_pnts *Points)
Reverse the order of vertices.
int Vect_line_insert_point(struct line_pnts *Points, int index, double x, double y, double z)
Insert new point at index position and move all old points at that position and above up...
int Vect_point_on_line(struct line_pnts *Points, double distance, double *x, double *y, double *z, double *angle, double *slope)
Find point on line in the specified distance.
int dig_alloc_points(struct line_pnts *points, int num)
struct line_pnts * Vect__new_line_struct(void)
Creates and initializes a struct line_pnts.
struct line_cats * Vect_new_cats_struct()
Creates and initializes line_cats structure.
double Vect_line_length(struct line_pnts *Points)
Calculate line length, 3D-length in case of 3D vector line.
int Vect_line_prune(struct line_pnts *Points)
Remove duplicate points, i.e. zero length segments.
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int Vect_line_segment(struct line_pnts *InPoints, double start, double end, struct line_pnts *OutPoints)
Create line segment.
int G_debug(int level, const char *msg,...)
Print debugging message.
double Vect_line_geodesic_length(struct line_pnts *Points)
Calculate line length.
double Vect_points_distance(double x1, double y1, double z1, double x2, double y2, double z2, int with_z)
Calculate distance of 2 points.
int Vect_line_delete_point(struct line_pnts *Points, int index)
Delete point at given index and move all points above down.
double G_geodesic_distance(double lon1, double lat1, double lon2, double lat2)
Calculates geodesic distance.
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int Vect_line_distance(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)
calculate line distance.
int Vect_get_line_cat(struct Map_info *Map, int line, int field)
Fetches FIRST category number for given vector line and field.
int dig_prune(struct line_pnts *points, double thresh)
int Vect_destroy_line_struct(struct line_pnts *p)
Frees all memory associated with a struct line_pnts, including the struct itself. ...
int Vect_read_line(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, int line)
Read vector feature.
int Vect_cat_get(struct line_cats *Cats, int field, int *cat)
Get first found category of given field.