GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-6da4f45b8e
vector/Vlib/copy.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/copy.c
3 
4  \brief Vector library - Copy vector features and attribute tables linked to
5  the map
6 
7  Higher level functions for reading/writing/manipulating vectors.
8 
9  (C) 2001-2009, 2012-2013 by the GRASS Development Team
10 
11  This program is free software under the GNU General Public License
12  (>=v2). Read the file COPYING that comes with GRASS for details.
13 
14  \author Original author CERL, probably Dave Gerdes or Mike Higgins.
15  \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
16  \author Update to GRASS 7 by Martin Landa <landa.martin gmail.com>
17  (OGR/PostGIS topology support)
18  */
19 
20 #include <grass/vector.h>
21 #include <grass/glocale.h>
22 
23 #include "local_proto.h"
24 
25 /*!
26  \brief Copy topological elements
27 
28  - simple features (None)
29  - native topo (GRASS)
30  - PostGIS Topo
31  */
32 #define TOPO_NONE -1
33 #define TOPO_NATIVE 1
34 #define TOPO_POSTGIS 2
35 
36 #ifdef HAVE_POSTGRES
37 #include "pg_local_proto.h"
38 #define NOPG_UNUSED
39 #else
40 #define NOPG_UNUSED UNUSED
41 #endif
42 
43 static int copy_lines_1(struct Map_info *, int, struct Map_info *);
44 static int copy_lines_2(struct Map_info *, int, int, struct Map_info *);
45 
46 #if 0
47 static int copy_nodes(struct Map_info *, struct Map_info *);
48 #endif
49 static int copy_line_nodes(struct Map_info *, int, int, struct line_pnts *,
50  struct Map_info *);
51 static int is_isle(struct Map_info *, int);
52 
53 /*!
54  \brief Copy all alive vector features from input vector map to
55  output vector map
56 
57  \param In input vector map
58  \param[out] Out output vector map
59 
60  \return 0 on success
61  \return 1 on error
62  */
63 int Vect_copy_map_lines(struct Map_info *In, struct Map_info *Out)
64 {
65  return Vect_copy_map_lines_field(In, -1, Out);
66 }
67 
68 /*!
69  \brief Copy all alive vector features from given layer from input
70  vector map to output vector map
71 
72  Note: Try to copy on level 2 otherwise level 1 is used.
73 
74  \param In input vector map
75  \param field layer number (-1 for all layers)
76  \param[out] Out output vector map
77 
78  \return 0 on success
79  \return 1 on error
80  */
81 int Vect_copy_map_lines_field(struct Map_info *In, int field,
82  struct Map_info *Out)
83 {
84  int ret, format, topo;
85 
86  if (Vect_level(In) < 1)
88  _("Unable to copy features. Input vector map <%s> is not open"),
89  Vect_get_full_name(In));
90 
91  format = Out->format; /* do not use Vect_maptype(), we need native
92  format for temporary maps here */
93  topo = TOPO_NONE;
94  if (format == GV_FORMAT_NATIVE) {
95  topo = TOPO_NATIVE;
96  }
97  else if (format == GV_FORMAT_POSTGIS && Out->fInfo.pg.toposchema_name) {
98  int type;
99 
100  topo = TOPO_POSTGIS;
101 
102  /* get type of first feature from input vector map */
103  Vect_rewind(In);
105  type = Vect_read_next_line(In, NULL, NULL);
106 
107  /* create feature table with given feature type */
108  if (0 > Vect_write_line(Out, type, NULL, NULL)) {
109  G_warning(_("Unable to create PostGIS layer <%s>"),
111  return 1;
112  }
113  }
114 
115  /* Note: sometimes is important to copy on level 2 (pseudotopo
116  centroids) and sometimes on level 1 if build take too long time
117  */
118  ret = 0;
119  if (Vect_level(In) >= 2) {
120  /* -> copy features on level 2 */
121 #if 0
122  if (topo == TOPO_POSTGIS) {
123  /* PostGIS topology - copy also nodes */
124  copy_nodes(In, Out);
125  }
126 #endif
127  /* copy features */
128  ret += copy_lines_2(In, field, topo, Out);
129 
130  if (topo == TOPO_NONE &&
131  /* check output feature type, centroids can be exported as
132  * points; boundaries as linestrings */
133  strcmp(Vect_get_finfo_geometry_type(Out), "polygon") == 0) {
134  /* copy areas - external formats and simple features access only */
135  ret += Vect__copy_areas(In, field, Out);
136  }
137  }
138  else {
139  /* -> copy features on level 1 */
140  if (topo == TOPO_NONE)
141  G_warning(_("Vector map <%s> not open on topological level. "
142  "Areas will be skipped!"),
143  Vect_get_full_name(In));
144 
145  ret += copy_lines_1(In, field, Out);
146  }
147 
148  return ret > 0 ? 1 : 0;
149 }
150 
151 /*!
152  \brief Copy vector features on level 1
153 
154  \param In input vector map
155  \param field layer number (-1 for all layers)
156  \param Out output vector map
157 
158  \return 0 on success
159  \return 1 on error
160  */
161 int copy_lines_1(struct Map_info *In, int field, struct Map_info *Out)
162 {
163  int ret, type;
164 
165  struct line_pnts *Points;
166  struct line_cats *Cats;
167 
168  Points = Vect_new_line_struct();
169  Cats = Vect_new_cats_struct();
170 
171  ret = 0;
172 
173  Vect_rewind(In);
174  while (TRUE) {
175  type = Vect_read_next_line(In, Points, Cats);
176  if (type == -1) {
177  G_warning(_("Unable to read vector map <%s>"),
178  Vect_get_full_name(In));
179  ret = 1;
180  break;
181  }
182  else if (type == -2) { /* EOF */
183  break; /* free allocated space and return */
184  }
185  else if (type == 0) { /* dead line */
186  continue;
187  }
188 
189  /* don't skip boundaries if field != -1 */
190  if (field != -1 && !(type & GV_BOUNDARY) &&
191  Vect_cat_get(Cats, field, NULL) == 0)
192  continue; /* different layer */
193 
194  Vect_write_line(Out, type, Points, Cats);
195  }
196 
197  Vect_destroy_line_struct(Points);
199 
200  return ret;
201 }
202 
203 /*!
204  \brief Copy vector features on level 2
205 
206  \param In input vector map
207  \param field layer number (-1 for all layers)
208  \param topo topo access (none, native, postgis)
209  \param Out output vector map
210 
211  \return 0 on success
212  \return 1 on error
213  */
214 int copy_lines_2(struct Map_info *In, int field, int topo, struct Map_info *Out)
215 {
216  int i, type, nlines, nskipped;
217  int ret, left, rite, centroid, with_z;
218 
219  struct line_pnts *Points, *CPoints, *NPoints;
220  struct line_cats *Cats, *CCats;
221 
222  const char *ftype = NULL;
223 
224  Points = Vect_new_line_struct();
225  CPoints = Vect_new_line_struct();
226  NPoints = Vect_new_line_struct();
227  Cats = Vect_new_cats_struct();
228  CCats = Vect_new_cats_struct();
229 
230  with_z = Vect_is_3d(In);
231 
232  ret = 0;
233  nlines = Vect_get_num_lines(In);
234  if (topo == TOPO_NONE) {
235  ftype = Vect_get_finfo_geometry_type(Out);
236  G_debug(2, "feature type: %s", ftype ? ftype : "?");
237  if (!ftype)
238  G_message(_("Copying features..."));
239  else
240  G_message(_("Copying features (%s)..."), ftype);
241  }
242  else
243  G_message(_("Copying features..."));
244 
245  Vect_append_point(NPoints, 0., 0., 0.);
246  nskipped = 0;
247  for (i = 1; i <= nlines; i++) {
248  if (!Vect_line_alive(In, i))
249  continue;
250 
251  G_percent(i, nlines, 2);
252  type = Vect_read_line(In, Points, Cats, i);
253  if (type == -1) {
254  G_warning(_("Unable to read vector map <%s>"),
255  Vect_get_full_name(In));
256  ret = 1;
257  break; /* free allocated space and return */
258  }
259  if (type == 0)
260  continue; /* dead line */
261  if (In->constraint.type_flag) {
262  /* skip feature by type */
263  if (!(type & In->constraint.type))
264  continue;
265  }
266 
267  if (topo == TOPO_NONE) {
268  /* OGR/PostGIS layers (simple features) */
269  int skip = FALSE;
270 
271  if (type == GV_BOUNDARY)
272  /* boundaries are written as linestrings when output
273  * feature type is defined as 'linestring', otherwise
274  * they are skipped */
275  if (ftype && strcmp(ftype, "linestring") != 0)
276  skip = TRUE;
277 
278  /* centroids are stored in topo polygon defined by areas
279  (topo required) */
280  if (type == GV_CENTROID) {
281  /* centroids are written as points when output feature
282  * type is defined as 'point', otherwise they are
283  * skipped */
284  if (ftype && strcmp(ftype, "point") != 0)
285  skip = TRUE;
286  }
287 
288  if (skip)
289  continue;
290  }
291 
292  /* don't skips boundaries if field != -1 */
293  if (field != -1) {
294  if (type & GV_BOUNDARY) {
295  if (Vect_cat_get(Cats, field, NULL) == 0) {
296  int skip_bndry = TRUE;
297 
298  Vect_get_line_areas(In, i, &left, &rite);
299  if (left < 0)
300  left = Vect_get_isle_area(In, abs(left));
301  if (left > 0) {
302  if ((centroid = Vect_get_area_centroid(In, left)) > 0) {
303  Vect_read_line(In, CPoints, CCats, centroid);
304  if (Vect_cat_get(CCats, field, NULL) != 0)
305  skip_bndry = FALSE;
306  }
307  }
308  if (skip_bndry) {
309  if (rite < 0)
310  rite = Vect_get_isle_area(In, abs(rite));
311  if (rite > 0) {
312  if ((centroid = Vect_get_area_centroid(In, rite)) >
313  0) {
314  Vect_read_line(In, CPoints, CCats, centroid);
315  if (Vect_cat_get(CCats, field, NULL) != 0)
316  skip_bndry = FALSE;
317  }
318  }
319  }
320  if (skip_bndry)
321  continue;
322  }
323  }
324  else if (Vect_cat_get(Cats, field, NULL) == 0) {
325  nskipped++;
326  continue; /* different layer */
327  }
328  }
329 
330  /* copy also nodes connected to the line (PostGIS Topology
331  * mode only) */
332  if (topo == TOPO_POSTGIS && (type & GV_LINES)) {
333  int n1, n2;
334 
335  struct P_line *Line;
336  struct Format_info_offset *offset;
337 
338  offset = &(Out->fInfo.pg.offset);
339 
340  n1 = n2 = -1;
341  Line = In->plus.Line[i];
342  if (Line) {
343  if (type == GV_LINE) {
344  struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
345 
346  n1 = topo->N1;
347  n2 = topo->N2;
348  }
349  else if (type == GV_BOUNDARY) {
350  struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
351 
352  n1 = topo->N1;
353  n2 = topo->N2;
354  }
355  }
356 
357  if (n1 > 0 &&
358  (n1 > offset->array_num || offset->array[n1 - 1] == 0))
359  copy_line_nodes(In, n1, with_z, NPoints, Out);
360  if (n2 > 0 &&
361  (n2 > offset->array_num || offset->array[n2 - 1] == 0))
362  copy_line_nodes(In, n2, with_z, NPoints, Out);
363  }
364 
365  if (-1 == Vect_write_line(Out, type, Points, Cats)) {
366  G_warning(_("Writing new feature failed"));
367  return 1;
368  }
369  }
370 
371  if (nskipped > 0)
373  _("%d features without category or from different layer skipped"),
374  nskipped);
375 
376  Vect_destroy_line_struct(Points);
377  Vect_destroy_line_struct(CPoints);
378  Vect_destroy_line_struct(NPoints);
381 
382  return ret;
383 }
384 
385 #if 0
386 /*!
387  \brief Copy nodes as points (PostGIS Topology only)
388 
389  \param In input vector map
390  \param Out output vector map
391 
392  \return 0 on success
393  \return 1 on error
394  */
395 int copy_nodes(struct Map_info *In, struct Map_info *Out)
396 {
397  int nnodes, node, with_z;
398 
399  struct line_pnts *Points;
400 
401  Points = Vect_new_line_struct();
402 
403  with_z = Vect_is_3d(In);
404 
405  nnodes = Vect_get_num_nodes(In);
406  G_message(_("Exporting nodes..."));
407  Vect_append_point(Points, 0., 0., 0.);
408  for (node = 1; node <= nnodes; node++) {
409  G_debug(3, "Exporting GRASS node %d", node);
410 
411  G_percent(node, nnodes, 5);
412  copy_line_nodes(In, node, with_z, Points, Out);
413  }
414 
415  Vect_destroy_line_struct(Points);
416 
417  return 0;
418 }
419 #endif
420 
421 int copy_line_nodes(struct Map_info *In, int node, int with_z,
422  struct line_pnts *Points, struct Map_info *Out NOPG_UNUSED)
423 {
424  double x, y, z;
425 
426  Vect_get_node_coor(In, node, &x, &y, &z);
427  Points->x[0] = x;
428  Points->y[0] = y;
429  if (with_z)
430  Points->z[0] = z;
431 
432 #ifdef HAVE_POSTGRES
433  if (-1 == V2__write_node_pg(Out, Points)) {
434  G_warning(_("Writing node %d failed"), node);
435  return 1;
436  }
437 #else
438  G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
439  return 1;
440 #endif
441 
442  return 0;
443 }
444 
445 /*!
446  \brief Check if area is part of an isle
447 
448  Check for areas that are part of isles which in turn are inside
449  another area.
450 
451  \param Map pointer to Map_info struct
452  \param area area id
453 
454  \return TRUE if area forms an isle otherwise FALSE
455  */
456 int is_isle(struct Map_info *Map, int area)
457 {
458  int i, line, left, right, isle, is_isle;
459 
460  struct ilist *List;
461 
462  List = Vect_new_list();
463  Vect_get_area_boundaries(Map, area, List);
464 
465  is_isle = FALSE;
466  /* do we need to check all boundaries ? no */
467  for (i = 0; i < List->n_values && !is_isle; i++) {
468  line = List->value[i];
469  if (1 != Vect_get_line_areas(Map, abs(line), &left, &right))
470  continue;
471 
472  isle = line > 0 ? left : right;
473 
474  if (isle < 0 && Vect_get_isle_area(Map, abs(isle)) > 0) {
475  is_isle = TRUE;
476  break;
477  }
478  }
479 
480  G_debug(3, "is_isle(): area %d skip? -> %s", area, is_isle ? "yes" : "no");
481  Vect_destroy_list(List);
482 
483  return is_isle;
484 }
485 
486 /*!
487  \brief Copy areas as polygons (OGR/PostGIS simple features access only)
488 
489  \param In input vector map
490  \param field layer number (-1 for all layers)
491  \param Out output vector map
492 
493  \return 0 on success
494  \return 1 on error
495  */
496 int Vect__copy_areas(struct Map_info *In, int field, struct Map_info *Out)
497 {
498  int i, area, nareas, cat, isle, nisles, nparts_alloc, nskipped;
499  struct line_pnts **Points;
500  struct line_cats *Cats;
501 
502  /* allocate points & cats */
503  Points = (struct line_pnts **)G_malloc(sizeof(struct line_pnts *));
504  Points[0] = Vect_new_line_struct();
505  nparts_alloc = 1;
506  Cats = Vect_new_cats_struct();
507 
508  /* copy areas */
509  nskipped = 0;
510  nareas = Vect_get_num_areas(In);
511  if (nareas > 0)
512  G_message(_("Exporting areas..."));
513  for (area = 1; area <= nareas; area++) {
514  G_debug(2, "area = %d", area);
515  G_percent(area, nareas, 3);
516 
517  /* get category */
518  Vect_reset_cats(Cats);
519  if (field > 0) {
520  cat = Vect_get_area_cat(In, area, field);
521  /* skip area without category in given layer
522  if (cat == -1) {
523  nskipped++;
524  continue;
525  }
526  */
527 
528  if (cat > 0)
529  Vect_cat_set(Cats, field, cat);
530  }
531 
532  /* skip isles */
533  if (Vect_get_area_centroid(In, area) == 0) {
534  /* no centroid - check if area forms an isle */
535  /* this check does not make sense because the area is also
536  * not exported if it is part of an isle inside another
537  * area: the isle gets exported as an inner ring
538  if (!is_isle(In, area))
539  G_warning(_("No centroid defined for area %d. "
540  "Area not exported."),
541  area);
542  */
543  G_debug(3, "Area %d: is_isle() -> %d", area, is_isle(In, area));
544  continue;
545  }
546 
547  /* get outer ring (area) */
548  Vect_get_area_points(In, area, Points[0]);
549 
550  /* get inner rings (isles) */
551  nisles = Vect_get_area_num_isles(In, area);
552  if (nisles + 1 > nparts_alloc) {
553  /* reallocate space for isles */
554  Points = (struct line_pnts **)G_realloc(
555  Points, (nisles + 1) * sizeof(struct line_pnts *));
556  for (i = nparts_alloc; i < nisles + 1; i++)
557  Points[i] = Vect_new_line_struct();
558  nparts_alloc = nisles + 1;
559  }
560  G_debug(3, "\tcat=%d, nisles=%d", cat, nisles);
561  for (i = 0; i < nisles; i++) {
562  isle = Vect_get_area_isle(In, area, i);
563  Vect_get_isle_points(In, isle, Points[i + 1]);
564  }
565 
566  if (In != Out) {
567  if (0 > V2__write_area_sfa(Out, (const struct line_pnts **)Points,
568  nisles + 1, Cats)) {
569  G_warning(_("Writing area %d failed"), area);
570  return -1;
571  }
572  }
573 #ifdef HAVE_POSTGRES
574  else { /* building simple features geometry from topogeometry data */
575  if (0 > V2__update_area_pg(Out, (const struct line_pnts **)Points,
576  nisles + 1, cat)) {
577  G_warning(_("Writing area %d failed"), area);
578  return -1;
579  }
580  }
581 #endif
582  }
583 
584  if (nskipped > 0)
586  _("%d areas without category or from different layer skipped"),
587  nskipped);
588 
589  /* free allocated space for isles */
590  for (i = 0; i < nparts_alloc; i++)
591  Vect_destroy_line_struct(Points[i]);
593 
594  return 0;
595 }
596 
597 /*!
598  \brief Copy attribute tables linked to vector map.
599 
600  Copy all attribute tables linked to the vector map if
601  <em>field</em> is 0, or selected attribute table defined by given
602  field if <em>field</em> > 0.
603 
604  Notice, that if input vector map has no tables defined, it will
605  copy nothing and return 0 (success).
606 
607  \param In input vector map
608  \param[out] Out output vector map
609  \param field layer number (0 for all tables linked to the vector map)
610 
611  \return 0 on success
612  \return -1 on error
613  */
614 int Vect_copy_tables(struct Map_info *In, struct Map_info *Out, int field)
615 {
616  int i, n, type;
617  struct field_info *Fi;
618 
619  n = Vect_get_num_dblinks(In);
620 
621  G_debug(2, "Vect_copy_tables(): copying %d tables", n);
622 
623  type = GV_1TABLE;
624  if (field < 1 && n > 1)
625  type = GV_MTABLE;
626 
627  for (i = 0; i < n; i++) {
628  Fi = Vect_get_dblink(In, i);
629  if (Fi == NULL) {
630  G_warning(_("Database connection not defined for layer %d"),
631  In->dblnk->field[i].number);
632  return -1;
633  }
634  if (field > 0 && Fi->number != field)
635  continue;
636 
637  if (Vect_copy_table(In, Out, Fi->number, Fi->number, Fi->name, type) !=
638  0) {
639 
640  G_warning(
641  _("Unable to copy table <%s> for layer %d from <%s> to <%s>"),
642  Fi->table, Fi->number, Vect_get_full_name(In),
643  Vect_get_name(Out));
644  return -1;
645  }
646  }
647 
648  return 0;
649 }
650 
651 /*!
652  \brief Copy attribute table linked to vector map based on type.
653 
654  \param In input vector map
655  \param[out] Out output vector map
656  \param field_in input layer number
657  \param field_out output layer number
658  \param field_name layer name (can be NULL)
659  \param type how many tables are linked to map: GV_1TABLE / GV_MTABLE
660 
661  \return 0 on success
662  \return -1 on error
663  */
664 int Vect_copy_table(struct Map_info *In, struct Map_info *Out, int field_in,
665  int field_out, const char *field_name, int type)
666 {
667  return Vect_copy_table_by_cats(In, Out, field_in, field_out, field_name,
668  type, NULL, 0);
669 }
670 
671 /*!
672  \brief Copy attribute table linked to vector map based on category
673  list.
674 
675  If <em>cat_list</em> is NULL, then Vect_copy_table() is called.
676 
677  \param In input vector map
678  \param[out] Out output vector map
679  \param field_in input layer number
680  \param field_out output layer number
681  \param field_name layer name (can be NULL)
682  \param type how many tables are linked to map: GV_1TABLE / GV_MTABLE
683  \param cat_list pointer to cat_list struct (can be NULL)
684 
685  \return 0 on success
686  \return -1 on error
687  */
688 int Vect_copy_table_by_cat_list(struct Map_info *In, struct Map_info *Out,
689  int field_in, int field_out,
690  const char *field_name, int type,
691  const struct cat_list *cat_list)
692 {
693  int *cats;
694  int ncats, ret;
695 
696  if (cat_list) {
697  if (Vect_cat_list_to_array(cat_list, &cats, &ncats) != 0)
698  return -1;
699 
700  ret = Vect_copy_table_by_cats(In, Out, field_in, field_out, field_name,
701  type, cats, ncats);
702 
703  G_free(cats);
704  }
705  else {
706  ret = Vect_copy_table(In, Out, field_in, field_out, field_name, type);
707  }
708 
709  return ret;
710 }
711 
712 /*!
713  \brief Copy attribute table linked to vector map based on category
714  numbers.
715 
716  \param In input vector map
717  \param[out] Out output vector map
718  \param field_in input layer number
719  \param field_out output layer number
720  \param field_name layer name (can be NULL)
721  \param type how many tables are linked to map: GV_1TABLE / GV_MTABLE
722  \param cats pointer to array of cats or NULL
723  \param ncats number of cats in 'cats'
724 
725  \return 0 on success
726  \return -1 on error
727  */
728 int Vect_copy_table_by_cats(struct Map_info *In, struct Map_info *Out,
729  int field_in, int field_out, const char *field_name,
730  int type, int *cats, int ncats)
731 {
732  int ret;
733  struct field_info *Fi, *Fin;
734  const char *name, *key;
735  dbDriver *driver;
736 
737  G_debug(2, "Vect_copy_table_by_cats(): field_in = %d field_out = %d",
738  field_in, field_out);
739 
740  Fi = Vect_get_field(In, field_in);
741  if (Fi == NULL) {
742  G_warning(_("Database connection not defined for layer %d"), field_in);
743  return -1;
744  }
745 
746  if (field_name != NULL)
747  name = field_name;
748  else
749  name = Fi->name;
750 
751  Fin = Vect_default_field_info(Out, field_out, name, type);
752  G_debug(3, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'", Fi->driver,
753  Fi->database, Fi->table, Fin->driver, Fin->database, Fin->table);
754 
755  ret = Vect_map_add_dblink(Out, Fin->number, Fin->name, Fin->table, Fi->key,
756  Fin->database, Fin->driver);
757  if (ret == -1) {
758  G_warning(_("Unable to add database link for vector map <%s>"),
759  Out->name);
760  return -1;
761  }
762 
763  if (cats)
764  key = Fi->key;
765  else
766  key = NULL;
767 
768  ret = db_copy_table_by_ints(Fi->driver, Fi->database, Fi->table,
769  Fin->driver, Vect_subst_var(Fin->database, Out),
770  Fin->table, key, cats, ncats);
771  if (ret == DB_FAILED) {
772  G_warning(_("Unable to copy table <%s>"), Fin->table);
773  return -1;
774  }
775 
777  Vect_subst_var(Fin->database, Out));
778 
779  if (!driver) {
780  G_warning(_("Unable to open database <%s> with driver <%s>"),
781  Fin->database, Fin->driver);
782  return -1;
783  }
784 
785  /* do not allow duplicate keys */
786  if (db_create_index2(driver, Fin->table, Fi->key) != DB_OK) {
787  G_warning(_("Unable to create index"));
788  return -1;
789  }
790 
792  DB_GROUP | DB_PUBLIC) != DB_OK) {
793  G_warning(_("Unable to grant privileges on table <%s>"), Fin->table);
794  return -1;
795  }
796 
798 
799  return 0;
800 }
#define NULL
Definition: ccmath.h:32
#define DB_FAILED
Definition: dbmi.h:72
#define DB_PUBLIC
Definition: dbmi.h:135
#define DB_GROUP
Definition: dbmi.h:134
#define DB_PRIV_SELECT
Definition: dbmi.h:132
#define DB_OK
Definition: dbmi.h:71
int db_copy_table_by_ints(const char *, const char *, const char *, const char *, const char *, const char *, const char *, int *, int)
Copy a table (by keys)
Definition: copy_tab.c:513
dbDriver * db_start_driver_open_database(const char *, const char *)
Open driver/database connection.
Definition: db.c:28
int db_close_database_shutdown_driver(dbDriver *)
Close driver/database connection.
Definition: db.c:61
int db_create_index2(dbDriver *, const char *, const char *)
Create unique index.
Definition: c_create_idx.c:61
int db_grant_on_table(dbDriver *, const char *, int, int)
Grant privileges on table.
Definition: c_priv.c:29
void G_percent(long, long, int)
Print percent complete messages.
Definition: percent.c:61
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
#define G_realloc(p, n)
Definition: defs/gis.h:96
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
#define G_malloc(n)
Definition: defs/gis.h:94
void void void G_important_message(const char *,...) __attribute__((format(printf
void G_message(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_get_node_coor(struct Map_info *, int, double *, double *, double *)
Get node coordinates.
Definition: level_two.c:274
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
plus_t Vect_get_num_areas(struct Map_info *)
Get number of areas in vector map.
Definition: level_two.c:87
int Vect_reset_cats(struct line_cats *)
Reset category structure to make sure cats structure is clean to be re-used.
struct field_info * Vect_default_field_info(struct Map_info *, int, const char *, int)
Get default information about link to database for new dblink.
Definition: field.c:358
int Vect_cat_set(struct line_cats *, int, int)
Add new field/cat to category structure if doesn't exist yet.
int Vect_get_area_boundaries(struct Map_info *, int, struct ilist *)
Creates list of boundaries for given area.
const char * Vect_get_full_name(struct Map_info *)
Get fully qualified name of vector map.
int Vect_cat_get(const struct line_cats *, int, int *)
Get first found category of given field.
int Vect_get_isle_points(struct Map_info *, int, struct line_pnts *)
Returns polygon array of points for given isle.
int Vect_get_area_points(struct Map_info *, int, struct line_pnts *)
Returns polygon array of points (outer ring) of given area.
void Vect_destroy_list(struct ilist *)
Frees all memory associated with a struct ilist, including the struct itself.
int Vect_level(struct Map_info *)
Returns level that Map is opened at.
Definition: level.c:29
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_get_area_isle(struct Map_info *, int, int)
Returns isle id for area.
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.
int Vect_get_area_num_isles(struct Map_info *, int)
Returns number of isles for given area.
char * Vect_subst_var(const char *, struct Map_info *)
Substitute variable in string.
Definition: field.c:912
int Vect_cat_list_to_array(const struct cat_list *, int **, int *)
Convert cat_list struct to ordered array of unique integers.
int Vect_line_alive(struct Map_info *, int)
Check if feature is alive or dead (topological level required)
int Vect_get_num_dblinks(struct Map_info *)
Get number of defined dblinks.
Definition: level_two.c:159
int Vect_get_area_cat(struct Map_info *, int, int)
Find FIRST category of given field and area.
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
struct field_info * Vect_get_field(struct Map_info *, int)
Get information about link to database (by layer number)
Definition: field.c:515
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition: line.c:45
const char * Vect_get_finfo_geometry_type(struct Map_info *)
Get geometry type as string (relevant only for non-native formats)
Definition: header_finfo.c:143
struct field_info * Vect_get_dblink(struct Map_info *, int)
Get information about link to database.
Definition: field.c:475
plus_t Vect_get_num_nodes(struct Map_info *)
Get number of nodes in vector map.
Definition: level_two.c:34
int Vect_get_area_centroid(struct Map_info *, int)
Returns centroid id for given area.
int Vect_map_add_dblink(struct Map_info *, int, const char *, const char *, const char *, const char *, const char *)
Add new db connection to Map_info structure.
Definition: field.c:120
char * Vect_get_finfo_layer_name(struct Map_info *)
Get layer name (relevant only for non-native formats)
Definition: header_finfo.c:73
int Vect_rewind(struct Map_info *)
Rewind vector map to cause reads to start at beginning.
const char * Vect_get_name(struct Map_info *)
Get name of vector map.
int Vect_read_next_line(struct Map_info *, struct line_pnts *, struct line_cats *)
Read next vector feature.
int Vect_set_constraint_type(struct Map_info *, int)
Set constraint type.
Definition: constraint.c:106
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
int Vect_get_line_areas(struct Map_info *, int, int *, int *)
Get area id on the left and right side of the boundary.
Definition: level_two.c:346
int Vect_is_3d(struct Map_info *)
Check if vector map is 3D.
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
Definition: line.c:148
int Vect_get_isle_area(struct Map_info *, int)
Returns area id for isle.
#define GV_CENTROID
Definition: dig_defines.h:186
#define GV_FORMAT_POSTGIS
PostGIS format.
Definition: dig_defines.h:89
#define GV_LINE
Definition: dig_defines.h:184
#define GV_LINES
Definition: dig_defines.h:193
#define GV_BOUNDARY
Definition: dig_defines.h:185
#define GV_1TABLE
One table linked to vector map.
Definition: dig_defines.h:99
#define GV_MTABLE
More tables linked to vector map.
Definition: dig_defines.h:101
#define GV_POINTS
Definition: dig_defines.h:192
#define GV_FORMAT_NATIVE
Geometry data formats supported by lib Don't change GV_FORMAT_* values, this order is hardcoded in li...
Definition: dig_defines.h:83
const struct driver * driver
Definition: driver/init.c:25
#define TRUE
Definition: gis.h:79
#define FALSE
Definition: gis.h:83
#define _(str)
Definition: glocale.h:10
const char * name
Definition: named_colr.c:6
Data structure used for building pseudo-topology.
Definition: dig_structs.h:388
int * array
Offset list.
Definition: dig_structs.h:436
int array_num
Number of items in offset list.
Definition: dig_structs.h:440
char * toposchema_name
Topology schema name and id.
Definition: dig_structs.h:686
struct Format_info_offset offset
Offset list used for building pseudo-topology (simple features access)
Definition: dig_structs.h:676
struct Format_info_pg pg
PostGIS info.
Definition: dig_structs.h:712
Vector map info.
Definition: dig_structs.h:1243
char * name
Map name (for 4.0)
Definition: dig_structs.h:1316
int type
Feature type constraint.
Definition: dig_structs.h:1359
int type_flag
Non-zero value to enable feature type constraint.
Definition: dig_structs.h:1355
int format
Map format (native, ogr, postgis)
Definition: dig_structs.h:1255
struct Map_info::@11 constraint
Constraints for sequential feature access.
struct dblinks * dblnk
Array of DB links.
Definition: dig_structs.h:1265
struct Format_info fInfo
Format info for non-native formats.
Definition: dig_structs.h:1400
struct Plus_head plus
Plus info (topology, version, ...)
Definition: dig_structs.h:1270
Vector geometry.
Definition: dig_structs.h:1553
void * topo
Topology info.
Definition: dig_structs.h:1577
Boundary topology.
Definition: dig_structs.h:1492
plus_t N1
Start node.
Definition: dig_structs.h:1496
plus_t N2
End node.
Definition: dig_structs.h:1500
Line topology.
Definition: dig_structs.h:1478
plus_t N1
Start node.
Definition: dig_structs.h:1482
plus_t N2
End node.
Definition: dig_structs.h:1486
struct P_line ** Line
Array of vector geometries.
Definition: dig_structs.h:871
Category list.
Definition: dig_structs.h:1697
Definition: driver.h:21
Layer (old: field) information.
Definition: dig_structs.h:131
char * table
Name of DB table.
Definition: dig_structs.h:151
char * driver
Name of DB driver ('sqlite', 'dbf', ...)
Definition: dig_structs.h:143
char * name
Layer name (optional)
Definition: dig_structs.h:139
char * database
Definition: dig_structs.h:147
char * key
Name of key column (usually 'cat')
Definition: dig_structs.h:155
int number
Layer number.
Definition: dig_structs.h:135
List of integers.
Definition: gis.h:706
int n_values
Number of values in the list.
Definition: gis.h:714
int * value
Array of values.
Definition: gis.h:710
Feature category info.
Definition: dig_structs.h:1677
int * field
Array of layers (fields)
Definition: dig_structs.h:1681
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
#define TOPO_POSTGIS
#define NOPG_UNUSED
int Vect_copy_table(struct Map_info *In, struct Map_info *Out, int field_in, int field_out, const char *field_name, int type)
Copy attribute table linked to vector map based on type.
int Vect_copy_tables(struct Map_info *In, struct Map_info *Out, int field)
Copy attribute tables linked to vector map.
#define TOPO_NONE
Copy topological elements.
int Vect_copy_table_by_cat_list(struct Map_info *In, struct Map_info *Out, int field_in, int field_out, const char *field_name, int type, const struct cat_list *cat_list)
Copy attribute table linked to vector map based on category list.
int copy_line_nodes(struct Map_info *In, int node, int with_z, struct line_pnts *Points, struct Map_info *Out NOPG_UNUSED)
int Vect_copy_map_lines(struct Map_info *In, struct Map_info *Out)
Copy all alive vector features from input vector map to output vector map.
int Vect_copy_table_by_cats(struct Map_info *In, struct Map_info *Out, int field_in, int field_out, const char *field_name, int type, int *cats, int ncats)
Copy attribute table linked to vector map based on category numbers.
int Vect__copy_areas(struct Map_info *In, int field, struct Map_info *Out)
Copy areas as polygons (OGR/PostGIS simple features access only)
int Vect_copy_map_lines_field(struct Map_info *In, int field, struct Map_info *Out)
Copy all alive vector features from given layer from input vector map to output vector map.
#define TOPO_NATIVE
int V2__update_area_pg(struct Map_info *Map, const struct line_pnts **points, int nparts, int cat)
Updates simple features geometry from GRASS-like topo.
Definition: write_pg.c:557
off_t V2__write_node_pg(struct Map_info *Map, const struct line_pnts *points)
Writes node on topological level (PostGIS Topology interface, internal use only)
Definition: write_pg.c:516
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:293
#define x