lines_io.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /* Cell-file line extraction */
  2. /* Input/output and line tracing routines */
  3. /* Mike Baba */
  4. /* DBA Systems */
  5. /* Farfax, VA */
  6. /* Jan 1990 */
  7. /* Jean Ezell */
  8. /* US Army Corps of Engineers */
  9. /* Construction Engineering Research Lab */
  10. /* Modelling and Simulation Team */
  11. /* Champaign, IL 61820 */
  12. /* March 1988 */
  13. /* input is a GRASS raster map */
  14. /* output is a binary or ascii digit file */
  15. /*
  16. * Modified for the new Grass 5.0 floating point and
  17. * null values raster map format.
  18. * Pierre de Mouveaux - 20 april 2000.
  19. */
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #ifdef __MINGW32__
  24. #include <process.h>
  25. #else
  26. #include <sys/wait.h>
  27. #endif
  28. #include <grass/gis.h>
  29. #include <grass/glocale.h>
  30. #include <grass/dbmi.h>
  31. #include <grass/vector.h>
  32. #include "global.h"
  33. /* function prototypes */
  34. static int write_ln(struct COOR *, struct COOR *, int);
  35. /* write_line - attempt to write a line to output */
  36. /* just returns if line is not completed yet */
  37. int write_line(struct COOR *seed)
  38. {
  39. struct COOR *point, *begin, *end, *last;
  40. int dir, line_type, n, n1;
  41. point = seed;
  42. if ((dir = at_end(point))) { /* already have one end of line */
  43. begin = point;
  44. end = find_end(point, dir, &line_type, &n);
  45. if (line_type == OPEN) {
  46. return (-1); /* unfinished line */
  47. }
  48. direction = dir;
  49. }
  50. else { /* in middle of a line */
  51. end = find_end(point, FORWARD, &line_type, &n);
  52. if (line_type == OPEN) { /* line not finished */
  53. return (-1);
  54. }
  55. if (line_type == END) { /* found one end at least *//* look for other one */
  56. begin = find_end(point, BACKWARD, &line_type, &n1);
  57. if (line_type == OPEN) { /* line not finished */
  58. return (-1);
  59. }
  60. if (line_type == LOOP) { /* this should NEVER be the case */
  61. G_warning(_("write_line: found half a loop!"));
  62. return (-1);
  63. }
  64. direction = at_end(begin); /* found both ends now; total length */
  65. n += n1; /* is sum of distances to each end */
  66. }
  67. else { /* line_type = LOOP by default */
  68. /* already have correct length */
  69. begin = end; /* end and beginning are the same */
  70. direction = FORWARD; /* direction is arbitrary */
  71. }
  72. }
  73. dir = direction;
  74. /* if (n > 2) */
  75. write_ln(begin, end, n);
  76. /* now free all the pointers */
  77. direction = dir;
  78. point = begin;
  79. /* skip first and last point */
  80. while ((point = move(point)) == begin);
  81. while (point && point != end) {
  82. last = point;
  83. point = move(point);
  84. if (point == last) {
  85. /* should not happen */
  86. G_warning("loop during free ptrs, ptr %d of %d", n1, n);
  87. point = move(point);
  88. }
  89. if (last->fptr != NULL)
  90. if (last->fptr->fptr == last)
  91. last->fptr->fptr = NULL;
  92. /* now it can already ne NULL */
  93. if (last->fptr != NULL)
  94. if (last->fptr->bptr == last)
  95. last->fptr->bptr = NULL;
  96. if (last->bptr != NULL)
  97. if (last->bptr->fptr == last)
  98. last->bptr->fptr = NULL;
  99. if (last->bptr != NULL)
  100. if (last->bptr->bptr == last)
  101. last->bptr->bptr = NULL;
  102. free_ptr(last);
  103. } /* end of for i */
  104. if (point != end) {
  105. /* should not happen */
  106. G_warning("Line end not reached, possible memory leak");
  107. }
  108. /* free first and last point */
  109. free_ptr(begin);
  110. if (end != begin)
  111. free_ptr(end);
  112. return (0);
  113. }
  114. /* write_ln - actual writing part of write_line */
  115. /* writes binary and supplemental file */
  116. static int write_ln(struct COOR *begin, struct COOR *end, /* start and end point of line */
  117. int n)
  118. { /* number of points to write */
  119. static struct line_pnts *points = NULL;
  120. double x, y;
  121. struct COOR *p, *last;
  122. int i, cat, field;
  123. static int count = 1;
  124. if (!points)
  125. points = Vect_new_line_struct();
  126. Vect_reset_line(points);
  127. field = 1;
  128. Vect_reset_cats(Cats);
  129. p = begin;
  130. y = cell_head.north - ((double)p->row + 0.5) * cell_head.ns_res;
  131. x = cell_head.west + ((double)p->col + 0.5) * cell_head.ew_res;
  132. /* value_flag is used only for CELL type */
  133. cat = (value_flag) ? p->val : count;
  134. Vect_cat_set(Cats, field, cat);
  135. Vect_append_point(points, x, y, 0.0);
  136. for (i = 0; i < n; i++) {
  137. last = p;
  138. /* this should NEVER happen */
  139. if ((p = move(p)) == NULL)
  140. G_fatal_error(_("write_line: line terminated unexpectedly\n"
  141. " previous (%d) point %p (%d,%d,%d) %p %p"),
  142. direction, last, last->row, last->col, last->node,
  143. last->fptr, last->bptr);
  144. y = cell_head.north - ((double)p->row + 0.5) * cell_head.ns_res;
  145. x = cell_head.west + ((double)p->col + 0.5) * cell_head.ew_res;
  146. if (p->val != cat && value_flag) {
  147. Vect_append_point(points, x, y, 0.0);
  148. if ((driver != NULL) && !value_flag) {
  149. insert_value(cat, p->val, p->dval);
  150. }
  151. Vect_write_line(&Map, GV_LINE, points, Cats);
  152. Vect_reset_line(points);
  153. Vect_reset_cats(Cats);
  154. cat = (value_flag) ? p->val : (++count);
  155. Vect_cat_set(Cats, field, cat);
  156. }
  157. Vect_append_point(points, x, y, 0.0);
  158. }
  159. if ((driver != NULL) && !value_flag) {
  160. insert_value(cat, p->val, p->dval);
  161. }
  162. Vect_write_line(&Map, GV_LINE, points, Cats);
  163. count++;
  164. return 0;
  165. }