grass  7.8.6
About: GRASS (Geographic Resources Analysis Support System) is a raster- and vector-based GIS, image processing system, graphics production system and spatial modeling system.
  Fossies Dox: grass-7.8.6.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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