overlay.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*!
  2. \file lib/vector/Vlib/overlay.c
  3. \brief Vector library - overlays
  4. Higher level functions for reading/writing/manipulating vectors.
  5. This is file is just example and starting point for writing overlay
  6. functions!!!
  7. (C) 2001-2009 by the GRASS Development Team
  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. \author Radim Blazek
  11. */
  12. #include <string.h>
  13. #include <grass/vector.h>
  14. #include <grass/glocale.h>
  15. int Vect_overlay_and(struct Map_info *, int, struct ilist *, struct ilist *,
  16. struct Map_info *, int, struct ilist *, struct ilist *,
  17. struct Map_info *);
  18. /*!
  19. \brief Get operator code from string
  20. \param str operator code string
  21. \return operator code
  22. \return -1 on error
  23. */
  24. int Vect_overlay_str_to_operator(const char *str)
  25. {
  26. if (strcmp(str, GV_ON_AND) == 0)
  27. return GV_O_AND;
  28. else if (strcmp(str, GV_ON_OVERLAP) == 0)
  29. return GV_O_OVERLAP;
  30. return -1;
  31. }
  32. /*!
  33. \brief Overlay 2 vector maps and create new one
  34. \param AMap vector map A
  35. \param atype feature type for A
  36. \param AList unused ?
  37. \param AAList unused ?
  38. \param BMap vector map B
  39. \param btype feature type for B
  40. \param BList unused ?
  41. \param BAList unused ?
  42. \param operator operator code
  43. \param[out] OMap output vector map
  44. \return 0 on success
  45. */
  46. int Vect_overlay(struct Map_info *AMap, int atype, struct ilist *AList, struct ilist *AAList, /* map A */
  47. struct Map_info *BMap, int btype, struct ilist *BList, struct ilist *BAList, /* map B */
  48. int operator, struct Map_info *OMap)
  49. { /* output map */
  50. switch (operator) {
  51. case GV_O_AND:
  52. Vect_overlay_and(AMap, atype, AList, AAList, BMap, btype, BList,
  53. BAList, OMap);
  54. break;
  55. default:
  56. G_fatal_error("Vect_overlay(): %s", _("unknown operator"));
  57. }
  58. return 0;
  59. }
  60. /*!
  61. \brief Overlay 2 vector maps with AND.
  62. AND supports:point line area
  63. point + - +
  64. line - - -
  65. area + - -
  66. \param AMap vector map A
  67. \param atype feature type for A
  68. \param AList unused ?
  69. \param AAList unused ?
  70. \param BMap vector map B
  71. \param btype feature type for B
  72. \param BList unused ?
  73. \param BAList unused ?
  74. \param OMap output vector map
  75. \return 1 on success
  76. \return 0 on error
  77. */
  78. int
  79. Vect_overlay_and(struct Map_info *AMap, int atype, struct ilist *AList,
  80. struct ilist *AAList, struct Map_info *BMap, int btype,
  81. struct ilist *BList, struct ilist *BAList,
  82. struct Map_info *OMap)
  83. {
  84. int i, j, k, line, altype, bltype, oltype, area, centr;
  85. struct line_pnts *Points;
  86. struct line_cats *ACats, *BCats, *OCats;
  87. struct ilist *AOList, *BOList;
  88. struct boxlist *boxlist;
  89. struct bound_box box;
  90. /* TODO: support Lists */
  91. Points = Vect_new_line_struct();
  92. ACats = Vect_new_cats_struct();
  93. BCats = Vect_new_cats_struct();
  94. OCats = Vect_new_cats_struct();
  95. AOList = Vect_new_list();
  96. BOList = Vect_new_list();
  97. boxlist = Vect_new_boxlist(0);
  98. /* TODO: support all types; at present only point x point, area x point and point x area supported */
  99. if ((atype & GV_LINES) || (btype & GV_LINES))
  100. G_warning(_("Overlay: line/boundary types not supported by AND operator"));
  101. if ((atype & GV_AREA) && (btype & GV_AREA))
  102. G_warning(_("Overlay: area x area types not supported by AND operator"));
  103. /* TODO: more points in one node in one map */
  104. /* point x point: select all points with identical coordinates in both maps */
  105. if ((atype & GV_POINTS) && (btype & GV_POINTS)) { /* both points and centroids */
  106. G_debug(3, "overlay: AND: point x point");
  107. for (i = 1; i <= Vect_get_num_lines(AMap); i++) {
  108. altype = Vect_read_line(AMap, Points, ACats, i);
  109. if (!(altype & GV_POINTS))
  110. continue;
  111. box.E = box.W = Points->x[0];
  112. box.N = box.S = Points->y[0];
  113. box.T = box.B = Points->z[0];
  114. Vect_select_lines_by_box(BMap, &box, GV_POINTS, boxlist);
  115. Vect_reset_cats(OCats);
  116. for (j = 0; j < boxlist->n_values; j++) {
  117. line = boxlist->id[j];
  118. bltype = Vect_read_line(BMap, NULL, BCats, line);
  119. if (!(bltype & GV_POINTS))
  120. continue;
  121. /* Identical points found -> write out */
  122. /* TODO: do something if fields in ACats and BCats are identical */
  123. for (k = 0; k < ACats->n_cats; k++)
  124. Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]);
  125. for (k = 0; k < BCats->n_cats; k++)
  126. Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]);
  127. /* TODO: what to do if one type is GV_POINT and second GV_CENTROID */
  128. oltype = altype;
  129. Vect_write_line(OMap, oltype, Points, OCats);
  130. Vect_list_append(AOList, i); /* add to list of written lines */
  131. Vect_list_append(BOList, line);
  132. break;
  133. }
  134. }
  135. }
  136. /* TODO: check only labeled areas */
  137. /* point x area: select points from A in areas in B */
  138. if ((atype & GV_POINTS) && (btype & GV_AREA)) { /* both points and centroids */
  139. G_debug(3, "overlay: AND: point x area");
  140. for (i = 1; i <= Vect_get_num_lines(AMap); i++) {
  141. altype = Vect_read_line(AMap, Points, ACats, i);
  142. if (!(altype & GV_POINTS))
  143. continue;
  144. area = Vect_find_area(BMap, Points->x[0], Points->y[0]);
  145. if (area == 0)
  146. continue;
  147. Vect_reset_cats(OCats);
  148. /* TODO: do something if fields in ACats and BCats are identical */
  149. for (k = 0; k < ACats->n_cats; k++)
  150. Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]);
  151. centr = Vect_get_area_centroid(BMap, area);
  152. if (centr > 0) {
  153. bltype = Vect_read_line(BMap, NULL, BCats, centr);
  154. for (k = 0; k < BCats->n_cats; k++)
  155. Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]);
  156. }
  157. /* Check if not yet written */
  158. if (!(Vect_val_in_list(AOList, i))) {
  159. Vect_write_line(OMap, altype, Points, OCats);
  160. Vect_list_append(AOList, i);
  161. }
  162. }
  163. }
  164. /* area x point: select points from B in areas in A */
  165. if ((btype & GV_POINTS) && (atype & GV_AREA)) { /* both points and centroids */
  166. G_debug(3, "overlay: AND: area x point");
  167. for (i = 1; i <= Vect_get_num_lines(BMap); i++) {
  168. bltype = Vect_read_line(BMap, Points, BCats, i);
  169. if (!(bltype & GV_POINTS))
  170. continue;
  171. area = Vect_find_area(AMap, Points->x[0], Points->y[0]);
  172. if (area == 0)
  173. continue;
  174. Vect_reset_cats(OCats);
  175. /* TODO: do something if fields in ACats and BCats are identical */
  176. for (k = 0; k < BCats->n_cats; k++)
  177. Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]);
  178. centr = Vect_get_area_centroid(AMap, area);
  179. if (centr > 0) {
  180. altype = Vect_read_line(AMap, NULL, ACats, centr);
  181. for (k = 0; k < ACats->n_cats; k++)
  182. Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]);
  183. }
  184. /* Check if not yet written */
  185. if (!(Vect_val_in_list(BOList, i))) {
  186. Vect_write_line(OMap, bltype, Points, OCats);
  187. Vect_list_append(BOList, i);
  188. }
  189. }
  190. }
  191. Vect_destroy_line_struct(Points);
  192. Vect_destroy_cats_struct(ACats);
  193. Vect_destroy_cats_struct(BCats);
  194. Vect_destroy_cats_struct(OCats);
  195. Vect_destroy_list(AOList);
  196. Vect_destroy_list(BOList);
  197. Vect_destroy_boxlist(boxlist);
  198. return 0;
  199. }