misc.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /****************************************************************
  2. *
  3. * MODULE: v.generalize
  4. *
  5. * AUTHOR(S): Daniel Bundala
  6. *
  7. * PURPOSE: miscellaneous functions of v.generalize
  8. *
  9. *
  10. * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
  11. *
  12. * This program is free software under the
  13. * GNU General Public License (>=v2).
  14. * Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. ****************************************************************/
  18. #include <grass/gis.h>
  19. #include <grass/vector.h>
  20. #include <grass/dbmi.h>
  21. #include <grass/glocale.h>
  22. #include "misc.h"
  23. int type_mask(struct Option *type_opt)
  24. {
  25. int res = 0;
  26. int i;
  27. for (i = 0; type_opt->answers[i]; i++)
  28. switch (type_opt->answers[i][0]) {
  29. case 'l':
  30. res |= GV_LINE;
  31. break;
  32. case 'b':
  33. res |= GV_BOUNDARY;
  34. break;
  35. case 'a':
  36. res |= GV_AREA;
  37. }
  38. return res;
  39. }
  40. int get_furthest(struct line_pnts *Points, int a, int b, int with_z,
  41. double *dist)
  42. {
  43. int index = a;
  44. double d = 0;
  45. int i;
  46. double x0 = Points->x[a];
  47. double x1 = Points->x[b];
  48. double y0 = Points->y[a];
  49. double y1 = Points->y[b];
  50. double z0 = Points->z[a];
  51. double z1 = Points->z[b];
  52. double px, py, pz, pdist, di;
  53. int status;
  54. for (i = a + 1; i < b; i++) {
  55. di = dig_distance2_point_to_line(Points->x[i], Points->y[i],
  56. Points->z[i], x0, y0, z0, x1, y1, z1,
  57. with_z, &px, &py, &pz, &pdist,
  58. &status);
  59. if (di > d) {
  60. d = di;
  61. index = i;
  62. }
  63. }
  64. *dist = d;
  65. return index;
  66. }
  67. /* TODO: The collection of categories is horrible in current version!
  68. * Rverything repeats many times. We need some data structure
  69. * implementing set! */
  70. int copy_tables_by_cats(struct Map_info *In, struct Map_info *Out)
  71. {
  72. /* this is the (mostly) code from v.extract, it should be moved to
  73. * some vector library (probably) */
  74. int nlines, line, nfields;
  75. int ttype, ntabs = 0;
  76. struct field_info *IFi, *OFi;
  77. struct line_cats *Cats;
  78. struct line_pnts *Points;
  79. int **ocats, *nocats, *fields;
  80. int i;
  81. /* Collect list of output cats */
  82. Points = Vect_new_line_struct();
  83. Cats = Vect_new_cats_struct();
  84. nfields = Vect_cidx_get_num_fields(In);
  85. ocats = (int **)G_malloc(nfields * sizeof(int *));
  86. nocats = (int *)G_malloc(nfields * sizeof(int));
  87. fields = (int *)G_malloc(nfields * sizeof(int));
  88. for (i = 0; i < nfields; i++) {
  89. nocats[i] = 0;
  90. ocats[i] =
  91. (int *)G_malloc(Vect_cidx_get_num_cats_by_index(In, i) *
  92. sizeof(int));
  93. fields[i] = Vect_cidx_get_field_number(In, i);
  94. }
  95. nlines = Vect_get_num_lines(Out);
  96. for (line = 1; line <= nlines; line++) {
  97. Vect_read_line(Out, NULL, Cats, line);
  98. for (i = 0; i < Cats->n_cats; i++) {
  99. int f = 0, j;
  100. for (j = 0; j < nfields; j++) { /* find field */
  101. if (fields[j] == Cats->field[i]) {
  102. f = j;
  103. break;
  104. }
  105. }
  106. ocats[f][nocats[f]] = Cats->cat[i];
  107. nocats[f]++;
  108. }
  109. }
  110. /* Copy tables */
  111. G_message(_("Writing attributes..."));
  112. /* Number of output tabs */
  113. for (i = 0; i < Vect_get_num_dblinks(In); i++) {
  114. int j, f = -1;
  115. IFi = Vect_get_dblink(In, i);
  116. for (j = 0; j < nfields; j++) { /* find field */
  117. if (fields[j] == IFi->number) {
  118. f = j;
  119. break;
  120. }
  121. }
  122. if (f >= 0 && nocats[f] > 0)
  123. ntabs++;
  124. }
  125. if (ntabs > 1)
  126. ttype = GV_MTABLE;
  127. else
  128. ttype = GV_1TABLE;
  129. for (i = 0; i < nfields; i++) {
  130. int ret;
  131. if (fields[i] == 0)
  132. continue;
  133. if (nocats[i] == 0)
  134. continue;
  135. /* if ( fields[i] == field && new_cat != -1 ) continue; */
  136. G_message(_("Layer %d"), fields[i]);
  137. /* Make a list of categories */
  138. IFi = Vect_get_field(In, fields[i]);
  139. if (!IFi) { /* no table */
  140. G_warning(_("Database connection not defined for layer %d"),
  141. fields[i]);
  142. continue;
  143. }
  144. OFi = Vect_default_field_info(Out, IFi->number, IFi->name, ttype);
  145. ret = db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
  146. OFi->driver, Vect_subst_var(OFi->database,
  147. Out),
  148. OFi->table, IFi->key, ocats[i],
  149. nocats[i]);
  150. if (ret == DB_FAILED) {
  151. G_warning(_("Unable to copy table <%s>"), IFi->table);
  152. }
  153. else {
  154. Vect_map_add_dblink(Out, OFi->number, OFi->name, OFi->table,
  155. IFi->key, OFi->database, OFi->driver);
  156. }
  157. }
  158. for (i = 0; i < nfields; i++)
  159. G_free(ocats[i]);
  160. G_free(ocats);
  161. G_free(nocats);
  162. G_free(fields);
  163. return 1;
  164. }