[GRASS-SVN] r55275 - grass/trunk/lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Mar 1 12:45:55 PST 2013
Author: mmetz
Date: 2013-03-01 12:45:54 -0800 (Fri, 01 Mar 2013)
New Revision: 55275
Modified:
grass/trunk/lib/vector/Vlib/break_lines.c
Log:
Vlib: fix Vect_break_lines_list()
Modified: grass/trunk/lib/vector/Vlib/break_lines.c
===================================================================
--- grass/trunk/lib/vector/Vlib/break_lines.c 2013-03-01 20:43:28 UTC (rev 55274)
+++ grass/trunk/lib/vector/Vlib/break_lines.c 2013-03-01 20:45:54 UTC (rev 55275)
@@ -123,12 +123,12 @@
return (ai - bi);
}
-static void sort_ilist(struct ilist *List, int (*cmp_ilist)(const void *, const void *))
+static void sort_ilist(struct ilist *List)
{
- int i, is_sorted = 1;
+ int i, j, is_sorted = 1;
for (i = 1; i < List->n_values; i++) {
- if (cmp_ilist(&List->value[i - 1], &List->value[i]) == 1) {
+ if (List->value[i - 1] > List->value[i]) {
is_sorted = 0;
break;
}
@@ -136,6 +136,17 @@
if (!is_sorted)
qsort(List->value, List->n_values, sizeof(int), cmp);
+
+ if (List->n_values > 1) {
+ j = 1;
+ for (i = 1; i < List->n_values; i++) {
+ if (List->value[j - 1] != List->value[i]) {
+ List->value[j] = List->value[i];
+ j++;
+ }
+ }
+ List->n_values = j;
+ }
}
int
@@ -158,6 +169,7 @@
int is3d;
int node, anode1, anode2, bnode1, bnode2;
double nodex, nodey;
+ int a_is_ref, b_is_ref, break_a, break_b;
APoints = Vect_new_line_struct();
BPoints = Vect_new_line_struct();
@@ -169,13 +181,18 @@
is3d = Vect_is_3d(Map);
- if (List_break) {
+ if (List_ref)
+ sort_ilist(List_ref);
+ if (List_break)
+ sort_ilist(List_break);
+
+ if (List_ref) {
+ nlines = List_ref->n_values;
+ nlines_org = List_ref->value[List_ref->n_values - 1];
+ }
+ else if (List_break) {
nlines = List_break->n_values;
- nlines_org = 0;
- for (i = 0; i < List_break->n_values; i++) {
- if (nlines_org < List_break->value[i])
- nlines_org = List_break->value[i];
- }
+ nlines_org = List_break->value[List_break->n_values - 1];
}
else {
nlines = Vect_get_num_lines(Map);
@@ -188,9 +205,9 @@
* 1. It seems that lines/boundaries are not broken at intersections
* with points/centroids. Check if true, if yes, skip GV_POINTS
* 2. list of lines to break and list of reference lines
- * aline: line to break, if List_break == NULL, break all
- * bline: reference line, if List_ref == NULL, use all
- * break bline only if it is in the list of lines to break
+ * aline: reference line, if List_ref == NULL, use all
+ * break aline only if it is in the list of lines to break
+ * bline: line to break, if List_break == NULL, break all
*/
/* To find intersection of two lines (Vect_line_intersection) is quite slow.
@@ -206,30 +223,42 @@
*/
nbreaks = 0;
- if (List_ref)
- sort_ilist(List_ref, cmp);
-
for (iline = 0; iline < nlines; iline++) {
G_percent(iline, nlines, 1);
- if (List_break) {
+
+ /* aline: reference line */
+ if (List_ref) {
+ aline = List_ref->value[iline];
+ }
+ else if (List_break) {
aline = List_break->value[iline];
}
else {
aline = iline + 1;
}
- if (List_ref &&
- !bsearch(&aline, List_ref->value, List_ref->n_values, sizeof(int), cmp))
- continue;
-
G_debug(3, "aline = %d", aline);
if (!Vect_line_alive(Map, aline))
continue;
+ a_is_ref = 0;
+ break_a = 1;
+ if (List_ref) {
+ a_is_ref = 1;
+ }
+
+ if (List_break) {
+ break_a = 0;
+ if (bsearch(&aline, List_break->value, List_break->n_values, sizeof(int), cmp)) {
+ break_a = 1;
+ }
+ }
+
atype = Vect_read_line(Map, APoints, ACats, aline);
if (!(atype & type))
continue;
+ Vect_line_prune(APoints);
Vect_line_box(APoints, &ABox);
/* Find which sides of the box are touched by intermediate (non-end) points of line */
@@ -267,20 +296,37 @@
for (j = 0; j < List->n_values; j++) {
+ /* bline: line to break */
bline = List->id[j];
+ b_is_ref = 0;
+ break_b = 1;
+ if (List_ref &&
+ bsearch(&bline, List_ref->value, List_ref->n_values, sizeof(int), cmp)) {
+ b_is_ref = 1;
+ /* reference bline will be broken when it is aline */
+ break_b = 0;
+ }
+
+ if (List_break) {
+ break_b = 0;
+ if (bsearch(&bline, List_break->value, List_break->n_values, sizeof(int), cmp)) {
+ break_b = 1;
+ }
+ }
+
+ if (!break_a && !break_b)
+ continue;
+
/* check intersection of aline with bline only once */
- if (bline > aline) {
- if (!List_ref)
- continue;
- else if (bsearch(&bline, List_ref->value, List_ref->n_values,
- sizeof(int), cmp))
- continue;
+ if (break_a && break_b && aline < bline && (!List_ref || b_is_ref)) {
+ continue;
}
G_debug(3, " j = %d bline = %d", j, bline);
btype = Vect_read_line(Map, BPoints, BCats, bline);
+ Vect_line_prune(BPoints);
BBox = &List->box[j];
@@ -333,7 +379,7 @@
* and the line is forming collapsed loop, for example 0,0;1,0;0,0 should be broken at 1,0.
* ---> */
if (aline == bline && naxlines == 0 && nbxlines == 0 &&
- APoints->n_points >= 3) {
+ APoints->n_points >= 3 && break_a) {
int centre;
G_debug(3, " Check collapsed loop");
@@ -372,24 +418,24 @@
}
nx = 0; /* number of intersections to be written to Err */
if (naxlines > 0) { /* intersection -> write out */
- if (!check)
+ if (!check && break_a)
Vect_delete_line(Map, aline);
for (k = 0; k < naxlines; k++) {
/* Write new line segments */
/* line may collapse, don't write zero length lines */
Vect_line_prune(AXLines[k]);
if ((atype & GV_POINTS) || AXLines[k]->n_points > 1) {
- if (!check) {
+ if (!check && break_a) {
ret = Vect_write_line(Map, atype, AXLines[k],
ACats);
- if (List_ref) {
- G_ilist_add(List_ref, ret);
- }
G_debug(3, "Line %d written, npoints = %d", ret,
AXLines[k]->n_points);
- if (List_break) {
- Vect_list_append(List_break, ret);
+ if (List_ref && a_is_ref) {
+ G_ilist_add(List_ref, ret);
}
+ if (List_break && break_a) {
+ G_ilist_add(List_break, ret);
+ }
}
}
@@ -410,29 +456,24 @@
G_free(AXLines);
if (nbxlines > 0) {
- int break_bline = 1;
-
- if (List_break && !Vect_val_in_list(List_break, bline)) {
- break_bline = 0;
- }
- if (aline == bline) { /* Self intersection, do not write twice, TODO: is it OK? */
- break_bline = 0;
- }
- if (break_bline) {
- if (!check)
+ if (aline != bline) { /* Self intersection, do not write twice, TODO: is it OK? */
+ if (!check && break_b)
Vect_delete_line(Map, bline);
for (k = 0; k < nbxlines; k++) {
/* Write new line segments */
/* line may collapse, don't write zero length lines */
Vect_line_prune(BXLines[k]);
if ((btype & GV_POINTS) || BXLines[k]->n_points > 1) {
- if (!check) {
+ if (!check && break_b) {
ret =
Vect_write_line(Map, btype, BXLines[k],
BCats);
G_debug(5, "Line %d written", ret);
+ if (List_ref && b_is_ref) {
+ G_ilist_add(List_ref, ret);
+ }
if (List_break) {
- Vect_list_append(List_break, ret);
+ G_ilist_add(List_break, ret);
}
}
}
@@ -476,11 +517,16 @@
G_free(yx);
G_free(zx);
}
- if (naxlines > 0)
+ if (naxlines > 0 && !check && break_a) {
+ G_debug(3, "aline was broken, use next one");
break; /* first line was broken and deleted -> take the next one */
+ }
}
- if (List_break) {
+ if (List_ref) {
+ nlines = List_ref->n_values;
+ }
+ else if (List_break) {
nlines = List_break->n_values;
}
else {
More information about the grass-commit
mailing list