GRASS 8 Programmer's Manual 8.6.0dev(2026)-5f4f7ad06c
Loading...
Searching...
No Matches
vector/Vlib/close.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/Vlib/close.c
3
4 \brief Vector library - Close vector map
5
6 Higher level functions for reading/writing/manipulating vectors.
7
8 (C) 2001-2015 by the GRASS Development Team
9
10 This program is free software under the GNU General Public License
11 (>=v2). Read the file COPYING that comes with GRASS for details.
12
13 \author Original author CERL, probably Dave Gerdes or Mike Higgins.
14 \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
15 \author Update to GRASS 7 Martin Landa <landa.martin gmail.com>
16 */
17
18#include <stdlib.h>
19#include <stdio.h>
20#include <string.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <unistd.h>
24
25#include <grass/vector.h>
26#include <grass/glocale.h>
27
28#include "local_proto.h"
29
30static int clo_dummy(struct Map_info *map UNUSED)
31{
32 return -1;
33}
34
35#if !defined HAVE_POSTGRES
36static int format(struct Map_info *map UNUSED)
37{
38 G_fatal_error(_("Requested format is not compiled in this version"));
39 return 0;
40}
41#endif
42
43static int (*Close_array[][2])(struct Map_info *) = {{clo_dummy, V1_close_nat},
44 {clo_dummy, V1_close_ogr},
45 {clo_dummy, V1_close_ogr}
46#ifdef HAVE_POSTGRES
47 ,
48 {clo_dummy, V1_close_pg}
49#else
50 ,
51 {clo_dummy, format}
52#endif
53};
54
55static void unlink_file(struct Map_info *, const char *);
56
57/*!
58 \brief Close vector map
59
60 \param Map pointer to Map_info
61
62 \return 0 on success
63 \return non-zero on error
64 */
66{
67 int create_link; /* used for external formats only */
68 struct Coor_info CInfo;
69
70 G_debug(1,
71 "Vect_close(): name = %s, mapset = %s, format = %d, level = %d, "
72 "is_tmp = %d",
73 Map->name, Map->mapset, Map->format, Map->level, Map->temporary);
74
75 if (Map->temporary && (Map->fInfo.ogr.dsn || Map->fInfo.pg.conninfo)) {
76 /* transfer features for external output format */
77 struct Map_info Out;
78
79 putenv("GRASS_VECTOR_EXTERNAL_IMMEDIATE=1");
80 if (-1 == Vect_open_new(&Out, Vect_get_name(Map), Vect_is_3d(Map))) {
81 G_warning(_("Unable to create vector map <%s>"),
83 return 1;
84 }
85
86 /* copy metadata */
87 Vect_hist_copy(Map, &Out);
89 /* copy dblinks (temporary map -> output map) to transfer
90 (input map -> output map) attributes */
92 /* afterwards, dblinks must be removed from temporary map
93 otherwise when deleting temporary map also original
94 attribute tables would be deleted */
95 Vect_map_del_dblink(Map, -1); /* delete db links for all layers */
96
98 Map, 1, &Out)) { /* always layer = 1 for OGR/PG maps */
99 G_warning(_("Copying features failed"));
100 return -1;
101 }
102
103 Vect_build(&Out);
104
105 Vect_close(&Out);
106 putenv("GRASS_VECTOR_EXTERNAL_IMMEDIATE="); /* unset variable */
107 }
108
109 /* check for external formats whether to create a link */
111 if (Map->format == GV_FORMAT_OGR || Map->format == GV_FORMAT_POSTGIS) {
112 char *def_file;
113
114 if (Map->format == GV_FORMAT_POSTGIS) {
115 if (getenv("GRASS_VECTOR_PGFILE"))
116 def_file = getenv("GRASS_VECTOR_PGFILE");
117 else
118 def_file = "PG";
119 }
120 else {
121 def_file = "OGR";
122 }
123 if (G_find_file2("", def_file, G_mapset())) {
124 FILE *fp;
125 const char *p;
126
127 struct Key_Value *key_val;
128
129 fp = G_fopen_old("", def_file, G_mapset());
130 if (!fp) {
131 G_warning(_("Unable to open %s file"), def_file);
132 }
133 else {
135 fclose(fp);
136
137 /* create a vector link in the current mapset ? */
138 p = G_find_key_value("link", key_val);
139 if (p && G_strcasecmp(p, "no") == 0) {
141 }
142 else {
143 p = G_find_key_value("link_name", key_val);
144 if (p) {
145 /* use different name for a link */
146 G_free(Map->name);
147 Map->name = G_store(p);
148 }
149 }
150 }
151 }
152 }
153
154 /* store support files for vector maps in the current mapset if in
155 write mode on level 2 */
156 if (strcmp(Map->mapset, G_mapset()) == 0 && Map->support_updated &&
157 Map->plus.built == GV_BUILD_ALL && create_link) {
158
159 unlink_file(Map, GV_TOPO_ELEMENT); /* topo */
160
161 unlink_file(Map, GV_SIDX_ELEMENT); /* sidx */
162
163 unlink_file(Map, GV_CIDX_ELEMENT); /* cidx */
164
165 if (Map->format == GV_FORMAT_OGR || Map->format == GV_FORMAT_POSTGIS) {
166 unlink_file(Map, GV_FIDX_ELEMENT); /* fidx */
167 }
168
170 Map->plus.coor_size = CInfo.size;
171 Map->plus.coor_mtime = CInfo.mtime;
172
173 /* write out topo file */
175
176 /* write out sidx file */
177 Map->plus.Spidx_new = TRUE; /* force writing */
179
180 /* write out cidx file */
182
183 /* write out fidx file */
184 if (Map->format == GV_FORMAT_OGR)
186 else if (Map->format == GV_FORMAT_POSTGIS)
188 }
189
190 /* spatial index must also be closed when opened with topo but not
191 * modified */
192 if (Map->plus.spidx_fp.file && Map->plus.Spidx_built == TRUE &&
193 !Map->support_updated && Map->plus.built == GV_BUILD_ALL) {
194
195 G_debug(1, "spatial index file closed");
196 fclose(Map->plus.spidx_fp.file);
197 }
198
199 /* release memory if required */
200 if (Map->level > 1 && Map->plus.release_support) {
201 G_debug(1, "free topology, spatial index, and category index");
202 dig_free_plus(&(Map->plus));
203 }
204
205 G_debug(1, "close history file");
206 if (Map->hist_fp)
207 fclose(Map->hist_fp);
208
209 /* close level 1 files / data sources if not head_only */
210 if (!Map->head_only) {
211 if (create_link && ((*Close_array[Map->format][1])(Map)) != 0) {
212 const char *mname = Vect_get_full_name(Map);
213 G_warning(_("Unable to close vector <%s>"), mname);
214 G_free((void *)mname);
215 return 1;
216 }
217 }
218
219 G_free(Map->name);
220 G_free(Map->mapset);
221 G_free(Map->location);
222 G_free(Map->gisdbase);
223
224 Map->open = VECT_CLOSED_CODE;
225
226 return 0;
227}
228
229/*!
230 \brief Save format definition file for vector map
231
232 \param Map pointer to Map_info structure
233
234 \return 1 on success
235 \return 0 on error
236 */
238{
239 FILE *fd;
240 char buf[GPATH_MAX];
241
242 if (Map->format != GV_FORMAT_OGR && Map->format != GV_FORMAT_POSTGIS) {
243 G_warning(_("Invalid request for writing frmt file - map format is %d"),
244 Map->format);
245 return 0;
246 }
247
248 /* create frmt file */
249 snprintf(buf, sizeof(buf), "%s/%s", GV_DIRECTORY, Map->name);
250 fd = G_fopen_new(buf, GV_FRMT_ELEMENT);
251 if (fd == NULL) {
252 G_fatal_error("Unable to create file '%s'", buf);
253 }
254
255 if (Map->format == GV_FORMAT_POSTGIS) {
256#ifdef HAVE_POSTGRES
257 fprintf(fd, "format: postgis\n");
258 fprintf(fd, "conninfo: %s\n", Map->fInfo.pg.conninfo);
259 fprintf(fd, "schema: %s\n", Map->fInfo.pg.schema_name);
260 fprintf(fd, "table: %s\n", Map->fInfo.pg.table_name);
261#else
262 G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
263 return 0;
264#endif
265 }
266 else if (Map->format == GV_FORMAT_OGR) {
267 fprintf(fd, "format: ogr\n");
268 fprintf(fd, "dsn: %s\n", Map->fInfo.ogr.dsn);
269 fprintf(fd, "layer: %s\n", Map->fInfo.ogr.layer_name);
270 }
271
272 G_verbose_message(_("Link to vector map <%s> created"), Map->name);
273
274 /* close frmt file */
275 fclose(fd);
276
277 return 1;
278}
279
280/*! Free memory of line cache
281
282 \param cache pointer to lines cache to be freed
283 */
285{
286 int i;
287
288 /* destroy lines in cache */
289 for (i = 0; i < cache->lines_alloc; i++) {
291 }
292 G_free(cache->lines);
293 G_free(cache->lines_types);
294 G_free(cache->lines_cats);
295
296 G_zero(cache, sizeof(struct Format_info_cache));
297}
298
299/*! Free memory of offset array
300
301 \param offset pointer to offset array to be freed
302 */
304{
305 G_free(offset->array);
306 G_zero(offset, sizeof(struct Format_info_offset));
307}
308
309void unlink_file(struct Map_info *Map, const char *name)
310{
311 char path[GPATH_MAX];
312
313 /* delete old support files if available */
315 if (access(path, F_OK) == 0) { /* file exists? */
316 G_debug(2, "\t%s: unlink", path);
317 unlink(path);
318 }
319}
#define NULL
Definition ccmath.h:32
AMI_err name(char **stream_name)
Definition ami_stream.h:426
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition gis/zero.c:23
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
FILE * G_fopen_new(const char *, const char *)
Open a new database file.
Definition gis/open.c:221
void void G_verbose_message(const char *,...) __attribute__((format(printf
FILE * G_fopen_old(const char *, const char *, const char *)
Open a database file for reading.
Definition gis/open.c:253
const char * G_find_file2(const char *, const char *, const char *)
Searches for a file from the mapset search list or in a specified mapset. (look but don't touch)
Definition find_file.c:234
const char * G_find_key_value(const char *, const struct Key_Value *)
Find given key (case sensitive)
Definition key_value1.c:85
struct Key_Value * G_fread_key_value(FILE *)
Read key/values pairs from file.
Definition key_value2.c:49
int int G_strcasecmp(const char *, const char *)
String compare ignoring case (upper or lower)
Definition strings.c:47
char * G_store(const char *)
Copy string to allocated memory.
Definition strings.c:87
int G_debug(int, const char *,...) __attribute__((format(printf
const char * G_mapset(void)
Get current mapset name.
Definition gis/mapset.c:33
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
Definition line.c:77
int Vect_cidx_save(struct Map_info *)
Save category index to binary file (cidx)
int Vect_coor_info(struct Map_info *, struct Coor_info *)
Update Coor_info structure.
int Vect_open_new(struct Map_info *, const char *, int)
Create new vector map for reading/writing.
int Vect_map_del_dblink(struct Map_info *, int)
Delete db connection from Map_info structure.
Definition field.c:155
const char * Vect_get_name(struct Map_info *)
Get name of vector map.
int Vect_copy_map_lines_field(struct Map_info *, int, struct Map_info *)
Copy all alive vector features from given layer from input vector map to output vector map.
int V2_close_pg(struct Map_info *)
Close vector map (PostGIS layer) on topological level (write out fidx file)
Definition close_pg.c:116
int V1_close_nat(struct Map_info *)
Close vector map.
Definition close_nat.c:34
int Vect_save_topo(struct Map_info *)
Save topology file for vector map.
Definition build.c:1009
int Vect_save_sidx(struct Map_info *)
Save spatial index file for vector map.
Definition build.c:1263
int Vect_copy_head_data(struct Map_info *, struct Map_info *)
Copy header data from one to another map.
Definition init_head.c:77
int Vect_hist_copy(struct Map_info *, struct Map_info *)
Copy history from one map to another.
Definition hist.c:131
const char * Vect_get_full_name(struct Map_info *)
Get fully qualified name of vector map.
void Vect_copy_map_dblinks(struct Map_info *, struct Map_info *, int)
Copy DB links from input vector map to output vector map.
Definition field.c:200
int Vect_build(struct Map_info *)
Build topology for vector map.
Definition build.c:579
int V1_close_ogr(struct Map_info *)
Close vector map (OGR dsn & layer) on level 1.
Definition close_ogr.c:33
int V1_close_pg(struct Map_info *)
Close vector map (PostGIS layer) on level 1.
Definition close_pg.c:39
int V2_close_ogr(struct Map_info *)
Close vector map on topological level (write out fidx file)
Definition close_ogr.c:83
int Vect_is_3d(struct Map_info *)
Check if vector map is 3D.
#define VECT_CLOSED_CODE
Vector map close code.
#define GV_FRMT_ELEMENT
Format description, data location (OGR)
Definition dig_defines.h:10
#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_BUILD_ALL
Topology levels - build everything (currently same as GV_BUILD_CENTROIDS)
#define GV_FIDX_ELEMENT
External format (OGR), feature index.
Definition dig_defines.h:26
#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_FORMAT_OGR
OGR format.
Definition dig_defines.h:85
void dig_free_plus(struct Plus_head *)
Free Plus structure.
Definition plus.c:173
#define GPATH_MAX
Definition gis.h:199
#define TRUE
Definition gis.h:78
#define FALSE
Definition gis.h:82
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:46
#define _(str)
Definition glocale.h:10
const char * name
Definition named_colr.c:6
Coor file info.
Lines cache for reading feature (non-native formats)
int * lines_types
List of line types (GV_POINT, GV_LINE, ...)
struct line_pnts ** lines
Lines array.
int lines_alloc
Number of allocated lines in cache.
int * lines_cats
List of line cats (used only for PostGIS Topology access)
Data structure used for building pseudo-topology.
int * array
Offset list.
Vector map info.
int format
Map format (native, ogr, postgis)
Definition path.h:15
#define unlink
Definition unistd.h:11
#define access
Definition unistd.h:7
#define F_OK
Definition unistd.h:22
int Vect_close(struct Map_info *Map)
Close vector map.
void Vect__free_offset(struct Format_info_offset *offset)
int Vect_save_frmt(struct Map_info *Map)
Save format definition file for vector map.
void Vect__free_cache(struct Format_info_cache *cache)
char * Vect__get_element_path(char *file_path, struct Map_info *Map, const char *element)
Get map element full path (internal use only)