GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-bb27c0570b
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,
63  struct ilist *AAList, /* map A */
64  struct Map_info *BMap, int btype, struct ilist *BList,
65  struct ilist *BAList, /* map B */
66  int operator, struct Map_info * OMap)
67 { /* output map */
68  switch (operator) {
69  case GV_O_AND:
70  Vect_overlay_and(AMap, atype, AList, AAList, BMap, btype, BList, BAList,
71  OMap);
72  break;
73  default:
74  G_fatal_error("Vect_overlay(): %s", _("unknown operator"));
75  }
76 
77  return 0;
78 }
79 
80 /*!
81  \brief Overlay 2 vector maps with AND.
82 
83  AND supports:point line area
84  point + - +
85  line - - -
86  area + - -
87 
88  \param AMap vector map A
89  \param atype feature type for A
90  \param AList unused ?
91  \param AAList unused ?
92  \param BMap vector map B
93  \param btype feature type for B
94  \param BList unused ?
95  \param BAList unused ?
96  \param OMap output vector map
97 
98  \return 1 on success
99  \return 0 on error
100  */
101 int Vect_overlay_and(struct Map_info *AMap, int atype,
102  struct ilist *AList UNUSED, struct ilist *AAList UNUSED,
103  struct Map_info *BMap, int btype,
104  struct ilist *BList UNUSED, struct ilist *BAList UNUSED,
105  struct Map_info *OMap)
106 {
107  int i, j, k, line, altype, bltype, oltype, area, centr;
108  struct line_pnts *Points;
109  struct line_cats *ACats, *BCats, *OCats;
110  struct ilist *AOList, *BOList;
111  struct boxlist *boxlist;
112  struct bound_box box;
113 
114  /* TODO: support Lists */
115 
116  Points = Vect_new_line_struct();
117  ACats = Vect_new_cats_struct();
118  BCats = Vect_new_cats_struct();
119  OCats = Vect_new_cats_struct();
120  AOList = Vect_new_list();
121  BOList = Vect_new_list();
123 
124  /* TODO: support all types; at present only point x point, area x point and
125  * point x area supported */
126  if ((atype & GV_LINES) || (btype & GV_LINES))
127  G_warning(
128  _("Overlay: line/boundary types not supported by AND operator"));
129 
130  if ((atype & GV_AREA) && (btype & GV_AREA))
131  G_warning(
132  _("Overlay: area x area types not supported by AND operator"));
133 
134  /* TODO: more points in one node in one map */
135 
136  /* point x point: select all points with identical coordinates in both maps
137  */
138  if ((atype & GV_POINTS) &&
139  (btype & GV_POINTS)) { /* both points and centroids */
140  G_debug(3, "overlay: AND: point x point");
141  for (i = 1; i <= Vect_get_num_lines(AMap); i++) {
142  altype = Vect_read_line(AMap, Points, ACats, i);
143  if (!(altype & GV_POINTS))
144  continue;
145 
146  box.E = box.W = Points->x[0];
147  box.N = box.S = Points->y[0];
148  box.T = box.B = Points->z[0];
150 
151  Vect_reset_cats(OCats);
152 
153  for (j = 0; j < boxlist->n_values; j++) {
154  line = boxlist->id[j];
155  bltype = Vect_read_line(BMap, NULL, BCats, line);
156  if (!(bltype & GV_POINTS))
157  continue;
158 
159  /* Identical points found -> write out */
160  /* TODO: do something if fields in ACats and BCats are identical
161  */
162  for (k = 0; k < ACats->n_cats; k++)
163  Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]);
164 
165  for (k = 0; k < BCats->n_cats; k++)
166  Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]);
167 
168  /* TODO: what to do if one type is GV_POINT and second
169  * GV_CENTROID */
170  oltype = altype;
171  Vect_write_line(OMap, oltype, Points, OCats);
172  Vect_list_append(AOList, i); /* add to list of written lines */
173  Vect_list_append(BOList, line);
174  break;
175  }
176  }
177  }
178 
179  /* TODO: check only labeled areas */
180  /* point x area: select points from A in areas in B */
181  if ((atype & GV_POINTS) &&
182  (btype & GV_AREA)) { /* both points and centroids */
183  G_debug(3, "overlay: AND: point x area");
184 
185  for (i = 1; i <= Vect_get_num_lines(AMap); i++) {
186  altype = Vect_read_line(AMap, Points, ACats, i);
187  if (!(altype & GV_POINTS))
188  continue;
189 
190  area = Vect_find_area(BMap, Points->x[0], Points->y[0]);
191  if (area == 0)
192  continue;
193 
194  Vect_reset_cats(OCats);
195 
196  /* TODO: do something if fields in ACats and BCats are identical */
197  for (k = 0; k < ACats->n_cats; k++)
198  Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]);
199 
200  centr = Vect_get_area_centroid(BMap, area);
201  if (centr > 0) {
202  bltype = Vect_read_line(BMap, NULL, BCats, centr);
203  for (k = 0; k < BCats->n_cats; k++)
204  Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]);
205  }
206 
207  /* Check if not yet written */
208  if (!(Vect_val_in_list(AOList, i))) {
209  Vect_write_line(OMap, altype, Points, OCats);
210  Vect_list_append(AOList, i);
211  }
212  }
213  }
214  /* area x point: select points from B in areas in A */
215  if ((btype & GV_POINTS) &&
216  (atype & GV_AREA)) { /* both points and centroids */
217  G_debug(3, "overlay: AND: area x point");
218 
219  for (i = 1; i <= Vect_get_num_lines(BMap); i++) {
220  bltype = Vect_read_line(BMap, Points, BCats, i);
221  if (!(bltype & GV_POINTS))
222  continue;
223 
224  area = Vect_find_area(AMap, Points->x[0], Points->y[0]);
225  if (area == 0)
226  continue;
227 
228  Vect_reset_cats(OCats);
229 
230  /* TODO: do something if fields in ACats and BCats are identical */
231  for (k = 0; k < BCats->n_cats; k++)
232  Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]);
233 
234  centr = Vect_get_area_centroid(AMap, area);
235  if (centr > 0) {
236  altype = Vect_read_line(AMap, NULL, ACats, centr);
237  for (k = 0; k < ACats->n_cats; k++)
238  Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]);
239  }
240 
241  /* Check if not yet written */
242  if (!(Vect_val_in_list(BOList, i))) {
243  Vect_write_line(OMap, bltype, Points, OCats);
244  Vect_list_append(BOList, i);
245  }
246  }
247  }
248 
249  Vect_destroy_line_struct(Points);
253  Vect_destroy_list(AOList);
254  Vect_destroy_list(BOList);
256 
257  return 0;
258 }
#define NULL
Definition: ccmath.h:32
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
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
plus_t Vect_get_num_lines(struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition: level_two.c:75
int Vect_reset_cats(struct line_cats *)
Reset category structure to make sure cats structure is clean to be re-used.
int Vect_cat_set(struct line_cats *, int, int)
Add new field/cat to category structure if doesn't exist yet.
struct boxlist * Vect_new_boxlist(int)
Creates and initializes a struct boxlist.
void Vect_destroy_boxlist(struct boxlist *)
Frees all memory associated with a struct boxlist, including the struct itself.
void Vect_destroy_list(struct ilist *)
Frees all memory associated with a struct ilist, including the struct itself.
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_list_append(struct ilist *, int)
Append new item to the end of list if not yet present.
int Vect_read_line(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition: line.c:45
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:32
int Vect_val_in_list(const struct ilist *, int)
Find a given item in the list.
int Vect_get_area_centroid(struct Map_info *, int)
Returns centroid id for given area.
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
int Vect_find_area(struct Map_info *, double, double)
Find the nearest area.
#define GV_ON_OVERLAP
Definition: dig_defines.h:208
#define GV_LINES
Definition: dig_defines.h:193
#define GV_ON_AND
Overlay operators.
Definition: dig_defines.h:207
@ GV_O_AND
Definition: dig_defines.h:210
@ GV_O_OVERLAP
Definition: dig_defines.h:210
#define GV_POINTS
Definition: dig_defines.h:192
#define GV_AREA
Definition: dig_defines.h:189
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition: gis.h:47
#define _(str)
Definition: glocale.h:10
int Vect_overlay_and(struct Map_info *, int, struct ilist *, struct ilist *, struct Map_info *, int, struct ilist *, struct ilist *, struct Map_info *)
int Vect_overlay_str_to_operator(const char *str)
Get operator code from string.
Definition: overlay.c:35
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
Vector map info.
Definition: dig_structs.h:1243
Bounding box.
Definition: dig_structs.h:64
double W
West.
Definition: dig_structs.h:80
double T
Top.
Definition: dig_structs.h:84
double S
South.
Definition: dig_structs.h:72
double N
North.
Definition: dig_structs.h:68
double E
East.
Definition: dig_structs.h:76
double B
Bottom.
Definition: dig_structs.h:88
List of bounding boxes with id.
Definition: dig_structs.h:1723
int * id
Array of ids.
Definition: dig_structs.h:1727
int n_values
Number of items in the list.
Definition: dig_structs.h:1739
List of integers.
Definition: gis.h:706
Feature category info.
Definition: dig_structs.h:1677
int * field
Array of layers (fields)
Definition: dig_structs.h:1681
int * cat
Array of categories.
Definition: dig_structs.h:1685
int n_cats
Number of categories attached to element.
Definition: dig_structs.h:1689
Feature geometry info - coordinates.
Definition: dig_structs.h:1651
double * y
Array of Y coordinates.
Definition: dig_structs.h:1659
double * x
Array of X coordinates.
Definition: dig_structs.h:1655
double * z
Array of Z coordinates.
Definition: dig_structs.h:1663