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

« back to all changes in this revision

Viewing changes to lib/vector/Vlib/read_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 read_ogr.c
 
2
   \file lib/vector/Vlib/read_ogr.c
3
3
 
4
4
   \brief Vector library - reading data (OGR format)
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-2011 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 Radim Blazek, Piero Cavalieri
16
 
 
17
 
   \date 2001
 
14
   \author Martin Landa <landa.martin gmail.com>
18
15
 */
19
16
 
20
 
#include <grass/gis.h>
21
 
#include <grass/Vect.h>
 
17
#include <grass/vector.h>
22
18
#include <grass/glocale.h>
23
19
 
24
20
#ifdef HAVE_OGR
25
21
#include <ogr_api.h>
26
22
 
27
 
/*!
28
 
 * \brief Recursively read feature and add all elements to points_cache and types_cache.
29
 
 *
30
 
 * ftype : if > 0 use this type (because parts of Polygon are read as wkbLineString)
31
 
 *
32
 
 * \param Map vector map layer
33
 
 * \param hGeom OGR geometry
34
 
 * \param ftype feature type
35
 
 * 
36
 
 * \return 0 OK
37
 
 * \return 1 error
38
 
 */
39
 
static int cache_feature(struct Map_info *Map, OGRGeometryH hGeom, int ftype)
 
23
static int cache_feature(struct Map_info *, OGRGeometryH, int);
 
24
static int read_line(const struct Map_info *, OGRGeometryH, long,
 
25
                     struct line_pnts *);
 
26
static int get_line_type(const struct Map_info *, long);
 
27
static int read_next_line_ogr(struct Map_info *, struct line_pnts *,
 
28
                              struct line_cats *, int);
 
29
#endif
 
30
 
 
31
/*!
 
32
  \brief Read next feature from OGR layer.
 
33
  Skip empty features (level 1 without topology).
 
34
  
 
35
  This function implements sequential access.
 
36
  
 
37
  The action of this routine can be modified by:
 
38
   - Vect_read_constraint_region()
 
39
   - Vect_read_constraint_type()
 
40
   - Vect_remove_constraints()
 
41
  
 
42
  \param Map pointer to Map_info structure
 
43
  \param[out] line_p container used to store line points within
 
44
  \param[out] line_c container used to store line categories within
 
45
  
 
46
  \return feature type
 
47
  \return -2 no more features (EOF)
 
48
  \return -1 out of memory
 
49
*/
 
50
int V1_read_next_line_ogr(struct Map_info *Map, struct line_pnts *line_p,
 
51
                          struct line_cats *line_c)
 
52
{
 
53
#ifdef HAVE_OGR
 
54
    return read_next_line_ogr(Map, line_p, line_c, FALSE);
 
55
#else
 
56
    G_fatal_error(_("GRASS is not compiled with OGR support"));
 
57
    return -1;
 
58
#endif
 
59
}
 
60
 
 
61
/*!
 
62
  \brief Read next feature from OGR layer on topological level.
 
63
 
 
64
  This function implements sequential access.
 
65
 
 
66
  \param Map pointer to Map_info structure
 
67
  \param[out] line_p container used to store line points within
 
68
  (pointer to line_pnts struct)
 
69
  \param[out] line_c container used to store line categories within
 
70
  (pointer to line_cats struct)
 
71
  
 
72
  \return feature type
 
73
  \return -2 no more features (EOF)
 
74
  \return -1 on failure
 
75
*/
 
76
int V2_read_next_line_ogr(struct Map_info *Map, struct line_pnts *line_p,
 
77
                          struct line_cats *line_c)
 
78
{
 
79
#ifdef HAVE_OGR
 
80
    int line, ret;
 
81
    struct P_line *Line;
 
82
    struct bound_box lbox, mbox;
 
83
 
 
84
    G_debug(3, "V2_read_next_line_ogr()");
 
85
    
 
86
    if (Map->constraint.region_flag)
 
87
        Vect_get_constraint_box(Map, &mbox);
 
88
    
 
89
    while(TRUE) {
 
90
        line = Map->next_line;
 
91
        
 
92
        if (Map->next_line > Map->plus.n_lines)
 
93
            return -2; /* nothing to read */
 
94
        
 
95
        Map->next_line++;
 
96
        Line = Map->plus.Line[line];
 
97
        if (Line == NULL) {     /* skip dead features */
 
98
            continue;
 
99
        }
 
100
 
 
101
        if (Map->constraint.type_flag) {
 
102
            /* skip feature by type */
 
103
            if (!(Line->type & Map->constraint.type))
 
104
                continue;
 
105
        }
 
106
 
 
107
        if (Line->type == GV_CENTROID) {
 
108
            G_debug(4, "Centroid");
 
109
            
 
110
            if (line_p != NULL) {
 
111
                int i, found;
 
112
                struct bound_box box;
 
113
                struct boxlist list;
 
114
                struct P_topo_c *topo = (struct P_topo_c *)Line->topo;
 
115
                
 
116
                /* get area bbox */
 
117
                Vect_get_area_box(Map, topo->area, &box);
 
118
                /* search in spatial index for centroid with area bbox */
 
119
                dig_init_boxlist(&list, TRUE);
 
120
                Vect_select_lines_by_box(Map, &box, Line->type, &list);
 
121
                
 
122
                found = 0;
 
123
                for (i = 0; i < list.n_values; i++) {
 
124
                    if (list.id[i] == line) {
 
125
                        found = i;
 
126
                        break;
 
127
                    }
 
128
                }
 
129
                
 
130
                Vect_reset_line(line_p);
 
131
                Vect_append_point(line_p, list.box[found].E, list.box[found].N, 0.0);
 
132
            }
 
133
            if (line_c != NULL) {
 
134
                /* cat = FID and offset = FID for centroid */
 
135
                Vect_reset_cats(line_c);
 
136
                Vect_cat_set(line_c, 1, (int) Line->offset);
 
137
            }
 
138
 
 
139
            ret = GV_CENTROID;
 
140
        }
 
141
        else {
 
142
            ret = read_next_line_ogr(Map, line_p, line_c, TRUE);
 
143
        }
 
144
 
 
145
        if (line_p && Map->constraint.region_flag) {
 
146
            /* skip feature by region */
 
147
            Vect_line_box(line_p, &lbox);
 
148
            if (!Vect_box_overlap(&lbox, &mbox))
 
149
                continue;
 
150
        }
 
151
        
 
152
        /* skip feature by field ignored */
 
153
                
 
154
        return ret;
 
155
    }
 
156
#else
 
157
    G_fatal_error(_("GRASS is not compiled with OGR support"));
 
158
    return -1;
 
159
#endif
 
160
}
 
161
 
 
162
/*!
 
163
  \brief Read feature from OGR layer at given offset (level 1 without topology)
 
164
  
 
165
  This function implements random access on level 1.
 
166
 
 
167
  \param Map pointer to Map_info structure 
 
168
  \param[out] line_p container used to store line points within
 
169
  (pointer line_pnts struct)
 
170
  \param[out] line_c container used to store line categories within
 
171
  (pointer line_cats struct)
 
172
  \param offset given offset 
 
173
  
 
174
  \return line type
 
175
  \return 0 dead line
 
176
  \return -2 no more features
 
177
  \return -1 on failure
 
178
*/
 
179
int V1_read_line_ogr(struct Map_info *Map,
 
180
                     struct line_pnts *line_p, struct line_cats *line_c, off_t offset)
 
181
{
 
182
#ifdef HAVE_OGR
 
183
    long fid;
 
184
    int type;
 
185
    OGRGeometryH hGeom;
 
186
 
 
187
    struct Format_info_ogr *ogr_info;
 
188
    
 
189
    ogr_info = &(Map->fInfo.ogr);
 
190
    G_debug(3, "V1_read_line_ogr(): offset = %lu offset_num = %lu",
 
191
            (long) offset, (long) ogr_info->offset.array_num);
 
192
 
 
193
    if (offset >= ogr_info->offset.array_num)
 
194
        return -2; /* nothing to read */
 
195
    
 
196
    if (line_p != NULL)
 
197
        Vect_reset_line(line_p);
 
198
    if (line_c != NULL)
 
199
        Vect_reset_cats(line_c);
 
200
 
 
201
    fid = ogr_info->offset.array[offset];
 
202
    G_debug(4, "  fid = %ld", fid);
 
203
    
 
204
    /* coordinates */
 
205
    if (line_p != NULL) {
 
206
        /* read feature to cache if necessary */
 
207
        if (ogr_info->cache.fid != fid) {
 
208
            G_debug(4, "Read feature (fid = %ld) to cache", fid);
 
209
            if (ogr_info->feature_cache) {
 
210
                OGR_F_Destroy(ogr_info->feature_cache);
 
211
            }
 
212
            ogr_info->feature_cache =
 
213
                OGR_L_GetFeature(ogr_info->layer, fid);
 
214
            if (ogr_info->feature_cache == NULL) {
 
215
                G_warning(_("Unable to get feature geometry, fid %ld"),
 
216
                          fid);
 
217
                return -1;
 
218
            }
 
219
            ogr_info->cache.fid = fid;
 
220
        }
 
221
        
 
222
        hGeom = OGR_F_GetGeometryRef(ogr_info->feature_cache);
 
223
        if (hGeom == NULL) {
 
224
            G_warning(_("Unable to get feature geometry, fid %ld"),
 
225
                      fid);
 
226
            return -1;
 
227
        }
 
228
        
 
229
        type = read_line(Map, hGeom, offset + 1, line_p);
 
230
    }
 
231
    else {
 
232
        type = get_line_type(Map, fid);
 
233
    }
 
234
 
 
235
    /* category */
 
236
    if (line_c != NULL) {
 
237
        Vect_cat_set(line_c, 1, (int) fid);
 
238
    }
 
239
 
 
240
    return type;
 
241
#else
 
242
    G_fatal_error(_("GRASS is not compiled with OGR support"));
 
243
    return -1;
 
244
#endif
 
245
}
 
246
 
 
247
#ifdef HAVE_OGR
 
248
/*!
 
249
  \brief Recursively read feature and add all elements to points_cache and types_cache.
 
250
  
 
251
  ftype: if > 0 use this type (because parts of Polygon are read as wkbLineString)
 
252
  
 
253
  \param Map pointer to Map_info structure
 
254
  \param[out] hGeom OGR geometry
 
255
  \param ftype feature type
 
256
  
 
257
  \return 0 on success
 
258
  \return 1 on error
 
259
*/
 
260
int cache_feature(struct Map_info *Map, OGRGeometryH hGeom, int ftype)
40
261
{
41
262
    int line, i, np, ng, tp;
 
263
 
 
264
    struct Format_info_ogr *ogr_info;
 
265
 
42
266
    OGRwkbGeometryType type;
43
267
    OGRGeometryH hGeom2;
44
268
 
45
 
    G_debug(4, "cache_feature");
 
269
    G_debug(4, "cache_feature() ftype = %d", ftype);
46
270
 
47
 
    /* Alloc space */
48
 
    line = Map->fInfo.ogr.lines_num;
49
 
    if (line == Map->fInfo.ogr.lines_alloc) {
50
 
        Map->fInfo.ogr.lines_alloc += 20;
51
 
        Map->fInfo.ogr.lines =
52
 
            (struct line_pnts **)G_realloc((void *)Map->fInfo.ogr.lines,
53
 
                                           Map->fInfo.ogr.lines_alloc *
 
271
    ogr_info = &(Map->fInfo.ogr);
 
272
    
 
273
    /* alloc space in lines cache */
 
274
    line = ogr_info->cache.lines_num;
 
275
    if (line == ogr_info->cache.lines_alloc) {
 
276
        ogr_info->cache.lines_alloc += 1;
 
277
        ogr_info->cache.lines =
 
278
            (struct line_pnts **)G_realloc((void *)ogr_info->cache.lines,
 
279
                                           ogr_info->cache.lines_alloc *
54
280
                                           sizeof(struct line_pnts *));
55
281
 
56
 
        Map->fInfo.ogr.lines_types =
57
 
            (int *)G_realloc(Map->fInfo.ogr.lines_types,
58
 
                             Map->fInfo.ogr.lines_alloc * sizeof(int));
59
 
 
60
 
        for (i = Map->fInfo.ogr.lines_num; i < Map->fInfo.ogr.lines_alloc;
61
 
             i++)
62
 
            Map->fInfo.ogr.lines[i] = Vect_new_line_struct();
63
 
 
 
282
        ogr_info->cache.lines_types =
 
283
            (int *)G_realloc(ogr_info->cache.lines_types,
 
284
                             ogr_info->cache.lines_alloc * sizeof(int));
 
285
 
 
286
        for (i = ogr_info->cache.lines_num; i < ogr_info->cache.lines_alloc; i++)
 
287
            ogr_info->cache.lines[i] = Vect_new_line_struct();
64
288
    }
65
 
    Vect_reset_line(Map->fInfo.ogr.lines[line]);
 
289
    Vect_reset_line(ogr_info->cache.lines[line]);
66
290
 
67
291
    type = wkbFlatten(OGR_G_GetGeometryType(hGeom));
68
292
 
69
293
    switch (type) {
70
294
    case wkbPoint:
71
295
        G_debug(4, "Point");
72
 
        Vect_append_point(Map->fInfo.ogr.lines[line],
 
296
        Vect_append_point(ogr_info->cache.lines[line],
73
297
                          OGR_G_GetX(hGeom, 0), OGR_G_GetY(hGeom, 0),
74
298
                          OGR_G_GetZ(hGeom, 0));
75
 
        Map->fInfo.ogr.lines_types[line] = GV_POINT;
76
 
        Map->fInfo.ogr.lines_num++;
 
299
        ogr_info->cache.lines_types[line] = GV_POINT;
 
300
        ogr_info->cache.lines_num++;
77
301
        return 0;
78
302
        break;
79
303
 
81
305
        G_debug(4, "LineString");
82
306
        np = OGR_G_GetPointCount(hGeom);
83
307
        for (i = 0; i < np; i++) {
84
 
            Vect_append_point(Map->fInfo.ogr.lines[line],
 
308
            Vect_append_point(ogr_info->cache.lines[line],
85
309
                              OGR_G_GetX(hGeom, i), OGR_G_GetY(hGeom, i),
86
310
                              OGR_G_GetZ(hGeom, i));
87
311
        }
88
312
 
89
313
        if (ftype > 0) {        /* Polygon rings */
90
 
            Map->fInfo.ogr.lines_types[line] = ftype;
 
314
            ogr_info->cache.lines_types[line] = ftype;
91
315
        }
92
316
        else {
93
 
            Map->fInfo.ogr.lines_types[line] = GV_LINE;
 
317
            ogr_info->cache.lines_types[line] = GV_LINE;
94
318
        }
95
 
        Map->fInfo.ogr.lines_num++;
 
319
        ogr_info->cache.lines_num++;
96
320
        return 0;
97
321
        break;
98
322
 
123
347
    }
124
348
}
125
349
 
126
 
/*!
127
 
 * \brief Read next line from OGR layer. Skip empty features.
128
 
 *
129
 
 *  The action of this routine can be modified by:
130
 
 *   - Vect_read_constraint_region()
131
 
 *   - Vect_read_constraint_type()
132
 
 *   - Vect_remove_constraints()
133
 
 *
134
 
 * \param Map vector map layer
135
 
 * \param line_p container used to store line points within
136
 
 * \param line_c container used to store line categories within
137
 
 *
138
 
 * \return  line type
139
 
 * \return  -2 no more features (EOF)
140
 
 * \return  -1 out of memory
141
 
 */
142
 
int
143
 
V1_read_next_line_ogr(struct Map_info *Map, struct line_pnts *line_p,
144
 
                      struct line_cats *line_c)
 
350
int read_next_line_ogr(struct Map_info *Map, struct line_pnts *line_p,
 
351
                       struct line_cats *line_c, int ignore_constraint)
145
352
{
146
353
    int itype;
147
 
    BOUND_BOX lbox, mbox;
 
354
    struct bound_box lbox, mbox;
148
355
    OGRFeatureH hFeature;
149
356
    OGRGeometryH hGeom;
150
357
 
 
358
    struct Format_info_ogr *ogr_info;
 
359
 
151
360
    G_debug(3, "V1_read_next_line_ogr()");
152
361
 
153
 
    if (line_p != NULL)
154
 
        Vect_reset_line(line_p);
155
 
    if (line_c != NULL)
156
 
        Vect_reset_cats(line_c);
157
 
 
158
 
    if (Map->Constraint_region_flag)
 
362
    if (Map->constraint.region_flag && !ignore_constraint)
159
363
        Vect_get_constraint_box(Map, &mbox);
160
364
 
161
 
    while (1) {
162
 
        /* Read feature to chache if necessary */
163
 
        while (Map->fInfo.ogr.lines_next == Map->fInfo.ogr.lines_num) {
164
 
            hFeature = OGR_L_GetNextFeature(Map->fInfo.ogr.layer);
165
 
 
 
365
    ogr_info = &(Map->fInfo.ogr);
 
366
    while (TRUE) {
 
367
        /* reset data structures */
 
368
        if (line_p != NULL)
 
369
            Vect_reset_line(line_p);
 
370
        if (line_c != NULL)
 
371
            Vect_reset_cats(line_c);
 
372
    
 
373
        /* read feature to cache if necessary */
 
374
        while (ogr_info->cache.lines_next == ogr_info->cache.lines_num) {
 
375
            hFeature = OGR_L_GetNextFeature(ogr_info->layer);
166
376
            if (hFeature == NULL) {
167
 
                return -2;
168
 
            }                   /* no more features */
 
377
                return -2;              /* nothing to read */
 
378
            }                   
169
379
 
170
380
            hGeom = OGR_F_GetGeometryRef(hFeature);
171
 
            if (hGeom == NULL) {        /* feature without geometry */
 
381
            if (hGeom == NULL) {        /* skip feature without geometry */
 
382
                G_warning(_("Feature without geometry. Skipped."));
172
383
                OGR_F_Destroy(hFeature);
173
384
                continue;
174
385
            }
175
386
 
176
 
            Map->fInfo.ogr.feature_cache_id = (int)OGR_F_GetFID(hFeature);
177
 
            if (Map->fInfo.ogr.feature_cache_id == OGRNullFID) {
 
387
            /* cache OGR feature */
 
388
            ogr_info->cache.fid = (int)OGR_F_GetFID(hFeature);
 
389
            if (ogr_info->cache.fid == OGRNullFID) {
178
390
                G_warning(_("OGR feature without ID"));
179
391
            }
180
392
 
181
 
            /* Cache the feature */
182
 
            Map->fInfo.ogr.lines_num = 0;
 
393
            /* cache feature */
 
394
            ogr_info->cache.lines_num = 0;
183
395
            cache_feature(Map, hGeom, -1);
184
 
            G_debug(4, "%d lines read to cache", Map->fInfo.ogr.lines_num);
 
396
            G_debug(4, "%d lines read to cache", ogr_info->cache.lines_num);
185
397
            OGR_F_Destroy(hFeature);
186
398
 
187
 
            Map->fInfo.ogr.lines_next = 0;      /* next to be read from cache */
 
399
            /* next to be read from cache */
 
400
            ogr_info->cache.lines_next = 0;     
188
401
        }
189
402
 
190
 
        /* Read next part of the feature */
191
 
        G_debug(4, "read next cached line %d", Map->fInfo.ogr.lines_next);
192
 
        itype = Map->fInfo.ogr.lines_types[Map->fInfo.ogr.lines_next];
 
403
        /* read next part of the feature */
 
404
        G_debug(4, "read next cached line %d", ogr_info->cache.lines_next);
 
405
        itype = ogr_info->cache.lines_types[ogr_info->cache.lines_next];
193
406
 
194
 
        /* Constraint on Type of line 
195
 
         * Default is all of  Point, Line, Area and whatever else comes along
196
 
         */
197
 
        if (Map->Constraint_type_flag) {
198
 
            if (!(itype & Map->Constraint_type)) {
199
 
                Map->fInfo.ogr.lines_next++;
 
407
        if (Map->constraint.type_flag && !ignore_constraint) {
 
408
            /* skip feature by type */
 
409
            if (!(itype & Map->constraint.type)) {
 
410
                ogr_info->cache.lines_next++;
200
411
                continue;
201
412
            }
202
413
        }
203
414
 
204
 
        /* Constraint on specified region */
205
 
        if (Map->Constraint_region_flag) {
206
 
            Vect_line_box(Map->fInfo.ogr.lines[Map->fInfo.ogr.lines_next],
 
415
        if (Map->constraint.region_flag && !ignore_constraint) {
 
416
            /* skip feature by region */
 
417
            Vect_line_box(ogr_info->cache.lines[ogr_info->cache.lines_next],
207
418
                          &lbox);
208
 
 
 
419
            
209
420
            if (!Vect_box_overlap(&lbox, &mbox)) {
210
 
                Map->fInfo.ogr.lines_next++;
 
421
                ogr_info->cache.lines_next++;
211
422
                continue;
212
423
            }
213
424
        }
214
 
 
 
425
        
 
426
        /* skip feature by field - ignored */
 
427
        
215
428
        if (line_p != NULL)
216
429
            Vect_append_points(line_p,
217
 
                               Map->fInfo.ogr.lines[Map->fInfo.ogr.
218
 
                                                    lines_next], GV_FORWARD);
219
 
 
220
 
        if (line_c != NULL && Map->fInfo.ogr.feature_cache_id != OGRNullFID)
221
 
            Vect_cat_set(line_c, 1, Map->fInfo.ogr.feature_cache_id);
222
 
 
223
 
        Map->fInfo.ogr.lines_next++;
 
430
                               ogr_info->cache.lines[ogr_info->cache.lines_next], GV_FORWARD);
 
431
 
 
432
        if (line_c != NULL && ogr_info->cache.fid != OGRNullFID)
 
433
            Vect_cat_set(line_c, 1, ogr_info->cache.fid);
 
434
 
 
435
        ogr_info->cache.lines_next++;
224
436
        G_debug(4, "next line read, type = %d", itype);
225
 
        return (itype);
 
437
        
 
438
        return itype;
226
439
    }
227
 
    return -2;                  /* not reached */
228
 
}
229
 
 
230
 
/*!
231
 
 * \brief Read next line from OGR layer.
232
 
 *
233
 
 * \param Map vector map layer
234
 
 * \param line_p container used to store line points within
235
 
 * \param line_c container used to store line categories within
236
 
 *
237
 
 * \return  line type
238
 
 * \return  -2 no more features (EOF)
239
 
 * \return  -1 out of memory
240
 
 */
241
 
int
242
 
V2_read_next_line_ogr(struct Map_info *Map, struct line_pnts *line_p,
243
 
                      struct line_cats *line_c)
244
 
{
245
 
    if (Map->next_line > Map->plus.n_lines)
246
 
        return -2;
247
 
 
248
 
    return V2_read_line_ogr(Map, line_p, line_c, Map->next_line++);
249
 
}
250
 
 
251
 
/*!
252
 
 * \brief Recursively descend to feature and read the part
253
 
 *
254
 
 * \param Map vector map layer
255
 
 * \param hGeom OGR geometry
256
 
 * \param offset given offset
257
 
 * \param Points container used to store line pointes within
258
 
 *
259
 
 * \return 0 OK
260
 
 * \return 1 error
261
 
 */
262
 
static int read_line(struct Map_info *Map, OGRGeometryH hGeom, long offset,
263
 
                     struct line_pnts *Points)
 
440
 
 
441
    return -1;                  /* not reached */
 
442
}
 
443
 
 
444
/*!
 
445
  \brief Recursively descend to feature and read the part
 
446
  
 
447
  \param Map pointer to Map_info structure
 
448
  \param hGeom OGR geometry
 
449
  \param offset given offset
 
450
  \param[out] Points container used to store line pointes within
 
451
  
 
452
  \return feature type
 
453
  \return -1 on error
 
454
*/
 
455
int read_line(const struct Map_info *Map, OGRGeometryH hGeom, long offset,
 
456
              struct line_pnts *Points)
264
457
{
265
458
    int i, nPoints;
 
459
    int eType, line;
 
460
    
 
461
    const struct Format_info_ogr *ogr_info;
 
462
    
 
463
    OGRGeometryH hGeom2;
 
464
 
 
465
    /* Read coors if hGeom is a simple element (wkbPoint,
 
466
     * wkbLineString) otherwise descend to geometry specified by
 
467
     * offset[offset] */
 
468
 
 
469
    ogr_info = &(Map->fInfo.ogr);
 
470
    
 
471
    eType = wkbFlatten(OGR_G_GetGeometryType(hGeom));
 
472
    G_debug(4, "OGR geometry type: %d", eType);
 
473
    
 
474
    switch (eType) {
 
475
    case wkbPoint:
 
476
        G_debug(4, "\t->Point");
 
477
        if (Points) {
 
478
            Vect_append_point(Points, OGR_G_GetX(hGeom, 0), OGR_G_GetY(hGeom, 0),
 
479
                              OGR_G_GetZ(hGeom, 0));
 
480
        }
 
481
        return GV_POINT;
 
482
        break;
 
483
 
 
484
    case wkbLineString:
 
485
        G_debug(4, "\t->LineString");   
 
486
        if (Points) {
 
487
            nPoints = OGR_G_GetPointCount(hGeom);
 
488
            for (i = 0; i < nPoints; i++) {
 
489
                Vect_append_point(Points, OGR_G_GetX(hGeom, i),
 
490
                                  OGR_G_GetY(hGeom, i), OGR_G_GetZ(hGeom, i));
 
491
            }
 
492
        }
 
493
        return GV_LINE;
 
494
        break;
 
495
 
 
496
    case wkbPolygon:
 
497
    case wkbMultiPoint:
 
498
    case wkbMultiLineString:
 
499
    case wkbMultiPolygon:
 
500
    case wkbGeometryCollection:
 
501
        G_debug(4, "\t->more geoms -> part %d", ogr_info->offset.array[offset]);
 
502
        hGeom2 = OGR_G_GetGeometryRef(hGeom, ogr_info->offset.array[offset]);
 
503
        line = read_line(Map, hGeom2, offset + 1, Points);
 
504
        if (eType == wkbPolygon || eType == wkbMultiPolygon)
 
505
            return GV_BOUNDARY;
 
506
        if (eType == wkbMultiPoint)
 
507
            return GV_POINT;
 
508
        if (eType == wkbMultiLineString)
 
509
            return GV_LINE;
 
510
        return line;
 
511
        break;
 
512
 
 
513
    default:
 
514
        G_warning(_("OGR feature type '%s' not supported"),
 
515
                  OGRGeometryTypeToName(eType));
 
516
        break;
 
517
    }
 
518
 
 
519
    return -1;
 
520
}
 
521
 
 
522
/*!
 
523
  \brief Recursively descend to feature and read the part
 
524
  
 
525
  \param Map pointer to Map_info structure
 
526
  \param hGeom OGR geometry
 
527
  \param offset given offset
 
528
  \param[out] Points container used to store line pointes within
 
529
  
 
530
  \return feature type
 
531
  \return -1 on error
 
532
*/
 
533
int get_line_type(const struct Map_info *Map, long fid)
 
534
{
266
535
    int eType;
267
 
    OGRGeometryH hGeom2;
268
 
 
269
 
    /* Read coors if hGeom is a simple element (wkbPoint, wkbLineString) otherwise
270
 
     * descend to geometry specified by offset[offset] */
271
 
 
272
 
    G_debug(4, "read_line() offset = %ld", offset);
273
 
 
 
536
 
 
537
    const struct Format_info_ogr *ogr_info;
 
538
    
 
539
    OGRFeatureH hFeat;
 
540
    OGRGeometryH hGeom;
 
541
 
 
542
    G_debug(4, "get_line_type() fid = %ld", fid);
 
543
 
 
544
    ogr_info = &(Map->fInfo.ogr);
 
545
    
 
546
    hFeat = OGR_L_GetFeature(ogr_info->layer, fid);
 
547
    if (hFeat == NULL)
 
548
        return -1;
 
549
 
 
550
    hGeom = OGR_F_GetGeometryRef(hFeat);
 
551
    if (hGeom == NULL)
 
552
        return -1;
 
553
    
274
554
    eType = wkbFlatten(OGR_G_GetGeometryType(hGeom));
 
555
 
 
556
    OGR_F_Destroy(hFeat);
 
557
 
275
558
    G_debug(4, "OGR Geometry of type: %d", eType);
276
559
 
277
560
    switch (eType) {
278
561
    case wkbPoint:
279
 
        G_debug(4, "Point");
280
 
        Vect_append_point(Points, OGR_G_GetX(hGeom, 0), OGR_G_GetY(hGeom, 0),
281
 
                          OGR_G_GetZ(hGeom, 0));
282
 
        return 0;
 
562
    case wkbMultiPoint:
 
563
        return GV_POINT;
283
564
        break;
284
 
 
 
565
        
285
566
    case wkbLineString:
286
 
        G_debug(4, "LineString");
287
 
        nPoints = OGR_G_GetPointCount(hGeom);
288
 
        for (i = 0; i < nPoints; i++) {
289
 
            Vect_append_point(Points, OGR_G_GetX(hGeom, i),
290
 
                              OGR_G_GetY(hGeom, i), OGR_G_GetZ(hGeom, i));
291
 
        }
292
 
        return 0;
 
567
    case wkbMultiLineString:
 
568
        return GV_LINE;
293
569
        break;
294
570
 
295
571
    case wkbPolygon:
296
 
    case wkbMultiPoint:
297
 
    case wkbMultiLineString:
298
572
    case wkbMultiPolygon:
299
573
    case wkbGeometryCollection:
300
 
        G_debug(4, " more geoms -> part %d", Map->fInfo.ogr.offset[offset]);
301
 
        hGeom2 = OGR_G_GetGeometryRef(hGeom, Map->fInfo.ogr.offset[offset]);
302
 
        return (read_line(Map, hGeom2, offset + 1, Points));
 
574
        return GV_BOUNDARY;
303
575
        break;
304
576
 
305
577
    default:
306
578
        G_warning(_("OGR feature type %d not supported"), eType);
307
579
        break;
308
580
    }
309
 
    return 1;
310
 
}
311
 
 
312
 
/*!
313
 
 * \brief Read line from layer on given offset.
314
 
 *
315
 
 * \param Map vector map layer
316
 
 * \param line_p container used to store line points within
317
 
 * \param line_c container used to store line categories within
318
 
 * \param line line id
319
 
 *
320
 
 * \return line type
321
 
 * \return -2 end of table (last row)
322
 
 * \return -1 out of memory
323
 
 */
324
 
int
325
 
V2_read_line_ogr(struct Map_info *Map, struct line_pnts *line_p,
326
 
                 struct line_cats *line_c, int line)
327
 
{
328
 
    int node;
329
 
    int offset;
330
 
    long FID;
331
 
    P_LINE *Line;
332
 
    P_NODE *Node;
333
 
    OGRGeometryH hGeom;
334
 
 
335
 
    G_debug(4, "V2_read_line_ogr() line = %d", line);
336
 
 
337
 
    if (line_p != NULL)
338
 
        Vect_reset_line(line_p);
339
 
    if (line_c != NULL)
340
 
        Vect_reset_cats(line_c);
341
 
 
342
 
    Line = Map->plus.Line[line];
343
 
    offset = (int)Line->offset;
344
 
 
345
 
    if (Line->type == GV_CENTROID) {
346
 
        G_debug(4, "Centroid");
347
 
        node = Line->N1;
348
 
        Node = Map->plus.Node[node];
349
 
 
350
 
        /* coordinates */
351
 
        if (line_p != NULL) {
352
 
            Vect_append_point(line_p, Node->x, Node->y, 0.0);
353
 
        }
354
 
 
355
 
        /* category */
356
 
        if (line_c != NULL) {
357
 
            /* cat = FID and offset = FID for centroid */
358
 
            Vect_cat_set(line_c, 1, (int)offset);
359
 
        }
360
 
 
361
 
        return (GV_CENTROID);
362
 
    }
363
 
    else {
364
 
        FID = Map->fInfo.ogr.offset[offset];
365
 
        G_debug(4, "  FID = %ld", FID);
366
 
 
367
 
        /* coordinates */
368
 
        if (line_p != NULL) {
369
 
            /* Read feature to cache if necessary */
370
 
            if (Map->fInfo.ogr.feature_cache_id != FID) {
371
 
                G_debug(4, "Read feature (FID = %ld) to cache.", FID);
372
 
                if (Map->fInfo.ogr.feature_cache) {
373
 
                    OGR_F_Destroy(Map->fInfo.ogr.feature_cache);
374
 
                }
375
 
                Map->fInfo.ogr.feature_cache =
376
 
                    OGR_L_GetFeature(Map->fInfo.ogr.layer, FID);
377
 
                if (Map->fInfo.ogr.feature_cache == NULL) {
378
 
                    G_fatal_error(_("Unable to get feature geometry, FID %ld"),
379
 
                                  FID);
380
 
                }
381
 
                Map->fInfo.ogr.feature_cache_id = FID;
382
 
            }
383
 
 
384
 
            hGeom = OGR_F_GetGeometryRef(Map->fInfo.ogr.feature_cache);
385
 
            if (hGeom == NULL) {
386
 
                G_fatal_error(_("Unable to get feature geometry, FID %ld"),
387
 
                              FID);
388
 
            }
389
 
 
390
 
            read_line(Map, hGeom, Line->offset + 1, line_p);
391
 
        }
392
 
 
393
 
        /* category */
394
 
        if (line_c != NULL) {
395
 
            Vect_cat_set(line_c, 1, (int)FID);
396
 
        }
397
 
 
398
 
        return Line->type;
399
 
    }
400
 
 
401
 
    return -2;                  /* not reached */
402
 
}
403
 
 
 
581
 
 
582
    return -1;
 
583
}
404
584
#endif