35 break_lines(Map,
NULL,
NULL, type, Err, 0);
63 struct ilist *List_ref,
int type,
66 return break_lines(Map, List_break, List_ref, type, Err, 0);
82 return break_lines(Map,
NULL,
NULL, type, Err, 1);
103 struct ilist *List_ref,
int type,
106 return break_lines(Map, List_break, List_ref, type, Err, 1);
109 static int cmp(
const void *a,
const void *
b)
119 static void sort_ilist(
struct ilist *List)
121 int i, j, is_sorted = 1;
123 for (i = 1; i < List->
n_values; i++) {
135 for (i = 1; i < List->
n_values; i++) {
145 int break_lines(
struct Map_info *Map,
struct ilist *List_break,
146 struct ilist *List_ref,
int type,
149 struct line_pnts *APoints, *BPoints, *Points;
152 int i, j, k,
l, ret, atype, btype, aline, bline, found, iline;
153 int nlines, nlines_org;
154 int naxlines, nbxlines, nx;
159 int touch1_n = 0, touch1_s = 0, touch1_e = 0, touch1_w = 0;
160 int touch2_n = 0, touch2_s = 0, touch2_e = 0, touch2_w = 0;
162 int node, anode1, anode2, bnode1, bnode2;
164 int a_is_ref, b_is_ref, break_a, break_b;
181 sort_ilist(List_ref);
183 sort_ilist(List_break);
189 else if (List_break) {
197 G_debug(3,
"nlines = %d", nlines);
222 for (iline = 0; iline < nlines; iline++) {
227 aline = List_ref->
value[iline];
229 else if (List_break) {
230 aline = List_break->
value[iline];
236 G_debug(3,
"aline = %d", aline);
248 if (bsearch(&aline, List_break->
value, List_break->
n_values,
sizeof(
int), cmp)) {
262 touch1_n = touch1_s = touch1_e = touch1_w = 0;
263 for (j = 1; j < APoints->
n_points; j++) {
264 if (APoints->
y[j] == ABox.
N)
266 if (APoints->
y[j] == ABox.
S)
268 if (APoints->
x[j] == ABox.
E)
270 if (APoints->
x[j] == ABox.
W)
273 G_debug(3,
"touch1: n = %d s = %d e = %d w = %d", touch1_n,
274 touch1_s, touch1_e, touch1_w);
275 touch2_n = touch2_s = touch2_e = touch2_w = 0;
276 for (j = 0; j < APoints->
n_points - 1; j++) {
277 if (APoints->
y[j] == ABox.
N)
279 if (APoints->
y[j] == ABox.
S)
281 if (APoints->
x[j] == ABox.
E)
283 if (APoints->
x[j] == ABox.
W)
286 G_debug(3,
"touch2: n = %d s = %d e = %d w = %d", touch2_n,
287 touch2_s, touch2_e, touch2_w);
293 for (j = -1; j < List->
n_values; j++) {
299 if (aline <= nlines_org)
313 bsearch(&bline, List_ref->
value, List_ref->
n_values,
sizeof(
int), cmp)) {
321 if (bsearch(&bline, List_break->
value, List_break->
n_values,
sizeof(
int), cmp)) {
326 if (!break_a && !break_b)
331 if (break_a && break_b &&
333 (!List_ref || b_is_ref)) {
337 G_debug(3,
" j = %d bline = %d", j, bline);
345 BBox = &List->
box[j];
353 if (anode1 == bnode1 || anode1 == bnode2)
355 else if (anode2 == bnode1 || anode2 == bnode2)
360 if ((node == anode1 && nodey == ABox.
N &&
361 !touch1_n && nodey == BBox->
S) ||
362 (node == anode2 && nodey == ABox.
N &&
363 !touch2_n && nodey == BBox->
S) ||
364 (node == anode1 && nodey == ABox.
S &&
365 !touch1_s && nodey == BBox->
N) ||
366 (node == anode2 && nodey == ABox.
S &&
367 !touch2_s && nodey == BBox->
N) ||
368 (node == anode1 && nodex == ABox.
E &&
369 !touch1_e && nodex == BBox->
W) ||
370 (node == anode2 && nodex == ABox.
E &&
371 !touch2_e && nodex == BBox->
W) ||
372 (node == anode1 && nodex == ABox.
W &&
373 !touch1_w && nodex == BBox->
E) ||
374 (node == anode2 && nodex == ABox.
W &&
375 !touch2_w && nodex == BBox->
E)) {
378 "lines %d and %d touching by end nodes only -> no intersection",
388 if (aline != bline) {
391 &naxlines, &nbxlines, 0);
396 &naxlines, &nbxlines, 0);
399 G_debug(3,
" naxlines = %d nbxlines = %d", naxlines, nbxlines);
404 if (aline == bline && naxlines == 0 && nbxlines == 0 &&
405 APoints->
n_points >= 3 && break_a) {
408 G_debug(3,
" Check collapsed loop");
411 if (APoints->
x[centre - 1] == APoints->
x[centre + 1] && APoints->
y[centre - 1] == APoints->
y[centre + 1] && APoints->
z[centre - 1] == APoints->
z[centre + 1]) {
420 for (i = 0; i <= centre; i++)
422 APoints->
y[i], APoints->
z[i]);
424 for (i = centre; i < APoints->
n_points; i++)
426 APoints->
y[i], APoints->
z[i]);
435 xx = (
double *)
G_malloc((naxlines + nbxlines) *
437 yx = (
double *)
G_malloc((naxlines + nbxlines) *
439 zx = (
double *)
G_malloc((naxlines + nbxlines) *
445 G_debug(3,
" aline = %d, bline = %d, naxlines = %d",
446 aline, bline, naxlines);
448 if (!check && break_a)
450 for (k = 0; k < naxlines; k++) {
455 if (!check && break_a) {
458 G_debug(3,
"Line %d written, npoints = %d", ret,
460 if (List_ref && a_is_ref) {
463 if (List_break && break_a) {
469 G_debug(3,
"axline %d has zero length", k);
474 xx[nx] = AXLines[k]->
x[0];
475 yx[nx] = AXLines[k]->
y[0];
476 zx[nx] = AXLines[k]->
z[0];
482 nbreaks += naxlines - 1;
488 if (aline != bline) {
490 G_debug(3,
" aline = %d, bline = %d, nbxlines = %d",
491 aline, bline, nbxlines);
493 if (!check && break_b)
495 for (k = 0; k < nbxlines; k++) {
500 if (!check && break_b) {
504 G_debug(5,
"Line %d written", ret);
505 if (List_ref && b_is_ref) {
514 G_debug(3,
"bxline %d has zero length", k);
520 for (l = 0; l < nx; l++) {
521 if (xx[l] == BXLines[k]->
x[0] &&
522 yx[l] == BXLines[k]->
y[0] &&
523 zx[l] == BXLines[k]->
z[0]) {
529 xx[nx] = BXLines[k]->
x[0];
530 yx[nx] = BXLines[k]->
y[0];
531 zx[nx] = BXLines[k]->
z[0];
537 nbreaks += nbxlines - 1;
539 for (k = 0; k < nbxlines; k++)
545 for (l = 0; l < nx; l++) {
555 if (naxlines > 0 && !check && break_a) {
556 G_debug(3,
"aline was broken, use next one");
564 else if (List_break) {
570 G_debug(3,
"nlines = %d", nlines);
void Vect_destroy_boxlist(struct boxlist *)
Frees all memory associated with a struct boxlist, including the struct itself.
plus_t Vect_get_num_lines(const struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
int n_points
Number of points.
int n_values
Number of values in the list.
void G_free(void *)
Free allocated memory.
int Vect_line_prune(struct line_pnts *)
Remove duplicate points, i.e. zero length segments.
void Vect_line_box(const struct line_pnts *, struct bound_box *)
Get bounding box of line.
int n_values
Number of items in the list.
#define GV_POINT
Feature types used in memory on run time (may change)
struct bound_box * box
Array of bounding boxes.
int Vect_get_node_coor(const struct Map_info *, int, double *, double *, double *)
Get node coordinates.
double * x
Array of X coordinates.
void G_ilist_add(struct ilist *, int)
Add item to ilist.
int Vect_select_lines_by_box(struct Map_info *, const struct bound_box *, int, struct boxlist *)
Select lines with bounding boxes by box.
Feature geometry info - coordinates.
int Vect_check_line_breaks(struct Map_info *Map, int type, struct Map_info *Err)
Check for and count intersecting lines, do not break.
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 Vect_check_line_breaks_list(struct Map_info *Map, struct ilist *List_break, struct ilist *List_ref, int type, struct Map_info *Err)
Check for and count intersecting lines, do not break.
int Vect_break_lines_list(struct Map_info *Map, struct ilist *List_break, struct ilist *List_ref, int type, struct Map_info *Err)
Break selected lines in vector map at each intersection.
int Vect_get_line_nodes(const struct Map_info *, int, int *, int *)
Get line nodes.
int Vect_line_intersection2(struct line_pnts *, struct line_pnts *, struct bound_box *, struct bound_box *, struct line_pnts ***, struct line_pnts ***, int *, int *, int)
Intersect 2 lines.
void G_percent(long, long, int)
Print percent complete messages.
double * y
Array of Y coordinates.
int Vect_is_3d(const struct Map_info *)
Check if vector map is 3D.
int Vect_delete_line(struct Map_info *, off_t)
Delete existing feature (topological level required)
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
List of bounding boxes with id.
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.
struct boxlist * Vect_new_boxlist(int)
Creates and initializes a struct boxlist.
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
void Vect_break_lines(struct Map_info *Map, int type, struct Map_info *Err)
Break lines in vector map at each intersection.
void void G_verbose_message(const char *,...) __attribute__((format(printf
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.