GRASS 8 Programmer's Manual 8.6.0dev(2026)-4bb960b182
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 SPDX-FileCopyrightText: 2001-2015 GRASS Development Team
9 SPDX-License-Identifier: GPL-2.0-or-later
10
11 \author Original author CERL, probably Dave Gerdes or Mike Higgins.
12 \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
13 \author Update to GRASS 7 Martin Landa <landa.martin gmail.com>
14 */
15
16#include <stdlib.h>
17#include <stdio.h>
18#include <string.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <unistd.h>
22
23#include <grass/vector.h>
24#include <grass/glocale.h>
25
26#include "local_proto.h"
27
28static int clo_dummy(struct Map_info *map G_UNUSED)
29{
30 return -1;
31}
32
33#if !defined HAVE_POSTGRES
34static int format(struct Map_info *map G_UNUSED)
35{
36 G_fatal_error(_("Requested format is not compiled in this version"));
37 return 0;
38}
39#endif
40
41static int (*Close_array[][2])(struct Map_info *) = {{clo_dummy, V1_close_nat},
42 {clo_dummy, V1_close_ogr},
43 {clo_dummy, V1_close_ogr}
44#ifdef HAVE_POSTGRES
45 ,
46 {clo_dummy, V1_close_pg}
47#else
48 ,
49 {clo_dummy, format}
50#endif
51};
52
53static void unlink_file(struct Map_info *, const char *);
54
55/*!
56 \brief Close vector map
57
58 \param Map pointer to Map_info
59
60 \return 0 on success
61 \return non-zero on error
62 */
64{
65 int create_link; /* used for external formats only */
66 struct Coor_info CInfo;
67
68 G_debug(1,
69 "Vect_close(): name = %s, mapset = %s, format = %d, level = %d, "
70 "is_tmp = %d",
71 Map->name, Map->mapset, Map->format, Map->level, Map->temporary);
72
73 if (Map->temporary && (Map->fInfo.ogr.dsn || Map->fInfo.pg.conninfo)) {
74 /* transfer features for external output format */
75 struct Map_info Out;
76
77 putenv("GRASS_VECTOR_EXTERNAL_IMMEDIATE=1");
78 if (-1 == Vect_open_new(&Out, Vect_get_name(Map), Vect_is_3d(Map))) {
79 G_warning(_("Unable to create vector map <%s>"),
81 return 1;
82 }
83
84 /* copy metadata */
85 Vect_hist_copy(Map, &Out);
87 /* copy dblinks (temporary map -> output map) to transfer
88 (input map -> output map) attributes */
90 /* afterwards, dblinks must be removed from temporary map
91 otherwise when deleting temporary map also original
92 attribute tables would be deleted */
93 Vect_map_del_dblink(Map, -1); /* delete db links for all layers */
94
96 Map, 1, &Out)) { /* always layer = 1 for OGR/PG maps */
97 G_warning(_("Copying features failed"));
98 return -1;
99 }
100
101 Vect_build(&Out);
102
103 Vect_close(&Out);
104 putenv("GRASS_VECTOR_EXTERNAL_IMMEDIATE="); /* unset variable */
105 }
106
107 /* check for external formats whether to create a link */
109 if (Map->format == GV_FORMAT_OGR || Map->format == GV_FORMAT_POSTGIS) {
110 char *def_file;
111
112 if (Map->format == GV_FORMAT_POSTGIS) {
113 if (getenv("GRASS_VECTOR_PGFILE"))
114 def_file = getenv("GRASS_VECTOR_PGFILE");
115 else
116 def_file = "PG";
117 }
118 else {
119 def_file = "OGR";
120 }
121 if (G_find_file2("", def_file, G_mapset())) {
122 FILE *fp;
123 const char *p;
124
125 struct Key_Value *key_val;
126
127 fp = G_fopen_old("", def_file, G_mapset());
128 if (!fp) {
129 G_warning(_("Unable to open %s file"), def_file);
130 }
131 else {
133 fclose(fp);
134
135 /* create a vector link in the current mapset ? */
136 p = G_find_key_value("link", key_val);
137 if (p && G_strcasecmp(p, "no") == 0) {
139 }
140 else {
141 p = G_find_key_value("link_name", key_val);
142 if (p) {
143 /* use different name for a link */
144 G_free(Map->name);
145 Map->name = G_store(p);
146 }
147 }
148 }
149 }
150 }
151
152 /* store support files for vector maps in the current mapset if in
153 write mode on level 2 */
154 if (strcmp(Map->mapset, G_mapset()) == 0 && Map->support_updated &&
155 Map->plus.built == GV_BUILD_ALL && create_link) {
156
157 unlink_file(Map, GV_TOPO_ELEMENT); /* topo */
158
159 unlink_file(Map, GV_SIDX_ELEMENT); /* sidx */
160
161 unlink_file(Map, GV_CIDX_ELEMENT); /* cidx */
162
163 if (Map->format == GV_FORMAT_OGR || Map->format == GV_FORMAT_POSTGIS) {
164 unlink_file(Map, GV_FIDX_ELEMENT); /* fidx */
165 }
166
168 Map->plus.coor_size = CInfo.size;
169 Map->plus.coor_mtime = CInfo.mtime;
170
171 /* write out topo file */
173
174 /* write out sidx file */
175 Map->plus.Spidx_new = TRUE; /* force writing */
177
178 /* write out cidx file */
180
181 /* write out fidx file */
182 if (Map->format == GV_FORMAT_OGR)
184 else if (Map->format == GV_FORMAT_POSTGIS)
186 }
187
188 /* spatial index must also be closed when opened with topo but not
189 * modified */
190 if (Map->plus.spidx_fp.file && Map->plus.Spidx_built == TRUE &&
191 !Map->support_updated && Map->plus.built == GV_BUILD_ALL) {
192
193 G_debug(1, "spatial index file closed");
194 fclose(Map->plus.spidx_fp.file);
195 }
196
197 /* release memory if required */
198 if (Map->level > 1 && Map->plus.release_support) {
199 G_debug(1, "free topology, spatial index, and category index");
200 dig_free_plus(&(Map->plus));
201 }
202
203 G_debug(1, "close history file");
204 if (Map->hist_fp)
205 fclose(Map->hist_fp);
206
207 /* close level 1 files / data sources if not head_only */
208 if (!Map->head_only) {
209 if (create_link && ((*Close_array[Map->format][1])(Map)) != 0) {
210 const char *mname = Vect_get_full_name(Map);
211 G_warning(_("Unable to close vector <%s>"), mname);
212 G_free((void *)mname);
213 return 1;
214 }
215 }
216
217 G_free(Map->name);
218 G_free(Map->mapset);
219 G_free(Map->location);
220 G_free(Map->gisdbase);
221
222 Map->open = VECT_CLOSED_CODE;
223
224 return 0;
225}
226
227/*!
228 \brief Save format definition file for vector map
229
230 \param Map pointer to Map_info structure
231
232 \return 1 on success
233 \return 0 on error
234 */
236{
237 FILE *fd;
238 char buf[GPATH_MAX];
239
240 if (Map->format != GV_FORMAT_OGR && Map->format != GV_FORMAT_POSTGIS) {
241 G_warning(_("Invalid request for writing frmt file - map format is %d"),
242 Map->format);
243 return 0;
244 }
245
246 /* create frmt file */
247 snprintf(buf, sizeof(buf), "%s/%s", GV_DIRECTORY, Map->name);
248 fd = G_fopen_new(buf, GV_FRMT_ELEMENT);
249 if (fd == NULL) {
250 G_fatal_error("Unable to create file '%s'", buf);
251 }
252
253 if (Map->format == GV_FORMAT_POSTGIS) {
254#ifdef HAVE_POSTGRES
255 fprintf(fd, "format: postgis\n");
256 fprintf(fd, "conninfo: %s\n", Map->fInfo.pg.conninfo);
257 fprintf(fd, "schema: %s\n", Map->fInfo.pg.schema_name);
258 fprintf(fd, "table: %s\n", Map->fInfo.pg.table_name);
259#else
260 G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
261 return 0;
262#endif
263 }
264 else if (Map->format == GV_FORMAT_OGR) {
265 fprintf(fd, "format: ogr\n");
266 fprintf(fd, "dsn: %s\n", Map->fInfo.ogr.dsn);
267 fprintf(fd, "layer: %s\n", Map->fInfo.ogr.layer_name);
268 }
269
270 G_verbose_message(_("Link to vector map <%s> created"), Map->name);
271
272 /* close frmt file */
273 fclose(fd);
274
275 return 1;
276}
277
278/*! Free memory of line cache
279
280 \param cache pointer to lines cache to be freed
281 */
283{
284 int i;
285
286 /* destroy lines in cache */
287 for (i = 0; i < cache->lines_alloc; i++) {
289 }
290 G_free(cache->lines);
291 G_free(cache->lines_types);
292 G_free(cache->lines_cats);
293
294 G_zero(cache, sizeof(struct Format_info_cache));
295}
296
297/*! Free memory of offset array
298
299 \param offset pointer to offset array to be freed
300 */
302{
303 G_free(offset->array);
304 G_zero(offset, sizeof(struct Format_info_offset));
305}
306
307void unlink_file(struct Map_info *Map, const char *name)
308{
309 char path[GPATH_MAX];
310
311 /* delete old support files if available */
313 if (access(path, F_OK) == 0) { /* file exists? */
314 G_debug(2, "\t%s: unlink", path);
315 unlink(path);
316 }
317}
#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:21
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
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 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:250
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
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 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_debug(int, const char *,...) __attribute__((format(printf
const char * G_mapset(void)
Get current mapset name.
Definition gis/mapset.c:31
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
Definition line.c:75
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:153
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:114
int V1_close_nat(struct Map_info *)
Close vector map.
Definition close_nat.c:32
int Vect_save_topo(struct Map_info *)
Save topology file for vector map.
Definition build.c:1007
int Vect_save_sidx(struct Map_info *)
Save spatial index file for vector map.
Definition build.c:1261
int Vect_copy_head_data(struct Map_info *, struct Map_info *)
Copy header data from one to another map.
Definition init_head.c:75
int Vect_hist_copy(struct Map_info *, struct Map_info *)
Copy history from one map to another.
Definition hist.c:129
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:198
int Vect_build(struct Map_info *)
Build topology for vector map.
Definition build.c:577
int V1_close_ogr(struct Map_info *)
Close vector map (OGR dsn & layer) on level 1.
Definition close_ogr.c:31
int V1_close_pg(struct Map_info *)
Close vector map (PostGIS layer) on level 1.
Definition close_pg.c:37
int V2_close_ogr(struct Map_info *)
Close vector map on topological level (write out fidx file)
Definition close_ogr.c:81
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:196
#define TRUE
Definition gis.h:75
#define FALSE
Definition gis.h:79
#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
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)