lines_io.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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;
  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. /* if (n > 2) */
  74. write_ln(begin, end, n);
  75. return (0);
  76. }
  77. /* write_ln - actual writing part of write_line */
  78. /* writes binary and supplemental file */
  79. static int write_ln(struct COOR *begin, struct COOR *end, /* start and end point of line */
  80. int n)
  81. { /* number of points to write */
  82. struct line_pnts *points = Vect_new_line_struct();
  83. double x, y;
  84. struct COOR *p, *last;
  85. int i, cat, field;
  86. static int count = 1;
  87. field = 1;
  88. ++n;
  89. Vect_reset_cats(Cats);
  90. p = begin;
  91. y = cell_head.north - ((double)p->row + 0.5) * cell_head.ns_res;
  92. x = cell_head.west + ((double)p->col + 0.5) * cell_head.ew_res;
  93. /* value_flag is used only for CELL type */
  94. cat = (value_flag) ? p->val : count;
  95. Vect_cat_set(Cats, field, cat);
  96. Vect_append_point(points, x, y, 0.0);
  97. for (i = 1; i < n; i++) {
  98. last = p;
  99. /* this should NEVER happen */
  100. if ((p = move(p)) == NULL)
  101. G_fatal_error(_("write_line: line terminated unexpectedly\n"
  102. " previous (%d) point %p (%d,%d,%d) %p %p"),
  103. direction, last, last->row, last->col, last->node,
  104. last->fptr, last->bptr);
  105. y = cell_head.north - ((double)p->row + 0.5) * cell_head.ns_res;
  106. x = cell_head.west + ((double)p->col + 0.5) * cell_head.ew_res;
  107. if (p->val != cat && value_flag) {
  108. Vect_append_point(points, x, y, 0.0);
  109. if ((driver != NULL) && !value_flag) {
  110. insert_value(cat, p->val, p->dval);
  111. }
  112. Vect_write_line(&Map, GV_LINE, points, Cats);
  113. Vect_reset_line(points);
  114. Vect_reset_cats(Cats);
  115. cat = (value_flag) ? p->val : (++count);
  116. Vect_cat_set(Cats, field, cat);
  117. }
  118. Vect_append_point(points, x, y, 0.0);
  119. }
  120. if ((driver != NULL) && !value_flag) {
  121. insert_value(cat, p->val, p->dval);
  122. }
  123. Vect_write_line(&Map, GV_LINE, points, Cats);
  124. count++;
  125. /* now free all the pointers */
  126. p = begin;
  127. for (i = 1; i < n; i++) {
  128. last = p;
  129. if ((p = move(p)) == NULL)
  130. break;
  131. if (last == p)
  132. break;
  133. if (last->fptr != NULL)
  134. if (last->fptr->fptr == last)
  135. last->fptr->fptr = NULL;
  136. /* now it can already ne NULL */
  137. if (last->fptr != NULL)
  138. if (last->fptr->bptr == last)
  139. last->fptr->bptr = NULL;
  140. if (last->bptr != NULL)
  141. if (last->bptr->fptr == last)
  142. last->bptr->fptr = NULL;
  143. if (last->bptr != NULL)
  144. if (last->bptr->bptr == last)
  145. last->bptr->bptr = NULL;
  146. G_free(last);
  147. } /* end of for i */
  148. if (p != NULL)
  149. G_free(p);
  150. return 0;
  151. }