do_lines.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include <math.h>
  2. #include <grass/gis.h>
  3. #include <grass/dbmi.h>
  4. #include <grass/vector.h>
  5. #include <grass/glocale.h>
  6. #include "local.h"
  7. /* function prototypes */
  8. static int plot_line(double *, double *, int, int, int);
  9. static int plot_points(double *, double *, int);
  10. static double v2angle(double *, double *, double, double);
  11. static double deg_angle(double, double, double, double);
  12. int do_lines(struct Map_info *Map, struct line_pnts *Points,
  13. dbCatValArray * Cvarr, int ctype, int field,
  14. struct cat_list *cat_list, int use, double value,
  15. int value_type, int feature_type, int *count_all, int dense)
  16. {
  17. double min = 0, max, u;
  18. int nlines, type, cat, no_contour = 0;
  19. int index;
  20. int count, j;
  21. struct line_cats *Cats;
  22. CELL cval;
  23. DCELL dval;
  24. Cats = Vect_new_cats_struct();
  25. nlines = Vect_get_num_lines(Map);
  26. count = 0;
  27. *count_all = 0;
  28. G_important_message(_("Reading features..."));
  29. for (index = 1; index <= nlines; index++) {
  30. G_percent(index, nlines, 2);
  31. type = Vect_read_line(Map, Points, Cats, index);
  32. cat = -1;
  33. if (field > 0) {
  34. if (Vect_cats_in_constraint(Cats, field, cat_list)) {
  35. Vect_cat_get(Cats, field, &cat);
  36. }
  37. }
  38. else
  39. cat = 0; /* categories do not matter */
  40. if ((type & GV_POINT) || (type & GV_LINE))
  41. (*count_all)++;
  42. if (cat < 0 || !(type & feature_type))
  43. continue;
  44. if (use == USE_ATTR) {
  45. if (ctype == DB_C_TYPE_INT) {
  46. if ((db_CatValArray_get_value_int(Cvarr, cat, &cval)) !=
  47. DB_OK) {
  48. G_warning(_("No record for line (cat = %d)"), cat);
  49. continue;
  50. }
  51. set_cat(cval);
  52. }
  53. else if (ctype == DB_C_TYPE_DOUBLE) {
  54. if ((db_CatValArray_get_value_double(Cvarr, cat, &dval)) !=
  55. DB_OK) {
  56. G_warning(_("No record for line (cat = %d)"), cat);
  57. continue;
  58. }
  59. set_dcat(dval);
  60. }
  61. else {
  62. G_fatal_error(_("Unable to use column specified"));
  63. }
  64. }
  65. else if (use == USE_CAT) {
  66. set_cat(cat);
  67. }
  68. else if (use == USE_VAL) {
  69. if (value_type == CELL_TYPE)
  70. set_cat((int)value);
  71. else
  72. set_dcat(value);
  73. }
  74. else if (use == USE_Z) {
  75. if (type & GV_POINTS) {
  76. min = Points->z[0];
  77. }
  78. else if (type & GV_LINES) {
  79. min = max = Points->z[0];
  80. for (j = 1; j < Points->n_points; j++) {
  81. if (Points->z[j] < min)
  82. min = Points->z[j];
  83. if (Points->z[j] > max)
  84. max = Points->z[j];
  85. }
  86. if (min != max) {
  87. G_debug(2,"no_contour: %d", no_contour);
  88. no_contour++;
  89. continue;
  90. }
  91. }
  92. set_dcat(min);
  93. }
  94. else if (use == USE_D) {
  95. min = 360.;
  96. max = 0.;
  97. for (j = 1; j < Points->n_points; j++) {
  98. u = deg_angle(Points->x[j], Points->y[j],
  99. Points->x[j - 1], Points->y[j - 1]);
  100. if (u < min)
  101. min = u;
  102. if (u > max)
  103. max = u;
  104. }
  105. }
  106. if ((type & GV_LINES)) {
  107. plot_line(Points->x, Points->y, Points->n_points, use, dense);
  108. count++;
  109. }
  110. else if (type & GV_POINTS) {
  111. plot_points(Points->x, Points->y, Points->n_points);
  112. count++;
  113. }
  114. }
  115. if (no_contour > 0)
  116. G_message(_("%d lines with varying height were not written to raster"),
  117. no_contour);
  118. Vect_destroy_cats_struct(Cats);
  119. return count;
  120. }
  121. static int plot_line(double *x, double *y, int n, int use, int dense)
  122. {
  123. if (dense) {
  124. while (--n > 0) {
  125. if (use == USE_D)
  126. set_dcat((DCELL) deg_angle(x[1], y[1], x[0], y[0]));
  127. plot_line_dense(x[0], y[0], x[1], y[1]);
  128. x++;
  129. y++;
  130. }
  131. }
  132. else {
  133. while (--n > 0) {
  134. if (use == USE_D)
  135. set_dcat((DCELL) deg_angle(x[1], y[1], x[0], y[0]));
  136. G_plot_line2(x[0], y[0], x[1], y[1]);
  137. x++;
  138. y++;
  139. }
  140. }
  141. return 0;
  142. }
  143. /* cos of the angle between two vectors is (a . b)/|a||b| */
  144. static double v2angle(double v1[2], double v2[2], double mag1, double mag2)
  145. {
  146. double costheta = (v1[0] * v2[0] + v1[1] * v2[1]) / (mag1 * mag2);
  147. return (acos(costheta));
  148. }
  149. static double deg_angle(double x0, double y0, double x1, double y1)
  150. {
  151. double v1[2], v2[2];
  152. double mag2;
  153. double v_ang;
  154. v1[0] = 1;
  155. v1[1] = 0;
  156. v2[0] = x0 - x1;
  157. v2[1] = y0 - y1;
  158. mag2 = sqrt(((v2[0] * v2[0]) + (v2[1] * v2[1])));
  159. v_ang = v2angle(v1, v2, 1.0, mag2);
  160. if (y0 < y1)
  161. v_ang = M_2PI - v_ang;
  162. return (v_ang * 360.0 / M_2PI);
  163. }
  164. static int plot_points(double *x, double *y, int n)
  165. {
  166. /* only plot the first point */
  167. if (n > 0)
  168. G_plot_point(*x, *y);
  169. return 0;
  170. }