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