[GRASS-SVN] r54954 - grass/branches/releasebranch_6_4/lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Feb 6 07:25:52 PST 2013
Author: mmetz
Date: 2013-02-06 07:25:52 -0800 (Wed, 06 Feb 2013)
New Revision: 54954
Modified:
grass/branches/releasebranch_6_4/lib/vector/Vlib/merge_lines.c
Log:
Vlib: fix #1875
Modified: grass/branches/releasebranch_6_4/lib/vector/Vlib/merge_lines.c
===================================================================
--- grass/branches/releasebranch_6_4/lib/vector/Vlib/merge_lines.c 2013-02-06 14:16:23 UTC (rev 54953)
+++ grass/branches/releasebranch_6_4/lib/vector/Vlib/merge_lines.c 2013-02-06 15:25:52 UTC (rev 54954)
@@ -22,6 +22,42 @@
#include <grass/Vect.h>
#include <grass/glocale.h>
+/* compare category structures
+ * return 0 identical
+ * return 1 not identical
+ */
+static int compare_cats(struct line_cats *ACats, struct line_cats *BCats)
+{
+ int i, j;
+
+ if (ACats->n_cats == 0 || BCats->n_cats == 0) {
+ if (ACats->n_cats == 0 && BCats->n_cats == 0)
+ return 0;
+
+ if (ACats->n_cats == 0 && BCats->n_cats > 0)
+ return 1;
+
+ if (ACats->n_cats > 0 && BCats->n_cats == 0)
+ return 1;
+ }
+
+ for (i = 0; i < ACats->n_cats; i++) {
+ int found = 0;
+
+ for (j = 0; j < BCats->n_cats; j++) {
+ if (ACats->cat[i] == BCats->cat[j] &&
+ ACats->field[i] == BCats->field[j]) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ return 1;
+ }
+
+ return 0;
+}
+
/*!
\brief Merge lines or boundaries in vector map.
@@ -44,22 +80,17 @@
int Vect_merge_lines(struct Map_info *Map, int type, int *new_lines,
struct Map_info *Err)
{
- int line, nlines, i, c, first, last, next_line, curr_line;
+ int line, nlines, i, first, last, next_line, curr_line;
int merged = 0, newl = 0;
- int next_node, direction, node_n_lines, same_type;
+ int next_node, direction, node_n_lines, ltype, lines_type;
struct Plus_head *Plus;
struct ilist *List;
struct line_pnts *MPoints, *Points;
struct line_cats *MCats, *Cats;
struct P_line *Line;
- if ((type & GV_BOUNDARY) && (type & GV_LINE)) {
+ if (!(type & GV_LINES)) {
G_warning
- ("Merging is done only with either lines or boundaries, not both types at the same time");
- return 0;
- }
- if (!(type & GV_BOUNDARY) && !(type & GV_LINE)) {
- G_warning
("Merging is done with lines or boundaries only, not with other types");
return 0;
}
@@ -80,9 +111,12 @@
continue;
Line = Plus->Line[line];
+ ltype = Line->type;
- if (!(Line->type & type))
+ if (!(ltype & type))
continue;
+
+ Vect_read_line(Map, NULL, MCats, line);
/* special cases:
* - loop back to start boundary via several other boundaries
@@ -96,17 +130,24 @@
first = -line;
while (1) {
node_n_lines = Vect_get_node_n_lines(Map, next_node);
- same_type = 0;
+ /* count lines/boundaries at this node */
+ lines_type = 0;
next_line = first;
for (i = 0; i < node_n_lines; i++) {
curr_line = Vect_get_node_line(Map, next_node, i);
- if ((Plus->Line[abs(curr_line)]->type & type)) {
- same_type++;
- if (abs(curr_line) != abs(first))
- next_line = curr_line;
+ if ((Plus->Line[abs(curr_line)]->type & GV_LINES))
+ lines_type++;
+ if ((Plus->Line[abs(curr_line)]->type == ltype)) {
+ if (abs(curr_line) != abs(first)) {
+ Vect_read_line(Map, NULL, Cats, abs(curr_line));
+
+ /* catgories must be identical */
+ if (compare_cats(MCats, Cats) == 0)
+ next_line = curr_line;
+ }
}
}
- if (same_type == 2 && abs(next_line) != abs(first) &&
+ if (lines_type == 2 && abs(next_line) != abs(first) &&
abs(next_line) != line) {
first = next_line;
@@ -134,18 +175,23 @@
while (1) {
Vect_list_append(List, last);
node_n_lines = Vect_get_node_n_lines(Map, next_node);
- same_type = 0;
+ lines_type = 0;
next_line = last;
for (i = 0; i < node_n_lines; i++) {
curr_line = Vect_get_node_line(Map, next_node, i);
- if ((Plus->Line[abs(curr_line)]->type & type)) {
- same_type++;
- if (abs(curr_line) != abs(last))
- next_line = curr_line;
+ if ((Plus->Line[abs(curr_line)]->type & GV_LINES))
+ lines_type++;
+ if ((Plus->Line[abs(curr_line)]->type == ltype)) {
+ if (abs(curr_line) != abs(last)) {
+ Vect_read_line(Map, NULL, Cats, abs(curr_line));
+
+ if (compare_cats(MCats, Cats) == 0)
+ next_line = curr_line;
+ }
}
}
- if (same_type == 2 && abs(next_line) != abs(last) &&
+ if (lines_type == 2 && abs(next_line) != abs(last) &&
abs(next_line) != abs(first)) {
last = next_line;
@@ -162,26 +208,21 @@
if (List->n_values > 1) {
G_debug(3, "merge %d lines", List->n_values);
Vect_reset_line(MPoints);
- Vect_reset_cats(MCats);
for (i = 0; i < List->n_values; i++) {
Vect_reset_line(Points);
- Vect_reset_cats(Cats);
Vect_read_line(Map, Points, Cats, abs(List->value[i]));
direction = (List->value[i] < 0 ? GV_BACKWARD : GV_FORWARD);
Vect_append_points(MPoints, Points, direction);
MPoints->n_points--;
- for (c = 0; c < Cats->n_cats; c++) {
- Vect_cat_set(MCats, Cats->field[c], Cats->cat[c]);
- }
if (Err) {
/* write out lines/boundaries to be merged */
- Vect_write_line(Err, type, Points, Cats);
+ Vect_write_line(Err, ltype, Points, Cats);
}
Vect_delete_line(Map, abs(List->value[i]));
}
MPoints->n_points++;
- Vect_write_line(Map, type, MPoints, MCats);
+ Vect_write_line(Map, ltype, MPoints, MCats);
merged += List->n_values;
newl++;
}
@@ -195,5 +236,11 @@
if (new_lines)
*new_lines = newl;
+ Vect_destroy_line_struct(Points);
+ Vect_destroy_cats_struct(Cats);
+ Vect_destroy_line_struct(MPoints);
+ Vect_destroy_cats_struct(MCats);
+ Vect_destroy_list(List);
+
return merged;
}
More information about the grass-commit
mailing list