GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
vector/Vlib/open.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/Vlib/open.c
3
4 \brief Vector library - Open existing or create new vector map
5 (native or OGR/PostGIS format)
6
7 Higher level functions for reading/writing/manipulating vectors.
8
9 (C) 2001-2015 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 Martin Landa <landa.martin gmail.com> (better OGR
17 support and native PostGIS access)
18 */
19
20#include <stdlib.h>
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26
27#include <grass/vector.h>
28#include <grass/glocale.h>
29
30#include "local_proto.h"
31
32#ifdef HAVE_POSTGRES
33#include "pg_local_proto.h"
34#endif
35
36/**
37 * @brief Number of levels
38 *
39 * - 1 without topology
40 * - 2 with 2D topology
41 *
42 * @todo Implement
43 * - 3 with 3D topology
44 */
45#define MAX_OPEN_LEVEL 2
46
47static int open_old_dummy(struct Map_info *Map UNUSED, int update UNUSED)
48{
49 return 0;
50}
51
52static int open_new_dummy(struct Map_info *Map UNUSED, const char *name UNUSED,
53 int with_z UNUSED)
54{
55 return 0;
56}
57
58#if !defined HAVE_POSTGRES
59static int format_old(struct Map_info *Map UNUSED, int update UNUSED)
60{
61 G_fatal_error(_("Requested format is not compiled in this version"));
62 return 0;
63}
64
65static int format_new(struct Map_info *Map UNUSED, const char *name UNUSED,
66 int with_z UNUSED)
67{
68 G_fatal_error(_("Requested format is not compiled in this version"));
69 return 0;
70}
71#endif
72
73static int Open_level = 0;
74
75static int (*Open_old_array[][2])(struct Map_info *,
76 int) = {{open_old_dummy, V1_open_old_nat},
77 {open_old_dummy, V1_open_old_ogr},
78 {open_old_dummy, V1_open_old_ogr}
79#ifdef HAVE_POSTGRES
80 ,
81 {open_old_dummy, V1_open_old_pg}
82#else
83 ,
84 {open_old_dummy, format_old}
85#endif
86};
87
88static int (*Open_new_array[][2])(struct Map_info *Map, const char *name,
89 int with_z) = {
90 {open_new_dummy, V1_open_new_nat},
91 {open_new_dummy, V1_open_new_ogr},
92 {open_new_dummy, V1_open_new_ogr}
93#ifdef HAVE_POSTGRES
94 ,
95 {open_new_dummy, V1_open_new_pg}
96#else
97 ,
98 {open_new_dummy, format_new}
99#endif
100};
101
102static int open_new(struct Map_info *, const char *, int, int);
103static int map_format(struct Map_info *);
104
105/*!
106 \brief Predetermine level at which a vector map will be opened for
107 reading.
108
109 If it can't open that level, the open will fail. The specified level
110 must be set before any call to open. The default is to try to open
111 the highest level possible, and keep stepping down until success.
112
113 NOTE: This should only be used to set when you wish to force a lower
114 level open. If you require a higher level, then just check the
115 return to verify the level instead of forcing it. This is because
116 future releases will have higher levels which will be downward
117 compatible and which your programs should support by default.
118
119 \param level vector access level
120
121 \return 0 on success
122 \return 1 on error (invalid access level)
123 */
125{
126 Open_level = level;
128 G_warning(_("Programmer requested unknown access level %d"),
129 Open_level);
130 Open_level = 0;
131 return 1;
132 }
133
134 return 0;
135}
136
137/*!
138 \brief Open existing vector map for reading (internal use only)
139
140 \param[out] Map pointer to Map_info structure
141 \param name name of vector map to open
142 \param mapset mapset name ("" for search path)
143 \param layer layer name (OGR format only)
144 \param update non-zero to open for update otherwise read-only mode
145 \param head_only read only header info from 'head', 'dbln', 'topo',
146 'cidx' is not opened. The header may be opened on level 2 only.
147 \param is_tmp non-zero code for temporary maps
148
149 \return level of openness (1, 2)
150 \return -1 in error
151 */
152int Vect__open_old(struct Map_info *Map, const char *name, const char *mapset,
153 const char *layer, int update, int head_only, int is_tmp)
154{
156 char path[GPATH_MAX];
157 FILE *fp;
158 int level, level_request;
159 int format, ret;
160 int ogr_mapset;
161 const char *fmapset;
162
163 G_debug(
164 1,
165 "Vect__open_old(): name = %s, mapset = %s, layer = %s, update = %d, "
166 "head_only = %d, is_tmp = %d",
167 name, mapset, layer ? layer : "NULL", update, head_only, is_tmp);
168
169 if (update && !is_tmp) {
170 is_tmp = getenv("GRASS_VECTOR_TEMPORARY") ? TEMPORARY_MAP_ENV
172 G_debug(1,
173 "Vect__open_old(): is_tmp = %d (check GRASS_VECTOR_TEMPORARY)",
174 is_tmp);
175 }
176
177 /* zero Map_info structure */
178 G_zero(Map, sizeof(struct Map_info));
179
180 /* TODO: Open header for update ('dbln') */
181
182 level_request = Open_level;
183 Open_level = 0;
184
185 /* initialize Map->head */
187 /* initialize support structures for 2D, update to 3D when reading
188 support files */
189 Map->plus.spidx_with_z = Map->plus.with_z = Map->head.with_z = WITHOUT_Z;
190 /* initialize Map->plus */
191 dig_init_plus(&(Map->plus));
192
193 /* check OGR mapset */
196 if (strcasecmp(xmapset, "ogr") == 0) {
197 /* unique OGR mapset detected */
198 G_debug(1, "OGR mapset detected");
200 Map->fInfo.ogr.dsn = G_store(xname);
201 if (layer) {
202 Map->fInfo.ogr.layer_name =
203 G_store(layer); /* no layer to be open */
204 }
205 }
206 Map->name = G_store(xname);
207 Map->mapset = G_store(xmapset);
208 }
209 else {
210 Map->name = G_store(name);
211
212 Map->temporary = is_tmp;
213 /* temporary maps can be accessed only in the current mapset */
214 if (mapset)
215 Map->mapset = G_store(mapset);
216 else
217 Map->mapset = G_store("");
218 }
219
221
222 if (!ogr_mapset) {
223 /* try to find vector map (not for OGR mapset) */
224 if (!Map->temporary) {
225 fmapset = G_find_vector2(Map->name, Map->mapset);
226 if (fmapset == NULL) {
227 if (mapset && strcmp(mapset, G_mapset()) == 0)
229 _("Vector map <%s> not found in current mapset"),
231 else
232 G_fatal_error(_("Vector map <%s> not found"),
234 return -1;
235 }
236 Map->mapset = G_store(fmapset);
237 }
238 else {
239 char file_path[GPATH_MAX];
240
241 /* reduce to current mapset if search path was set */
242 if (strcmp(Map->mapset, "") == 0)
243 Map->mapset = G_store(G_mapset());
244 /* temporary map: reduce to current mapset if search path
245 * was set */
246 if (strcmp(Map->mapset, "") == 0)
247 Map->mapset = G_store(G_mapset());
248 else {
249 if (strcmp(Map->mapset, G_mapset()) != 0) {
250 G_warning(_("Temporary vector maps can be accessed only in "
251 "the current mapset"));
252 return -1;
253 }
254 }
255
257 if (access(file_path, F_OK) != 0) {
258 /* unable to find header file for temporary map, try
259 * to switch to normal mode, useful when updating
260 * existing map */
261 Map->temporary = FALSE;
262 Vect__get_path(path, Map); /* path must be updated for
263 * subsequent operations */
265 if (access(file_path, F_OK) != 0)
266 return -1;
267 }
268 }
269 }
270
271 Map->location = G_store(G_location());
272 Map->gisdbase = G_store(G_gisdbase());
273
274 if (update && !ogr_mapset && (0 != strcmp(Map->mapset, G_mapset()))) {
275 G_warning(_("Vector map which is not in the current mapset cannot be "
276 "opened for update"));
277 return -1;
278 }
279
280 G_debug(1, "Map: name = %s, mapset = %s, temporary = %d", Map->name,
281 Map->mapset, Map->temporary);
282
283 /* read vector format information */
284 if (ogr_mapset) {
286 }
287 else {
288 format = 0;
289 fp = G_fopen_old(path, GV_FRMT_ELEMENT, Map->mapset);
290 if (fp == NULL) {
291 G_debug(1, "Vector format: %d (native)", format);
293 }
294 else {
295 format = dig_read_frmt_ascii(fp, &(Map->fInfo));
296 fclose(fp);
297
298 G_debug(1, "Vector format: %d (non-native)", format);
299 if (format < 0) {
300 G_fatal_error(_("Unable to open vector map <%s>"),
302 return -1;
303 }
304 }
305 }
306 Map->format = format;
307
308 /* read vector head (ignored for OGR mapset) */
309 if (!ogr_mapset && Vect__read_head(Map) != 0) {
310 G_fatal_error(_("Unable to read header file of vector map <%s>"),
312 }
313
314 /* projection is not written to head but zone ??? */
315 if (Vect_get_zone(Map) == -1)
318
319 G_debug(1, "Level request = %d", level_request);
320
321 /* There are only 2 possible open levels, 1 and 2. Try first to
322 open 'support' files (topo, sidx, cidx), these files are the same
323 for all formats. If it is not possible and requested level is
324 2, return error, otherwise call Open_old_array[format][1], to
325 open remaining files/sources (level 1)
326 */
327
328 /* try to open support files if level was not requested or
329 * requested level is 2 (format independent) */
330 if (level_request == 0 || level_request > 1) {
331 level = 2; /* we expect success */
332
333 /* open topo */
334 ret = -1;
335#ifdef HAVE_POSTGRES
336 if (Map->format == GV_FORMAT_POSTGIS)
337 /* try to read full-topology for PostGIS links */
339#endif
340 if (ret != 0) {
341 /* read topology for native format
342 read pseudo-topology for OGR/PostGIS links */
344
345 if (ret == 1) { /* topo file is not available */
346 G_debug(1, "topo file for vector '%s' not available.",
348 level = 1;
349 }
350 else if (ret == -1) {
352 _("Unable to open topology file for vector map <%s>"),
354 }
355 }
356
357 /* open spatial index */
358 if (level >= 2) {
359 ret = Vect_open_sidx(Map, (update != 0));
360 if (ret == 1) { /* sidx file is not available */
361 G_debug(1, "sidx file for vector '%s' not available.",
363 if (!Map->fInfo.pg
364 .toposchema_name) /* optional for PostGIS Topology */
365 level = 1;
366 }
367 else if (ret == -1) {
369 _("Unable to open spatial index file for vector map <%s>"),
371 }
372 /* check with_z consistency */
373 if ((Map->plus.with_z != 0 && Map->plus.spidx_with_z == 0) ||
374 (Map->plus.with_z == 0 && Map->plus.spidx_with_z != 0)) {
375 G_warning(
376 "Vector map <%s>: topology is %s, but spatial index is %s",
378 (Map->plus.with_z != 0 ? "3D" : "2D"),
379 (Map->plus.spidx_with_z != 0 ? "3D" : "2D"));
380 level = 1;
381 }
382 }
383
384 /* open category index */
385 if (level >= 2) {
387 if (ret == 1) { /* category index is not available */
388 G_debug(1, "cidx file for vector '%s' not available.",
390 if (!Map->fInfo.pg
391 .toposchema_name) { /* optional for PostGIS Topology */
392 dig_free_plus(&(Map->plus)); /* free topology */
393 level = 1;
394 }
395 }
396 else if (ret == -1) { /* file exists, but cannot be opened */
398 _("Unable to open category index file for vector map <%s>"),
400 }
401 }
402 /* open OGR specific support files */
403 if (level == 2 && Map->format == GV_FORMAT_OGR) {
404 if (V2_open_old_ogr(Map) < 0) {
405 dig_free_plus(&(Map->plus));
406 level = 1;
407 }
408 }
409#ifdef HAVE_POSTGRES
410 /* open OGR (pseudo-topology access only) specific support
411 * files */
412 if (level == 2 && Map->format == GV_FORMAT_POSTGIS) {
413 if (V2_open_old_pg(Map) < 0) {
414 dig_free_plus(&(Map->plus));
415 level = 1;
416 }
417 }
418#endif
419 if (level_request == 2 && level < 2) {
420 if (!ogr_mapset) {
421 /* for direct OGR read access is built pseudo-topology on the
422 * fly */
423 G_warning(_("Unable to open vector map <%s> on level %d. "
424 "Try to rebuild vector topology with v.build."),
426 return -1;
427 }
428 }
429 }
430 else {
431 level = 1; /* i.e. requested level is 1 */
432 }
433
434 /* open level 1 files / sources (format specific) */
436 /* no need to open coordinates */
437 if (0 != (*Open_old_array[format][1])(Map, update)) { /* cannot open */
438 if (level >= 2) { /* support files opened */
439 dig_free_plus(&(Map->plus));
440 }
441 G_fatal_error(_("Unable to open vector map <%s>"),
443 return -1;
444 }
445 if (ogr_mapset && !head_only && level_request != 1) {
446 /* build pseudo-topology on the fly */
447 int verbose;
448
449 verbose = G_verbose();
450 G_message(_("Building topology for OGR layer <%s> from datasource "
451 "'%s'..."),
452 Map->fInfo.ogr.layer_name, Map->fInfo.ogr.dsn);
453 G_set_verbose(0);
454 if (Vect_build(Map)) {
455 level = 2;
456 }
457 G_set_verbose(verbose);
458 if (level < level_request)
459 G_fatal_error(_("Unable to open vector map <%s> on level %d"),
460 Map->fInfo.ogr.layer_name, level_request);
461 }
462 if (level < 2 && Map->head.with_z) {
463 /* topo has been initialized as 2D, update to 3D */
464 dig_free_plus(&(Map->plus));
465 dig_init_plus(&(Map->plus));
466 Map->plus.with_z = Map->head.with_z;
467 }
468 }
469 else if (level > 1) {
470 /* take dimension from topo if topo is available */
471 Map->head.with_z = Map->plus.with_z;
472 }
473
474 /* set status */
475 Map->open = VECT_OPEN_CODE;
476 Map->level = level;
477 Map->head_only = head_only;
478 Map->support_updated = FALSE;
479 if (update) {
480 Map->mode = GV_MODE_RW;
481 Map->plus.mode = GV_MODE_RW;
482 }
483 else {
484 Map->mode = GV_MODE_READ;
485 Map->plus.mode = GV_MODE_READ;
486 }
487 if (head_only) {
488 Map->head_only = TRUE;
489 }
490 else {
491 Map->head_only = FALSE;
492 }
493
494 G_debug(1, "Vect__open_old(): vector opened on level %d", level);
495
496 if (level == 1) { /* without topology */
497 Map->plus.built = GV_BUILD_NONE;
498 }
499 else { /* level 2, with topology */
500 Map->plus.built =
501 GV_BUILD_ALL; /* highest level of topology for level 2 */
502 }
503
504 Map->plus.uplist.do_uplist = FALSE;
505
506 /* read db links */
507 Map->dblnk = Vect_new_dblinks_struct();
509
510 /* open history file */
511 if (update && !ogr_mapset) { /* native only */
513 if (Map->hist_fp == NULL) {
514 G_warning(_("Unable to open history file for vector map <%s>"),
516 return -1;
517 }
518 G_fseek(Map->hist_fp, (off_t)0, SEEK_END);
519 Vect_hist_write(Map, "-------------------------------------------------"
520 "--------------------------------\n");
521 }
522 else {
523 if (Map->format == GV_FORMAT_NATIVE || Map->format == GV_FORMAT_OGR ||
524 Map->format == GV_FORMAT_POSTGIS) {
525 Map->hist_fp = G_fopen_old(path, GV_HIST_ELEMENT, Map->mapset);
526 /* If NULL (does not exist) then Vect_hist_read() handle that */
527 }
528 else {
529 Map->hist_fp = NULL;
530 }
531 }
532
533 if (!head_only) { /* cannot rewind if not fully opened */
535 }
536
537 /* delete support files if native format was opened for update (not
538 * head_only) */
539 if (update && !head_only) {
540 char file_path[GPATH_MAX];
541
543 if (access(file_path, F_OK) == 0) /* topo file exists? */
545
547 if (access(file_path, F_OK) == 0) /* sidx file exists? */
549
551 if (access(file_path, F_OK) == 0) /* cidx file exists? */
553
556 if (access(file_path, F_OK) == 0) /* fidx file exists? */
558 }
559 Map->support_updated = TRUE;
560 }
561
562 return level;
563}
564
565/*!
566 \brief Open existing vector map for reading
567
568 This function is replaced by Vect_open_old2() to handle also direct
569 OGR support.
570
571 Calls G_fatal_error() on failure.
572
573 \param[out] Map pointer to Map_info structure
574 \param name name of vector map to open
575 \param mapset mapset name ("" for search path)
576
577 \return 1 open on level 1 (without topology)
578 \return 2 open on level 2 (with topology)
579 \return -1 on error
580 */
581int Vect_open_old(struct Map_info *Map, const char *name, const char *mapset)
582{
584}
585
586/*!
587 \brief Open existing temporary vector map for reading
588
589 Temporary vector maps are stored in the current mapset (directory
590 <tt>.tmp/<hostname>/vector</tt>).
591
592 Calls G_fatal_error() on failure.
593
594 \todo Create new vector map if doesn't exist.
595
596 \param[out] Map pointer to Map_info structure
597 \param name name of vector map to open
598 \param mapset mapset name ("" for search path)
599
600 \return 1 open on level 1 (without topology)
601 \return 2 open on level 2 (with topology)
602 \return -1 on error
603 */
604int Vect_open_tmp_old(struct Map_info *Map, const char *name,
605 const char *mapset)
606{
608}
609
610/*!
611 \brief Open existing vector map for reading
612
613 Calls G_fatal_error() on failure.
614
615 \param[out] Map pointer to Map_info structure
616 \param name name of vector map to open (datasource for direct OGR access)
617 \param mapset mapset name ("" for search path, "OGR" for direct OGR access)
618 \param layer layer name (OGR layer for direct OGR access)
619
620 \return 1 open on level 1 (without topology)
621 \return 2 open on level 2 (with topology)
622 \return -1 on error
623 */
624int Vect_open_old2(struct Map_info *Map, const char *name, const char *mapset,
625 const char *layer)
626{
627 return Vect__open_old(Map, name, mapset, layer, FALSE, FALSE, FALSE);
628}
629
630/*!
631 \brief Open existing vector map for reading/writing
632
633 This function is replaced by Vect_open_update2() to handle also
634 direct OGR support.
635
636 By default list of updated features is not maintained, see
637 Vect_set_updated() for details.
638
639 Calls G_fatal_error() on failure.
640
641 \param[out] Map pointer to Map_info structure
642 \param name name of vector map to update
643 \param mapset mapset name
644
645 \return 1 open on level 1 (without topology)
646 \return 2 open on level 2 (with topology)
647 \return -1 on error
648 */
649int Vect_open_update(struct Map_info *Map, const char *name, const char *mapset)
650{
652}
653
654/*!
655 \brief Open existing temporary vector map for reading/writing
656
657 Temporary vector maps are stored in the current mapset (directory
658 <tt>.tmp/<hostname>/vector</tt>).
659
660 By default list of updated features is not maintained, see
661 Vect_set_updated() for details.
662
663 Calls G_fatal_error() on failure.
664
665 \todo Create new vector map if doesn't exist.
666
667 \param[out] Map pointer to Map_info structure
668 \param name name of vector map to update
669 \param mapset mapset name
670
671 \return 1 open on level 1 (without topology)
672 \return 2 open on level 2 (with topology)
673 \return -1 on error
674 */
675int Vect_open_tmp_update(struct Map_info *Map, const char *name,
676 const char *mapset)
677{
679}
680
681/*!
682 \brief Open existing vector map for reading/writing
683
684 By default list of updated features is not maintained, see
685 Vect_set_updated() for details.
686
687 Calls G_fatal_error() on failure.
688
689 \param[out] Map pointer to Map_info structure
690 \param name name of vector map to open (datasource for direct OGR access)
691 \param mapset mapset name ("" for search path, "OGR" for direct OGR access)
692 \param layer layer name (OGR layer for direct OGR access)
693
694 \return 1 open on level 1 (without topology)
695 \return 2 open on level 2 (with topology)
696 \return -1 on error
697 */
698int Vect_open_update2(struct Map_info *Map, const char *name,
699 const char *mapset, const char *layer)
700{
701 return Vect__open_old(Map, name, mapset, layer, TRUE, FALSE, FALSE);
702}
703
704/*!
705 \brief Reads only info about vector map (headers)
706
707 Reads from headers of 'head', 'dbln', 'topo' and 'cidx' file.
708
709 This function is replaced by Vect_open_old_head2() to handle also
710 direct OGR support.
711
712 Calls G_fatal_error() on failure.
713
714 \param[out] Map pointer to Map_info structure
715 \param name name of vector map to read
716 \param mapset mapset name ("" for search path)
717
718 \return 1 open on level 1 (without topology)
719 \return 2 open on level 2 (with topology)
720 \return -1 on error
721 */
722int Vect_open_old_head(struct Map_info *Map, const char *name,
723 const char *mapset)
724{
726}
727
728/*!
729 \brief Reads only info about vector map (headers)
730
731 Reads from headers of 'head', 'dbln', 'topo' and 'cidx' file.
732
733 Calls G_fatal_error() on failure.
734
735 \param[out] Map pointer to Map_info structure
736 \param name name of vector map to read (dsn for OGR)
737 \param mapset mapset name ("" for search path)
738 \param layer layer name (OGR format)
739
740 \param name name of vector map to open (datasource for direct OGR access)
741 \param mapset mapset name ("" for search path, "OGR" for direct OGR access)
742 \param layer layer name (OGR layer for direct OGR access)
743
744 \return 1 open on level 1 (without topology)
745 \return 2 open on level 2 (with topology)
746 \return -1 on error
747 */
748int Vect_open_old_head2(struct Map_info *Map, const char *name,
749 const char *mapset, const char *layer)
750{
751 return Vect__open_old(Map, name, mapset, layer, FALSE, TRUE, FALSE);
752}
753
754/*! \brief Open header file of existing vector map for updating
755 (mostly for database link updates)
756
757 \param[out] Map pointer to Map_info structure
758 \param name name of vector map to update
759 \param mapset mapset name
760
761 \return 1 open on level 1 (without topology)
762 \return 2 open on level 2 (with topology)
763 \return -1 on error
764 */
765int Vect_open_update_head(struct Map_info *Map, const char *name,
766 const char *mapset)
767{
769}
770
771int open_new(struct Map_info *Map, const char *name, int with_z, int is_tmp)
772{
773 int ret;
775
776 G_debug(1, "Vect_open_new(): name = %s with_z = %d is_tmp = %d", name,
777 with_z, is_tmp);
778
779 /* zero Map_info structure */
780 G_zero(Map, sizeof(struct Map_info));
781
782 /* init header info */
784
785 /* check for fully-qualified map name */
787 if (strcmp(xmapset, G_mapset()) != 0) {
788 G_warning(_("Unable to create vector map: <%s> is not in the "
789 "current mapset (%s)"),
790 name, G_mapset());
791 return -1;
792 }
793 name = xname;
794 }
795
796 /* check for [A-Za-z][A-Za-z0-9_]* in name */
797 if (Vect_legal_filename(name) < 0) {
799 _("Unable to create vector map: <%s> is not SQL compliant"), name);
800 return -1;
801 }
802
803 /* store basic info */
804 Map->name = G_store(name);
805 Map->mapset = G_store(G_mapset());
806 Map->location = G_store(G_location());
807 Map->gisdbase = G_store(G_gisdbase());
808 Map->temporary = is_tmp;
809
810 /* determine output format */
811 Map->format = map_format(Map);
812
813 if (Map->format != GV_FORMAT_OGR_DIRECT &&
814 getenv("GRASS_VECTOR_PGFILE") ==
815 NULL) { /* GRASS_VECTOR_PGFILE defined by v.out.postgis */
816 char *env;
817 char path[GPATH_MAX];
818
819 G_debug(2, " using non-direct format");
820
821 /* check if map already exists
822 temporary maps are automatically overwritten
823 */
824 if (Map->temporary) {
825 if (-1 == Vect__delete(name, Map->temporary)) {
826 G_warning(_("Unable to delete vector map <%s>"), name);
827 return -1;
828 }
829 }
830
831 env = getenv("GRASS_VECTOR_TEMPORARY");
832 if (!Map->temporary || (env && strcmp(env, "move") == 0)) {
833 if (G_find_vector2(name, G_mapset()) != NULL) {
834 G_warning(
835 _("Vector map <%s> already exists and will be overwritten"),
836 name);
837
839 if (ret == -1) {
840 G_warning(_("Unable to delete vector map <%s>"), name);
841 return -1;
842 }
843 }
844 }
845
846 /* write header file
847
848 note: header & history file is also written for external
849 formats since vector library create links automatically
850 when closing the map
851 */
852 Map->head.size = 0;
853 Map->head.head_size = GV_COOR_HEAD_SIZE + 4;
855
856 /* create history file */
858 Map->hist_fp = G_fopen_new(path, GV_HIST_ELEMENT);
859 if (Map->hist_fp == NULL) {
860 G_warning(_("Unable to open history file of vector map <%s>"),
861 name);
862 return -1;
863 }
864 }
865
866 /* set 2D/3D */
867 Map->plus.spidx_with_z = Map->plus.with_z = Map->head.with_z =
868 (with_z != 0);
869
870 Map->level = LEVEL_1;
871
872 if ((*Open_new_array[Map->format][1])(Map, name, with_z) < 0) {
873 if (getenv("GRASS_VECTOR_PGFILE") ==
874 NULL) /* GRASS_VECTOR_PGFILE defined by v.out.postgis */
875 Vect_delete(name); /* clean up */
876 return -1;
877 }
878
879 Open_level = 0;
880
881 /* initialize topo */
882 Map->plus.Spidx_file = 0;
883 dig_init_plus(&(Map->plus));
884
885 /* open new spatial index */
886 if (Vect_open_sidx(Map, 2) < 0)
888 _("Unable to open spatial index file for vector map <%s>"),
890
891 Map->open = VECT_OPEN_CODE;
892 Map->head_only = FALSE;
893 Map->support_updated = FALSE;
894 Map->plus.built = GV_BUILD_NONE;
895 Map->mode = GV_MODE_RW;
896 Map->plus.uplist.do_uplist = FALSE;
897
900
901 Map->dblnk = Vect_new_dblinks_struct();
902
903 if (Map->fInfo.ogr.driver_name) {
904 G_verbose_message(_("Using OGR/%s format"), Map->fInfo.ogr.driver_name);
905 }
906 else if (Map->fInfo.pg.conninfo) {
907 if (Map->fInfo.pg.toposchema_name)
908 G_verbose_message(_("Using PostGIS Topology format"));
909 else
910 G_verbose_message(_("Using PostGIS format"));
911 }
912 else {
913 G_verbose_message(_("Using native format"));
914 }
915
916 return 1;
917}
918
919/*!
920 \brief Create new vector map for reading/writing
921
922 By default list of updated features is not maintained, see
923 Vect_set_updated() for details.
924
925 By default map format is native (GV_FORMAT_NATIVE). If OGR file is
926 found in the current mapset then the map (ie. OGR layer) is created
927 in given OGR datasource (GV_FORMAT_OGR). Similarly if PG file exists
928 then the map (ie. PostGIS table) is created using PostGIS interface
929 (GV_FORMAT_POSTGIS). The format of map is stored in Map->format.
930
931 \param[out] Map pointer to Map_info structure
932 \param name name of vector map to be created
933 \param with_z WITH_Z for 3D vector data otherwise WITHOUT_Z
934
935 \return 1 on success
936 \return -1 on error
937 */
938int Vect_open_new(struct Map_info *Map, const char *name, int with_z)
939{
940 int is_tmp;
941
942 is_tmp = getenv("GRASS_VECTOR_TEMPORARY") ? TEMPORARY_MAP_ENV
944 G_debug(1, "Vect_open_new(): is_tmp = %d", is_tmp);
945
946 return open_new(Map, name, with_z, is_tmp);
947}
948
949/*!
950 \brief Create new temporary vector map
951
952 Temporary vector maps are stored in the current mapset (directory
953 <tt>.tmp/<hostname>/vector</tt>). If the map already exists, it is
954 overwritten.
955
956 Temporary vector maps are automatically deleted when closing the map
957 (see Vect_close() for details).
958
959 If <em>name</em> is not given (is NULL), then the name is determined
960 by process id (<tt>tmp_<pid></tt>).
961
962 \param[out] Map pointer to output Map_info struct
963 \param name name for new vector map (or NULL)
964 \param with_z WITH_Z for 3D vector data otherwise WITHOUT_Z
965
966 \return 1 on success
967 \return -1 on error
968 */
969int Vect_open_tmp_new(struct Map_info *Map, const char *name, int with_z)
970{
971 char tmp_name[GNAME_MAX];
972
973 if (!name) {
974 snprintf(tmp_name, sizeof(tmp_name), "tmp_%d", getpid());
975 }
976 else {
977 snprintf(tmp_name, sizeof(tmp_name), "%s", name);
978 }
979 G_debug(1, "Vect_open_tmp_new(): name = '%s' with_z = %d", name, with_z);
980
981 return open_new(Map, tmp_name, with_z, TEMPORARY_MAP); /* temporary map */
982}
983
984/*!
985 \brief Update Coor_info structure
986
987 \param Map pointer to Map_info structure
988 \param[out] Info pointer to Coor_info structure
989
990 \return 1 on success
991 \return 0 on error
992 */
994{
995 char file_path[GPATH_MAX];
996 struct stat stat_buf;
997
998 switch (Map->format) {
999 case GV_FORMAT_NATIVE:
1001 G_debug(1, "get coor info: %s", file_path);
1002 if (0 != stat(file_path, &stat_buf)) {
1003 G_warning(_("Unable to stat file <%s>"), file_path);
1004 Info->size = -1L;
1005 Info->mtime = -1L;
1006 }
1007 else {
1008 Info->size = (off_t)stat_buf.st_size; /* file size */
1009 Info->mtime = (long)stat_buf.st_mtime; /* last modified time */
1010 }
1011
1012 /* stat does not give correct size on MINGW
1013 * if the file is opened */
1014#ifdef __MINGW32__
1015 if (Map->open == VECT_OPEN_CODE) {
1016 dig_fseek(&(Map->dig_fp), 0L, SEEK_END);
1017 G_debug(2, "dig_ftell = %d", dig_ftell(&(Map->dig_fp)));
1018 Info->size = dig_ftell(&(Map->dig_fp));
1019 }
1020#endif
1021 break;
1022 case GV_FORMAT_OGR:
1024 case GV_FORMAT_POSTGIS:
1025 Info->size = 0L;
1026 Info->mtime = 0L;
1027 break;
1028 }
1029 G_debug(1, "Vect_coor_info(): Info->size = %lu, Info->mtime = %ld",
1030 (unsigned long)Info->size, Info->mtime);
1031
1032 return 1;
1033}
1034
1035/*!
1036 \brief Gets vector map format (as string)
1037
1038 Note: string is allocated by G_store(). Free allocated memory with
1039 G_free().
1040
1041 Currently are implemented:
1042 - Native format (native)
1043 - OGR format (ogr)
1044 - PostGIS format (postgis)
1045
1046 \param Map pointer to Map_info structure
1047
1048 \return maptype string on success (allocated by G_store())
1049 \return error message on error
1050 */
1051const char *Vect_maptype_info(struct Map_info *Map)
1052{
1053 char maptype[1000];
1054
1055 switch (Map->format) {
1056 case GV_FORMAT_NATIVE:
1057 snprintf(maptype, sizeof(maptype), "native");
1058 break;
1059 case GV_FORMAT_OGR:
1061 snprintf(maptype, sizeof(maptype), "OGR");
1062 break;
1063 case GV_FORMAT_POSTGIS:
1064 snprintf(maptype, sizeof(maptype), "PostGIS");
1065 break;
1066 default:
1067 snprintf(maptype, sizeof(maptype),
1068 _("unknown %d (update Vect_maptype_info)"), Map->format);
1069 }
1070
1071 return G_store(maptype);
1072}
1073
1074/*!
1075 \brief Gets vector map format
1076
1077 Currently are implemented:
1078 - Native format (GV_FORMAT_NATIVE)
1079 - OGR format linked via v.external (GV_FORMAT_OGR)
1080 - OGR format (GV_FORMAT_OGR_DIRECT)
1081 - PostGIS format (GV_FORMAT_POSTGIS)
1082
1083 \param Map pointer to Map_info structure
1084
1085 \return map format code
1086 */
1088{
1089 if (Map->temporary) {
1090 const struct Format_info *finfo;
1091
1092 finfo = &(Map->fInfo);
1093 if (finfo->ogr.driver_name) {
1094 return GV_FORMAT_OGR;
1095 }
1096 if (finfo->pg.conninfo) {
1097 return GV_FORMAT_POSTGIS;
1098 }
1099 }
1100
1101 return Map->format;
1102}
1103
1104/*!
1105 \brief Open topology file ('topo')
1106
1107 \param[in,out] Map pointer to Map_info structure
1108 \param head_only TRUE to read only header
1109
1110 \return 0 on success
1111 \return 1 file does not exist
1112 \return -1 on error
1113 */
1114int Vect_open_topo(struct Map_info *Map, int head_only)
1115{
1116 int err, ret;
1118 struct gvfile fp;
1119 struct Coor_info CInfo;
1120 struct Plus_head *Plus;
1121
1122 G_debug(1, "Vect_open_topo(): name = %s mapset = %s", Map->name,
1123 Map->mapset);
1124
1125 Plus = &(Map->plus);
1126
1129 if (access(file_path, F_OK) != 0) { /* does not exist */
1130 return 1;
1131 }
1132
1133 dig_file_init(&fp);
1134 fp.file = G_fopen_old(path, GV_TOPO_ELEMENT, Map->mapset);
1135
1136 if (fp.file == NULL) { /* topo file is not available */
1137 G_debug(1, "Cannot open topo file for vector '%s@%s'.", Map->name,
1138 Map->mapset);
1139 return -1;
1140 }
1141
1142 /* get coor info */
1143 /* NOTE: coor file not yet opened */
1145
1146 /* load head */
1147 if (dig_Rd_Plus_head(&fp, Plus) == -1)
1148 return -1;
1149
1150 G_debug(1, "Topo head: coor size = %lu, coor mtime = %ld",
1151 (unsigned long)Plus->coor_size, Plus->coor_mtime);
1152
1153 /* do checks */
1154 err = 0;
1155 if (CInfo.size != Plus->coor_size) {
1156 G_warning(
1157 _("Size of 'coor' file differs from value saved in topology file"));
1158 err = 1;
1159 }
1160 /* Do not check mtime because mtime is changed by copy */
1161 /*
1162 if ( CInfo.mtime != Plus->coor_mtime ) {
1163 G_warning ( "Time of last modification for 'coor' file differs from value
1164 saved in topo file.\n"); err = 1;
1165 }
1166 */
1167 if (err) {
1168 G_warning(_("Please rebuild topology for vector map <%s@%s>"),
1169 Map->name, Map->mapset);
1170 return -1;
1171 }
1172
1173 /* load file to the memory */
1174 /* dig_file_load ( &fp); */
1175
1176 /* load topo to memory */
1177 ret = dig_load_plus(Plus, &fp, head_only);
1178
1179 fclose(fp.file);
1180 /* dig_file_free(&fp); */
1181
1182 return ret == 0 ? -1 : 0;
1183}
1184
1185/*!
1186 \brief Open spatial index file ('sidx')
1187
1188 \param[in,out] Map pointer to Map_info
1189 \param mode 0 old, 1 update, 2 new
1190
1191 \return 1 if sidx file is not available
1192 \return 0 on success
1193 \return -1 on error
1194 */
1196{
1197 int err;
1198 struct Coor_info CInfo;
1199 struct Plus_head *Plus;
1200
1201 G_debug(1, "Vect_open_sidx(): name = %s mapset= %s mode = %s", Map->name,
1202 Map->mapset, mode == 0 ? "old" : (mode == 1 ? "update" : "new"));
1203
1204 Plus = &(Map->plus);
1205
1206 if (Plus->Spidx_built) {
1207 G_debug(1, "Spatial index already opened");
1208 return 0;
1209 }
1210
1211 dig_file_init(&(Plus->spidx_fp));
1212
1213 if (mode < 2) {
1215
1218 if (access(file_path, F_OK) != 0) /* does not exist */
1219 return 1;
1220
1221 Plus->spidx_fp.file = G_fopen_old(path, GV_SIDX_ELEMENT, Map->mapset);
1222
1223 if (Plus->spidx_fp.file == NULL) { /* sidx file is not available */
1224 G_debug(1, "Cannot open spatial index file for vector '%s@%s'.",
1225 Map->name, Map->mapset);
1226 return -1;
1227 }
1228
1229 /* get coor info */
1230 /* NOTE: coor file not yet opened */
1232
1233 /* initialize spatial index */
1234 Plus->Spidx_new = FALSE;
1235
1236 if (mode == 0) {
1237 /* free old indices */
1239 /* initialize file based indices */
1240 Plus->Spidx_file = 1;
1242 }
1243
1244 /* load head */
1245 if (dig_Rd_spidx_head(&(Plus->spidx_fp), Plus) == -1) {
1246 fclose(Plus->spidx_fp.file);
1247 return -1;
1248 }
1249
1250 G_debug(1, "Sidx head: coor size = %lu, coor mtime = %ld",
1251 (unsigned long)Plus->coor_size, Plus->coor_mtime);
1252
1253 /* do checks */
1254 err = 0;
1255 if (CInfo.size != Plus->coor_size) {
1256 G_warning(
1257 _("Size of 'coor' file differs from value saved in sidx file"));
1258 err = 1;
1259 }
1260 /* Do not check mtime because mtime is changed by copy */
1261 /*
1262 if ( CInfo.mtime != Plus->coor_mtime ) {
1263 G_warning ( "Time of last modification for 'coor' file differs from
1264 value saved in topo file.\n"); err = 1;
1265 }
1266 */
1267 if (err) {
1268 G_warning(_("Please rebuild topology for vector map <%s@%s>"),
1269 Map->name, Map->mapset);
1270 fclose(Plus->spidx_fp.file);
1271 return -1;
1272 }
1273 }
1274
1275 if (mode) {
1276 /* open new spatial index */
1277 Plus->Spidx_new = TRUE;
1278
1279 /* file based or memory based */
1280 if (getenv("GRASS_VECTOR_LOWMEM")) {
1281 /* free old indices */
1283 /* initialize file based indices */
1284 Plus->Spidx_file = 1;
1286 }
1287 G_debug(1, "%s based spatial index",
1288 Plus->Spidx_file == 0 ? "Memory" : "File");
1289
1290 if (mode == 1) {
1291 /* load spatial index for update */
1292 if (dig_Rd_spidx(&(Plus->spidx_fp), Plus) == -1) {
1293 fclose(Plus->spidx_fp.file);
1294 return -1;
1295 }
1296 }
1297 }
1298
1299 Plus->Spidx_built = TRUE;
1300
1301 return 0;
1302}
1303
1304/* check for external formats definition */
1305int map_format(struct Map_info *Map)
1306{
1307 int format;
1308 char *def_file;
1309
1310 format = GV_FORMAT_NATIVE;
1311 /* temporary maps can be stored only in native format */
1312 if (Map->temporary || getenv("GRASS_VECTOR_EXTERNAL_IGNORE"))
1313 return format;
1314
1315 if (G_find_file2("", "OGR", G_mapset())) {
1316 /* OGR */
1317 FILE *fp;
1318 const char *p;
1319
1320 struct Key_Value *key_val;
1321 struct Format_info_ogr *ogr_info;
1322
1323 G_debug(2, " using OGR format");
1324 if (getenv("GRASS_VECTOR_EXTERNAL_IMMEDIATE")) {
1325 /* vector features are written directly to OGR layer */
1326 format = GV_FORMAT_OGR;
1327 }
1328 else {
1329 /* vector features are written to the temporary vector map
1330 * in the native format and when closing the map
1331 * transferred to output OGR layer */
1332 format = GV_FORMAT_NATIVE;
1333 Map->temporary = TEMPORARY_MAP;
1334 }
1335 fp = G_fopen_old("", "OGR", G_mapset());
1336 if (!fp) {
1337 G_fatal_error(_("Unable to open OGR file"));
1338 }
1340 fclose(fp);
1341
1342 ogr_info = &(Map->fInfo.ogr);
1343 /* format */
1344 p = G_find_key_value("format", key_val);
1345 if (p)
1346 ogr_info->driver_name = G_store(p);
1347 /* dsn */
1348 p = G_find_key_value("dsn", key_val);
1349 if (p)
1350 ogr_info->dsn = G_store(p);
1351 /* options */
1352 p = G_find_key_value("options", key_val);
1353 if (p)
1354 ogr_info->layer_options = G_tokenize(p, ",");
1355
1356 ogr_info->layer_name = G_store(Map->name);
1357 }
1358
1359 def_file = getenv("GRASS_VECTOR_PGFILE"); /* GRASS_VECTOR_PGFILE defined by
1360 v.out.postgis */
1361 if (G_find_file2("", def_file ? def_file : "PG", G_mapset())) {
1362 /* PostGIS */
1363 if (Map->fInfo.ogr.driver_name) {
1364 G_warning(_("OGR output also detected, using OGR"));
1365 }
1366 else {
1367 FILE *fp;
1368 const char *p;
1369
1370 struct Key_Value *key_val;
1371 struct Format_info_pg *pg_info;
1372
1373 G_debug(2, " using PostGIS format");
1374 fp = G_fopen_old("", def_file ? def_file : "PG", G_mapset());
1375 if (!fp) {
1376 G_fatal_error(_("Unable to open PG file"));
1377 }
1379 fclose(fp);
1380
1381 pg_info = &(Map->fInfo.pg);
1382 /* conninfo */
1383 p = G_find_key_value("conninfo", key_val);
1384 if (p) {
1385 pg_info->conninfo = G_store(p);
1386 G_debug(1, "PG: conninfo = '%s'", pg_info->conninfo);
1387 }
1388
1389 /* schema (default: public) */
1390 p = G_find_key_value("schema", key_val);
1391 if (p)
1392 pg_info->schema_name = G_store(p);
1393 else
1394 pg_info->schema_name = G_store("public");
1395 G_debug(1, "PG: schema_name = '%s'", pg_info->schema_name);
1396
1397 /* fid column (default: FID_COLUMN) */
1398 p = G_find_key_value("fid", key_val);
1399 if (p)
1400 pg_info->fid_column = G_store(p);
1401 else
1402#ifdef HAVE_POSTGRES
1403 pg_info->fid_column = G_store(GV_PG_FID_COLUMN);
1404#endif
1405 G_debug(1, "PG: fid_column = '%s'", pg_info->fid_column);
1406
1407 /* geometry column (default: GEOMETRY_COLUMN) */
1408 p = G_find_key_value("geometry_name", key_val);
1409 if (p)
1410 pg_info->geom_column = G_store(p);
1411 else
1412#ifdef HAVE_POSTGRES
1413 pg_info->geom_column = G_store(GV_PG_GEOMETRY_COLUMN);
1414#endif
1415 G_debug(1, "PG: geom_column = '%s'", pg_info->geom_column);
1416
1417 /* srid (default: 0) */
1418 p = G_find_key_value("srid", key_val);
1419 if (p) {
1420 pg_info->srid = atoi(p);
1421 }
1422 else {
1423 /* not defined by v.external.out, so try if EPSG code
1424 * is defined */
1426 if (p)
1427 pg_info->srid = atoi(p);
1428 }
1429 G_debug(1, "PG: srid = %d", pg_info->srid);
1430
1431 /* table name */
1432 Map->fInfo.pg.table_name = G_store(Map->name);
1433
1434 /* PostGIS topology enabled ? */
1435 p = G_find_key_value("topology", key_val);
1436 if (p && G_strcasecmp(p, "yes") == 0) {
1437 /* define topology name */
1438 p = G_find_key_value("toposchema_name", key_val);
1439 if (p)
1440 pg_info->toposchema_name = G_store(p);
1441 else
1442 G_asprintf(&(pg_info->toposchema_name), "topo_%s",
1443 pg_info->table_name);
1444
1445 G_debug(1, "PG: topology = yes, schema_name = %s",
1446 pg_info->toposchema_name);
1447 }
1448 G_debug(1, "PG: topology = no");
1449
1450 if (getenv("GRASS_VECTOR_EXTERNAL_IMMEDIATE")) {
1451 /* vector features are written directly to PostGIS layer */
1452 format = GV_FORMAT_POSTGIS;
1453 }
1454 else {
1455 /* vector features are written to the temporary vector map
1456 * in the native format and when closing the map
1457 * transferred to output PostGIS layer */
1458 format = GV_FORMAT_NATIVE;
1459 Map->temporary = TEMPORARY_MAP;
1460 }
1461 }
1462 }
1463
1464 G_debug(2, "map_format = %d", format);
1465 return format;
1466}
1467
1468/*!
1469 \brief Get map directory name (internal use only)
1470
1471 \param file_path path string buffer
1472 \param Map pointer to Map_info struct
1473
1474 \return buffer containing path
1475 */
1476char *Vect__get_path(char *path, struct Map_info *Map)
1477{
1478 if (Map->temporary) {
1479 char path_tmp[GPATH_MAX];
1480
1482 if (snprintf(path, GPATH_MAX, "%s/%s/%s", path_tmp, GV_DIRECTORY,
1483 Map->name) >= GPATH_MAX)
1484 G_fatal_error(_("Filepath '%s/%s' exceeds max length"), path_tmp,
1485 Map->name);
1486 }
1487 else {
1488 if (snprintf(path, GPATH_MAX, "%s/%s", GV_DIRECTORY, Map->name) >=
1489 GPATH_MAX)
1490 G_fatal_error(_("Filepath '%s/%s' exceeds max length"),
1492 }
1493
1494 return path;
1495}
1496
1497/*!
1498 \brief Get map element full path (internal use only)
1499
1500 Allocate string should be freed by G_free().
1501
1502 \param Map pointer to Map_info struct
1503 \param element element name, eg. GV_TOPO_ELEMENT
1504
1505 \return allocated buffer containing path
1506 */
1508 const char *element)
1509{
1510 char path[GPATH_MAX];
1511
1513 if (Map->temporary)
1515 else
1516 G_file_name(file_path, path, element, Map->mapset);
1517
1518 return file_path;
1519}
#define NULL
Definition ccmath.h:32
AMI_err name(char **stream_name)
Definition ami_stream.h:426
FILE * G_fopen_modify(const char *, const char *)
Open a database file for update (r+ mode)
Definition gis/open.c:313
int G_name_is_fully_qualified(const char *, char *, char *)
Check if map name is fully qualified (map @ mapset)
Definition nme_in_mps.c:36
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition gis/zero.c:23
const char * G_database_epsg_code(void)
Get EPGS code for the current location.
Definition proj3.c:236
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
FILE * G_fopen_new(const char *, const char *)
Open a new database file.
Definition gis/open.c:221
void G__temp_element(char *, int)
Populates element with a path string (internal use only!)
Definition tempfile.c:160
void G_fseek(FILE *, off_t, int)
Change the file position of the stream.
Definition gis/seek.c:50
void void G_verbose_message(const char *,...) __attribute__((format(printf
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition file_name.c:61
FILE * G_fopen_old(const char *, const char *, const char *)
Open a database file for reading.
Definition gis/open.c:253
const char * G_gisdbase(void)
Get name of top level database directory.
Definition gisdbase.c:26
const char * G_find_file2(const char *, const char *, const char *)
Searches for a file from the mapset search list or in a specified mapset. (look but don't touch)
Definition find_file.c:234
char ** G_tokenize(const char *, const char *)
Tokenize string.
Definition gis/token.c:47
int G_verbose(void)
Get current verbosity level.
Definition verbose.c:60
const char * G_location(void)
Get current location name.
Definition location.c:32
int G_asprintf(char **, const char *,...) __attribute__((format(printf
const char * G_find_key_value(const char *, const struct Key_Value *)
Find given key (case sensitive)
Definition key_value1.c:85
struct Key_Value * G_fread_key_value(FILE *)
Read key/values pairs from file.
Definition key_value2.c:49
int G_zone(void)
Query cartographic zone.
Definition zone.c:23
int int G_strcasecmp(const char *, const char *)
String compare ignoring case (upper or lower)
Definition strings.c:47
char * G_store(const char *)
Copy string to allocated memory.
Definition strings.c:87
int G_set_verbose(int)
Set verbosity level.
Definition verbose.c:125
char * G_file_name_tmp(char *, const char *, const char *, const char *)
Builds full path names to GIS data files in temporary directory (for internal use only)
Definition file_name.c:125
void G_message(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
const char * G_find_vector2(const char *, const char *)
Find a vector map (look but don't touch)
Definition find_vect.c:62
int G_projection(void)
Query cartographic projection.
Definition proj1.c:32
const char * G_mapset(void)
Get current mapset name.
Definition gis/mapset.c:33
int V1_open_old_ogr(struct Map_info *, int)
Open existing OGR layer on non-topological level.
Definition open_ogr.c:41
int Vect_cidx_open(struct Map_info *, int)
Read category index from cidx file if exists.
int Vect_set_proj(struct Map_info *, int)
Set projection in map header.
int V1_open_new_pg(struct Map_info *, const char *, int)
Prepare PostGIS database for creating new feature table (level 1)
Definition open_pg.c:226
struct dblinks * Vect_new_dblinks_struct(void)
Create and init new dblinks structure.
Definition field.c:47
int Vect_read_dblinks(struct Map_info *)
Read dblinks to existing structure.
Definition field.c:837
int Vect_set_zone(struct Map_info *, int)
Set projection zone in map header.
int V1_open_new_nat(struct Map_info *, const char *, int)
Create new vector map (level 1)
Definition open_nat.c:97
int V1_open_old_nat(struct Map_info *, int)
Open existing vector map (level 1)
Definition open_nat.c:40
int V2_open_old_pg(struct Map_info *)
Open vector map - PostGIS feature table on topological level.
Definition open_pg.c:166
const char * Vect_get_name(struct Map_info *)
Get name of vector map.
int Vect_get_zone(struct Map_info *)
Get projection zone from map header.
int Vect_delete(const char *)
Delete vector map including attribute tables.
Definition map.c:367
int Vect_legal_filename(const char *)
Check if output is legal vector name.
Definition legal_vname.c:31
int Vect__read_head(struct Map_info *)
Reads head information from text file (GV_HEAD_ELEMENT) - for internal use only.
const char * Vect_get_full_name(struct Map_info *)
Get fully qualified name of vector map.
int Vect_build(struct Map_info *)
Build topology for vector map.
Definition build.c:579
void Vect__init_head(struct Map_info *)
Initialize Map_info head structure (dig_head)
Definition init_head.c:29
int Vect_rewind(struct Map_info *)
Rewind vector map to cause reads to start at beginning.
int V1_open_new_ogr(struct Map_info *, const char *, int)
Prepare OGR datasource for creating new OGR layer (level 1)
Definition open_ogr.c:169
int Vect__write_head(struct Map_info *)
Writes head information to text file (GV_HEAD_ELEMENT)
int Vect_hist_write(struct Map_info *, const char *)
Write string to history file.
Definition hist.c:65
int V2_open_old_ogr(struct Map_info *)
Open existing OGR layer on topological level.
Definition open_ogr.c:138
int V1_open_old_pg(struct Map_info *, int)
Open vector map - PostGIS feature table on non-topological level.
Definition open_pg.c:73
#define GV_FRMT_ELEMENT
Format description, data location (OGR)
Definition dig_defines.h:10
#define GV_BUILD_NONE
Topology levels - nothing to build.
#define VECT_OPEN_CODE
Vector map open code.
#define GV_FORMAT_POSTGIS
PostGIS format.
Definition dig_defines.h:89
#define GV_DIRECTORY
Name of vector directory.
Definition dig_defines.h:8
#define GV_SIDX_ELEMENT
Native format, spatial index.
Definition dig_defines.h:22
#define GV_MODE_READ
Read-only vector map open mode.
#define LEVEL_1
Vector level - without topology.
#define GV_BUILD_ALL
Topology levels - build everything (currently same as GV_BUILD_CENTROIDS)
#define GV_COOR_ELEMENT
Native format, coordinates.
Definition dig_defines.h:12
#define GV_FIDX_ELEMENT
External format (OGR), feature index.
Definition dig_defines.h:26
#define GV_COOR_HEAD_SIZE
Coordinates file head size.
#define GV_FORMAT_OGR_DIRECT
OGR format (direct access)
Definition dig_defines.h:87
#define WITHOUT_Z
2D/3D vector data
#define GV_CIDX_ELEMENT
Native format, category index.
Definition dig_defines.h:24
#define GV_TOPO_ELEMENT
Native format, topology file.
Definition dig_defines.h:20
#define GV_PG_GEOMETRY_COLUMN
GRASS-PostGIS data provider - default geometry column.
#define GV_HEAD_ELEMENT
Native format, header information.
Definition dig_defines.h:14
#define GV_FORMAT_OGR
OGR format.
Definition dig_defines.h:85
#define GV_MODE_RW
Read-write vector map open mode.
#define GV_PG_FID_COLUMN
GRASS-PostGIS data provider - default fid column.
#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
#define GV_HIST_ELEMENT
Native format, history file.
Definition dig_defines.h:18
int dig_load_plus(struct Plus_head *, struct gvfile *, int)
Reads topo file to topo structure.
Definition plus.c:195
void dig_free_plus(struct Plus_head *)
Free Plus structure.
Definition plus.c:173
int dig_init_plus(struct Plus_head *)
Initialize Plus_head structure.
Definition plus.c:30
int dig_read_frmt_ascii(FILE *, struct Format_info *)
Read external vector format file.
Definition frmt.c:33
off_t dig_ftell(struct gvfile *file)
Get struct gvfile position.
Definition file.c:36
int dig_Rd_spidx(struct gvfile *, struct Plus_head *)
Read spatial index from sidx file Only needed when old vector is opened in update mode.
int dig_Rd_Plus_head(struct gvfile *, struct Plus_head *)
Read Plus_head from file.
int dig_fseek(struct gvfile *file, off_t offset, int whence)
Set struct gvfile position.
Definition file.c:60
int dig_Rd_spidx_head(struct gvfile *, struct Plus_head *)
Read spatial index header from sidx file.
Definition spindex_rw.c:262
void dig_spidx_free(struct Plus_head *)
Free spatial index (nodes, lines, areas, isles)
Definition spindex.c:243
void dig_file_init(struct gvfile *file)
Initialize gvfile structure.
Definition file.c:171
int dig_spidx_init(struct Plus_head *)
Initit spatial index (nodes, lines, areas, isles)
Definition spindex.c:35
#define GMAPSET_MAX
Definition gis.h:197
#define GPATH_MAX
Definition gis.h:199
#define TRUE
Definition gis.h:78
#define FALSE
Definition gis.h:82
#define GNAME_MAX
Definition gis.h:196
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:46
#define _(str)
Definition glocale.h:10
int Vect__delete(const char *map, int is_tmp)
Delete vector map (internal use only)
Definition map.c:381
const char * name
Definition named_colr.c:6
int Vect__open_topo_pg(struct Map_info *Map, int head_only, int update)
Read full-topology for PostGIS links.
Definition open_pg.c:327
#define strcasecmp
Definition strings.h:8
Coor file info.
Non-native format info (OGR)
Non-native format info (PostGIS)
Non-native format info (currently only OGR is implemented)
Vector map info.
char * mapset
Mapset name.
struct dig_head head
Header info.
int level
Topology level.
int head_only
Open only header.
int format
Map format (native, ogr, postgis)
Basic topology-related info.
int mode
Access mode.
File definition.
Definition dig_structs.h:92
FILE * file
File descriptor.
Definition dig_structs.h:96
Definition path.h:15
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
#define unlink
Definition unistd.h:11
#define access
Definition unistd.h:7
#define getpid
Definition unistd.h:20
#define F_OK
Definition unistd.h:22
int Vect__open_old(struct Map_info *Map, const char *name, const char *mapset, const char *layer, int update, int head_only, int is_tmp)
Open existing vector map for reading (internal use only)
int Vect_open_tmp_new(struct Map_info *Map, const char *name, int with_z)
Create new temporary vector map.
int Vect_open_old(struct Map_info *Map, const char *name, const char *mapset)
Open existing vector map for reading.
int Vect_set_open_level(int level)
Predetermine level at which a vector map will be opened for reading.
const char * Vect_maptype_info(struct Map_info *Map)
Gets vector map format (as string)
int Vect_open_tmp_update(struct Map_info *Map, const char *name, const char *mapset)
Open existing temporary vector map for reading/writing.
int Vect_open_update_head(struct Map_info *Map, const char *name, const char *mapset)
Open header file of existing vector map for updating (mostly for database link updates)
int Vect_open_old2(struct Map_info *Map, const char *name, const char *mapset, const char *layer)
Open existing vector map for reading.
int Vect_open_old_head2(struct Map_info *Map, const char *name, const char *mapset, const char *layer)
Reads only info about vector map (headers)
int Vect_coor_info(struct Map_info *Map, struct Coor_info *Info)
Update Coor_info structure.
char * Vect__get_element_path(char *file_path, struct Map_info *Map, const char *element)
Get map element full path (internal use only)
int Vect_open_topo(struct Map_info *Map, int head_only)
Open topology file ('topo')
char * Vect__get_path(char *path, struct Map_info *Map)
Get map directory name (internal use only)
#define MAX_OPEN_LEVEL
Number of levels.
int Vect_open_new(struct Map_info *Map, const char *name, int with_z)
Create new vector map for reading/writing.
int Vect_open_sidx(struct Map_info *Map, int mode)
Open spatial index file ('sidx')
int Vect_open_old_head(struct Map_info *Map, const char *name, const char *mapset)
Reads only info about vector map (headers)
int Vect_maptype(struct Map_info *Map)
Gets vector map format.
int Vect_open_update(struct Map_info *Map, const char *name, const char *mapset)
Open existing vector map for reading/writing.
int Vect_open_tmp_old(struct Map_info *Map, const char *name, const char *mapset)
Open existing temporary vector map for reading.
int Vect_open_update2(struct Map_info *Map, const char *name, const char *mapset, const char *layer)
Open existing vector map for reading/writing.