~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to lib/vector/Vlib/open_ogr.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*!
2
 
   \file open_ogr.c
 
2
   \file lib/vector/Vlib/open_ogr.c
3
3
 
4
 
   \brief Vector library - open vector map (OGR format)
 
4
   \brief Vector library - Open OGR layer as vector map layer
5
5
 
6
6
   Higher level functions for reading/writing/manipulating vectors.
7
7
 
8
 
   (C) 2001-2008 by the GRASS Development Team
 
8
   (C) 2001-2010 by the GRASS Development Team
9
9
 
10
 
   This program is free software under the 
11
 
   GNU General Public License (>=v2). 
12
 
   Read the file COPYING that comes with GRASS
13
 
   for details.
 
10
   This program is free software under the GNU General Public License
 
11
   (>=v2). Read the file COPYING that comes with GRASS for details.
14
12
 
15
13
   \author Original author CERL, probably Dave Gerdes or Mike Higgins.
16
 
   Update to GRASS 5.7 Radim Blazek and David D. Gray.
17
 
 
18
 
   \date 2001
 
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)
19
16
 */
20
17
 
21
18
#include <unistd.h>
23
20
#include <sys/types.h>
24
21
#include <sys/stat.h>
25
22
 
26
 
#include <grass/Vect.h>
27
 
#include <grass/gis.h>
 
23
#include <grass/vector.h>
 
24
#include <grass/dbmi.h>
28
25
#include <grass/glocale.h>
29
26
 
30
27
#ifdef HAVE_OGR
31
28
#include <ogr_api.h>
32
 
 
33
 
/**
34
 
   \brief Open existing vector map
35
 
 
36
 
   Map->name and Map->mapset must be set before.
37
 
 
38
 
   \param Map pointer to vector map
39
 
   \param update non-zero for write mode, otherwise read-only
40
 
   (write mode is currently not supported)
41
 
 
 
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
   
42
40
   \return 0 success
43
41
   \return -1 error
44
42
*/
45
43
int V1_open_old_ogr(struct Map_info *Map, int update)
46
44
{
 
45
#ifdef HAVE_OGR
47
46
    int i, layer, nLayers;
 
47
 
 
48
    struct Format_info_ogr *ogr_info;
 
49
    
48
50
    OGRDataSourceH Ogr_ds;
49
 
    OGRLayerH Ogr_layer = NULL;
 
51
    OGRLayerH Ogr_layer;
50
52
    OGRFeatureDefnH Ogr_featuredefn;
51
53
    OGRwkbGeometryType Ogr_geom_type;
52
54
    
53
 
    if (update) {
54
 
        G_fatal_error(_("OGR format cannot be updated"));
55
 
        return -1;
56
 
    }
 
55
    Ogr_layer = NULL;
 
56
    Ogr_geom_type = wkbUnknown;
57
57
 
58
 
    G_debug(2, "V1_open_old_ogr(): dsn = %s layer = %s", Map->fInfo.ogr.dsn,
59
 
            Map->fInfo.ogr.layer_name);
 
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);
60
71
 
61
72
    OGRRegisterAll();
62
73
 
63
 
    /*Data source handle */
64
 
    Ogr_ds = OGROpen(Map->fInfo.ogr.dsn, FALSE, NULL);
 
74
    /* open data source handle */
 
75
    Ogr_ds = OGROpen(ogr_info->dsn, FALSE, NULL);
65
76
    if (Ogr_ds == NULL)
66
77
        G_fatal_error(_("Unable to open OGR data source '%s'"),
67
 
                      Map->fInfo.ogr.dsn);
68
 
    Map->fInfo.ogr.ds = Ogr_ds;
 
78
                      ogr_info->dsn);
 
79
    ogr_info->ds = Ogr_ds;
69
80
 
70
 
    /* Layer number */
 
81
    /* get layer number */
71
82
    layer = -1;
72
83
    nLayers = OGR_DS_GetLayerCount(Ogr_ds);
73
84
    G_debug(2, "%d layers found in data source", nLayers);
74
85
 
75
86
    for (i = 0; i < nLayers; i++) {
76
 
        Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
 
87
        Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i); 
77
88
        Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
78
 
        if (strcmp(OGR_FD_GetName(Ogr_featuredefn), Map->fInfo.ogr.layer_name) == 0) {
79
 
            Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
 
89
        if (strcmp(OGR_FD_GetName(Ogr_featuredefn), ogr_info->layer_name) == 0) {
 
90
            Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
80
91
            layer = i;
81
92
            break;
82
93
        }
83
94
    }
84
95
    if (layer == -1) {
85
96
        OGR_DS_Destroy(Ogr_ds);
86
 
        G_fatal_error(_("Unable to open layer <%s>"),
87
 
                      Map->fInfo.ogr.layer_name);
 
97
        G_fatal_error(_("OGR layer <%s> not found"),
 
98
                      ogr_info->layer_name);
88
99
    }
89
100
    G_debug(2, "OGR layer %d opened", layer);
90
101
 
91
 
    Map->fInfo.ogr.layer = Ogr_layer;
92
 
 
93
 
    Map->fInfo.ogr.lines = NULL;
94
 
    Map->fInfo.ogr.lines_types = NULL;
95
 
    Map->fInfo.ogr.lines_alloc = 0;
96
 
    Map->fInfo.ogr.lines_num = 0;
97
 
    Map->fInfo.ogr.lines_next = 0;
98
 
 
 
102
    ogr_info->layer = Ogr_layer;
 
103
    if (update && OGR_L_TestCapability(ogr_info->layer, OLCTransactions))
 
104
        OGR_L_StartTransaction(ogr_info->layer);
 
105
    
99
106
    switch(Ogr_geom_type) {
100
107
    case wkbPoint25D: case wkbLineString25D: case wkbPolygon25D:
101
108
    case wkbMultiPoint25D: case wkbMultiLineString25D: case wkbMultiPolygon25D:
102
109
    case wkbGeometryCollection25D:
103
 
        Map->head.with_z = WITH_Z;
104
 
        break;
 
110
        Map->head.with_z = WITH_Z;
 
111
        break;
105
112
    default:
106
 
        Map->head.with_z = WITHOUT_Z;
107
 
        break;
 
113
        Map->head.with_z = WITHOUT_Z;
 
114
        break;
108
115
    }
109
116
    
110
 
    Map->fInfo.ogr.feature_cache = NULL;
111
 
    Map->fInfo.ogr.feature_cache_id = -1;       /* FID >= 0 */
112
 
 
113
 
    return (0);
 
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
114
124
}
115
125
 
116
 
/**
117
 
   \brief Open OGR specific level 2 files (feature index)
118
 
 
119
 
   \param Map pointer to vector map
120
 
 
 
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
   
121
134
   \return 0 success
122
135
   \return -1 error
123
136
*/
124
137
int V2_open_old_ogr(struct Map_info *Map)
125
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
*/
 
245
int Vect_open_fidx(struct Map_info *Map, struct Format_info_offset *offset)
 
246
{
126
247
    char elem[GPATH_MAX];
127
248
    char buf[5];                /* used for format version */
128
249
    long length;
129
 
    GVFILE fp;
 
250
    int Version_Major, Version_Minor, Back_Major, Back_Minor, byte_order;
 
251
    
 
252
    struct gvfile fp;
130
253
    struct Port_info port;
131
 
    int Version_Major, Version_Minor, Back_Major, Back_Minor, byte_order;
132
 
 
133
 
    G_debug(3, "V2_open_old_ogr()");
134
 
 
135
 
    sprintf(elem, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
 
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);
136
259
    dig_file_init(&fp);
137
 
    fp.file = G_fopen_old(elem, "fidx", Map->mapset);
 
260
    fp.file = G_fopen_old(elem, GV_FIDX_ELEMENT, Map->mapset);
138
261
    if (fp.file == NULL) {
139
 
        G_warning(_("Unable to open fidx file for vector map <%s@%s>"),
140
 
                  Map->name, Map->mapset);
 
262
        G_debug(1, "unable to open fidx file for vector map <%s>",
 
263
                Vect_get_full_name(Map));
141
264
        return -1;
142
265
    }
143
266
 
144
267
    /* Header */
145
268
    if (0 >= dig__fread_port_C(buf, 5, &fp))
146
 
        return (-1);
 
269
        return -1;
147
270
    Version_Major = buf[0];
148
271
    Version_Minor = buf[1];
149
 
    Back_Major = buf[2];
150
 
    Back_Minor = buf[3];
151
 
    byte_order = buf[4];
152
 
 
153
 
 
 
272
    Back_Major    = buf[2];
 
273
    Back_Minor    = buf[3];
 
274
    byte_order    = buf[4];
 
275
    
154
276
    /* check version numbers */
155
277
    if (Version_Major > 5 || Version_Minor > 0) {
156
278
        if (Back_Major > 5 || Back_Minor > 0) {
157
279
            G_fatal_error(_("Feature index format version %d.%d is not supported by this release."
158
280
                           " Try to rebuild topology or upgrade GRASS."),
159
281
                          Version_Major, Version_Minor);
160
 
            return (-1);
 
282
            return -1;
161
283
        }
162
284
        G_warning(_("Your GRASS version does not fully support feature index format %d.%d of the vector."
163
285
                   " Consider to rebuild topology or upgrade GRASS."),
170
292
    /* Body */
171
293
    /* bytes 6 - 9 : header size */
172
294
    if (0 >= dig__fread_port_L(&length, 1, &fp))
173
 
        return (-1);
174
 
    G_debug(3, "  header size %ld", length);
 
295
        return -1;
 
296
    G_debug(4, "  header size %ld", length);
175
297
 
176
 
    fseek(fp.file, length, SEEK_SET);
 
298
    G_fseek(fp.file, length, SEEK_SET);
177
299
 
178
300
    /* number of records  */
179
 
    if (0 >= dig__fread_port_I(&(Map->fInfo.ogr.offset_num), 1, &fp))
180
 
        return (-1);
181
 
 
 
301
    if (0 >= dig__fread_port_I(&(offset->array_num), 1, &fp))
 
302
        return -1;
 
303
    
182
304
    /* alloc space */
183
 
    Map->fInfo.ogr.offset =
184
 
        (int *)G_malloc(Map->fInfo.ogr.offset_num * sizeof(int));
185
 
    Map->fInfo.ogr.offset_alloc = Map->fInfo.ogr.offset_num;
186
 
 
 
305
    offset->array = (int *) G_malloc(offset->array_num * sizeof(int));
 
306
    offset->array_alloc = offset->array_num;
 
307
    
187
308
    /* offsets */
188
 
    if (0 >= dig__fread_port_I(Map->fInfo.ogr.offset,
189
 
                               Map->fInfo.ogr.offset_num, &fp))
190
 
        return (-1);
 
309
    if (0 >= dig__fread_port_I(offset->array,
 
310
                               offset->array_num, &fp))
 
311
        return -1;
191
312
 
192
313
    fclose(fp.file);
193
314
 
194
 
    G_debug(3, "%d records read from fidx", Map->fInfo.ogr.offset_num);
195
 
 
196
 
 
197
 
    Map->fInfo.ogr.next_line = 1;
 
315
    G_debug(3, "%d records read from fidx", offset->array_num);
198
316
 
199
317
    return 0;
200
318
}
201
 
 
202
 
#endif