GRASS GIS 7 Programmer's Manual  7.5.svn(2017)-r71924
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
open_ogr.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/open_ogr.c
3 
4  \brief Vector library - Open OGR layer as vector map layer
5 
6  Higher level functions for reading/writing/manipulating vectors.
7 
8  (C) 2001-2010 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.0 Martin Landa <landa.martin gmail.com> (2009)
16  */
17 
18 #include <unistd.h>
19 #include <string.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 
23 #include <grass/vector.h>
24 #include <grass/dbmi.h>
25 #include <grass/glocale.h>
26 
27 #ifdef HAVE_OGR
28 #include <ogr_api.h>
29 #endif
30 
31 /*!
32  \brief Open existing OGR layer on non-topological level
33 
34  Note: Map->name, Map->mapset, Map->fInfo.ogr.dsn and
35  Map->fInfo.ogr.layer_name must be set before.
36 
37  \param[in,out] Map pointer to Map_info structure
38  \param update TRUE for write mode, otherwise read-only
39 
40  \return 0 success
41  \return -1 error
42 */
43 int V1_open_old_ogr(struct Map_info *Map, int update)
44 {
45 #ifdef HAVE_OGR
46  int i, layer, nLayers;
47 
48  struct Format_info_ogr *ogr_info;
49 
50  OGRDataSourceH Ogr_ds;
51  OGRLayerH Ogr_layer;
52  OGRFeatureDefnH Ogr_featuredefn;
53  OGRwkbGeometryType Ogr_geom_type;
54 
55  Ogr_layer = NULL;
56  Ogr_geom_type = wkbUnknown;
57 
58  ogr_info = &(Map->fInfo.ogr);
59  if (!ogr_info->dsn) {
60  G_fatal_error(_("OGR datasource not defined"));
61  return -1;
62  }
63 
64  if (!ogr_info->layer_name) {
65  G_fatal_error(_("OGR layer not defined"));
66  return -1;
67  }
68 
69  G_debug(2, "V1_open_old_ogr(): dsn = %s layer = %s", ogr_info->dsn,
70  ogr_info->layer_name);
71 
72  OGRRegisterAll();
73 
74  /* open data source handle */
75  Ogr_ds = OGROpen(ogr_info->dsn, FALSE, NULL);
76  if (Ogr_ds == NULL)
77  G_fatal_error(_("Unable to open OGR data source '%s'"),
78  ogr_info->dsn);
79  ogr_info->ds = Ogr_ds;
80 
81  /* get layer number */
82  layer = -1;
83  nLayers = OGR_DS_GetLayerCount(Ogr_ds);
84  G_debug(2, "%d layers found in data source", nLayers);
85 
86  for (i = 0; i < nLayers; i++) {
87  Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
88  Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
89  if (strcmp(OGR_FD_GetName(Ogr_featuredefn), ogr_info->layer_name) == 0) {
90  Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
91  layer = i;
92  break;
93  }
94  }
95  if (layer == -1) {
96  OGR_DS_Destroy(Ogr_ds);
97  G_fatal_error(_("OGR layer <%s> not found"),
98  ogr_info->layer_name);
99  }
100  G_debug(2, "OGR layer %d opened", layer);
101 
102  ogr_info->layer = Ogr_layer;
103  if (update && OGR_L_TestCapability(ogr_info->layer, OLCTransactions))
104  OGR_L_StartTransaction(ogr_info->layer);
105 
106  switch(Ogr_geom_type) {
107  case wkbPoint25D: case wkbLineString25D: case wkbPolygon25D:
108  case wkbMultiPoint25D: case wkbMultiLineString25D: case wkbMultiPolygon25D:
109  case wkbGeometryCollection25D:
110  Map->head.with_z = WITH_Z;
111  break;
112  default:
113  Map->head.with_z = WITHOUT_Z;
114  break;
115  }
116 
117  ogr_info->cache.fid = -1; /* FID >= 0 */
118 
119  return 0;
120 #else
121  G_fatal_error(_("GRASS is not compiled with OGR support"));
122  return -1;
123 #endif
124 }
125 
126 /*!
127  \brief Open existing OGR layer on topological level
128 
129  This functions reads feature index (fidx) file required for
130  pseudo-topology.
131 
132  \param[in,out] Map pointer to Map_info structure
133 
134  \return 0 success
135  \return -1 error
136 */
137 int V2_open_old_ogr(struct Map_info *Map)
138 {
139 #ifdef HAVE_OGR
140 
141  G_debug(3, "V2_open_old_ogr(): name = %s mapset = %s", Map->name,
142  Map->mapset);
143 
144  if (Vect_open_fidx(Map, &(Map->fInfo.ogr.offset)) != 0) {
145  G_warning(_("Unable to open feature index file for vector map <%s>"),
146  Vect_get_full_name(Map));
147  G_zero(&(Map->fInfo.ogr.offset), sizeof(struct Format_info_offset));
148  }
149 
150  Map->fInfo.ogr.next_line = 1; /* reset feature cache */
151 
152  return 0;
153 #else
154  G_fatal_error(_("GRASS is not compiled with OGR support"));
155  return -1;
156 #endif
157 }
158 
159 /*!
160  \brief Prepare OGR datasource for creating new OGR layer (level 1)
161 
162  New OGR layer is created when writing features by
163  Vect_wrile_line().
164 
165  \param[out] Map pointer to Map_info structure
166  \param name name of OGR layer to create
167  \param with_z WITH_Z for 3D vector data otherwise WITHOUT_Z
168 
169  \return 0 success
170  \return -1 error
171 */
172 int V1_open_new_ogr(struct Map_info *Map, const char *name, int with_z)
173 {
174 #ifdef HAVE_OGR
175  int i, nlayers;
176 
177  struct Format_info_ogr *ogr_info;
178 
179  OGRSFDriverH Ogr_driver;
180  OGRDataSourceH Ogr_ds;
181  OGRLayerH Ogr_layer;
182  OGRFeatureDefnH Ogr_featuredefn;
183 
184  OGRRegisterAll();
185 
186  ogr_info = &(Map->fInfo.ogr);
187 
188  G_debug(1, "V1_open_new_ogr(): name = %s with_z = %d", name, with_z);
189  Ogr_driver = OGRGetDriverByName(ogr_info->driver_name);
190  if (!Ogr_driver) {
191  G_warning(_("Unable to get OGR driver <%s>"), ogr_info->driver_name);
192  return -1;
193  }
194  ogr_info->driver = Ogr_driver;
195 
196  /* TODO: creation options */
197  Ogr_ds = OGR_Dr_CreateDataSource(Ogr_driver, ogr_info->dsn, NULL);
198  if (!Ogr_ds) {
199  G_warning(_("Unable to create OGR data source '%s'"),
200  ogr_info->dsn);
201  return -1;
202  }
203  ogr_info->ds = Ogr_ds;
204 
205  nlayers = OGR_DS_GetLayerCount(Ogr_ds);
206  for (i = 0; i < nlayers; i++) {
207  Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
208  Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
209  if (strcmp(OGR_FD_GetName(Ogr_featuredefn), name) == 0) {
210  if (G_get_overwrite()) {
211  G_warning(_("OGR layer <%s> already exists and will be overwritten"),
212  ogr_info->layer_name);
213 
214  if (OGR_DS_DeleteLayer(Ogr_ds, i) != OGRERR_NONE) {
215  G_warning(_("Unable to delete OGR layer <%s>"),
216  ogr_info->layer_name);
217  return -1;
218  }
219  }
220  else {
221  G_fatal_error(_("OGR layer <%s> already exists in datasource '%s'"),
222  ogr_info->layer_name, ogr_info->dsn);
223  }
224  ogr_info->layer = NULL;
225  break;
226  }
227  }
228 
229  return 0;
230 #else
231  G_fatal_error(_("GRASS is not compiled with OGR support"));
232  return -1;
233 #endif
234 }
235 
236 /*!
237  \brief Open feature index file
238 
239  \param[in,out] Map pointer to Map_info struct
240  \param[out] offset pointer to Format_info_offset (OGR or PG)
241 
242  \return 0 on success
243  \return -1 on error
244 */
246 {
247  char elem[GPATH_MAX];
248  char buf[5]; /* used for format version */
249  long length;
250  int Version_Major, Version_Minor, Back_Major, Back_Minor, byte_order;
251 
252  struct gvfile fp;
253  struct Port_info port;
254 
255  G_debug(1, "Vect_open_fidx(): name = %s mapset = %s format = %d",
256  Map->name, Map->mapset, Map->format);
257 
258  sprintf(elem, "%s/%s", GV_DIRECTORY, Map->name);
259  dig_file_init(&fp);
260  fp.file = G_fopen_old(elem, GV_FIDX_ELEMENT, Map->mapset);
261  if (fp.file == NULL) {
262  G_debug(1, "unable to open fidx file for vector map <%s>",
263  Vect_get_full_name(Map));
264  return -1;
265  }
266 
267  /* Header */
268  if (0 >= dig__fread_port_C(buf, 5, &fp))
269  return -1;
270  Version_Major = buf[0];
271  Version_Minor = buf[1];
272  Back_Major = buf[2];
273  Back_Minor = buf[3];
274  byte_order = buf[4];
275 
276  /* check version numbers */
277  if (Version_Major > 5 || Version_Minor > 0) {
278  if (Back_Major > 5 || Back_Minor > 0) {
279  G_fatal_error(_("Feature index format version %d.%d is not supported by this release."
280  " Try to rebuild topology or upgrade GRASS."),
281  Version_Major, Version_Minor);
282  return -1;
283  }
284  G_warning(_("Your GRASS version does not fully support feature index format %d.%d of the vector."
285  " Consider to rebuild topology or upgrade GRASS."),
286  Version_Major, Version_Minor);
287  }
288 
289  dig_init_portable(&port, byte_order);
290  dig_set_cur_port(&port);
291 
292  /* Body */
293  /* bytes 6 - 9 : header size */
294  if (0 >= dig__fread_port_L(&length, 1, &fp))
295  return -1;
296  G_debug(4, " header size %ld", length);
297 
298  G_fseek(fp.file, length, SEEK_SET);
299 
300  /* number of records */
301  if (0 >= dig__fread_port_I(&(offset->array_num), 1, &fp))
302  return -1;
303 
304  /* alloc space */
305  offset->array = (int *) G_malloc(offset->array_num * sizeof(int));
306  offset->array_alloc = offset->array_num;
307 
308  /* offsets */
309  if (0 >= dig__fread_port_I(offset->array,
310  offset->array_num, &fp))
311  return -1;
312 
313  fclose(fp.file);
314 
315  G_debug(3, "%d records read from fidx", offset->array_num);
316 
317  return 0;
318 }
int * array
Offset list.
Definition: dig_structs.h:446
int Vect_open_fidx(struct Map_info *Map, struct Format_info_offset *offset)
Open feature index file.
Definition: open_ogr.c:245
char * name
Map name (for 4.0)
Definition: dig_structs.h:1332
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
OGRSFDriverH driver
Pointer to OGRDriver.
Definition: dig_structs.h:538
OGRDataSourceH ds
Pointer to OGRDataSource.
Definition: dig_structs.h:542
int dig__fread_port_I(int *, size_t, struct gvfile *)
Read integers from the Portable Vector Format.
Definition: portable.c:343
int dig__fread_port_C(char *, size_t, struct gvfile *)
Read chars from the Portable Vector Format.
Definition: portable.c:509
struct Format_info_cache cache
Lines cache for reading feature.
Definition: dig_structs.h:573
struct Format_info_offset offset
Offset list used for building pseudo-topology.
Definition: dig_structs.h:589
long fid
Feature id.
Definition: dig_structs.h:497
const char * Vect_get_full_name(const struct Map_info *Map)
Get fully qualified name of vector map.
char * dsn
OGR datasource name.
Definition: dig_structs.h:525
int dig__fread_port_L(long *, size_t, struct gvfile *)
Read longs from the Portable Vector Format.
Definition: portable.c:260
struct Format_info fInfo
Format info for non-native formats.
Definition: dig_structs.h:1415
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 G_get_overwrite()
Get overwrite value.
Definition: parser.c:914
#define NULL
Definition: ccmath.h:32
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:159
int with_z
2D/3D vector data
Definition: dig_structs.h:347
Data structure used for building pseudo-topology.
Definition: dig_structs.h:397
#define FALSE
Definition: gis.h:53
int next_line
Next line to be read.
Definition: dig_structs.h:596
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
int V2_open_old_ogr(struct Map_info *Map)
Open existing OGR layer on topological level.
Definition: open_ogr.c:137
fclose(fd)
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:151
char * mapset
Mapset name.
Definition: dig_structs.h:1336
#define WITH_Z
Definition: dig_defines.h:171
#define WITHOUT_Z
2D/3D vector data
Definition: dig_defines.h:170
struct dig_head head
Header info.
Definition: dig_structs.h:1403
int array_num
Number of items in offset list.
Definition: dig_structs.h:450
int array_alloc
Space allocated for offset list.
Definition: dig_structs.h:454
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
void G_fseek(FILE *fp, off_t offset, int whence)
Change the file position of the stream.
Definition: gis/seek.c:48
char * driver_name
OGR driver name.
Definition: dig_structs.h:521
Portability info.
Definition: dig_structs.h:186
#define _(str)
Definition: glocale.h:13
int format
Map format (native, ogr, postgis)
Definition: dig_structs.h:1271
int dig_set_cur_port(struct Port_info *)
Set current Port_info structure.
Definition: portable.c:1001
OGRLayerH layer
Pointer to OGRLayer.
Definition: dig_structs.h:546
#define GV_FIDX_ELEMENT
External format (OGR), feature index.
Definition: dig_defines.h:26
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:23
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition: gis/open.c:253
const char * name
Definition: named_colr.c:7
File definition.
Definition: dig_structs.h:96
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
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:203