19 static int extend_lines(
struct Map_info *,
int,
int,
int,
int,
double,
21 static int find_extended_intersection(
double,
double,
double,
double,
double,
22 double,
double *,
double *);
23 static int check_extended_direction(
double,
double,
double,
int,
double,
69 int parallel,
double thresh)
72 int i, j, first_node, n_nodes;
74 struct ilist *List_exclude, *List_found;
94 for (i = 0; i < List->
n_values; i++) {
95 int line, extended, node[2];
97 line = List->
value[i];
105 node[0] = node[1] = -1;
107 if (node[0] < 0 || node[1] < 0)
113 for (j = first_node; j < n_nodes && !extended; j++) {
125 List_exclude, List_found);
129 G_debug(3,
"Vedit_extend_lines(): lines=%d,%d", line, found);
130 if (extend_lines(Map, !j, line, found, parallel, thresh,
132 G_debug(3,
"Vedit_extend_lines(): lines=%d,%d -> extended",
134 nlines_modified += 2;
140 }
while(List_found->
n_values > 0 && !extended);
147 return nlines_modified;
150 int extend_lines(
struct Map_info *Map,
int first,
int line_from,
int line_to,
151 int parallel,
double thresh,
struct ilist *List)
159 int type_from, type_to;
161 struct line_pnts *Points_from, *Points_to, *Points_final;
170 type_from =
Vect_read_line(Map, Points_from, Cats_from, line_from);
174 if (!(type_from &
GV_LINES) || !(type_to & GV_LINES))
179 int n_points, seg, is, line_to_extended;
180 double x, y, px, py, x1, y1;
181 double dist, spdist, lpdist, length;
182 double angle_t, angle_f;
187 n_points = Points_from->
n_points - 1;
190 x = Points_from->
x[0];
191 y = Points_from->
y[0];
194 x = Points_from->
x[n_points];
195 y = Points_from->
y[n_points];
198 &px, &py,
NULL, &dist, &spdist, &lpdist);
200 if (!(seg > 0 && dist > 0.0 && (thresh < 0. || dist <= thresh)))
213 line_to_extended = 0;
216 if (!find_extended_intersection(x, y, angle_f, px, py, angle_t,
230 if (!check_extended_direction(x, y, angle_f, first, x1, y1))
246 if (seg > 1 && seg < Points_to->n_points - 1)
250 line_to_extended = 1;
252 x2 = Points_to->
x[0];
253 y2 = Points_to->
y[0];
255 line_to_extended = 2;
257 x2 = Points_to->
x[Points_to->
n_points - 1];
258 y2 = Points_to->
y[Points_to->
n_points - 1];
262 if (!check_extended_direction(x2, y2, angle_t, seg == 1, x1,
271 Points_from->
x[0] = x1;
272 Points_from->
y[0] = y1;
274 Points_from->
x[n_points] = x1;
275 Points_from->
y[n_points] = y1;
284 if (line_to_extended == 1) {
287 for (is = 0; is < Points_to->
n_points; is++)
289 Points_to->
y[is], Points_to->
z[is]);
292 }
else if (line_to_extended == 2) {
294 for (is = 0; is < Points_to->
n_points; is++)
296 Points_to->
y[is], Points_to->
z[is]);
305 for (is = 0; is < seg; is++)
307 Points_to->
y[is], Points_to->
z[is]);
313 Points_final, Cats_to);
320 for (is = seg; is < Points_to->
n_points; is++)
322 Points_to->
y[is], Points_to->
z[is]);
330 Points_final, Cats_to);
342 return line_new > 0 ? 1 : 0;
345 static int find_extended_intersection(
double x1,
double y1,
double angle1,
346 double x2,
double y2,
double angle2,
347 double *
x,
double *y)
349 double c1, s1, c2, s2, d, a;
351 if (fabs(sin(angle1 - angle2)) <=
TOL) {
355 angle = atan2(y2 - y1, x2 - x1);
356 if (fabs(sin(angle - angle1)) <=
TOL) {
372 d = -c1 * s2 + c2 * s1;
377 a = (-s2 * (x2 - x1) + c2 * (y2 - y1)) / d;
384 static int check_extended_direction(
double x,
double y,
double angle,
385 int start_node,
double extx,
double exty)
388 int xdir, ydir, xext, yext;
395 xdir = (fabs(tmp) <=
TOL ? 0 : (tmp > 0 ? 1 : -1));
397 ydir = (fabs(tmp) <=
TOL ? 0 : (tmp > 0 ? 1 : -1));
401 xext = (fabs(tmp) <=
TOL ? 0 : (tmp > 0 ? 1 : -1));
403 yext = (fabs(tmp) <=
TOL ? 0 : (tmp > 0 ? 1 : -1));
405 if (xext != 0 && yext != 0) {
407 if (xdir / xext <= 0 || ydir / yext <= 0)
410 }
else if (xext == 0 && yext == 0) {
412 }
else if (xext == 0) {
415 if (xdir != 0 || ydir / yext <= 0)
421 if (ydir != 0 || xdir / xext <= 0)
int Vect_reset_list(struct ilist *)
Reset ilist structure.
off_t Vect_rewrite_line(struct Map_info *, off_t, int, const struct line_pnts *, const struct line_cats *)
Rewrites existing feature (topological level required)
int n_points
Number of points.
int n_values
Number of values in the list.
int Vect_line_distance(const struct line_pnts *, double, double, double, int, double *, double *, double *, double *, double *, double *)
Calculate distance of point to line.
double Vect_line_length(const struct line_pnts *)
Calculate line length, 3D-length in case of 3D vector line.
int Vect_get_node_coor(const struct Map_info *, int, double *, double *, double *)
Get node coordinates.
double * x
Array of X coordinates.
Feature geometry info - coordinates.
void Vect_destroy_list(struct ilist *)
Frees all memory associated with a struct ilist, including the struct itself.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
int Vedit_extend_lines(struct Map_info *Map, struct ilist *List, int nodes, int parallel, double thresh)
Extend lines in given threshold.
#define WITHOUT_Z
2D/3D vector data
int Vect_get_line_nodes(const struct Map_info *, int, int *, int *)
Get line nodes.
double * y
Array of Y coordinates.
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
int Vect_list_append(struct ilist *, int)
Append new item to the end of list if not yet present.
int Vect_line_insert_point(struct line_pnts *, int, double, double, double)
Insert new point at index position and move all old points at that position and above up...
int Vect_line_alive(const struct Map_info *, int)
Check if feature is alive or dead (topological level required)
double * z
Array of Z coordinates.
int * value
Array of values.
int Vect_point_on_line(const struct line_pnts *, double, double *, double *, double *, double *, double *)
Find point on line in the specified distance.
int Vect_find_line_list(struct Map_info *, double, double, double, int, double, int, const struct ilist *, struct ilist *)
Find the nearest line(s).
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
int Vect_read_line(const struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
int G_debug(int, const char *,...) __attribute__((format(printf
void Vect_reset_line(struct line_pnts *)
Reset line.
int Vect_get_line_type(const struct Map_info *, int)
Get line type.