GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
plus_node.c
Go to the documentation of this file.
1 
17 #include <stdlib.h>
18 #include <math.h>
19 #include <grass/Vect.h>
20 #include <grass/glocale.h>
21 
22 static double dist_squared(double, double, double, double);
23 
41 int
42 dig_node_add_line(struct Plus_head *plus, int nodeid, int lineid,
43  struct line_pnts *points, int type)
44 {
45  register int i, j, nlines;
46  float angle;
47  int ret;
48  P_NODE *node;
49 
50  G_debug(3, "dig_node_add_line(): node = %d line = %d", nodeid, lineid);
51 
52  node = plus->Node[nodeid];
53  nlines = node->n_lines;
54 
55  /* reallocate memory */
56  ret = dig_node_alloc_line(node, 1);
57  if (ret == -1)
58  return -1;
59 
60  if (type & GV_LINES) {
61  if (lineid < 0)
62  angle = dig_calc_end_angle(points, 0);
63  else
64  angle = dig_calc_begin_angle(points, 0);
65  }
66  else {
67  angle = -9.;
68  }
69  G_debug(3, " angle = %f", angle);
70 
71  /* make sure the new angle is less than the empty space at end */
72  node->angles[nlines] = 999.;
73 
74  for (i = 0; i <= nlines; i++) { /* alloced for 1 more */
75  if (angle < node->angles[i]) {
76  /* make room for insertion */
77  for (j = nlines - 1; j >= i; j--) {
78  node->angles[j + 1] = node->angles[j];
79  node->lines[j + 1] = node->lines[j];
80  }
81  node->angles[i] = angle;
82  node->lines[i] = lineid;
83  break;
84  }
85  }
86 
87  node->n_lines++;
88 
89  G_debug(3,
90  "dig_node_add_line(): line %d added position %d n_lines: %d angle %f",
91  lineid, i, node->n_lines, angle);
92 
93  return ((int)node->n_lines);
94 }
95 
96 
106 int dig_add_node(struct Plus_head *plus, double x, double y, double z)
107 {
108  int nnum;
109  P_NODE *node;
110 
111  /* First look if we have space in array of pointers to nodes
112  * and reallocate if necessary */
113  G_debug(3, "dig_add_node(): n_nodes = %d, alloc_nodes = %d",
114  plus->n_nodes, plus->alloc_nodes);
115  if (plus->n_nodes >= plus->alloc_nodes) { /* array is full */
116  if (dig_alloc_nodes(plus, 1000) == -1)
117  return -1;
118  }
119 
120  /* allocate node structure */
121  nnum = plus->n_nodes + 1;
122 
123  plus->Node[nnum] = dig_alloc_node();
124 
125  node = plus->Node[nnum];
126  node->x = x;
127  node->y = y;
128  node->z = z;
129 
130  dig_spidx_add_node(plus, nnum, x, y, z);
131 
132  plus->n_nodes++;
133 
134  G_debug(3, "new node = %d, n_nodes = %d, alloc_nodes = %d", nnum,
135  plus->n_nodes, plus->alloc_nodes);
136 
137  return (nnum);
138 }
139 
150 int dig_which_node(struct Plus_head *plus, double x, double y, double thresh)
151 {
152  register int i;
153  register int first_time;
154  register int have_match;
155  int winner;
156  double least_dist, dist;
157  P_NODE *node;
158 
159  first_time = 1;
160  have_match = 0;
161  winner = 0;
162  least_dist = 0.0;
163  for (i = 1; i <= plus->n_nodes; i++) {
164  if (plus->Node[i] == NULL)
165  continue;
166 
167  node = plus->Node[i];
168  if ((fabs(node->x - x) <= thresh) && (fabs(node->y - y) <= thresh)) {
169  dist = dist_squared(x, y, node->x, node->y);
170  if (first_time) {
171  least_dist = dist;
172  first_time = 0;
173  winner = i;
174  have_match = 1;
175  }
176  if (dist < least_dist) {
177  least_dist = dist;
178  winner = i;
179  }
180  }
181  }
182 
183  if (!have_match)
184  return (-1);
185 
186  return (winner);
187 } /* which_node () */
188 
202 float dig_node_line_angle(struct Plus_head *plus, int nodeid, int lineid)
203 {
204  int i, nlines;
205  P_NODE *node;
206 
207  G_debug(3, "dig_node_line_angle: node = %d line = %d", nodeid, lineid);
208 
209  node = plus->Node[nodeid];
210  nlines = node->n_lines;
211 
212  for (i = 0; i < nlines; i++) {
213  if (node->lines[i] == lineid)
214  return (node->angles[i]);
215  }
216 
217  G_fatal_error(_("Attempt to read line angle for the line which is not connected to the node: "
218  "node %d, line %d"), nodeid, lineid);
219 
220  return 0.0; /* not reached */
221 }
222 
223 static double dist_squared(double x1, double y1, double x2, double y2)
224 {
225  double dx, dy;
226 
227  dx = x1 - x2;
228  dy = y1 - y2;
229  return (dx * dx + dy * dy);
230 }
int dig_alloc_nodes(struct Plus_head *Plus, int add)
Definition: struct_alloc.c:93
P_NODE * dig_alloc_node()
Definition: struct_alloc.c:40
float dig_node_line_angle(struct Plus_head *plus, int nodeid, int lineid)
Return line angle.
Definition: plus_node.c:202
int dig_node_add_line(struct Plus_head *plus, int nodeid, int lineid, struct line_pnts *points, int type)
Add line info to node.
Definition: plus_node.c:42
int y
Definition: plot.c:34
int dig_node_alloc_line(P_NODE *node, int add)
Definition: struct_alloc.c:63
int dig_add_node(struct Plus_head *plus, double x, double y, double z)
Add new node to plus structure.
Definition: plus_node.c:106
int GV_LINES
Definition: vdigit/main.py:24
int dig_spidx_add_node(struct Plus_head *Plus, int node, double x, double y, double z)
Add new node to spatial index.
Definition: spindex.c:120
return NULL
Definition: dbfopen.c:1394
int dig_which_node(struct Plus_head *plus, double x, double y, double thresh)
Return actual index into node arrays of the first set of matching coordinates.
Definition: plus_node.c:150
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
float dig_calc_begin_angle(struct line_pnts *points, double thresh)
Definition: angle.c:31
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
float dig_calc_end_angle(struct line_pnts *points, double thresh)
Definition: angle.c:82