GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
overlay.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/overlay.c
3 
4  \brief Vector library - overlays
5 
6  Higher level functions for reading/writing/manipulating vectors.
7 
8  This is file is just example and starting point for writing overlay
9  functions!!!
10 
11  (C) 2001-2009 by the GRASS Development Team
12 
13  This program is free software under the GNU General Public License
14  (>=v2). Read the file COPYING that comes with GRASS for details.
15 
16  \author Radim Blazek
17 */
18 
19 #include <string.h>
20 #include <grass/vector.h>
21 #include <grass/glocale.h>
22 
23 int Vect_overlay_and(struct Map_info *, int, struct ilist *, struct ilist *,
24  struct Map_info *, int, struct ilist *, struct ilist *,
25  struct Map_info *);
26 
27 /*!
28  \brief Get operator code from string
29 
30  \param str operator code string
31 
32  \return operator code
33  \return -1 on error
34  */
35 int Vect_overlay_str_to_operator(const char *str)
36 {
37 
38  if (strcmp(str, GV_ON_AND) == 0)
39  return GV_O_AND;
40  else if (strcmp(str, GV_ON_OVERLAP) == 0)
41  return GV_O_OVERLAP;
42 
43  return -1;
44 }
45 
46 /*!
47  \brief Overlay 2 vector maps and create new one
48 
49  \param AMap vector map A
50  \param atype feature type for A
51  \param AList unused ?
52  \param AAList unused ?
53  \param BMap vector map B
54  \param btype feature type for B
55  \param BList unused ?
56  \param BAList unused ?
57  \param operator operator code
58  \param[out] OMap output vector map
59 
60  \return 0 on success
61  */
62 int Vect_overlay(struct Map_info *AMap, int atype, struct ilist *AList, struct ilist *AAList, /* map A */
63  struct Map_info *BMap, int btype, struct ilist *BList, struct ilist *BAList, /* map B */
64  int operator, struct Map_info *OMap)
65 { /* output map */
66  switch (operator) {
67  case GV_O_AND:
68  Vect_overlay_and(AMap, atype, AList, AAList, BMap, btype, BList,
69  BAList, OMap);
70  break;
71  default:
72  G_fatal_error("Vect_overlay(): %s", _("unknown operator"));
73  }
74 
75  return 0;
76 }
77 
78 /*!
79  \brief Overlay 2 vector maps with AND.
80 
81  AND supports:point line area
82  point + - +
83  line - - -
84  area + - -
85 
86  \param AMap vector map A
87  \param atype feature type for A
88  \param AList unused ?
89  \param AAList unused ?
90  \param BMap vector map B
91  \param btype feature type for B
92  \param BList unused ?
93  \param BAList unused ?
94  \param OMap output vector map
95 
96  \return 1 on success
97  \return 0 on error
98  */
99 int
100 Vect_overlay_and(struct Map_info *AMap, int atype, struct ilist *AList,
101  struct ilist *AAList, struct Map_info *BMap, int btype,
102  struct ilist *BList, struct ilist *BAList,
103  struct Map_info *OMap)
104 {
105  int i, j, k, line, altype, bltype, oltype, area, centr;
106  struct line_pnts *Points;
107  struct line_cats *ACats, *BCats, *OCats;
108  struct ilist *AOList, *BOList;
109  struct boxlist *boxlist;
110  struct bound_box box;
111 
112  /* TODO: support Lists */
113 
114  Points = Vect_new_line_struct();
115  ACats = Vect_new_cats_struct();
116  BCats = Vect_new_cats_struct();
117  OCats = Vect_new_cats_struct();
118  AOList = Vect_new_list();
119  BOList = Vect_new_list();
120  boxlist = Vect_new_boxlist(0);
121 
122  /* TODO: support all types; at present only point x point, area x point and point x area supported */
123  if ((atype & GV_LINES) || (btype & GV_LINES))
124  G_warning(_("Overlay: line/boundary types not supported by AND operator"));
125 
126  if ((atype & GV_AREA) && (btype & GV_AREA))
127  G_warning(_("Overlay: area x area types not supported by AND operator"));
128 
129  /* TODO: more points in one node in one map */
130 
131  /* point x point: select all points with identical coordinates in both maps */
132  if ((atype & GV_POINTS) && (btype & GV_POINTS)) { /* both points and centroids */
133  G_debug(3, "overlay: AND: point x point");
134  for (i = 1; i <= Vect_get_num_lines(AMap); i++) {
135  altype = Vect_read_line(AMap, Points, ACats, i);
136  if (!(altype & GV_POINTS))
137  continue;
138 
139  box.E = box.W = Points->x[0];
140  box.N = box.S = Points->y[0];
141  box.T = box.B = Points->z[0];
142  Vect_select_lines_by_box(BMap, &box, GV_POINTS, boxlist);
143 
144  Vect_reset_cats(OCats);
145 
146  for (j = 0; j < boxlist->n_values; j++) {
147  line = boxlist->id[j];
148  bltype = Vect_read_line(BMap, NULL, BCats, line);
149  if (!(bltype & GV_POINTS))
150  continue;
151 
152  /* Identical points found -> write out */
153  /* TODO: do something if fields in ACats and BCats are identical */
154  for (k = 0; k < ACats->n_cats; k++)
155  Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]);
156 
157  for (k = 0; k < BCats->n_cats; k++)
158  Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]);
159 
160  /* TODO: what to do if one type is GV_POINT and second GV_CENTROID */
161  oltype = altype;
162  Vect_write_line(OMap, oltype, Points, OCats);
163  Vect_list_append(AOList, i); /* add to list of written lines */
164  Vect_list_append(BOList, line);
165  break;
166  }
167  }
168  }
169 
170  /* TODO: check only labeled areas */
171  /* point x area: select points from A in areas in B */
172  if ((atype & GV_POINTS) && (btype & GV_AREA)) { /* both points and centroids */
173  G_debug(3, "overlay: AND: point x area");
174 
175  for (i = 1; i <= Vect_get_num_lines(AMap); i++) {
176  altype = Vect_read_line(AMap, Points, ACats, i);
177  if (!(altype & GV_POINTS))
178  continue;
179 
180  area = Vect_find_area(BMap, Points->x[0], Points->y[0]);
181  if (area == 0)
182  continue;
183 
184  Vect_reset_cats(OCats);
185 
186  /* TODO: do something if fields in ACats and BCats are identical */
187  for (k = 0; k < ACats->n_cats; k++)
188  Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]);
189 
190  centr = Vect_get_area_centroid(BMap, area);
191  if (centr > 0) {
192  bltype = Vect_read_line(BMap, NULL, BCats, centr);
193  for (k = 0; k < BCats->n_cats; k++)
194  Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]);
195  }
196 
197  /* Check if not yet written */
198  if (!(Vect_val_in_list(AOList, i))) {
199  Vect_write_line(OMap, altype, Points, OCats);
200  Vect_list_append(AOList, i);
201  }
202 
203  }
204  }
205  /* area x point: select points from B in areas in A */
206  if ((btype & GV_POINTS) && (atype & GV_AREA)) { /* both points and centroids */
207  G_debug(3, "overlay: AND: area x point");
208 
209  for (i = 1; i <= Vect_get_num_lines(BMap); i++) {
210  bltype = Vect_read_line(BMap, Points, BCats, i);
211  if (!(bltype & GV_POINTS))
212  continue;
213 
214  area = Vect_find_area(AMap, Points->x[0], Points->y[0]);
215  if (area == 0)
216  continue;
217 
218  Vect_reset_cats(OCats);
219 
220  /* TODO: do something if fields in ACats and BCats are identical */
221  for (k = 0; k < BCats->n_cats; k++)
222  Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]);
223 
224  centr = Vect_get_area_centroid(AMap, area);
225  if (centr > 0) {
226  altype = Vect_read_line(AMap, NULL, ACats, centr);
227  for (k = 0; k < ACats->n_cats; k++)
228  Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]);
229  }
230 
231  /* Check if not yet written */
232  if (!(Vect_val_in_list(BOList, i))) {
233  Vect_write_line(OMap, bltype, Points, OCats);
234  Vect_list_append(BOList, i);
235  }
236 
237  }
238  }
239 
240  Vect_destroy_line_struct(Points);
244  Vect_destroy_list(AOList);
245  Vect_destroy_list(BOList);
246  Vect_destroy_boxlist(boxlist);
247 
248  return 0;
249 }
void Vect_destroy_boxlist(struct boxlist *)
Frees all memory associated with a struct boxlist, including the struct itself.
Bounding box.
Definition: dig_structs.h:65
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int * id
Array of ids.
Definition: dig_structs.h:1755
double W
West.
Definition: dig_structs.h:82
plus_t Vect_get_num_lines(const struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition: level_two.c:74
int Vect_get_area_centroid(const struct Map_info *, int)
Returns centroid id for given area.
int Vect_val_in_list(const struct ilist *, int)
Find a given item in the list.
#define GV_POINTS
Definition: dig_defines.h:191
double E
East.
Definition: dig_structs.h:78
#define NULL
Definition: ccmath.h:32
int n_values
Number of items in the list.
Definition: dig_structs.h:1767
Feature category info.
Definition: dig_structs.h:1702
double N
North.
Definition: dig_structs.h:70
int Vect_select_lines_by_box(struct Map_info *, const struct bound_box *, int, struct boxlist *)
Select lines with bounding boxes by box.
Definition: sindex.c:34
Feature geometry info - coordinates.
Definition: dig_structs.h:1675
void Vect_destroy_list(struct ilist *)
Frees all memory associated with a struct ilist, including the struct itself.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition: line.c:45
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
int n_cats
Number of categories attached to element.
Definition: dig_structs.h:1715
int Vect_overlay_and(struct Map_info *, int, struct ilist *, struct ilist *, struct Map_info *, int, struct ilist *, struct ilist *, struct Map_info *)
Overlay 2 vector maps with AND.
Definition: overlay.c:100
int * cat
Array of categories.
Definition: dig_structs.h:1711
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
double B
Bottom.
Definition: dig_structs.h:90
double T
Top.
Definition: dig_structs.h:86
int Vect_reset_cats(struct line_cats *)
Reset category structure to make sure cats structure is clean to be re-used.
int Vect_find_area(struct Map_info *, double, double)
Find the nearest area.
Vector map info.
Definition: dig_structs.h:1259
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
int Vect_overlay(struct Map_info *AMap, int atype, struct ilist *AList, struct ilist *AAList, struct Map_info *BMap, int btype, struct ilist *BList, struct ilist *BAList, int operator, struct Map_info *OMap)
Overlay 2 vector maps and create new one.
Definition: overlay.c:62
int Vect_list_append(struct ilist *, int)
Append new item to the end of list if not yet present.
List of bounding boxes with id.
Definition: dig_structs.h:1750
void G_warning(const char *,...) __attribute__((format(printf
#define GV_ON_AND
Overlay operators.
Definition: dig_defines.h:205
double S
South.
Definition: dig_structs.h:74
#define GV_AREA
Definition: dig_defines.h:188
#define _(str)
Definition: glocale.h:10
List of integers.
Definition: gis.h:700
int * field
Array of layers (fields)
Definition: dig_structs.h:1707
#define GV_LINES
Definition: dig_defines.h:192
struct boxlist * Vect_new_boxlist(int)
Creates and initializes a struct boxlist.
#define GV_ON_OVERLAP
Definition: dig_defines.h:206
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
Definition: line.c:77
int Vect_read_line(const struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
int G_debug(int, const char *,...) __attribute__((format(printf
int Vect_overlay_str_to_operator(const char *str)
Get operator code from string.
Definition: overlay.c:35
int Vect_cat_set(struct line_cats *, int, int)
Add new field/cat to category structure if doesn&#39;t exist yet.