GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
build_ogr.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/build_ogr.c
3 
4  \brief Vector library - Building topology for OGR
5 
6  Higher level functions for reading/writing/manipulating vectors.
7 
8  Category: FID, not all layer have FID, OGRNullFID is defined
9  (5/2004) as -1, so FID should be only >= 0
10 
11  (C) 2001-2010, 2012 by the GRASS Development Team
12 
13  This program is free software under the GNU General Public License
14  (>=v2). Read the file COPYING that comes with GRASS for details.
15 
16  \author Radim Blazek, Piero Cavalieri
17  \author Various updates for GRASS 7 by Martin Landa <landa.martin gmail.com>
18 */
19 
20 #include <string.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <grass/vector.h>
24 #include <grass/glocale.h>
25 
26 #ifdef HAVE_OGR
27 #include <ogr_api.h>
28 #include <cpl_error.h>
29 #endif
30 
31 #include "local_proto.h"
32 
33 /*!
34  \brief Build pseudo-topology (simple features) for OGR layer
35 
36  Build levels:
37  - GV_BUILD_NONE
38  - GV_BUILD_BASE
39  - GV_BUILD_ATTACH_ISLES
40  - GV_BUILD_CENTROIDS
41  - GV_BUILD_ALL
42 
43  \param Map pointer to Map_info structure
44  \param build build level
45 
46  \return 1 on success
47  \return 0 on error
48  */
49 int Vect_build_ogr(struct Map_info *Map, int build)
50 {
51 #ifdef HAVE_OGR
52  struct Plus_head *plus;
53  struct Format_info_ogr *ogr_info;
54 
55  plus = &(Map->plus);
56  ogr_info = &(Map->fInfo.ogr);
57 
58  G_debug(1, "Vect_build_ogr(): dsn='%s' layer='%s', build=%d",
59  ogr_info->dsn, ogr_info->layer_name, build);
60 
61  if (build == plus->built)
62  return 1; /* do nothing */
63 
64  /* TODO move this init to better place (Vect_open_ ?), because in
65  theory build may be reused on level2 */
66  if (build >= plus->built && build > GV_BUILD_BASE) {
67  G_free((void *) ogr_info->offset.array);
68  G_zero(&(ogr_info->offset), sizeof(struct Format_info_offset));
69  }
70 
71  if (!ogr_info->layer) {
72  G_warning(_("Empty OGR layer, nothing to build"));
73  return 0;
74  }
75 
76  if (OGR_L_TestCapability(ogr_info->layer, OLCTransactions)) {
77  CPLPushErrorHandler(CPLQuietErrorHandler);
78  if (OGR_L_CommitTransaction(ogr_info->layer) != OGRERR_NONE)
79  G_debug(1, "Unable to commit transaction");
80  CPLPushErrorHandler(CPLDefaultErrorHandler);
81  }
82 
83  /* test layer capabilities */
84  if (!OGR_L_TestCapability(ogr_info->layer, OLCRandomRead)) {
85  if (strcmp(OGR_Dr_GetName(OGR_DS_GetDriver(Map->fInfo.ogr.ds)),
86  "PostgreSQL") == 0)
87  G_warning(_("Feature table <%s> has no primary key defined"),
88  ogr_info->layer_name);
89  G_warning(_("Random read is not supported by OGR for this layer. "
90  "Unable to build topology."));
91  return 0;
92  }
93 
94  if (build > GV_BUILD_NONE)
95  G_message(_("Using external data format '%s' (feature type '%s')"),
98 
99  return Vect__build_sfa(Map, build);
100 #else
101  G_fatal_error(_("GRASS is not compiled with OGR support"));
102  return 0;
103 #endif
104 }
105 
106 /*!
107  \brief Save feature index file for vector map
108 
109  \param Map pointer to Map_info structure
110  \param offset pointer to Format_info_offset struct
111  (see Format_info_ogr and Format_info_pg struct for implementation issues)
112 
113  \return 1 on success
114  \return 0 on error
115  */
116 int Vect_save_fidx(struct Map_info *Map,
117  struct Format_info_offset *offset)
118 {
119 #ifdef HAVE_OGR
120  char fname[GPATH_MAX], elem[GPATH_MAX];
121  char buf[5];
122  long length;
123  struct gvfile fp;
124  struct Port_info port;
125 
126  if (strcmp(Map->mapset, G_mapset()) != 0 ||
127  Map->support_updated == FALSE ||
128  Map->plus.built != GV_BUILD_ALL)
129  return 1;
130 
131  length = 9;
132 
133  sprintf(elem, "%s/%s", GV_DIRECTORY, Map->name);
135  G_debug(4, "Open fidx: %s", fname);
136  dig_file_init(&fp);
137  fp.file = fopen(fname, "w");
138  if (fp.file == NULL) {
139  G_warning(_("Unable to open fidx file for write <%s>"), fname);
140  return 0;
141  }
142 
144  dig_set_cur_port(&port);
145 
146  /* Header */
147  /* bytes 1 - 5 */
148  buf[0] = 5;
149  buf[1] = 0;
150  buf[2] = 5;
151  buf[3] = 0;
152  buf[4] = (char)dig__byte_order_out();
153  if (0 >= dig__fwrite_port_C(buf, 5, &fp))
154  return 0;
155 
156  /* bytes 6 - 9 : header size */
157  if (0 >= dig__fwrite_port_L(&length, 1, &fp))
158  return 0;
159 
160  /* Body */
161  /* number of records */
162  if (0 >= dig__fwrite_port_I(&(offset->array_num), 1, &fp))
163  return 0;
164 
165  /* offsets */
166  if (0 >= dig__fwrite_port_I(offset->array,
167  offset->array_num, &fp))
168  return 0;
169 
170  G_debug(3, "Vect_save_fidx(): offset_num = %d", offset->array_num);
171 
172  fclose(fp.file);
173 
174  return 1;
175 #else
176  G_fatal_error(_("GRASS is not compiled with OGR support"));
177  return 0;
178 #endif
179 }
int * array
Offset list.
Definition: dig_structs.h:446
char * name
Map name (for 4.0)
Definition: dig_structs.h:1332
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int built
Highest level of topology currently available.
Definition: dig_structs.h:873
char * Vect__get_element_path(char *file_path, const struct Map_info *Map, const char *element)
Get map element full path (internal use only)
void dig_init_portable(struct Port_info *, int)
Set Port_info structure to byte order of file.
Definition: portable.c:905
#define GV_DIRECTORY
Name of vector directory.
Definition: dig_defines.h:8
int dig__fwrite_port_I(const int *, size_t, struct gvfile *)
Write integers to the Portable Vector Format.
Definition: portable.c:758
OGRDataSourceH ds
Pointer to OGRDataSource.
Definition: dig_structs.h:542
int dig__fwrite_port_C(const char *, size_t, struct gvfile *)
Write chars to the Portable Vector Format.
Definition: portable.c:890
struct Format_info_offset offset
Offset list used for building pseudo-topology.
Definition: dig_structs.h:589
#define GV_BUILD_BASE
Topology levels - basic level (without areas and isles)
Definition: dig_defines.h:125
int Vect_build_ogr(struct Map_info *Map, int build)
Build pseudo-topology (simple features) for OGR layer.
Definition: build_ogr.c:49
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
char * dsn
OGR datasource name.
Definition: dig_structs.h:525
struct Format_info fInfo
Format info for non-native formats.
Definition: dig_structs.h:1415
#define NULL
Definition: ccmath.h:32
#define GV_BUILD_NONE
Topology levels - nothing to build.
Definition: dig_defines.h:123
void G_message(const char *,...) __attribute__((format(printf
Basic topology-related info.
Definition: dig_structs.h:784
Data structure used for building pseudo-topology.
Definition: dig_structs.h:397
#define FALSE
Definition: gis.h:63
int Vect_save_fidx(struct Map_info *Map, struct Format_info_offset *offset)
Save feature index file for vector map.
Definition: build_ogr.c:116
struct Plus_head plus
Plus info (topology, version, ...)
Definition: dig_structs.h:1286
Non-native format info (OGR)
Definition: dig_structs.h:516
void dig_file_init(struct gvfile *file)
Initialize gvfile strcuture.
Definition: file.c:170
struct Format_info_ogr ogr
OGR info.
Definition: dig_structs.h:722
#define GPATH_MAX
Definition: gis.h:180
int Vect__build_sfa(struct Map_info *, int)
Build pseudo-topology (for simple features) - internal use only.
Definition: build_sfa.c:694
char * mapset
Mapset name.
Definition: dig_structs.h:1336
int array_num
Number of items in offset list.
Definition: dig_structs.h:450
int support_updated
Support files were updated.
Definition: dig_structs.h:1327
Vector map info.
Definition: dig_structs.h:1259
char * layer_name
OGR layer name.
Definition: dig_structs.h:529
FILE * file
File descriptor.
Definition: dig_structs.h:101
int dig__byte_order_out()
Get byte order.
Definition: portable.c:1013
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:23
void G_warning(const char *,...) __attribute__((format(printf
const char * Vect_get_finfo_geometry_type(const struct Map_info *)
Get geometry type as string (relevant only for non-native formats)
Definition: header_finfo.c:144
Portability info.
Definition: dig_structs.h:186
#define _(str)
Definition: glocale.h:10
const char * Vect_get_finfo_format_info(const struct Map_info *)
Get format info as string (relevant only for non-native formats)
Definition: header_finfo.c:108
#define GV_BUILD_ALL
Topology levels - build everything (currently same as GV_BUILD_CENTROIDS)
Definition: dig_defines.h:133
int dig_set_cur_port(struct Port_info *)
Set current Port_info structure.
Definition: portable.c:1001
int dig__fwrite_port_L(const long *, size_t, struct gvfile *)
Write longs to the Portable Vector Format.
Definition: portable.c:702
OGRLayerH layer
Pointer to OGRLayer.
Definition: dig_structs.h:546
#define GV_FIDX_ELEMENT
External format (OGR), feature index.
Definition: dig_defines.h:26
File definition.
Definition: dig_structs.h:96
int G_debug(int, const char *,...) __attribute__((format(printf