11
11
#include <grass/gis.h>
12
12
#include <grass/dbmi.h>
13
#include <grass/Vect.h>
13
#include <grass/vector.h>
14
14
#include <grass/glocale.h>
17
/* compare category structures
19
* return 1 not identical
21
static int compare_cats(struct line_cats *ACats, struct line_cats *BCats)
25
if (ACats->n_cats == 0 || BCats->n_cats == 0) {
26
if (ACats->n_cats == 0 && BCats->n_cats == 0)
29
if (ACats->n_cats == 0 && BCats->n_cats > 0)
32
if (ACats->n_cats > 0 && BCats->n_cats == 0)
36
for (i = 0; i < ACats->n_cats; i++) {
39
for (j = 0; j < BCats->n_cats; j++) {
40
if (ACats->cat[i] == BCats->cat[j] &&
41
ACats->field[i] == BCats->field[j]) {
53
/* merge a given line with all other lines of the same type and
54
* with the same categories */
55
static int merge_line(struct Map_info *Map, int line,
56
struct line_pnts *MPoints, struct line_cats *MCats)
58
int nlines, i, first, last, next_line, curr_line;
59
int merged = 0, newl = 0;
60
int next_node, direction, node_n_lines, type, ltype, lines_type;
61
static struct ilist *List = NULL;
62
static struct line_pnts *Points = NULL;
63
static struct line_cats *Cats = NULL;
66
nlines = Vect_get_num_lines(Map);
69
Points = Vect_new_line_struct();
71
Cats = Vect_new_cats_struct();
73
List = Vect_new_list();
75
Vect_reset_line(Points);
76
Vect_reset_cats(Cats);
77
Vect_reset_cats(MCats);
78
Vect_reset_list(List);
80
if (!Vect_line_alive(Map, line))
83
ltype = Vect_get_line_type(Map, line);
88
Vect_read_line(Map, MPoints, MCats, line);
91
* - loop back to start boundary via several other boundaries
92
* - one boundary forming closed loop
93
* - node with 3 entries but only 2 boundaries, one of them connecting twice,
94
* the other one must then be topologically incorrect in case of boundary */
96
/* go backward as long as there is only one other line/boundary at the current node */
97
G_debug(3, "go backward");
98
Vect_get_line_nodes(Map, line, &next_node, NULL);
102
node_n_lines = Vect_get_node_n_lines(Map, next_node);
103
/* count lines/boundaries at this node */
106
for (i = 0; i < node_n_lines; i++) {
107
curr_line = Vect_get_node_line(Map, next_node, i);
108
if ((Vect_get_line_type(Map, abs(curr_line)) & GV_LINES))
110
if ((Vect_get_line_type(Map, abs(curr_line)) == ltype)) {
111
if (abs(curr_line) != abs(first)) {
112
Vect_read_line(Map, NULL, Cats, abs(curr_line));
114
/* catgories must be identical */
115
if (compare_cats(MCats, Cats) == 0)
116
next_line = curr_line;
120
if (lines_type == 2 && abs(next_line) != abs(first) &&
121
abs(next_line) != line) {
125
Vect_get_line_nodes(Map, -first, &next_node, NULL);
128
Vect_get_line_nodes(Map, first, NULL, &next_node);
135
/* go forward as long as there is only one other line/boundary at the current node */
136
G_debug(3, "go forward");
138
/* reverse direction */
142
Vect_get_line_nodes(Map, -last, &next_node, NULL);
145
Vect_get_line_nodes(Map, last, NULL, &next_node);
148
Vect_reset_list(List);
150
G_ilist_add(List, last);
151
node_n_lines = Vect_get_node_n_lines(Map, next_node);
154
for (i = 0; i < node_n_lines; i++) {
155
curr_line = Vect_get_node_line(Map, next_node, i);
156
if ((Vect_get_line_type(Map, abs(curr_line)) & GV_LINES))
158
if ((Vect_get_line_type(Map, abs(curr_line)) == ltype)) {
159
if (abs(curr_line) != abs(last)) {
160
Vect_read_line(Map, NULL, Cats, abs(curr_line));
162
if (compare_cats(MCats, Cats) == 0)
163
next_line = curr_line;
168
if (lines_type == 2 && abs(next_line) != abs(last) &&
169
abs(next_line) != abs(first)) {
173
Vect_get_line_nodes(Map, -last, &next_node, NULL);
176
Vect_get_line_nodes(Map, last, NULL, &next_node);
184
G_debug(3, "merge %d lines", List->n_values);
185
Vect_reset_line(MPoints);
187
for (i = 0; i < List->n_values; i++) {
188
Vect_reset_line(Points);
189
Vect_read_line(Map, Points, Cats, abs(List->value[i]));
190
direction = (List->value[i] < 0 ? GV_BACKWARD : GV_FORWARD);
191
Vect_append_points(MPoints, Points, direction);
193
Vect_delete_line(Map, abs(List->value[i]));
196
merged += List->n_values;
17
202
/* Check if point is inside area with category of given field. All cats are set in
18
203
* Cats with original field.
19
204
* returns number of cats.