GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
plus_area.c
Go to the documentation of this file.
1/**
2 * \file plus_area.c
3 *
4 * \brief Vector library - update topo for areas (lower level functions)
5 *
6 * Lower level functions for reading/writing/manipulating vectors.
7 *
8 * This program is free software under the GNU General Public License
9 * (>=v2). Read the file COPYING that comes with GRASS for details.
10 *
11 * \author CERL (probably Dave Gerdes), Radim Blazek
12 *
13 * \date 2001-2006
14 */
15
16#include <stdlib.h>
17#include <grass/vector.h>
18#include <grass/glocale.h>
19
20static int debug_level = -1;
21
22/*!
23 * \brief Build topo for area from lines
24 *
25 * Area is built in clockwise order.
26 * Take a given line and start off to the RIGHT/LEFT and try to complete
27 * an area.
28 *
29 * Possible Scenarios:
30 * - I. path runs into first line. : AREA!
31 * - II. path runs into a dead end (no other area lines at node) : no area
32 * - III. path runs into a previous line that is not 1st line or to 1st line
33 * but not to start node : no area
34 *
35 * After we find an area then we call point_in_area() to see if the
36 * specified point is w/in the area
37 *
38 * Old returns -1: error 0: no area (1: point in area)
39 * -2: island !!
40 *
41 * \param[in] plus pointer to Plus_head structure
42 * \param[in] first_line line id of first line
43 * \param[in] side side of line to build area on (GV_LEFT | GV_RIGHT)
44 * \param[in] lines pointer to array of lines
45 *
46 * \return -1 on error
47 * \return 0 no area
48 * \return number of lines
49 */
51 int side, plus_t **lines)
52{
53 register int i;
54 int prev_line, next_line;
55 static plus_t *array;
56 char *p;
57 static int array_size; /* 0 on startup */
58 int n_lines;
59 struct P_line *Line;
60 struct P_topo_b *topo;
61 int node;
62
63 if (debug_level == -1) {
64 const char *dstr = G_getenv_nofatal("DEBUG");
65
66 if (dstr != NULL)
67 debug_level = atoi(dstr);
68 else
69 debug_level = 0;
70 }
71
72 G_debug(3, "dig_build_area_with_line(): first_line = %d, side = %d",
74
75 /* First check if line is not degenerated (degenerated lines have angle -9)
76 * Following degenerated lines are skip by dig_angle_next_line() */
77 Line = plus->Line[first_line];
78 if (Line->type != GV_BOUNDARY)
79 return -1;
80
81 topo = (struct P_topo_b *)Line->topo;
82 node =
83 topo->N1; /* to check one is enough, because if degenerated N1 == N2 */
84 if (dig_node_line_angle(plus, node, first_line) == -9.) {
85 G_debug(3, "First line degenerated");
86 return (0);
87 }
88
89 if (array_size == 0) { /* first time */
90 array_size = 1000;
91 array = (plus_t *)dig__falloc(array_size, sizeof(plus_t));
92 if (array == NULL)
93 return (dig_out_of_memory());
94 }
95
96 if (side == GV_LEFT) {
97 first_line = -first_line; /* start at node1, reverse direction */
98 }
99 array[0] = first_line;
100 prev_line = -first_line; /* start at node2 for direct and node1 for
101 reverse direction */
102 /* angle of first line */
103 n_lines = 1;
104 while (1) {
105 next_line =
107 G_debug(3, "next_line = %d", next_line);
108
109 if (next_line == 0) {
110 G_debug(3, "Cannot build area, no next line for line %d",
111 prev_line);
112 return (-1); /* Not found */
113 }
114
115 /* Check if adjacent lines do not have the same angle */
116 if (!dig_node_angle_check(plus, next_line, GV_BOUNDARY)) {
117 G_debug(3,
118 "Cannot build area, a neighbour of the line %d has the "
119 "same angle at the node",
120 next_line);
121 return 0;
122 }
123
124 /* I. Area closed. This also handles the problem w/ 1 single area line
125 */
126 if (first_line == next_line) {
127 /* GOT ONE! fill area struct and return */
128 G_debug(3, "Got one! :");
129
130 /* avoid loop when not debugging */
131 if (debug_level > 2) {
132 for (i = 0; i < n_lines; i++) {
133 G_debug(3, " area line (%d) = %d", i, array[i]);
134 }
135 }
136
137 *lines = array;
138 return (n_lines);
139 }
140
141 /* II. Note this is a dead end */
142 /* ( if prev_line != -first_line so it goes after the previous test) ?
143 */
144 if (prev_line == next_line) {
145 G_debug(3, "Dead_end:");
146 return (0); /* dead end */
147 }
148
149 /* III. Unclosed ?, I would say started from free end */
150 for (i = 0; i < n_lines; i++)
151 if (abs(next_line) == abs(array[i])) {
152 G_debug(3, "Unclosed area:");
153 return (0); /* ran into a different area */
154 }
155
156 /* otherwise keep going */
157 if (n_lines >= array_size) {
158 p = dig__frealloc(array, array_size + 100, sizeof(plus_t),
159 array_size);
160 if (p == NULL)
161 return (dig_out_of_memory());
162 array = (plus_t *)p;
163 array_size += 100;
164 }
165 array[n_lines++] = next_line;
166 prev_line = -next_line;
167 }
168
169 return 0;
170}
171
172/*!
173 * \brief Allocate space for new area and create boundary info from array.
174 *
175 * Then for each line in area, update line (right,left) info.
176 *
177 * Neither islands nor centroids are filled.
178 *
179 * \param[in] plus pointer to Plus_head structure
180 * \param[in] n_lines number of lines
181 * \param[in] lines array of lines, negative for reverse direction
182 * \param[in] box bounding box
183 *
184 * \return number of new area
185 * \return -1 on error
186 */
187int dig_add_area(struct Plus_head *plus, int n_lines, plus_t *lines,
188 struct bound_box *box)
189{
190 register int i;
191 register int area, line;
192 struct P_area *Area;
193 struct P_line *Line;
194 struct P_topo_b *topo;
195
196 G_debug(3, "dig_add_area():");
197 /* First look if we have space in array of pointers to areas
198 * and reallocate if necessary */
199 if (plus->n_areas >= plus->alloc_areas) { /* array is full */
200 if (dig_alloc_areas(plus, 1000) == -1)
201 return -1;
202 }
203
204 /* allocate area structure */
205 area = plus->n_areas + 1;
206 G_debug(3, " new area = %d", area);
207 Area = dig_alloc_area();
208 if (Area == NULL)
209 return -1;
210
211 if (dig_area_alloc_line(Area, n_lines) == -1) {
212 dig_free_area(Area);
213 return -1;
214 }
215
216 for (i = 0; i < n_lines; i++) {
217 line = lines[i];
218 Area->lines[i] = line;
219 Line = plus->Line[abs(line)];
220 topo = (struct P_topo_b *)Line->topo;
221 if (line < 0) { /* reverse direction -> area on left */
222 if (topo->left != 0) {
223 G_warning(_("Line %d already has area/isle %d to left"), line,
224 topo->left);
225 dig_free_area(Area);
226 return -1;
227 }
228
229 G_debug(3, " Line %d left set to %d.", line, area);
230 topo->left = area;
231 }
232 else {
233 if (topo->right != 0) {
234 G_warning(_("Line %d already has area/isle %d to right"), line,
235 topo->right);
236 dig_free_area(Area);
237 return -1;
238 }
239
240 G_debug(3, " Line %d right set to %d.", line, area);
241 topo->right = area;
242 }
243 }
244 Area->n_lines = n_lines;
245 Area->centroid = 0;
246
247 plus->Area[area] = Area;
248
249 dig_spidx_add_area(plus, area, box);
250
251 plus->n_areas++;
252
253 return (area);
254}
255
256/*!
257 * \brief Add isle to area if does not exist yet.
258 *
259 * \param[in] plus pointer to Plus_head structure
260 * \param[in] area area id
261 * \param[in] isle isle id
262 *
263 * \return 0
264 */
265int dig_area_add_isle(struct Plus_head *plus, int area, int isle)
266{
267 int i;
268 struct P_area *Area;
269
270 G_debug(3, "dig_area_add_isle(): area = %d isle = %d", area, isle);
271
272 if (debug_level == -1) {
273 const char *dstr = G_getenv_nofatal("DEBUG");
274
275 if (dstr != NULL)
276 debug_level = atoi(dstr);
277 else
278 debug_level = 0;
279 }
280
281 Area = plus->Area[area];
282 if (Area == NULL)
283 G_fatal_error("Attempt to add isle to dead area");
284
285 if (debug_level > 0) {
286 for (i = 0; i < Area->n_isles; i++) {
287 if (Area->isles[i] == isle) {
288 /* Already exists: bug in vector libs */
289 G_warning(_("Isle already registered in area"));
290 return 0;
291 }
292 }
293 }
294
295 if (Area->alloc_isles <= Area->n_isles) /* array is full */
296 dig_area_alloc_isle(Area, 1);
297
298 Area->isles[Area->n_isles] = isle;
299 Area->n_isles++;
300 G_debug(3, " -> n_isles = %d", Area->n_isles);
301
302 return 0;
303}
304
305/*!
306 * \brief Delete isle from area.
307 *
308 * \param[in] plus pointer to Plus_head structure
309 * \param[in] area area id
310 * \param[in] isle isle id
311 *
312 * \return 0
313 */
314int dig_area_del_isle(struct Plus_head *plus, int area, int isle)
315{
316 int i;
317 struct P_area *Area;
318
319 G_debug(3, "dig_area_del_isle(): area = %d isle = %d", area, isle);
320
321 Area = plus->Area[area];
322 if (Area == NULL)
323 G_fatal_error(_("Attempt to delete isle from dead area"));
324
325 /* find index of the isle */
326 i = 0;
327 while (i < Area->n_isles && Area->isles[i] != isle)
328 i++;
329
330 if (i == Area->n_isles) {
332 _("Attempt to delete not registered isle %d from area %d"), isle,
333 area);
334 }
335
336 i++;
337 while (i < Area->n_isles) {
338 Area->isles[i - 1] = Area->isles[i];
339 i++;
340 }
341
342 Area->n_isles--;
343
344 return 0;
345}
346
347/*!
348 * \brief Delete area from Plus_head structure
349 *
350 * This function deletes area from the topo structure and resets references
351 * to this area in boundaries, isles (within), and the centroid (if any) to 0.
352 * Possible new area is not created by this function, so that
353 * old boundaries participating in this area are left without area information
354 * even if form new area.
355 * Not enabled now: If area is inside other area, area info for islands within
356 * deleted area is reset to that area outside.
357 * (currently area info of isles is set to 0)
358 *
359 * \param[in] plus pointer to Plus_head structure
360 * \param[in] area area id
361 *
362 * \return 0 on error
363 * \return 1 on success
364 */
365int dig_del_area(struct Plus_head *plus, int area)
366{
367 int i, line;
368
369 struct P_area *Area;
370 struct P_line *Line;
371 struct P_isle *Isle;
372 struct P_topo_b *btopo;
373 struct P_topo_c *ctopo;
374
375 G_debug(3, "dig_del_area() area = %d", area);
376 Area = plus->Area[area];
377
378 if (Area == NULL) {
379 G_warning(_("Attempt to delete dead area"));
380 return 0;
381 }
382
384
385 /* Set area for all lines to 0 */
386 /* isle = 0; */
387 for (i = 0; i < Area->n_lines; i++) {
388 line = Area->lines[i]; /* >0 = clockwise -> right, <0 = counterclockwise
389 ->left */
390 Line = plus->Line[abs(line)];
391 btopo = (struct P_topo_b *)Line->topo;
392 if (line > 0) {
393 G_debug(3, " Set line %d right side to 0", line);
394 btopo->right = 0;
395 }
396 else {
397 G_debug(3, " Set line %d left side to 0", line);
398 btopo->left = 0;
399 }
400
401 /* Find the isle this area is part of (used late below) */
402 /*
403 if ( line > 0 ) {
404 if ( Line->left < 0 ) isle = Line->left;
405 } else {
406 if ( Line->right < 0 ) isle = Line->right;
407 }
408 */
409 }
410
411 /* Unset area information of centroid */
412 /* TODO: duplicate centroids have also area information ->
413 * 1) do not save such info
414 * 2) find all by box and reset info */
415 line = Area->centroid;
416 if (line > 0) {
417 Line = plus->Line[line];
418 if (!Line) {
419 G_warning(_("Dead centroid %d registered for area (bug in the "
420 "vector library)"),
421 line);
422 }
423 else {
424 ctopo = (struct P_topo_c *)Line->topo;
425 ctopo->area = 0;
426 }
427 }
428
429 /* Find the area this area is within */
430 /*
431 area_out = 0;
432 if ( isle > 0 ) {
433 Isle = plus->Isle[abs(isle)];
434 area_out = Isle->area;
435 }
436 */
437
438 /* Reset information about area outside for isles within this area */
439 G_debug(3, " n_isles = %d", Area->n_isles);
440 for (i = 0; i < Area->n_isles; i++) {
441 Isle = plus->Isle[Area->isles[i]];
442 if (Isle == NULL) {
443 G_fatal_error(_("Attempt to delete area %d info from dead isle %d"),
444 area, Area->isles[i]);
445 }
446 else {
447 /* Isle->area = area_out; */
448 Isle->area = 0;
449 }
450 }
451
452 /* free structures */
453 dig_free_area(Area);
454 plus->Area[area] = NULL;
455 return 1;
456}
457
458/*!
459 * \brief Find line number of next angle to follow a line
460 *
461 * Assume that lines are sorted in increasing angle order and angles
462 * of points and degenerated lines are set to -9 (ignored).
463 *
464 * \param[in] plus pointer to Plus_head structure
465 * \param[in] current_line current line id, negative if request for end node
466 * \param[in] side side GV_RIGHT or GV_LEFT
467 * \param[in] type line type (GV_LINE, GV_BOUNDARY or both)
468 * \param[out] angle
469 *
470 * \return line number of next angle to follow a line (negative if connected by
471 * end node) (number of current line may be returned if dangle - this is used in
472 * build) \return 0 on error or not found
473 */
475 int type, float *angle)
476{
477 int next;
478 int line;
479 plus_t node;
480 struct P_node *Node;
481 struct P_line *Line;
482
483 if (debug_level == -1) {
484 const char *dstr = G_getenv_nofatal("DEBUG");
485
486 if (dstr != NULL)
487 debug_level = atoi(dstr);
488 else
489 debug_level = 0;
490 }
491
492 G_debug(3, "dig__angle_next_line: line = %d, side = %d, type = %d",
494
495 Line = plus->Line[abs(current_line)];
496
497 if (!(Line->type & GV_LINES)) {
498 if (angle)
499 *angle = -9.;
500 return 0;
501 }
502
503 node = 0;
504 if (current_line > 0) {
505 if (Line->type == GV_LINE) {
506 struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
507
508 node = topo->N1;
509 }
510 else if (Line->type == GV_BOUNDARY) {
511 struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
512
513 node = topo->N1;
514 }
515 }
516 else {
517 if (Line->type == GV_LINE) {
518 struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
519
520 node = topo->N2;
521 }
522 else if (Line->type == GV_BOUNDARY) {
523 struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
524
525 node = topo->N2;
526 }
527 }
528
529 G_debug(3, " node = %d", node);
530
531 Node = plus->Node[node];
532 G_debug(3, " n_lines = %d", Node->n_lines);
533 /* avoid loop when not debugging */
534 if (debug_level > 2) {
535 int i;
536
537 for (i = 0; i < Node->n_lines; i++) {
538 G_debug(3, " i = %d line = %d angle = %f", i, Node->lines[i],
539 Node->angles[i]);
540 }
541 }
542
543 /* first find index for that line */
544 next = Node->n_lines - 1;
545 while (next >= 0 && Node->lines[next] != current_line) {
546 next--;
547 }
548
549 if (next == -1) {
550 /* internal error, should not happen */
552 "dig_angle_next_line(): line %d not found at its own node %d",
553 current_line, node);
554 if (angle)
555 *angle = -9.;
556 return 0; /* not found */
557 }
558
559 G_debug(3, " current position = %d", next);
560 while (1) {
561 if (side == GV_RIGHT) { /* go up (greater angle) */
562 if (next == Node->n_lines - 1)
563 next = 0;
564 else
565 next++;
566 }
567 else { /* go down (smaller angle) */
568 if (next == 0)
569 next = Node->n_lines - 1;
570 else
571 next--;
572 }
573 G_debug(3, " next = %d line = %d angle = %f", next, Node->lines[next],
574 Node->angles[next]);
575
576 if (Node->angles[next] == -9.) { /* skip points and degenerated */
577 G_debug(3, " point/degenerated -> skip");
578 if (Node->lines[next] == current_line)
579 break; /* Yes, that may happen if input line is degenerated and
580 isolated and this breaks loop */
581 else
582 continue;
583 }
584
585 line = Node->lines[next];
586 Line = plus->Line[abs(line)];
587
588 if (Line->type & type) { /* line found */
589 G_debug(3, " this one");
590 if (angle)
591 *angle = Node->angles[next];
592 return line;
593 }
594
595 /* input line reached, this must be last, because current_line may be
596 * correct return value (dangle) */
597 if (line == current_line)
598 break;
599 }
600 G_debug(3, " No next line for line %d at node %d", current_line,
601 (int)node);
602 if (angle)
603 *angle = -9.;
604
605 return 0;
606}
607
608/*!
609 * \brief Check if angles of adjacent lines differ.
610 *
611 * Negative line number for end point. Assume that lines are sorted
612 * in increasing angle order and angles of points and degenerated
613 * lines are set to 9 (ignored).
614 *
615 * \param[in] plus pointer to Plus_head structure
616 * \param[in] line current line id, negative if request for node 2
617 * \param[in] type line type (GV_LINE, GV_BOUNDARY or both)
618 *
619 * \return 1 angles differ
620 * \return 0 angle of a line up or down is identical
621 */
622int dig_node_angle_check(struct Plus_head *plus, plus_t line, int type)
623{
624 int next, prev;
625 float angle1, angle2;
626 plus_t node = 0;
627 struct P_line *Line;
628
629 G_debug(3, "dig_node_angle_check: line = %d, type = %d", line, type);
630
631 Line = plus->Line[abs(line)];
632 if (!(Line->type & GV_LINES))
633 return 0;
634
635 if (line > 0) {
636 if (Line->type == GV_LINE) {
637 struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
638
639 node = topo->N1;
640 }
641 else if (Line->type == GV_BOUNDARY) {
642 struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
643
644 node = topo->N1;
645 }
646 }
647 else {
648 if (Line->type == GV_LINE) {
649 struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
650
651 node = topo->N2;
652 }
653 else if (Line->type == GV_BOUNDARY) {
654 struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
655
656 node = topo->N2;
657 }
658 }
659
660 angle1 = dig_node_line_angle(plus, node, line);
661
662 /* Next */
663 next = dig_angle_next_line(plus, line, GV_RIGHT, type, &angle2);
664 /* angle2 = dig_node_line_angle(plus, node, next); */
665 if (angle1 == angle2) {
666 G_debug(
667 3,
668 " The line to the right has the same angle: node = %d, line = %d",
669 node, next);
670 return 0;
671 }
672
673 /* Previous */
674 prev = dig_angle_next_line(plus, line, GV_LEFT, type, &angle2);
675 /* angle2 = dig_node_line_angle(plus, node, prev); */
676 if (angle1 == angle2) {
677 G_debug(
678 3,
679 " The line to the left has the same angle: node = %d, line = %d",
680 node, prev);
681 return 0;
682 }
683
684 return 1; /* OK */
685}
686
687/*!
688 * \brief Allocate space for new island and create boundary info from array.
689 *
690 * The order of input lines is expected to be counter clockwise.
691 * Then for each line in isle, update line (right,left) info.
692 *
693 * Area number the island is within is not filled.
694 *
695 * \param[in] plus pointer to Plus_head structure
696 * \param[in] n_lines number of lines
697 * \param[in] lines array of lines, negative for reverse direction
698 * \param[in] box bounding box
699 *
700 * \return number of new isle
701 * \return -1 on error
702 */
703int dig_add_isle(struct Plus_head *plus, int n_lines, plus_t *lines,
704 struct bound_box *box)
705{
706 register int i;
707 register int isle, line;
708 struct P_isle *Isle;
709 struct P_line *Line;
710 struct P_topo_b *topo;
711
712 G_debug(3, "dig_add_isle():");
713 /* First look if we have space in array of pointers to isles
714 * and reallocate if necessary */
715 if (plus->n_isles >= plus->alloc_isles) { /* array is full */
716 if (dig_alloc_isles(plus, 1000) == -1)
717 return -1;
718 }
719
720 /* allocate isle structure */
721 isle = plus->n_isles + 1;
722 Isle = dig_alloc_isle();
723 if (Isle == NULL)
724 return -1;
725
726 if ((dig_isle_alloc_line(Isle, n_lines)) == -1) {
727 dig_free_isle(Isle);
728 return -1;
729 }
730
731 Isle->area = 0;
732
733 for (i = 0; i < n_lines; i++) {
734 line = lines[i];
735 G_debug(3, " i = %d line = %d", i, line);
736 Isle->lines[i] = line;
737 Line = plus->Line[abs(line)];
738 topo = (struct P_topo_b *)Line->topo;
739 if (line < 0) { /* revers direction -> isle on left */
740 if (topo->left != 0) {
741 G_warning(_("Line %d already has area/isle %d to left"), line,
742 topo->left);
743 dig_free_isle(Isle);
744 return -1;
745 }
746 topo->left = -isle;
747 }
748 else {
749 if (topo->right != 0) {
750 G_warning(_("Line %d already has area/isle %d to right"), line,
751 topo->right);
752 dig_free_isle(Isle);
753 return -1;
754 }
755
756 topo->right = -isle;
757 }
758 }
759
760 Isle->n_lines = n_lines;
761
762 plus->Isle[isle] = Isle;
763
764 dig_spidx_add_isle(plus, isle, box);
765
766 plus->n_isles++;
767
768 return (isle);
769}
770
771/*!
772 * \brief Delete island from Plus_head structure
773 *
774 * Reset references to it in lines and area outside.
775 *
776 * \param[in] plus pointer to Plus_head structure
777 * \param[in] isle isle id
778 *
779 * \return 1
780 */
781int dig_del_isle(struct Plus_head *plus, int isle)
782{
783 int i, line;
784 struct P_line *Line;
785 struct P_isle *Isle;
786 struct P_topo_b *topo;
787
788 G_debug(3, "dig_del_isle() isle = %d", isle);
789 Isle = plus->Isle[isle];
790
792
793 /* Set area for all lines to 0 */
794 for (i = 0; i < Isle->n_lines; i++) {
795 line = Isle->lines[i]; /* >0 = clockwise -> right, <0 = counterclockwise
796 ->left */
797 Line = plus->Line[abs(line)];
798 topo = (struct P_topo_b *)Line->topo;
799 if (line > 0)
800 topo->right = 0;
801 else
802 topo->left = 0;
803 }
804
805 /* Delete reference from area it is within */
806 G_debug(3, " area outside isle = %d", Isle->area);
807 if (Isle->area > 0) {
808 if (plus->Area[Isle->area] == NULL) {
809 G_fatal_error(_("Attempt to delete isle %d info from dead area %d"),
810 isle, Isle->area);
811 }
812 else {
813 dig_area_del_isle(plus, Isle->area, isle);
814 }
815 }
816
817 /* free structures */
818 dig_free_isle(Isle);
819 plus->Isle[isle] = NULL;
820
821 return 1;
822}
#define NULL
Definition ccmath.h:32
const char * G_getenv_nofatal(const char *)
Get environment variable.
Definition env.c:405
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
#define GV_LINE
#define GV_LINES
#define GV_BOUNDARY
#define GV_RIGHT
#define GV_LEFT
Boundary side indicator left/right.
void * dig__falloc(int, int)
Definition allocation.c:117
int dig_spidx_add_isle(struct Plus_head *, int, const struct bound_box *)
Add new island to spatial index.
Definition spindex.c:394
float dig_node_line_angle(struct Plus_head *, int, int)
Return line angle.
Definition plus_node.c:198
int dig_spidx_del_area(struct Plus_head *, int)
Delete area from spatial index.
Definition spindex.c:514
int dig_spidx_add_area(struct Plus_head *, int, const struct bound_box *)
Add new area to spatial index.
Definition spindex.c:360
int dig_alloc_areas(struct Plus_head *, int)
Reallocate array of pointers to areas.
int dig_alloc_isles(struct Plus_head *, int)
Reallocate array of pointers to isles.
int dig_area_alloc_isle(struct P_area *, int)
Allocate space in P_area for add new isles.
int dig_spidx_del_isle(struct Plus_head *, int)
Delete isle from spatial index.
Definition spindex.c:567
void * dig__frealloc(void *, int, int, int)
Definition allocation.c:132
void dig_free_area(struct P_area *)
Free area structure.
struct P_isle * dig_alloc_isle(void)
Allocate new isle structure.
struct P_area * dig_alloc_area(void)
Allocate new area structure.
int dig_isle_alloc_line(struct P_isle *, int)
Allocate space in P_isle for add new lines.
int dig_area_alloc_line(struct P_area *, int)
allocate space in P_area for add new lines
void dig_free_isle(struct P_isle *)
Free isle structure.
int dig_out_of_memory(void)
For now just print message and return error code.
int plus_t
plus_t size
Definition dig_structs.h:39
#define _(str)
Definition glocale.h:10
int dig_angle_next_line(struct Plus_head *plus, plus_t current_line, int side, int type, float *angle)
Find line number of next angle to follow a line.
Definition plus_area.c:474
int dig_add_area(struct Plus_head *plus, int n_lines, plus_t *lines, struct bound_box *box)
Allocate space for new area and create boundary info from array.
Definition plus_area.c:187
int dig_area_add_isle(struct Plus_head *plus, int area, int isle)
Add isle to area if does not exist yet.
Definition plus_area.c:265
int dig_node_angle_check(struct Plus_head *plus, plus_t line, int type)
Check if angles of adjacent lines differ.
Definition plus_area.c:622
int dig_add_isle(struct Plus_head *plus, int n_lines, plus_t *lines, struct bound_box *box)
Allocate space for new island and create boundary info from array.
Definition plus_area.c:703
int dig_area_del_isle(struct Plus_head *plus, int area, int isle)
Delete isle from area.
Definition plus_area.c:314
int dig_del_area(struct Plus_head *plus, int area)
Delete area from Plus_head structure.
Definition plus_area.c:365
int dig_build_area_with_line(struct Plus_head *plus, plus_t first_line, int side, plus_t **lines)
Build topo for area from lines.
Definition plus_area.c:50
int dig_del_isle(struct Plus_head *plus, int isle)
Delete island from Plus_head structure.
Definition plus_area.c:781
Area (topology) info.
plus_t n_isles
Number of islands inside.
plus_t * isles
1st generation interior islands
plus_t n_lines
Number of boundary lines.
plus_t * lines
List of boundary lines.
plus_t centroid
Number of first centroid within area.
plus_t alloc_isles
Allocated space for isles.
Isle (topology) info.
plus_t * lines
List of boundary lines.
plus_t n_lines
Number of boundary lines.
plus_t area
Area it exists w/in, if any.
Vector geometry.
char type
Line type.
void * topo
Topology info.
Topological feature - node.
plus_t n_lines
Number of attached lines (size of lines, angle)
float * angles
List of angles of connected lines.
plus_t * lines
List of connected lines.
Boundary topology.
plus_t left
Area number to the left, negative for isle.
plus_t N1
Start node.
plus_t N2
End node.
plus_t right
Area number to the right, negative for isle.
Centroid topology.
plus_t area
Area number, negative for duplicate centroid.
Line topology.
plus_t N1
Start node.
plus_t N2
End node.
Basic topology-related info.
struct P_line ** Line
Array of vector geometries.
plus_t alloc_areas
Number of allocated areas.
struct P_area ** Area
Array of areas.
plus_t alloc_isles
Number of allocated isles.
plus_t n_isles
Current number of isles.
struct P_isle ** Isle
Array of isles.
struct P_node ** Node
Array of nodes.
plus_t n_areas
Current number of areas.
Bounding box.
Definition dig_structs.h:62