GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-809ca1ee84
vector/Vlib/write.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/write.c
3 
4  \brief Vector library - write vector features
5 
6  Higher level functions for reading/writing/manipulating vectors.
7 
8  Supported operations:
9  - Write a new feature
10  - Rewrite existing feature
11  - Delete existing feature
12  - Restore deleted feature
13 
14  (C) 2001-2010, 2012-2013 by the GRASS Development Team
15 
16  This program is free software under the GNU General Public License
17  (>=v2). Read the file COPYING that comes with GRASS for details.
18 
19  \author Radim Blazek
20  \author Updated by Martin Landa <landa.martin gmail.com> (restore lines, OGR
21  & PostGIS support)
22  */
23 
24 #include <inttypes.h>
25 #include <sys/types.h>
26 #include <grass/glocale.h>
27 #include <grass/vector.h>
28 
29 static off_t write_dummy(struct Map_info *Map UNUSED, int type UNUSED,
30  const struct line_pnts *points UNUSED,
31  const struct line_cats *cats UNUSED)
32 {
33  G_warning("Vect_write_line() %s", _("for this format/level not supported"));
34  return -1;
35 }
36 
37 static off_t rewrite_dummy(struct Map_info *Map UNUSED, off_t line UNUSED,
38  int type UNUSED,
39  const struct line_pnts *points UNUSED,
40  const struct line_cats *cats UNUSED)
41 {
42  G_warning("Vect_rewrite_line() %s",
43  _("for this format/level not supported"));
44  return -1;
45 }
46 
47 static int delete_dummy(struct Map_info *Map UNUSED, off_t line UNUSED)
48 {
49  G_warning("Vect_delete_line() %s",
50  _("for this format/level not supported"));
51  return -1;
52 }
53 
54 static int restore_dummy(struct Map_info *Map UNUSED, off_t offset UNUSED,
55  off_t line UNUSED)
56 {
57  G_warning("Vect_restore_line() %s",
58  _("for this format/level not supported"));
59  return -1;
60 }
61 
62 #if !defined HAVE_OGR || !defined HAVE_POSTGRES
63 static int format(struct Map_info *Map UNUSED, off_t line UNUSED)
64 {
65  G_fatal_error(_("Requested format is not compiled in this version"));
66  return 0;
67 }
68 
69 static int format2(struct Map_info *Map UNUSED, off_t offset UNUSED,
70  off_t line UNUSED)
71 {
72  G_fatal_error(_("Requested format is not compiled in this version"));
73  return 0;
74 }
75 
76 static off_t format_l(struct Map_info *Map UNUSED, int type UNUSED,
77  const struct line_pnts *points UNUSED,
78  const struct line_cats *cats UNUSED)
79 {
80  G_fatal_error(_("Requested format is not compiled in this version"));
81  return 0;
82 }
83 
84 static off_t format_l2(struct Map_info *Map UNUSED, off_t line UNUSED,
85  int type UNUSED, const struct line_pnts *points UNUSED,
86  const struct line_cats *cats UNUSED)
87 {
88  G_fatal_error(_("Requested format is not compiled in this version"));
89  return 0;
90 }
91 #endif
92 
93 static off_t (*Vect_write_line_array[][3])(struct Map_info *, int,
94  const struct line_pnts *,
95  const struct line_cats *) = {
96  {write_dummy, V1_write_line_nat, V2_write_line_nat}
97 #ifdef HAVE_OGR
98  ,
99  {write_dummy, V1_write_line_ogr, V2_write_line_sfa},
100  {write_dummy, V1_write_line_ogr, V2_write_line_sfa}
101 #else
102  ,
103  {write_dummy, format_l, format_l},
104  {write_dummy, format_l, format_l}
105 #endif
106 #ifdef HAVE_POSTGRES
107  ,
108  {write_dummy, V1_write_line_pg, V2_write_line_pg}
109 #else
110  ,
111  {write_dummy, format_l, format_l}
112 #endif
113 };
114 
115 static off_t (*Vect_rewrite_line_array[][3])(struct Map_info *, off_t, int,
116  const struct line_pnts *,
117  const struct line_cats *) = {
118  {rewrite_dummy, V1_rewrite_line_nat, V2_rewrite_line_nat}
119 #ifdef HAVE_OGR
120  ,
121  {rewrite_dummy, V1_rewrite_line_ogr, V2_rewrite_line_sfa},
122  {rewrite_dummy, V1_rewrite_line_ogr, V2_rewrite_line_sfa}
123 #else
124  ,
125  {rewrite_dummy, format_l2, format_l2},
126  {rewrite_dummy, format_l2, format_l2}
127 #endif
128 #ifdef HAVE_POSTGRES
129  ,
130  {rewrite_dummy, V1_rewrite_line_pg, V2_rewrite_line_pg}
131 #else
132  ,
133  {rewrite_dummy, format_l2, format_l2}
134 #endif
135 };
136 
137 static int (*Vect_delete_line_array[][3])(struct Map_info *, off_t) = {
138  {delete_dummy, V1_delete_line_nat, V2_delete_line_nat}
139 #ifdef HAVE_OGR
140  ,
141  {delete_dummy, V1_delete_line_ogr, V2_delete_line_sfa},
142  {delete_dummy, V1_delete_line_ogr, V2_delete_line_sfa}
143 #else
144  ,
145  {delete_dummy, format, format},
146  {delete_dummy, format, format}
147 #endif
148 #ifdef HAVE_POSTGRES
149  ,
150  {delete_dummy, V1_delete_line_pg, V2_delete_line_pg}
151 #else
152  ,
153  {delete_dummy, format, format}
154 #endif
155 };
156 
157 static int (*Vect_restore_line_array[][3])(struct Map_info *, off_t, off_t) = {
158  {restore_dummy, V1_restore_line_nat, V2_restore_line_nat}
159 #ifdef HAVE_OGR
160  ,
161  {restore_dummy, restore_dummy, restore_dummy},
162  {restore_dummy, restore_dummy, restore_dummy}
163 #else
164  ,
165  {restore_dummy, format2, format2},
166  {restore_dummy, format2, format2}
167 #endif
168 #ifdef HAVE_POSTGRES
169  ,
170  {restore_dummy, restore_dummy, restore_dummy}
171 #else
172  ,
173  {restore_dummy, format2, format2}
174 #endif
175 };
176 
177 static int check_map(struct Map_info *);
178 
179 /*!
180  \brief Writes a new feature
181 
182  New feature is written to the end of file (in the case of native
183  format). Topological level is not required.
184 
185  A warning is printed on error.
186 
187  \param Map pointer to Map_info structure
188  \param type feature type (see dig_defines.h for supported types)
189  \param points pointer to line_pnts structure (feature geometry)
190  \param cats pointer to line_cats structure (feature categories)
191 
192  \return new feature id (on level 2) (or 0 when build level < GV_BUILD_BASE)
193  \return offset into file where the feature starts (on level 1)
194  \return -1 on error
195  */
196 off_t Vect_write_line(struct Map_info *Map, int type,
197  const struct line_pnts *points,
198  const struct line_cats *cats)
199 {
200  off_t offset;
201 
202  G_debug(3, "Vect_write_line(): name = %s, format = %d, level = %d",
203  Map->name, Map->format, Map->level);
204 
205  if (!check_map(Map))
206  return -1;
207 
208  offset = (*Vect_write_line_array[Map->format][Map->level])(Map, type,
209  points, cats);
210 
211  if (offset < 0)
212  G_warning(_("Unable to write feature in vector map <%s>"),
213  Vect_get_name(Map));
214 
215  return offset;
216 }
217 
218 /*!
219  \brief Rewrites existing feature (topological level required)
220 
221  Note: Topology must be built at level >= GV_BUILD_BASE
222 
223  A warning is printed on error.
224 
225  The number of points or cats or type may change. If necessary, the
226  old feature is deleted and new is written.
227 
228  \param Map pointer to Map_info structure
229  \param line feature id (level 2) or feature offset (level 1)
230  \param type feature type (GV_POINT, GV_LINE, ...)
231  \param points feature geometry
232  \param cats feature categories
233 
234  \return new feature id (on level 2) (or 0 when build level < GV_BUILD_BASE)
235  \return offset into file where the feature starts (on level 1)
236  \return -1 on error
237  */
238 off_t Vect_rewrite_line(struct Map_info *Map, off_t line, int type,
239  const struct line_pnts *points,
240  const struct line_cats *cats)
241 {
242  off_t ret;
243 
244  G_debug(3,
245  "Vect_rewrite_line(): name = %s, format = %d, level = %d, "
246  "line/offset = %" PRId64,
247  Map->name, Map->format, Map->level, line);
248 
249  if (!check_map(Map))
250  return -1;
251 
252  ret = (*Vect_rewrite_line_array[Map->format][Map->level])(Map, line, type,
253  points, cats);
254  if (ret == -1)
255  G_warning(_("Unable to rewrite feature/offset %" PRId64
256  " in vector map <%s>"),
257  line, Vect_get_name(Map));
258 
259  return ret;
260 }
261 
262 /*!
263  \brief Delete existing feature (topological level required)
264 
265  Note: Topology must be built at level >= GV_BUILD_BASE
266 
267  A warning is printed on error.
268 
269  \param Map pointer to Map_info structure
270  \param line feature id (level 2) or feature offset (level 1)
271 
272  \return 0 on success
273  \return -1 on error
274  */
275 int Vect_delete_line(struct Map_info *Map, off_t line)
276 {
277  int ret;
278 
279  G_debug(3, "Vect_delete_line(): name = %s, line/offset = %" PRId64,
280  Map->name, line);
281 
282  if (!check_map(Map))
283  return -1;
284 
285  ret = (*Vect_delete_line_array[Map->format][Map->level])(Map, line);
286 
287  if (ret == -1)
288  G_warning(_("Unable to delete feature/offset %" PRId64
289  " from vector map <%s>"),
290  line, Vect_get_name(Map));
291 
292  return ret;
293 }
294 
295 /*!
296  \brief Restore previously deleted feature (topological level required)
297 
298  Note: Topology must be built at level >= GV_BUILD_BASE
299 
300  A warning is printed on error.
301 
302  \param Map pointer to Map_info structure
303  \param offset feature offset to be restored
304  \param line feature id to be restored (used only on level 2)
305 
306  \return 0 on success
307  \return -1 on error
308  */
309 int Vect_restore_line(struct Map_info *Map, off_t offset, off_t line)
310 {
311  int ret;
312 
313  G_debug(3,
314  "Vect_restore_line(): name = %s, level = %d, offset = %" PRId64
315  ", line = %" PRId64,
316  Map->name, Map->level, offset, line);
317 
318  if (!check_map(Map))
319  return -1;
320 
321  ret =
322  (*Vect_restore_line_array[Map->format][Map->level])(Map, offset, line);
323 
324  if (ret == -1)
325  G_warning(_("Unable to restore feature/offset %" PRId64
326  " in vector map <%s>"),
327  offset, Vect_get_name(Map));
328 
329  return ret;
330 }
331 
332 int check_map(struct Map_info *Map)
333 {
334  if (!VECT_OPEN(Map)) {
335  G_warning(_("Vector map <%s> is not opened"), Vect_get_name(Map));
336  return 0;
337  }
338 
339  if (Map->mode != GV_MODE_RW && Map->mode != GV_MODE_WRITE) {
340  G_warning(_("Vector map <%s> is not opened in write mode"),
341  Vect_get_name(Map));
342  return 0;
343  }
344 
345  return 1;
346 }
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
off_t V1_rewrite_line_ogr(struct Map_info *, off_t, int, const struct line_pnts *, const struct line_cats *)
Rewrites feature at the given offset on level 1 (OGR interface)
Definition: write_ogr.c:89
off_t V2_write_line_sfa(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes feature on level 2 (OGR/PostGIS interface, pseudo-topological level)
Definition: write_sfa.c:52
int V1_delete_line_pg(struct Map_info *, off_t)
off_t V1_write_line_nat(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes feature to 'coor' file at level 1 (internal use only)
Definition: write_nat.c:45
off_t V1_write_line_ogr(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes feature on level 1 (OGR interface)
Definition: write_ogr.c:63
int V2_delete_line_pg(struct Map_info *, off_t)
off_t V2_write_line_pg(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
off_t V2_rewrite_line_sfa(struct Map_info *, off_t, int, const struct line_pnts *, const struct line_cats *)
Rewrites feature at the given offset on level 2 (OGR/PostGIS interface, pseudo-topological level)
Definition: write_sfa.c:152
off_t V2_write_line_nat(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes feature to 'coor' file at topological level (internal use only)
Definition: write_nat.c:67
int V2_delete_line_nat(struct Map_info *, off_t)
Deletes feature at topological level (internal use only)
Definition: write_nat.c:290
int V1_restore_line_nat(struct Map_info *, off_t, off_t)
Restores feature at level 1 (internal use only)
Definition: write_nat.c:350
int V1_delete_line_ogr(struct Map_info *, off_t)
Deletes feature at the given offset on level 1 (OGR interface)
Definition: write_ogr.c:119
off_t V2_rewrite_line_nat(struct Map_info *, off_t, int, const struct line_pnts *, const struct line_cats *)
Rewrites feature to 'coor' file at topological level (internal use only)
Definition: write_nat.c:161
off_t V1_rewrite_line_nat(struct Map_info *, off_t, int, const struct line_pnts *, const struct line_cats *)
Rewrites feature to 'coor' file at level 1 (internal use only)
Definition: write_nat.c:105
const char * Vect_get_name(struct Map_info *)
Get name of vector map.
int V2_restore_line_nat(struct Map_info *, off_t, off_t)
Restores feature at topological level (internal use only)
Definition: write_nat.c:398
int V1_delete_line_nat(struct Map_info *, off_t)
Deletes feature at level 1 (internal use only)
Definition: write_nat.c:248
off_t V2_rewrite_line_pg(struct Map_info *, off_t, int, const struct line_pnts *, const struct line_cats *)
int V2_delete_line_sfa(struct Map_info *, off_t)
Deletes feature on level 2 (OGR/PostGIS interface)
Definition: write_sfa.c:193
off_t V1_write_line_pg(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
off_t V1_rewrite_line_pg(struct Map_info *, off_t, int, const struct line_pnts *, const struct line_cats *)
#define VECT_OPEN(Map)
Check if vector map is open.
Definition: dig_defines.h:137
#define GV_MODE_WRITE
Write vector map open mode.
Definition: dig_defines.h:106
#define GV_MODE_RW
Read-write vector map open mode.
Definition: dig_defines.h:108
#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
Vector map info.
Definition: dig_structs.h:1243
int level
Topology level.
Definition: dig_structs.h:1297
char * name
Map name (for 4.0)
Definition: dig_structs.h:1316
int type
Feature type constraint.
Definition: dig_structs.h:1359
int format
Map format (native, ogr, postgis)
Definition: dig_structs.h:1255
Feature category info.
Definition: dig_structs.h:1677
Feature geometry info - coordinates.
Definition: dig_structs.h:1651
int Vect_delete_line(struct Map_info *Map, off_t line)
Delete existing feature (topological level required)
off_t Vect_write_line(struct Map_info *Map, int type, const struct line_pnts *points, const struct line_cats *cats)
Writes a new feature.
int Vect_restore_line(struct Map_info *Map, off_t offset, off_t line)
Restore previously deleted feature (topological level required)
off_t Vect_rewrite_line(struct Map_info *Map, off_t line, int type, const struct line_pnts *points, const struct line_cats *cats)
Rewrites existing feature (topological level required)