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