GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
read_nat.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/Vlib/read_nat.c
3
4 \brief Vector library - reading features (native format)
5
6 Higher level functions for reading/writing/manipulating vectors.
7
8 (C) 2001-2009, 2011-2012 by the GRASS Development Team
9
10 This program is free software under the GNU General Public License
11 (>=v2). Read the file COPYING that comes with GRASS for details.
12
13 \author Original author CERL, probably Dave Gerdes or Mike Higgins.
14 \author Update to GRASS 5.7 by Radim Blazek and David D. Gray.
15 \author Update to GRASS 7 by Martin Landa <landa.martin gmail.com>
16 */
17
18#include <sys/types.h>
19#include <grass/vector.h>
20#include <grass/glocale.h>
21
22static int read_line_nat(struct Map_info *, struct line_pnts *,
23 struct line_cats *, off_t);
24
25/*! \brief Read vector feature on non-topological level (level 1) -
26 native format - internal use only
27
28 This function implements random access for native format,
29 constraints are ignored!
30
31 \param Map pointer to Map_info struct
32 \param[out] Points container used to store line points within
33 (pointer to line_pnts struct)
34 \param[out] Cats container used to store line categories within
35 (pointer to line_cats struct)
36 \param offset given offset
37
38 \return feature type (GV_POINT, GV_LINE, ...)
39 \return 0 dead line
40 \return -2 nothing to read
41 \return -1 on failure
42 */
43int V1_read_line_nat(struct Map_info *Map, struct line_pnts *Points,
44 struct line_cats *Cats, off_t offset)
45{
46 return read_line_nat(Map, Points, Cats, offset);
47}
48
49/*! \brief Read next vector feature on non-topological level (level
50 1) - native format - internal use only.
51
52 This function implements sequential access, constraints are
53 reflected, see Vect_set_constraint_region(),
54 Vect_set_constraint_type(), or Vect_set_constraint_field().
55
56 Dead features are skipped.
57
58 Vect_rewind() can be used to reset reading.
59
60 \param Map pointer to Map_info struct
61 \param[out] line_p container used to store line points within
62 (pointer to line_pnts struct)
63 \param[out] line_c container used to store line categories within
64 (pointer to line_cats struct)
65
66 \return feature type (GV_POINT, GV_LINE, ...)
67 \return 0 dead line
68 \return -2 nothing to read
69 \return -1 on failure
70 */
72 struct line_cats *line_c)
73{
74 int itype;
75 off_t offset;
76 struct bound_box lbox, mbox;
77
78 G_debug(3, "V1_read_next_line_nat()");
79
80 if (Map->constraint.region_flag)
82
83 while (TRUE) {
84 offset = dig_ftell(&(Map->dig_fp));
85 itype = read_line_nat(Map, line_p, line_c, offset);
86 if (itype < 0)
87 return itype; /* nothing to read or failure */
88
89 if (itype == 0) /* skip dead line */
90 continue;
91
92 if (Map->constraint.type_flag) {
93 /* skip feature by type */
94 if (!(itype & Map->constraint.type))
95 continue;
96 }
97
98 if (line_p && Map->constraint.region_flag) {
99 /* skip feature by region */
101
102 if (!Vect_box_overlap(&lbox, &mbox))
103 continue;
104 }
105
106 if (line_c && Map->constraint.field_flag) {
107 /* skip feature by field */
108 if (Vect_cat_get(line_c, Map->constraint.field, NULL) == 0)
109 continue;
110 }
111
112 return itype;
113 }
114
115 return -1; /* NOTREACHED */
116}
117
118/*! \brief Read vector feature on topological level (level 2) -
119 native format - internal use only
120
121 This function implements random access for native format,
122 constraints are ignored!
123
124 Note: Topology must be built at level >= GV_BUILD_BASE
125
126 \param Map pointer to Map_info struct
127 \param[out] line_p container used to store line points within (pointer to
128 line_pnts struct)
129 \param[out] line_c container used to store line categories
130 within (pointer to line_cats struct)
131 \param line feature id to read (starts at 1)
132
133 \return feature type (GV_POINT, GV_LINE, ...)
134 \return -2 nothing to read
135 \return -1 on failure
136 */
138 struct line_cats *line_c, int line)
139{
140 struct P_line *Line;
141
142 G_debug(3, "V2_read_line_nat(): line = %d", line);
143
144 if (line < 1 || line > Map->plus.n_lines) {
145 G_warning(_("Attempt to access feature with invalid id (%d)"), line);
146 return -1;
147 }
148
149 Line = Map->plus.Line[line];
150 if (Line == NULL) {
151 G_warning(_("Attempt to access dead feature %d"), line);
152 return -1;
153 }
154
155 return read_line_nat(Map, line_p, line_c, Line->offset);
156}
157
158/*! \brief Read next vector feature on topological level (level 2) -
159 native format - internal use only.
160
161 This function implements sequential access, constraints are
162 reflected, see Vect_set_constraint_region(),
163 Vect_set_constraint_type(), or Vect_set_constraint_field().
164
165 Use Vect_rewind() to reset reading.
166
167 Dead feature are skipped.
168
169 \param Map pointer to Map_info struct
170 \param[out] line_p container used to store line points within
171 (pointer to line_pnts struct)
172 \param[out] line_c container used to store line categories within
173 (pointer to line_cats struct)
174
175 \return feature type (GV_POINT, GV_LINE, ...)
176 \return -2 nothing to read
177 \return -1 on error
178 */
180 struct line_cats *line_c)
181{
182 int line, ret;
183 struct P_line *Line;
184 struct bound_box lbox, mbox;
185
186 G_debug(3, "V2_read_next_line_nat()");
187
188 if (Map->constraint.region_flag)
190
191 while (TRUE) {
192 line = Map->next_line;
193
194 if (line > Map->plus.n_lines)
195 return -2; /* nothing to read */
196
197 Line = Map->plus.Line[line];
198 if (Line == NULL) {
199 /* skip dead line */
200 Map->next_line++;
201 continue;
202 }
203
204 if (Map->constraint.type_flag) {
205 /* skip feature by type */
206 if (!(Line->type & Map->constraint.type)) {
207 Map->next_line++;
208 continue;
209 }
210 }
211
212 Map->next_line++;
213 ret = read_line_nat(Map, line_p, line_c, Line->offset);
214 if (ret < 0)
215 return ret;
216
217 if (line_p && Map->constraint.region_flag) {
218 /* skip feature by bbox */
220
221 if (!Vect_box_overlap(&lbox, &mbox))
222 continue;
223 }
224
225 if (line_c && Map->constraint.field_flag) {
226 /* skip feature by field */
227 if (Vect_cat_get(line_c, Map->constraint.field, NULL) == 0)
228 continue;
229 }
230
231 return ret;
232 }
233
234 return -1; /* NOTREACHED */
235}
236
237/*!
238 \brief Read line from coor file
239
240 \param Map vector map layer
241 \param[out] p container used to store line points within
242 \param[out] c container used to store line categories within
243 \param offset given offset
244
245 \return line type ( > 0 )
246 \return 0 dead line
247 \return -1 out of memory
248 \return -2 end of file
249 */
250int read_line_nat(struct Map_info *Map, struct line_pnts *p,
251 struct line_cats *c, off_t offset)
252{
253 register int i, dead = 0;
254 int n_points;
255 off_t size;
256 int n_cats, do_cats;
257 int type;
258 char rhead, nc;
259 short field;
260
261 G_debug(3, "Vect__Read_line_nat: offset = %lu", (unsigned long)offset);
262
263 Map->head.last_offset = offset;
264
265 /* reads must set in_head, but writes use default */
266 dig_set_cur_port(&(Map->head.port));
267
268 dig_fseek(&(Map->dig_fp), offset, 0);
269
270 if (0 >= dig__fread_port_C(&rhead, 1, &(Map->dig_fp)))
271 return (-2);
272
273 if (!(rhead & 0x01)) /* dead line */
274 dead = 1;
275
276 if (rhead & 0x02) /* categories exists */
277 do_cats =
278 1; /* do not return here let file offset moves forward to next */
279 else /* line */
280 do_cats = 0;
281
282 rhead >>= 2;
283 type = dig_type_from_store((int)rhead);
284
285 G_debug(3, " type = %d, do_cats = %d dead = %d", type, do_cats, dead);
286
287 if (c != NULL)
288 c->n_cats = 0;
289
290 if (do_cats) {
291 if (Map->head.coor_version.minor == 1) { /* coor format 5.1 */
292 if (0 >= dig__fread_port_I(&n_cats, 1, &(Map->dig_fp)))
293 return (-2);
294 }
295 else { /* coor format 5.0 */
296 if (0 >= dig__fread_port_C(&nc, 1, &(Map->dig_fp)))
297 return (-2);
298 n_cats = (int)nc;
299 }
300 G_debug(3, " n_cats = %d", n_cats);
301
302 if (c != NULL) {
303 c->n_cats = n_cats;
304 if (n_cats > 0) {
305 if (0 > dig_alloc_cats(c, (int)n_cats + 1))
306 return -1;
307
308 if (Map->head.coor_version.minor == 1) { /* coor format 5.1 */
309 if (0 >=
310 dig__fread_port_I(c->field, n_cats, &(Map->dig_fp)))
311 return (-2);
312 }
313 else { /* coor format 5.0 */
314 for (i = 0; i < n_cats; i++) {
315 if (0 >= dig__fread_port_S(&field, 1, &(Map->dig_fp)))
316 return (-2);
317 c->field[i] = (int)field;
318 }
319 }
320 if (0 >= dig__fread_port_I(c->cat, n_cats, &(Map->dig_fp)))
321 return (-2);
322 }
323 }
324 else {
325 if (Map->head.coor_version.minor == 1) { /* coor format 5.1 */
326 size = (off_t)(2 * PORT_INT) * n_cats;
327 }
328 else { /* coor format 5.0 */
329 size = (off_t)(PORT_SHORT + PORT_INT) * n_cats;
330 }
331
332 dig_fseek(&(Map->dig_fp), size, SEEK_CUR);
333 }
334 }
335
336 if (type & GV_POINTS) {
337 n_points = 1;
338 }
339 else {
340 if (0 >= dig__fread_port_I(&n_points, 1, &(Map->dig_fp)))
341 return (-2);
342 }
343
344 G_debug(3, " n_points = %d", n_points);
345
346 if (p != NULL) {
347 if (0 > dig_alloc_points(p, n_points + 1))
348 return (-1);
349
350 p->n_points = n_points;
351 if (0 >= dig__fread_port_D(p->x, n_points, &(Map->dig_fp)))
352 return (-2);
353 if (0 >= dig__fread_port_D(p->y, n_points, &(Map->dig_fp)))
354 return (-2);
355
356 if (Map->head.with_z) {
357 if (0 >= dig__fread_port_D(p->z, n_points, &(Map->dig_fp)))
358 return (-2);
359 }
360 else {
361 for (i = 0; i < n_points; i++)
362 p->z[i] = 0.0;
363 }
364 }
365 else {
366 if (Map->head.with_z)
367 size = (off_t)n_points * 3 * PORT_DOUBLE;
368
369 else
370 size = (off_t)n_points * 2 * PORT_DOUBLE;
371
372 dig_fseek(&(Map->dig_fp), size, SEEK_CUR);
373 }
374
375 G_debug(3, " off = %lu", (unsigned long)dig_ftell(&(Map->dig_fp)));
376
377 if (dead)
378 return 0;
379
380 return type;
381}
#define NULL
Definition ccmath.h:32
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
void Vect_line_box(const struct line_pnts *, struct bound_box *)
Get bounding box of line.
Definition line.c:888
int Vect_cat_get(const struct line_cats *, int, int *)
Get first found category of given field.
int Vect_get_constraint_box(struct Map_info *, struct bound_box *)
Get constraint box.
Definition constraint.c:79
int Vect_box_overlap(const struct bound_box *, const struct bound_box *)
Tests for overlap of two boxes.
#define PORT_SHORT
Definition dig_defines.h:49
#define PORT_DOUBLE
Sizes of types used in portable format (different names used in Vlib/ and diglib/ for the same thing)
Definition dig_defines.h:45
#define PORT_INT
Definition dig_defines.h:48
#define GV_POINTS
int dig__fread_port_D(double *, size_t, struct gvfile *)
Read doubles from the Portable Vector Format.
Definition portable.c:79
int dig_alloc_points(struct line_pnts *, int)
allocate room for 'num' X and Y arrays in struct line_pnts
off_t dig_ftell(struct gvfile *file)
Get struct gvfile position.
Definition file.c:36
int dig_set_cur_port(struct Port_info *)
Set current Port_info structure.
Definition portable.c:996
int dig__fread_port_C(char *, size_t, struct gvfile *)
Read chars from the Portable Vector Format.
Definition portable.c:511
int dig__fread_port_S(short *, size_t, struct gvfile *)
Read shorts from the Portable Vector Format.
Definition portable.c:428
int dig__fread_port_I(int *, size_t, struct gvfile *)
Read integers from the Portable Vector Format.
Definition portable.c:345
int dig_fseek(struct gvfile *file, off_t offset, int whence)
Set struct gvfile position.
Definition file.c:60
int dig_type_from_store(int)
Convert type from store type.
int dig_alloc_cats(struct line_cats *, int)
Allocate room for 'num' fields and category arrays in struct line_cats.
#define TRUE
Definition gis.h:78
#define _(str)
Definition glocale.h:10
int V2_read_line_nat(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, int line)
Read vector feature on topological level (level 2) - native format - internal use only.
Definition read_nat.c:137
int V1_read_next_line_nat(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c)
Read next vector feature on non-topological level (level 1) - native format - internal use only.
Definition read_nat.c:71
int V1_read_line_nat(struct Map_info *Map, struct line_pnts *Points, struct line_cats *Cats, off_t offset)
Read vector feature on non-topological level (level 1) - native format - internal use only.
Definition read_nat.c:43
int V2_read_next_line_nat(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c)
Read next vector feature on topological level (level 2) - native format - internal use only.
Definition read_nat.c:179
Vector map info.
Vector geometry.
char type
Line type.
off_t offset
Offset in coor file for line.
Bounding box.
Definition dig_structs.h:62
Feature category info.
int * field
Array of layers (fields)
int * cat
Array of categories.
int n_cats
Number of categories attached to element.
Feature geometry info - coordinates.
double * y
Array of Y coordinates.
double * x
Array of X coordinates.
int n_points
Number of points.
double * z
Array of Z coordinates.