GRASS 8 Programmer's Manual 8.6.0dev(2026)-5f4f7ad06c
Loading...
Searching...
No Matches
write_sfa.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/Vlib/write_sfa.c
3
4 \brief Vector library - write vector feature - simple feature access (level
5 2)
6
7 Higher level functions for reading/writing/manipulating vectors.
8
9 See write_ogr.c (OGR interface) and write_pg.c (PostGIS interface)
10 for implementation issues.
11
12 \todo SFA version of V2__delete_area_cats_from_cidx_nat()
13 \todo function to delete corresponding entry in fidx
14 \todo SFA version of V2__add_area_cats_to_cidx_nat
15 \todo SFA version of V2__add_line_to_topo_nat
16
17 (C) 2011-2012 by Martin Landa, and the GRASS Development Team
18
19 This program is free software under the GNU General Public License
20 (>=v2). Read the file COPYING that comes with GRASS for details.
21
22 \author Martin Landa <landa.martin gmail.com>
23 */
24
25#include <grass/vector.h>
26#include <grass/glocale.h>
27
28#include "local_proto.h"
29
30#ifdef HAVE_POSTGRES
31#include "pg_local_proto.h"
32#endif
33
34static void V2__add_line_to_topo_sfa(struct Map_info *, int,
35 const struct line_pnts *,
36 const struct line_cats *);
37
38/*!
39 \brief Writes feature on level 2 (OGR/PostGIS interface, pseudo-topological
40 level)
41
42 \param Map pointer to Map_info structure
43 \param type feature type (see V1_write_line_ogr() for list of supported
44 types) \param points pointer to line_pnts structure (feature geometry) \param
45 cats pointer to line_cats structure (feature categories)
46
47 \return feature index in offset array (related to pseudo-topology)
48 \return -1 on error
49 */
51 const struct line_pnts *points,
52 const struct line_cats *cats)
53{
54 int line;
55 off_t offset;
56 struct Plus_head *plus;
57 struct bound_box box;
59
60 line = 0;
61 plus = &(Map->plus);
62
63 G_debug(3, "V2_write_line_sfa(): type = %d (format = %d)", type,
64 Map->format);
65
66 if (Map->format == GV_FORMAT_POSTGIS) {
67 offset_info = &(Map->fInfo.pg.offset);
68 offset = V1_write_line_pg(Map, type, points, cats);
69 }
70 else {
71 offset_info = &(Map->fInfo.pg.offset);
72 offset = V1_write_line_ogr(Map, type, points, cats);
73 }
74 if (offset < 0)
75 return -1;
76
77 if (!(plus->update_cidx)) {
78 plus->cidx_up_to_date = FALSE; /* category index will be outdated */
79 }
80
81 /* Update topology */
82 if (plus->built >= GV_BUILD_BASE) {
83 dig_line_box(points, &box);
84 line = dig_add_line(plus, type, points, &box, offset);
85 G_debug(3, "\tline added to topo with line = %d", line);
86 if (line == 1)
87 Vect_box_copy(&(plus->box), &box);
88 else
89 Vect_box_extend(&(plus->box), &box);
90
91 if (type == GV_BOUNDARY) {
92 int ret, cline;
93 long fid;
94 double x, y;
95
96 struct bound_box box;
97 struct line_pnts *CPoints;
98
99 /* add virtual centroid to pseudo-topology */
100 ret = Vect_get_point_in_poly(points, &x, &y);
101 if (ret == 0) {
104
105 fid = offset_info->array[offset];
106
107 dig_line_box(CPoints, &box);
108 cline = dig_add_line(plus, GV_CENTROID, CPoints, &box, fid);
109 G_debug(4, "\tCentroid: x = %f, y = %f, cat = %lu, line = %d",
110 x, y, fid, cline);
111 dig_cidx_add_cat(plus, 1, (int)fid, cline, GV_CENTROID);
112
114 }
115 else {
116 G_warning(_("Unable to calculate centroid for area"));
117 }
118 }
119 V2__add_line_to_topo_sfa(Map, line, points, cats);
120 }
121
122 G_debug(3, "updated lines : %d , updated nodes : %d",
123 plus->uplist.n_uplines, plus->uplist.n_upnodes);
124
125 /* returns int line, but is defined as off_t for compatibility with
126 * Write_line_array in write.c */
127 return line;
128}
129
130/*!
131 \brief Rewrites feature at the given offset on level 2 (OGR/PostGIS
132 interface, pseudo-topological level)
133
134 Note: Topology must be built at level >= GV_BUILD_BASE
135
136 \param Map pointer to Map_info structure
137 \param line feature id to be rewritten
138 \param type feature type (see V1_write_line_ogr() for supported types)
139 \param points pointer to line_pnts structure (feature geometry)
140 \param cats pointer to line_cats structure feature categories
141
142 \return feature index in offset array (related to pseudo-topology)
143 \return -1 on error
144 */
146 const struct line_pnts *points,
147 const struct line_cats *cats)
148{
149 G_debug(3, "V2_rewrite_line_sfa(): line=%d type=%d", (int)line, type);
150
151 if (line < 1 || line > Map->plus.n_lines) {
152 G_warning(_("Attempt to access feature with invalid id (%d)"),
153 (int)line);
154 return -1;
155 }
156
157 if (type != V2_read_line_sfa(Map, NULL, NULL, line)) {
158 G_warning(_("Unable to rewrite feature (incompatible feature types)"));
159 return -1;
160 }
161
162 if (V2_delete_line_sfa(Map, line) != 0)
163 return -1;
164
165 return V2_write_line_sfa(Map, type, points, cats);
166}
167
168/*!
169 \brief Deletes feature on level 2 (OGR/PostGIS interface)
170
171 Note: Topology must be built at level >= GV_BUILD_BASE
172
173 \todo Update fidx
174
175 \param pointer to Map_info structure
176 \param line feature id to be deleted
177
178 \return 0 on success
179 \return -1 on error
180 */
182{
183 int ret, i, type, first;
184 struct P_line *Line;
185 struct Plus_head *plus;
186 static struct line_cats *Cats = NULL;
187 static struct line_pnts *Points = NULL;
188
189 G_debug(3, "V2_delete_line_sfa(): line = %d", (int)line);
190
191 type = first = 0;
192 Line = NULL;
193 plus = &(Map->plus);
194
195 if (line < 1 || line > Map->plus.n_lines) {
196 G_warning(_("Attempt to access feature with invalid id (%d)"),
197 (int)line);
198 return -1;
199 }
200
201 if (!(plus->update_cidx)) {
202 plus->cidx_up_to_date = FALSE; /* category index will be outdated */
203 }
204
205 if (plus->built >= GV_BUILD_BASE) {
206 Line = Map->plus.Line[line];
207
208 if (Line == NULL)
209 G_fatal_error(_("Attempt to delete dead feature"));
210 type = Line->type;
211 }
212
213 if (!Cats) {
215 }
216 if (!Points) {
217 Points = Vect_new_line_struct();
218 }
219
220 type = V2_read_line_sfa(Map, Points, Cats, line);
221 if (type < 0)
222 return -1;
223
224 /* Update category index */
225 if (plus->update_cidx) {
226 for (i = 0; i < Cats->n_cats; i++) {
227 dig_cidx_del_cat(plus, Cats->field[i], Cats->cat[i], line, type);
228 }
229 }
230 /* Update fidx */
231 /* TODO */
232
233 /* delete the line from coor */
234 if (Map->format == GV_FORMAT_POSTGIS)
236 else
238
239 if (ret == -1) {
240 return ret;
241 }
242
243 /* Update topology */
244 if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY) {
245 /* TODO */
246 /* remove centroid together with boundary (is really an OGR polygon) */
247 }
248 /* Delete reference from area */
249 if (plus->built >= GV_BUILD_CENTROIDS && type == GV_CENTROID) {
250 /* for OGR mapsets, virtual centroid will be removed when
251 * polygon is removed */
252 }
253
254 /* delete the line from topo */
255 dig_del_line(plus, line, Points->x[0], Points->y[0], Points->z[0]);
256
257 /* Rebuild areas/isles and attach centroids and isles */
258 if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY) {
259 /* maybe not needed VERIFY */
260 }
261 return ret;
262}
263
264/*!
265 \brief Writes area on topological level (Simple Features interface,
266 internal use only)
267
268 \param Map pointer to Map_info structure
269 \param points feature geometry (exterior + interior rings)
270 \param nparts number of parts including exterior ring
271 \param cats feature categories
272
273 \return feature offset
274 \return -1 on error
275 */
276off_t V2__write_area_sfa(struct Map_info *Map, const struct line_pnts **points,
277 int nparts, const struct line_cats *cats)
278{
279 if (Map->format == GV_FORMAT_OGR) {
280 return V2__write_area_ogr(Map, points, nparts, cats);
281 }
282 else if (Map->format == GV_FORMAT_POSTGIS) {
283#ifdef HAVE_POSTGRES
284 return V2__write_area_pg(Map, points, nparts, cats);
285#else
286 G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
287 return -1;
288#endif
289 }
290 else {
291 G_warning(_("Unsupported vector map format (%d)"), Map->format);
292 }
293 return -1;
294}
295
296/*!
297 \brief Add feature to topo file (internal use only)
298
299 \param Map pointer to Map_info structure
300 \param line feature id
301 \param points pointer to line_pnts structure (feature geometry)
302 \param cats pointer to line_cats structure (feature categories)
303 */
304void V2__add_line_to_topo_sfa(struct Map_info *Map, int line,
305 const struct line_pnts *points,
306 const struct line_cats *cats)
307{
308 int first, s, i;
309 int type, area, side;
310
311 struct Plus_head *plus;
312 struct P_line *Line;
313
314 struct bound_box box, abox;
315
316 G_debug(3, "V2__add_line_to_topo_sfa(): line = %d npoints = %d", line,
317 points->n_points);
318
319 first = TRUE;
320 plus = &(Map->plus);
321 Line = plus->Line[line];
322 type = Line->type;
323
324 if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY) {
325 struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
326
327 if (topo->N1 != topo->N2) {
328 G_warning(_("Boundary is not closed. Skipping."));
329 return;
330 }
331
332 /* Build new areas/isles */
333 for (s = 0; s < 2; s++) {
334 side = (s == 0 ? GV_LEFT : GV_RIGHT);
335 area = Vect_build_line_area(Map, line, side);
336 if (area > 0) { /* area */
337 Vect_get_area_box(Map, area, &box);
338 if (first) {
339 Vect_box_copy(&abox, &box);
340 first = FALSE;
341 }
342 else
343 Vect_box_extend(&abox, &box);
344 }
345 else if (area < 0) {
346 /* isle -> must be attached -> add to abox */
347 Vect_get_isle_box(Map, -area, &box);
348 if (first) {
349 Vect_box_copy(&abox, &box);
350 first = FALSE;
351 }
352 else
353 Vect_box_extend(&abox, &box);
354 }
355 G_debug(4, "Vect_build_line_area(): -> area = %d", area);
356 }
357
358 /* Attach centroid/isle to the new area */
359 if (plus->built >= GV_BUILD_ATTACH_ISLES)
361 if (plus->built >= GV_BUILD_CENTROIDS)
363 }
364
365 /* Add category index */
366 for (i = 0; i < cats->n_cats; i++) {
367 dig_cidx_add_cat_sorted(plus, cats->field[i], cats->cat[i], line, type);
368 }
369
370 return;
371}
#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
int Vect_attach_centroids(struct Map_info *, const struct bound_box *)
(Re)Attach centroids in given bounding box to areas
Definition build.c:498
int V1_delete_line_pg(struct Map_info *, off_t)
Deletes feature at the given offset (level 1)
Definition write_pg.c:324
int Vect_build_line_area(struct Map_info *, int, int)
Build area on given side of line (GV_LEFT or GV_RIGHT)
Definition build.c:72
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:61
int Vect_box_extend(struct bound_box *, const struct bound_box *)
Extend box A by box B.
int Vect_get_point_in_poly(const struct line_pnts *, double *, double *)
Get point inside polygon.
Definition Vlib/poly.c:208
int Vect_get_area_box(struct Map_info *, int, struct bound_box *)
Get bounding box of area.
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:107
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
int Vect_get_isle_box(struct Map_info *, int, struct bound_box *)
Get bounding box of isle.
int Vect_attach_isles(struct Map_info *, const struct bound_box *)
(Re)Attach isles in given bounding box to areas
Definition build.c:420
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition line.c:45
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
Definition line.c:148
int V2_read_line_sfa(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Reads feature from OGR/PostGIS layer on topological level.
Definition read_sfa.c:40
int Vect_box_copy(struct bound_box *, const struct bound_box *)
Copy box B to box A.
off_t V1_write_line_pg(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes feature on level 1 (PostGIS interface)
Definition write_pg.c:109
#define GV_CENTROID
#define GV_FORMAT_POSTGIS
PostGIS format.
Definition dig_defines.h:89
#define GV_BOUNDARY
#define GV_BUILD_ATTACH_ISLES
Topology levels - attach islands to areas.
#define GV_BUILD_BASE
Topology levels - basic level (without areas and isles)
#define GV_BUILD_AREAS
Topology levels - build areas.
#define GV_BUILD_CENTROIDS
Topology levels - assign centroids to areas.
#define GV_RIGHT
#define GV_FORMAT_OGR
OGR format.
Definition dig_defines.h:85
#define GV_LEFT
Boundary side indicator left/right.
int dig_cidx_add_cat(struct Plus_head *, int, int, int, int)
int dig_del_line(struct Plus_head *, int, double, double, double)
Delete line from Plus_head structure.
Definition plus_line.c:217
int dig_cidx_del_cat(struct Plus_head *, int, int, int, int)
int dig_cidx_add_cat_sorted(struct Plus_head *, int, int, int, int)
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:133
int dig_line_box(const struct line_pnts *, struct bound_box *)
#define TRUE
Definition gis.h:78
#define FALSE
Definition gis.h:82
#define _(str)
Definition glocale.h:10
Data structure used for building pseudo-topology.
Vector map info.
Vector geometry.
char type
Line type.
off_t offset
Offset in coor file for line.
void * topo
Topology info.
Boundary topology.
Basic topology-related info.
struct P_line ** Line
Array of vector geometries.
int cidx_up_to_date
Category index to be updated.
int update_cidx
Update category index if vector is modified.
struct Plus_head::@10 uplist
List of updated lines/nodes.
struct bound_box box
Bounding box of features.
int built
Highest level of topology currently available.
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.
off_t V2__write_area_ogr(struct Map_info *Map, const struct line_pnts **points, int nparts, const struct line_cats *cats)
Writes area on topological level (OGR Simple Features interface, internal use only)
Definition write_ogr.c:146
off_t V2__write_area_pg(struct Map_info *Map, const struct line_pnts **points, int nparts, const struct line_cats *cats)
Writes area on topological level (PostGIS Simple Features interface, internal use only)
Definition write_pg.c:540
int V2_delete_line_sfa(struct Map_info *Map, off_t line)
Deletes feature on level 2 (OGR/PostGIS interface)
Definition write_sfa.c:181
off_t V2_rewrite_line_sfa(struct Map_info *Map, off_t line, int type, const struct line_pnts *points, const struct line_cats *cats)
Rewrites feature at the given offset on level 2 (OGR/PostGIS interface, pseudo-topological level)
Definition write_sfa.c:145
off_t V2__write_area_sfa(struct Map_info *Map, const struct line_pnts **points, int nparts, const struct line_cats *cats)
Writes area on topological level (Simple Features interface, internal use only)
Definition write_sfa.c:276
off_t V2_write_line_sfa(struct Map_info *Map, int type, const struct line_pnts *points, const struct line_cats *cats)
Writes feature on level 2 (OGR/PostGIS interface, pseudo-topological level)
Definition write_sfa.c:50
#define x