GRASS GIS 7 Programmer's Manual  7.5.svn(2018)-r72274
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
build_nat.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/build_nat.c
3 
4  \brief Vector library - Building topology for native format
5 
6  (C) 2001-2013 by the GRASS Development Team
7 
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 
11  \author Original author CERL, probably Dave Gerdes or Mike Higgins.
12  \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
13  */
14 
15 #include <string.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <sys/types.h>
19 #include <grass/glocale.h>
20 #include <grass/vector.h>
21 
22 static struct line_pnts *Points;
23 
24 /*!
25  \brief Build topology
26 
27  \param Map vector map
28  \param build build level
29 
30  \return 1 on success
31  \return 0 on error
32  */
33 int Vect_build_nat(struct Map_info *Map, int build)
34 {
35  struct Plus_head *plus;
36  int i, s, type, line;
37  off_t offset;
38  int side, area;
39  struct line_cats *Cats;
40  struct P_line *Line;
41  struct P_area *Area;
42  struct bound_box box;
43 
44  G_debug(3, "Vect_build_nat() build = %d", build);
45 
46  plus = &(Map->plus);
47 
48  if (build == plus->built)
49  return 1; /* Do nothing */
50 
51  /* Check if upgrade or downgrade */
52  if (build < plus->built) {
53  /* -> downgrade */
54  Vect__build_downgrade(Map, build);
55  return 1;
56  }
57 
58  /* -> upgrade */
59  if (!Points)
60  Points = Vect_new_line_struct();
61  Cats = Vect_new_cats_struct();
62 
63  if (plus->built < GV_BUILD_BASE) {
64  int npoints, c;
65 
66  /*
67  * We shall go through all primitives in coor file and add
68  * new node for each end point to nodes structure if the node
69  * with the same coordinates doesn't exist yet.
70  */
71 
72  /* register lines, create nodes */
73  Vect_rewind(Map);
74  G_message(_("Registering primitives..."));
75  i = 0;
76  npoints = 0;
77  while (TRUE) {
78  /* register line */
79  type = Vect_read_next_line(Map, Points, Cats);
80 
81  /* Note: check for dead lines is not needed, because they
82  are skipped by V1_read_next_line() */
83  if (type == -1) {
84  G_warning(_("Unable to read vector map"));
85  return 0;
86  }
87  else if (type == -2) {
88  break;
89  }
90 
91  G_progress(++i, 1e4);
92 
93  npoints += Points->n_points;
94 
95  offset = Map->head.last_offset;
96 
97  G_debug(3, "Register line: offset = %lu", (unsigned long)offset);
98  dig_line_box(Points, &box);
99  line = dig_add_line(plus, type, Points, &box, offset);
100  if (line == 1)
101  Vect_box_copy(&(plus->box), &box);
102  else
103  Vect_box_extend(&(plus->box), &box);
104 
105  /* Add all categories to category index */
106  if (build == GV_BUILD_ALL) {
107  for (c = 0; c < Cats->n_cats; c++) {
108  dig_cidx_add_cat(plus, Cats->field[c], Cats->cat[c],
109  line, type);
110  }
111  if (Cats->n_cats == 0) /* add field 0, cat 0 */
112  dig_cidx_add_cat(plus, 0, 0, line, type);
113  }
114  }
115  G_progress(1, 1);
116 
117  G_message(n_("One primitive registered", "%d primitives registered", plus->n_lines), plus->n_lines);
118  G_message(n_("One vertex registered", "%d vertices registered", npoints), npoints);
119 
120  plus->built = GV_BUILD_BASE;
121  }
122 
123  if (build < GV_BUILD_AREAS)
124  return 1;
125 
126  if (plus->built < GV_BUILD_AREAS) {
127  /* Build areas */
128  /* Go through all bundaries and try to build area for both sides */
129  G_important_message(_("Building areas..."));
130  G_percent(0, plus->n_lines, 1);
131  for (line = 1; line <= plus->n_lines; line++) {
132  G_percent(line, plus->n_lines, 1);
133 
134  /* build */
135  if (plus->Line[line] == NULL) {
136  continue;
137  } /* dead line */
138  Line = plus->Line[line];
139  if (Line->type != GV_BOUNDARY) {
140  continue;
141  }
142 
143  for (s = 0; s < 2; s++) {
144  if (s == 0)
145  side = GV_LEFT;
146  else
147  side = GV_RIGHT;
148 
149  G_debug(3, "Build area for line = %d, side = %d", line, side);
150  Vect_build_line_area(Map, line, side);
151  }
152  }
153  G_message(n_("One area built", "%d areas built", plus->n_areas), plus->n_areas);
154  G_message(n_("One isle built", "%d isles built", plus->n_isles), plus->n_isles);
155  plus->built = GV_BUILD_AREAS;
156  }
157 
158  if (build < GV_BUILD_ATTACH_ISLES)
159  return 1;
160 
161  /* Attach isles to areas */
162  if (plus->built < GV_BUILD_ATTACH_ISLES) {
163  G_important_message(_("Attaching islands..."));
164  for (i = 1; i <= plus->n_isles; i++) {
165  G_percent(i, plus->n_isles, 1);
166  Vect_get_isle_box(Map, i, &box);
167  Vect_attach_isle(Map, i, &box);
168  }
170  }
171 
172  if (build < GV_BUILD_CENTROIDS)
173  return 1;
174 
175  /* Attach centroids to areas */
176  if (plus->built < GV_BUILD_CENTROIDS) {
177  int nlines;
178  struct P_topo_c *topo;
179 
180  G_important_message(_("Attaching centroids..."));
181 
182  nlines = Vect_get_num_lines(Map);
183  for (line = 1; line <= nlines; line++) {
184  G_percent(line, nlines, 1);
185 
186  Line = plus->Line[line];
187  if (!Line)
188  continue; /* Dead */
189 
190  if (Line->type != GV_CENTROID)
191  continue;
192 
193  Vect_read_line(Map, Points, NULL, line);
194  area = Vect_find_area(Map, Points->x[0], Points->y[0]);
195 
196  if (area > 0) {
197  G_debug(3, "Centroid (line=%d) in area %d", line, area);
198 
199  Area = plus->Area[area];
200  topo = (struct P_topo_c *)Line->topo;
201 
202  if (Area->centroid == 0) { /* first */
203  Area->centroid = line;
204  topo->area = area;
205  }
206  else { /* duplicate */
207  topo->area = -area;
208  }
209  }
210  }
211  plus->built = GV_BUILD_CENTROIDS;
212  }
213 
214  /* Add areas to category index */
215  for (i = 1; i <= plus->n_areas; i++) {
216  int c;
217 
218  if (plus->Area[i] == NULL)
219  continue;
220 
221  if (plus->Area[i]->centroid > 0) {
222  Vect_read_line(Map, NULL, Cats, plus->Area[i]->centroid);
223 
224  for (c = 0; c < Cats->n_cats; c++) {
225  dig_cidx_add_cat(plus, Cats->field[c], Cats->cat[c], i,
226  GV_AREA);
227  }
228  }
229 
230  if (plus->Area[i]->centroid == 0 || Cats->n_cats == 0) /* no centroid or no cats */
231  dig_cidx_add_cat(plus, 0, 0, i, GV_AREA);
232  }
233 
235 
236  return 1;
237 }
int Vect_build_nat(struct Map_info *Map, int build)
Build topology.
Definition: build_nat.c:33
#define TRUE
Definition: gis.h:49
plus_t n_areas
Current number of areas.
Definition: dig_structs.h:951
int Vect_get_isle_box(const struct Map_info *Map, int isle, struct bound_box *Box)
Get bounding box of isle.
Bounding box.
Definition: dig_structs.h:65
int built
Highest level of topology currently available.
Definition: dig_structs.h:873
plus_t area
Area number, negative for duplicate centroid.
Definition: dig_structs.h:1537
void G_important_message(const char *msg,...)
Print a message to stderr even in brief mode (verbosity=1)
Definition: gis/error.c:131
#define GV_LEFT
Boundary side indicator left/right.
Definition: dig_defines.h:174
Vector geometry.
Definition: dig_structs.h:1574
if(!YY_CURRENT_BUFFER)
Definition: sqlp.yy.c:803
struct P_line ** Line
Array of vector geometries.
Definition: dig_structs.h:887
struct line_pnts * Vect_new_line_struct()
Creates and initializes a line_pnts structure.
Definition: line.c:45
#define GV_BUILD_BASE
Topology levels - basic level (without areas and isles)
Definition: dig_defines.h:125
#define n_(strs, strp, num)
Definition: glocale.h:14
struct P_area ** Area
Array of areas.
Definition: dig_structs.h:891
int dig_line_box(const struct line_pnts *, struct bound_box *)
int n_points
Number of points.
Definition: dig_structs.h:1692
#define GV_CENTROID
Definition: dig_defines.h:185
void Vect_destroy_cats_struct(struct line_cats *p)
Frees all memory associated with line_cats structure, including the struct itself.
plus_t n_isles
Current number of isles.
Definition: dig_structs.h:955
plus_t centroid
Number of first centroid within area.
Definition: dig_structs.h:1628
#define NULL
Definition: ccmath.h:32
plus_t n_lines
Current number of lines.
Definition: dig_structs.h:947
Feature category info.
Definition: dig_structs.h:1702
int dig_cidx_add_cat(struct Plus_head *, int, int, int, int)
Definition: diglib/cindex.c:73
int dig_add_line(struct Plus_head *, int, const struct line_pnts *, const struct bound_box *, off_t)
Add new line to Plus_head structure.
Definition: plus_line.c:136
int Vect_find_area(struct Map_info *Map, double x, double y)
Find the nearest area.
double * x
Array of X coordinates.
Definition: dig_structs.h:1680
char type
Line type.
Definition: dig_structs.h:1586
Feature geometry info - coordinates.
Definition: dig_structs.h:1675
Centroid topology.
Definition: dig_structs.h:1532
Basic topology-related info.
Definition: dig_structs.h:784
#define GV_BUILD_AREAS
Topology levels - build areas.
Definition: dig_defines.h:127
int Vect_build_line_area(struct Map_info *Map, int iline, int side)
Build area on given side of line (GV_LEFT or GV_RIGHT)
Definition: build.c:77
void * topo
Topology info.
Definition: dig_structs.h:1599
int n_cats
Number of categories attached to element.
Definition: dig_structs.h:1715
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
int * cat
Array of categories.
Definition: dig_structs.h:1711
#define GV_BOUNDARY
Definition: dig_defines.h:184
struct Plus_head plus
Plus info (topology, version, ...)
Definition: dig_structs.h:1286
struct bound_box box
Bounding box of features.
Definition: dig_structs.h:877
void G_percent(long n, long d, int s)
Print percent complete messages.
Definition: percent.c:62
struct dig_head head
Header info.
Definition: dig_structs.h:1403
#define GV_BUILD_ATTACH_ISLES
Topology levels - attach islands to areas.
Definition: dig_defines.h:129
int Vect_attach_isle(struct Map_info *Map, int isle, const struct bound_box *box)
(Re)Attach isle to area
Definition: build.c:377
Vector map info.
Definition: dig_structs.h:1259
void G_progress(long n, int s)
Print progress info messages.
Definition: percent.c:160
double * y
Array of Y coordinates.
Definition: dig_structs.h:1684
Area (topology) info.
Definition: dig_structs.h:1605
struct line_cats * Vect_new_cats_struct()
Creates and initializes line_cats structure.
int Vect_box_copy(struct bound_box *A, const struct bound_box *B)
Copy box B to box A.
plus_t Vect_get_num_lines(const struct Map_info *Map)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition: level_two.c:74
int Vect_read_next_line(const struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c)
Read next vector feature.
#define GV_RIGHT
Definition: dig_defines.h:175
#define GV_AREA
Definition: dig_defines.h:188
#define _(str)
Definition: glocale.h:13
int Vect_box_extend(struct bound_box *A, const struct bound_box *B)
Extend box A by box B.
void G_message(const char *msg,...)
Print a message to stderr.
Definition: gis/error.c:90
off_t last_offset
Offset of last read line.
Definition: dig_structs.h:366
int Vect_read_line(const struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, int line)
Read vector feature (topological level required)
#define GV_BUILD_CENTROIDS
Topology levels - assign centroids to areas.
Definition: dig_defines.h:131
int * field
Array of layers (fields)
Definition: dig_structs.h:1707
#define GV_BUILD_ALL
Topology levels - build everything (currently same as GV_BUILD_CENTROIDS)
Definition: dig_defines.h:133
void Vect__build_downgrade(struct Map_info *Map, int build)
Downgrade build level (for internal use only)
Definition: build.c:759
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
int Vect_rewind(struct Map_info *Map)
Rewind vector map to cause reads to start at beginning.