~ubuntu-branches/ubuntu/wily/grass/wily

« back to all changes in this revision

Viewing changes to vector/v.out.ogr/main.c

Tags: 7.0.0~rc1+ds1-1~exp1
* New upstream release candidate.
* Repack upstream tarball, remove precompiled Python objects.
* Add upstream metadata.
* Update gbp.conf and Vcs-Git URL to use the experimental branch.
* Update watch file for GRASS 7.0.
* Drop build dependencies for Tcl/Tk, add build dependencies:
  python-numpy, libnetcdf-dev, netcdf-bin, libblas-dev, liblapack-dev
* Update Vcs-Browser URL to use cgit instead of gitweb.
* Update paths to use grass70.
* Add configure options: --with-netcdf, --with-blas, --with-lapack,
  remove --with-tcltk-includes.
* Update patches for GRASS 7.
* Update copyright file, changes:
  - Update copyright years
  - Group files by license
  - Remove unused license sections
* Add patches for various typos.
* Fix desktop file with patch instead of d/rules.
* Use minimal dh rules.
* Bump Standards-Version to 3.9.6, no changes.
* Use dpkg-maintscript-helper to replace directories with symlinks.
  (closes: #776349)
* Update my email to use @debian.org address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 ***************************************************************
3
3
 *
4
4
 * MODULE:       v.out.ogr
5
 
 * 
 
5
 *
6
6
 * AUTHOR(S):    Radim Blazek
7
 
 *               Some extensions: Markus Neteler
8
 
 *
9
 
 * PURPOSE:      Category manipulations
10
 
 *               
11
 
 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
12
 
 *
13
 
 *               This program is free software under the 
14
 
 *               GNU General Public License (>=v2). 
15
 
 *               Read the file COPYING that comes with GRASS
16
 
 *               for details.
 
7
 *               Some extensions: Markus Neteler, Benjamin Ducke
 
8
 *               Multi-features support by Martin Landa <landa.martin gmail.com> 
 
9
 *
 
10
 * PURPOSE:      Converts GRASS vector to one of supported OGR vector formats.
 
11
 *
 
12
 * COPYRIGHT:    (C) 2001-2013 by the GRASS Development Team
 
13
 *
 
14
 *               This program is free software under the GNU General
 
15
 *               Public License (>=v2).  Read the file COPYING that
 
16
 *               comes with GRASS for details.
17
17
 *
18
18
 **************************************************************/
 
19
 
19
20
#include <stdlib.h>
20
21
#include <string.h>
 
22
 
 
23
 
21
24
#include <grass/gis.h>
22
 
#include <grass/dbmi.h>
23
 
#include <grass/Vect.h>
24
 
#include <grass/config.h>
25
25
#include <grass/gprojects.h>
26
26
#include <grass/glocale.h>
27
 
#include "ogr_api.h"
28
 
#include "cpl_string.h"
29
 
 
30
 
int fout, fskip;                /* features written/ skip */
31
 
int nocat, noatt, nocatskip;    /* number of features without cats/atts written/skip */
32
 
 
33
 
int mk_att(int cat, struct field_info *Fi, dbDriver *Driver,
34
 
           int ncol, int doatt, OGRFeatureH Ogr_feature);
35
 
 
36
 
char *OGR_list_write_drivers();
37
 
char OGRdrivers[2000];
 
27
 
 
28
#include "local_proto.h"
 
29
 
 
30
#include "ogr_srs_api.h"
38
31
 
39
32
int main(int argc, char *argv[])
40
33
{
41
 
    int i, j, k, centroid, otype, donocat;
42
 
    char *mapset;
 
34
    int i, otype, ftype, donocat;
 
35
    int num_to_export;
43
36
    int field;
 
37
    int overwrite, found;
 
38
 
44
39
    struct GModule *module;
45
 
    struct Option *in_opt, *dsn_opt, *layer_opt, *type_opt, *frmt_opt,
46
 
        *field_opt, *dsco, *lco;
47
 
    struct Flag *cat_flag, *esristyle, *poly_flag;
48
 
    char buf[2000];
49
 
    char key1[200], key2[200];
50
 
    struct Key_Value *projinfo, *projunits;
 
40
    struct Options options;
 
41
    struct Flags flags;
 
42
 
 
43
    char buf[SQL_BUFFER_SIZE];
 
44
    char key1[SQL_BUFFER_SIZE], key2[SQL_BUFFER_SIZE];
51
45
    struct Cell_head cellhd;
52
46
    char **tokens;
53
47
 
54
48
    /* Vector */
55
49
    struct Map_info In;
56
 
    struct line_pnts *Points;
57
 
    struct line_cats *Cats;
58
 
    int type, cat;
59
50
 
60
51
    /* Attributes */
61
 
    int doatt = 0, ncol = 0, colsqltype, colctype, keycol = -1;
 
52
    int doatt = 0, ncol = 0, colsqltype, colwidth, keycol = -1;
 
53
    int *colctype = NULL;
 
54
    const char **colname = NULL;
62
55
    struct field_info *Fi = NULL;
63
56
    dbDriver *Driver = NULL;
64
 
    dbHandle handle;
65
57
    dbTable *Table;
66
58
    dbString dbstring;
67
59
    dbColumn *Column;
68
60
 
 
61
    int n_feat;           /* number of written features */
 
62
    int n_nocat, n_noatt; /* number of features without cats/atts written/skip */
 
63
 
69
64
    /* OGR */
70
 
    int drn, ogr_ftype = OFTInteger;
 
65
    int drn;
 
66
    OGRFieldType ogr_ftype = OFTInteger;
71
67
    OGRDataSourceH Ogr_ds;
72
68
    OGRSFDriverH Ogr_driver;
73
69
    OGRLayerH Ogr_layer;
74
70
    OGRFieldDefnH Ogr_field;
75
 
    OGRFeatureH Ogr_feature;
76
71
    OGRFeatureDefnH Ogr_featuredefn;
77
 
    OGRGeometryH Ogr_geometry;
78
 
    unsigned int wkbtype = wkbUnknown;  /* ?? */
 
72
    OGRwkbGeometryType wkbtype = wkbUnknown;
79
73
    OGRSpatialReferenceH Ogr_projection;
80
74
    char **papszDSCO = NULL, **papszLCO = NULL;
 
75
    int num_types;
81
76
 
82
77
    G_gisinit(argv[0]);
83
78
 
84
79
    /* Module options */
85
80
    module = G_define_module();
86
 
    module->keywords = _("vector, export");
87
 
    module->description =
88
 
        _("Converts to one of the supported OGR vector formats.");
89
 
 
90
 
    in_opt = G_define_standard_option(G_OPT_V_INPUT);
91
 
 
92
 
    type_opt = G_define_standard_option(G_OPT_V_TYPE);
93
 
    type_opt->options = "point,kernel,centroid,line,boundary,area,face";
94
 
    type_opt->answer = "line,boundary";
95
 
    type_opt->description =
96
 
        _("Feature type. Combination of types is not supported "
97
 
          "by all formats.");
98
 
    type_opt->guisection = _("Input");
99
 
 
100
 
    dsn_opt = G_define_option();
101
 
    dsn_opt->key = "dsn";
102
 
    dsn_opt->type = TYPE_STRING;
103
 
    dsn_opt->required = YES;
104
 
    dsn_opt->label = _("OGR output datasource name");
105
 
    dsn_opt->description =
106
 
        _("For example: ESRI Shapefile: filename or directory for storage");
107
 
 
108
 
    layer_opt = G_define_option();
109
 
    layer_opt->key = "olayer";
110
 
    layer_opt->type = TYPE_STRING;
111
 
    layer_opt->required = NO;
112
 
    layer_opt->label =
113
 
        _("OGR layer name. If not specified, input name is used.");
114
 
    layer_opt->description = _("For example: ESRI Shapefile: shapefile name");
115
 
    layer_opt->guisection = _("Creation");
116
 
 
117
 
    field_opt = G_define_standard_option(G_OPT_V_FIELD);
118
 
    field_opt->guisection = _("Input");
119
 
 
120
 
    frmt_opt = G_define_option();
121
 
    frmt_opt->key = "format";
122
 
    frmt_opt->type = TYPE_STRING;
123
 
    frmt_opt->required = NO;
124
 
    frmt_opt->multiple = NO;
125
 
    frmt_opt->answer = "ESRI_Shapefile";
126
 
    frmt_opt->options = OGR_list_write_drivers();
127
 
    frmt_opt->description = _("OGR format");
128
 
    frmt_opt->guisection = _("Creation");
129
 
 
130
 
    dsco = G_define_option();
131
 
    dsco->key = "dsco";
132
 
    dsco->type = TYPE_STRING;
133
 
    dsco->required = NO;
134
 
    dsco->multiple = YES;
135
 
    dsco->answer = "";
136
 
    dsco->description =
137
 
        _("OGR dataset creation option (format specific, NAME=VALUE)");
138
 
    dsco->guisection = _("Creation");
139
 
 
140
 
    lco = G_define_option();
141
 
    lco->key = "lco";
142
 
    lco->type = TYPE_STRING;
143
 
    lco->required = NO;
144
 
    lco->multiple = YES;
145
 
    lco->answer = "";
146
 
    lco->description =
147
 
        _("OGR layer creation option (format specific, NAME=VALUE)");
148
 
    lco->guisection = _("Creation");
149
 
 
150
 
    cat_flag = G_define_flag();
151
 
    cat_flag->key = 'c';
152
 
    cat_flag->description = _("Export features with category (labeled) only. "
153
 
                              "Otherwise all features are exported");
154
 
 
155
 
    esristyle = G_define_flag();
156
 
    esristyle->key = 'e';
157
 
    esristyle->description = _("Use ESRI-style .prj file format "
158
 
                               "(applies to Shapefile output only)");
159
 
 
160
 
    poly_flag = G_define_flag();
161
 
    poly_flag->key = 'p';
162
 
    poly_flag->description = _("Export lines as polygons");
163
 
 
164
 
    if (G_parser(argc, argv))
165
 
        exit(EXIT_FAILURE);
166
 
 
167
 
 
168
 
    /* read options */
169
 
    field = atoi(field_opt->answer);
170
 
 
171
 
    /* Check output type */
172
 
    otype = Vect_option_to_types(type_opt);
173
 
 
174
 
    if (!layer_opt->answer) {
175
 
        char xname[GNAME_MAX],  xmapset[GMAPSET_MAX];
176
 
        
177
 
        if (G__name_is_fully_qualified(in_opt->answer, xname, xmapset))
178
 
            layer_opt->answer = G_store(xname);
 
81
    G_add_keyword(_("vector"));
 
82
    G_add_keyword(_("export"));
 
83
    G_add_keyword("OGR");
 
84
 
 
85
    module->label =
 
86
        _("Exports a vector map layer to any of the supported OGR vector formats.");
 
87
    module->description = _("By default a vector map layer is exported to Esri Shapefile format.");
 
88
    module->overwrite = TRUE;
 
89
    
 
90
    /* parse & read options */
 
91
    parse_args(argc, argv, &options, &flags);
 
92
    
 
93
    /* check for weird options */
 
94
    if (G_strncasecmp(options.dsn->answer, "PG:", 3) == 0 &&
 
95
        strcmp(options.format->answer, "PostgreSQL") != 0)
 
96
        G_warning(_("Data source starts with \"PG:\" prefix, expecting \"PostgreSQL\" "
 
97
                    "format (\"%s\" given)"), options.format->answer);
 
98
    
 
99
    /* parse dataset creation options */
 
100
    i = 0;
 
101
    while (options.dsco->answers[i]) {
 
102
        tokens = G_tokenize(options.dsco->answers[i], "=");
 
103
        if (G_number_of_tokens(tokens))
 
104
            papszDSCO = CSLSetNameValue(papszDSCO, tokens[0], tokens[1]);
 
105
        G_free_tokens(tokens);
 
106
        i++;
 
107
    }
 
108
 
 
109
    /* parse layer creation options */
 
110
    i = 0;
 
111
    while (options.lco->answers[i]) {
 
112
        tokens = G_tokenize(options.lco->answers[i], "=");
 
113
        if (G_number_of_tokens(tokens))
 
114
            papszLCO = CSLSetNameValue(papszLCO, tokens[0], tokens[1]);
 
115
        G_free_tokens(tokens);
 
116
        i++;
 
117
    }
 
118
 
 
119
    /*
 
120
       If no output type specified: determine one automatically.
 
121
       Centroids, Boundaries and Kernels always have to be exported
 
122
       explicitely, using the "type=" option.
 
123
     */
 
124
    if (!flags.new->answer) {
 
125
        /* open input vector (topology required) */
 
126
        Vect_set_open_level(2);
 
127
        if (Vect_open_old2(&In, options.input->answer, "",
 
128
                                options.field->answer) < 0)
 
129
            G_fatal_error(_("Unable to open vector map <%s>"),
 
130
                            options.input->answer);
 
131
 
 
132
        if (strcmp(options.type->answer, "auto") == 0) {
 
133
            G_debug(2, "Automatic type determination.");
 
134
 
 
135
            options.type->answers = G_malloc(sizeof(char *) * 10);
 
136
            G_zero(options.type->answers, sizeof(char *) * 10);
 
137
            num_types = 0;
 
138
 
 
139
            if (Vect_get_num_primitives(&In, GV_POINT) > 0) {
 
140
                options.type->answers[num_types++] = G_store("point");
 
141
                G_debug(3, "Adding points to export list.");
 
142
            }
 
143
 
 
144
            if (Vect_get_num_primitives(&In, GV_LINE) > 0) {
 
145
                options.type->answers[num_types++] = G_store("line");
 
146
                G_debug(3, "Adding lines to export list.");
 
147
            }
 
148
 
 
149
            if (Vect_get_num_areas(&In) > 0) {
 
150
                options.type->answers[num_types++] = G_store("area");
 
151
                G_debug(3, "Adding areas to export list.");
 
152
            }
 
153
 
 
154
            /*  Faces and volumes:
 
155
               For now, volumes will just be exported as sets of faces.
 
156
             */
 
157
            if (Vect_get_num_primitives(&In, GV_FACE) > 0) {
 
158
                options.type->answers[num_types++] = G_store("face");
 
159
                G_debug(3, "Adding faces to export list.");
 
160
            }
 
161
 
 
162
            /* this check HAS TO FOLLOW RIGHT AFTER check for GV_FACE! */
 
163
            if (Vect_get_num_volumes(&In) > 0) {
 
164
                G_warning(_("Volumes will be exported as sets of faces"));
 
165
                if (num_types == 0) {
 
166
                    /* no other types yet? */
 
167
                    options.type->answers[num_types++] = G_store("volume");
 
168
                    G_debug(3, "Adding volumes to export list.");
 
169
                }
 
170
                else {
 
171
                    if (strcmp(options.type->answers[num_types - 1], "face")
 
172
                        != 0) {
 
173
                        /* only put faces on export list if that's not the case already */
 
174
                        options.type->answers[num_types++] =
 
175
                            G_store("volume");
 
176
                        G_debug(3, "Adding volumes to export list.");
 
177
                    }
 
178
                }
 
179
            }
 
180
 
 
181
            if (num_types == 0) {
 
182
                G_warning(_("Unable to determine input map's vector feature type(s)."));
 
183
            }
 
184
        }
 
185
    }
 
186
 
 
187
    field = Vect_get_field_number(&In, options.field->answer);
 
188
 
 
189
    /* check output feature type */
 
190
    otype = Vect_option_to_types(options.type);
 
191
    ftype = Vect_option_to_types(options.otype);
 
192
 
 
193
    if (!options.layer->answer) {
 
194
        char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
 
195
 
 
196
        if (flags.append->answer)
 
197
            G_fatal_error(_("Appending to OGR layer requires option '%s'"),
 
198
                          options.layer->key);
 
199
 
 
200
        if (G_name_is_fully_qualified(options.input->answer, xname, xmapset))
 
201
            options.layer->answer = G_store(xname);
179
202
        else
180
 
            layer_opt->answer = G_store(in_opt->answer);
181
 
    }
182
 
 
183
 
    if (otype & GV_POINTS)
184
 
        wkbtype = wkbPoint;
185
 
    else if (otype & GV_LINES)
186
 
        wkbtype = wkbLineString;
187
 
    else if (otype & GV_AREA)
188
 
        wkbtype = wkbPolygon;
189
 
    else if (otype & GV_FACE)
190
 
        wkbtype = wkbPolygon25D;
191
 
 
192
 
    if (poly_flag->answer)
193
 
        wkbtype = wkbPolygon;
 
203
            options.layer->answer = G_store(options.input->answer);
 
204
    }
 
205
 
 
206
    if (ftype == GV_BOUNDARY) {
 
207
        if (!flags.multi->answer)
 
208
            wkbtype = wkbPolygon;
 
209
        else
 
210
            wkbtype = wkbMultiPolygon;
 
211
    }
 
212
    else if (otype & GV_POINTS) {
 
213
        if (!flags.multi->answer)
 
214
            wkbtype = wkbPoint;
 
215
        else
 
216
            wkbtype = wkbMultiPoint;
 
217
    }
 
218
    else if (otype & GV_LINES || ftype == GV_LINE) {
 
219
        if (!flags.multi->answer)
 
220
            wkbtype = wkbLineString;
 
221
        else
 
222
            wkbtype = wkbMultiLineString;
 
223
    }
 
224
    else if (otype & GV_AREA) {
 
225
        if (!flags.multi->answer)
 
226
            wkbtype = wkbPolygon;
 
227
        else
 
228
            wkbtype = wkbMultiPolygon;
 
229
    }
 
230
    else if (otype & (GV_FACE | GV_VOLUME)) {
 
231
        if (!flags.multi->answer)
 
232
            wkbtype = wkbPolygon25D;
 
233
        else
 
234
            wkbtype = wkbMultiPolygon25D;
 
235
    }
194
236
 
195
237
    if (((GV_POINTS & otype) && (GV_LINES & otype)) ||
196
238
        ((GV_POINTS & otype) && (GV_AREA & otype)) ||
197
239
        ((GV_POINTS & otype) && (GV_FACE & otype)) ||
 
240
        ((GV_POINTS & otype) && (GV_KERNEL & otype)) ||
 
241
        ((GV_POINTS & otype) && (GV_VOLUME & otype)) ||
198
242
        ((GV_LINES & otype) && (GV_AREA & otype)) ||
199
 
        ((GV_LINES & otype) && (GV_FACE & otype))
 
243
        ((GV_LINES & otype) && (GV_FACE & otype)) ||
 
244
        ((GV_LINES & otype) && (GV_KERNEL & otype)) ||
 
245
        ((GV_LINES & otype) && (GV_VOLUME & otype)) ||
 
246
        ((GV_KERNEL & otype) && (GV_POINTS & otype)) ||
 
247
        ((GV_KERNEL & otype) && (GV_LINES & otype)) ||
 
248
        ((GV_KERNEL & otype) && (GV_AREA & otype)) ||
 
249
        ((GV_KERNEL & otype) && (GV_FACE & otype)) ||
 
250
        ((GV_KERNEL & otype) && (GV_VOLUME & otype))
200
251
        ) {
201
252
        G_warning(_("The combination of types is not supported"
202
253
                    " by all formats."));
203
254
        wkbtype = wkbUnknown;
204
255
    }
205
256
 
206
 
 
207
 
    if (cat_flag->answer)
208
 
        donocat = 0;
209
 
    else
210
 
        donocat = 1;
211
 
 
212
 
    Points = Vect_new_line_struct();
213
 
    Cats = Vect_new_cats_struct();
214
 
 
215
 
    /* open input vector */
216
 
    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) {
217
 
        G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);
218
 
    }
219
 
 
220
 
    Vect_set_open_level(2);
221
 
    Vect_open_old(&In, in_opt->answer, mapset);
222
 
 
223
 
    if (Vect_get_num_islands(&In) > 0 && !cat_flag->answer)
224
 
        G_warning(_("The map contains islands. To preserve them in the output map, use the -c flag"));
225
 
 
226
257
    /* fetch PROJ info */
227
258
    G_get_default_window(&cellhd);
228
 
    if (cellhd.proj == PROJECTION_XY)
229
 
        Ogr_projection = NULL;
230
 
    else {
231
 
        projinfo = G_get_projinfo();
232
 
        projunits = G_get_projunits();
233
 
        Ogr_projection = GPJ_grass_to_osr(projinfo, projunits);
234
 
        if (esristyle->answer &&
235
 
            (strcmp(frmt_opt->answer, "ESRI_Shapefile") == 0))
 
259
    Ogr_projection = NULL;
 
260
    if (cellhd.proj != PROJECTION_XY) {
 
261
        const char *epsg;
 
262
 
 
263
        Ogr_projection = NULL;
 
264
        /* try EPSG code first */
 
265
        epsg = G_database_epsg_code();
 
266
        if (!epsg) {
 
267
            struct Key_Value *projinfo, *projunits;
 
268
            
 
269
            projinfo = G_get_projinfo();
 
270
            projunits = G_get_projunits();
 
271
            Ogr_projection = GPJ_grass_to_osr(projinfo, projunits);
 
272
        }
 
273
        else {
 
274
            Ogr_projection = OSRNewSpatialReference(NULL);
 
275
            if (OSRImportFromEPSG(Ogr_projection, atoi(epsg)) != OGRERR_NONE)
 
276
                G_fatal_error(_("Unknown EPSG code %s"), epsg);
 
277
        }
 
278
        if (flags.esristyle->answer &&
 
279
            (strcmp(options.format->answer, "ESRI_Shapefile") == 0))
236
280
            OSRMorphToESRI(Ogr_projection);
237
281
    }
238
282
 
 
283
    /* create new OGR layer in datasource */
 
284
    if (flags.new->answer) {
 
285
        const char *name;
 
286
 
 
287
        name =
 
288
            options.layer->answer ? options.layer->answer : options.input->
 
289
            answer;
 
290
 
 
291
        create_ogr_layer(options.dsn->answer, options.format->answer, name,
 
292
                         wkbtype, papszDSCO, papszLCO);
 
293
 
 
294
        G_message(_("OGR layer <%s> created in datasource <%s> (format '%s')"),
 
295
                  name, options.dsn->answer, options.format->answer);
 
296
        exit(EXIT_SUCCESS);
 
297
    }
 
298
 
 
299
    if (flags.cat->answer)
 
300
        donocat = 1;
 
301
    else
 
302
        donocat = 0;
 
303
 
 
304
    if ((GV_AREA & otype) && Vect_get_num_islands(&In) > 0 &&
 
305
        flags.cat->answer)
 
306
        G_warning(_("The map contains islands. With the -c flag, "
 
307
                    "islands will appear as filled areas, not holes in the output map."));
 
308
 
 
309
 
 
310
    /* check what users wants to export and what's present in the map */
 
311
    if (Vect_get_num_primitives(&In, GV_POINT) > 0 && !(otype & GV_POINTS))
 
312
        G_warning(_n("%d point found, but not requested to be exported. "
 
313
                     "Verify 'type' parameter.",
 
314
                     "%d points found, but not requested to be exported. "
 
315
                     "Verify 'type' parameter.",
 
316
                     Vect_get_num_primitives(&In, GV_POINT)),
 
317
                  Vect_get_num_primitives(&In, GV_POINT));
 
318
 
 
319
    if (Vect_get_num_primitives(&In, GV_LINE) > 0 && !(otype & GV_LINES))
 
320
        G_warning(_n("%d line found, but not requested to be exported. "
 
321
                     "Verify 'type' parameter.",
 
322
                     "%d line(s) found, but not requested to be exported. "
 
323
                     "Verify 'type' parameter.",
 
324
                     Vect_get_num_primitives(&In, GV_LINE)),
 
325
                  Vect_get_num_primitives(&In, GV_LINE));
 
326
 
 
327
    if (Vect_get_num_primitives(&In, GV_BOUNDARY) > 0 &&
 
328
        !(otype & GV_BOUNDARY) && !(otype & GV_AREA))
 
329
        G_warning(_n("%d boundary found, but not requested to be exported. "
 
330
                     "Verify 'type' parameter.",
 
331
                     "%d boundaries found, but not requested to be exported. "
 
332
                     "Verify 'type' parameter.",
 
333
                     Vect_get_num_primitives(&In, GV_BOUNDARY)),
 
334
                  Vect_get_num_primitives(&In, GV_BOUNDARY));
 
335
 
 
336
    if (Vect_get_num_primitives(&In, GV_CENTROID) > 0 &&
 
337
        !(otype & GV_CENTROID) && !(otype & GV_AREA))
 
338
        G_warning(_n("%d centroid found, but not requested to be exported. "
 
339
                     "Verify 'type' parameter.",
 
340
                     "%d centroids found, but not requested to be exported. "
 
341
                     "Verify 'type' parameter.",
 
342
                     Vect_get_num_primitives(&In, GV_CENTROID)),
 
343
                  Vect_get_num_primitives(&In, GV_CENTROID));
 
344
 
 
345
    if (Vect_get_num_areas(&In) > 0 && !(otype & GV_AREA))
 
346
        G_warning(_n("%d area found, but not requested to be exported. "
 
347
                     "Verify 'type' parameter.",
 
348
                     "%d areas found, but not requested to be exported. "
 
349
                     "Verify 'type' parameter.",
 
350
                     Vect_get_num_areas(&In)),
 
351
                  Vect_get_num_areas(&In));
 
352
 
 
353
    if (Vect_get_num_primitives(&In, GV_FACE) > 0 && !(otype & GV_FACE))
 
354
        G_warning(_n("%d face found, but not requested to be exported. "
 
355
                     "Verify 'type' parameter.",
 
356
                     "%d faces found, but not requested to be exported. "
 
357
                     "Verify 'type' parameter.",
 
358
                     Vect_get_num_primitives(&In, GV_FACE)),
 
359
                  Vect_get_num_primitives(&In, GV_FACE));
 
360
 
 
361
    if (Vect_get_num_volumes(&In) > 0 && !(otype & GV_VOLUME))
 
362
        G_warning(_n("%d volume found, but not requested to be exported. "
 
363
                     "Verify 'type' parameter.",
 
364
                     "%d volumes found, but not requested to be exported. "
 
365
                     "Verify 'type' parameter.",
 
366
                     Vect_get_num_volumes(&In)),
 
367
                  Vect_get_num_volumes(&In));
 
368
 
 
369
    /* warn and eventually abort if there is nothing to be exported */
 
370
    num_to_export = 0;
 
371
    if (Vect_get_num_primitives(&In, GV_POINT) < 1 && (otype & GV_POINTS)) {
 
372
        G_warning(_("No points found, but requested to be exported. "
 
373
                    "Will skip this feature type."));
 
374
    }
 
375
    else {
 
376
        if (otype & GV_POINT)
 
377
            num_to_export += Vect_get_num_primitives(&In, GV_POINT);
 
378
    }
 
379
 
 
380
    if (Vect_get_num_primitives(&In, GV_LINE) < 1 && (otype & GV_LINE)) {
 
381
        G_warning(_("No lines found, but requested to be exported. "
 
382
                    "Will skip this feature type."));
 
383
    }
 
384
    else {
 
385
        if (otype & GV_LINE)
 
386
            num_to_export += Vect_get_num_primitives(&In, GV_LINE);
 
387
    }
 
388
 
 
389
    if (Vect_get_num_primitives(&In, GV_BOUNDARY) < 1 &&
 
390
        (otype & GV_BOUNDARY)) {
 
391
        G_warning(_("No boundaries found, but requested to be exported. "
 
392
                   "Will skip this feature type."));
 
393
    }
 
394
    else {
 
395
        if (otype & GV_BOUNDARY)
 
396
            num_to_export += Vect_get_num_primitives(&In, GV_BOUNDARY);
 
397
    }
 
398
 
 
399
    if (Vect_get_num_areas(&In) < 1 && (otype & GV_AREA)) {
 
400
        G_warning(_("No areas found, but requested to be exported. "
 
401
                    "Will skip this feature type."));
 
402
    }
 
403
    else {
 
404
        if (otype & GV_AREA)
 
405
            num_to_export += Vect_get_num_areas(&In);
 
406
    }
 
407
 
 
408
    if (Vect_get_num_primitives(&In, GV_CENTROID) < 1 &&
 
409
        (otype & GV_CENTROID)) {
 
410
        G_warning(_("No centroids found, but requested to be exported. "
 
411
                   "Will skip this feature type."));
 
412
    }
 
413
    else {
 
414
        if (otype & GV_CENTROID)
 
415
            num_to_export += Vect_get_num_primitives(&In, GV_CENTROID);
 
416
    }
 
417
 
 
418
    if (Vect_get_num_primitives(&In, GV_FACE) < 1 && (otype & GV_FACE)) {
 
419
        G_warning(_("No faces found, but requested to be exported. "
 
420
                    "Will skip this feature type."));
 
421
    }
 
422
    else {
 
423
        if (otype & GV_FACE)
 
424
            num_to_export += Vect_get_num_primitives(&In, GV_FACE);
 
425
    }
 
426
 
 
427
    if (Vect_get_num_primitives(&In, GV_KERNEL) < 1 && (otype & GV_KERNEL)) {
 
428
        G_warning(_("No kernels found, but requested to be exported. "
 
429
                    "Will skip this feature type."));
 
430
    }
 
431
    else {
 
432
        if (otype & GV_KERNEL)
 
433
            num_to_export += Vect_get_num_primitives(&In, GV_KERNEL);
 
434
    }
 
435
 
 
436
    if (Vect_get_num_volumes(&In) < 1 && (otype & GV_VOLUME)) {
 
437
        G_warning(_("No volumes found, but requested to be exported. "
 
438
                    "Will skip this feature type."));
 
439
    }
 
440
    else {
 
441
        if (otype & GV_VOLUME)
 
442
            num_to_export += Vect_get_num_volumes(&In);
 
443
    }
 
444
 
 
445
    G_debug(1, "Requested to export %d features", num_to_export);
 
446
 
239
447
    /* Open OGR DSN */
240
 
    /* OGRRegisterAll(); */  /* drivers are already registered */
241
448
    G_debug(2, "driver count = %d", OGRGetDriverCount());
242
449
    drn = -1;
243
450
    for (i = 0; i < OGRGetDriverCount(); i++) {
246
453
        /* chg white space to underscore in OGR driver names */
247
454
        sprintf(buf, "%s", OGR_Dr_GetName(Ogr_driver));
248
455
        G_strchg(buf, ' ', '_');
249
 
        if (strcmp(buf, frmt_opt->answer) == 0) {
 
456
        if (strcmp(buf, options.format->answer) == 0) {
250
457
            drn = i;
251
458
            G_debug(2, " -> driver = %d", drn);
252
459
        }
253
460
    }
254
461
    if (drn == -1)
255
 
        G_fatal_error(_("OGR driver <%s> not found"), frmt_opt->answer);
 
462
        G_fatal_error(_("OGR driver <%s> not found"), options.format->answer);
256
463
    Ogr_driver = OGRGetDriver(drn);
257
 
 
258
 
    /* parse dataset creation options */
259
 
    i = 0;
260
 
    while (dsco->answers[i]) {
261
 
        tokens = G_tokenize(dsco->answers[i], "=");
262
 
        if (G_number_of_tokens(tokens))
263
 
            papszDSCO = CSLSetNameValue(papszDSCO, tokens[0], tokens[1]);
264
 
        G_free_tokens(tokens);
265
 
        i++;
266
 
    }
267
 
 
268
 
    G_debug(1, "Create OGR data source");
269
 
    Ogr_ds = OGR_Dr_CreateDataSource(Ogr_driver, dsn_opt->answer, papszDSCO);
 
464
    
 
465
    if (flags.append->answer) {
 
466
        G_debug(1, "Append to OGR layer");
 
467
        Ogr_ds = OGR_Dr_Open(Ogr_driver, options.dsn->answer, TRUE);
 
468
        
 
469
        if (Ogr_ds == NULL) {
 
470
            G_debug(1, "Create OGR data source");
 
471
            Ogr_ds = OGR_Dr_CreateDataSource(Ogr_driver, options.dsn->answer,
 
472
                                             papszDSCO);
 
473
        }
 
474
    }
 
475
    else {
 
476
        if (flags.update->answer) {
 
477
            G_debug(1, "Update OGR data source");
 
478
            Ogr_ds = OGR_Dr_Open(Ogr_driver, options.dsn->answer, TRUE);
 
479
        }
 
480
        else {
 
481
            G_debug(1, "Create OGR data source");
 
482
            Ogr_ds = OGR_Dr_CreateDataSource(Ogr_driver, options.dsn->answer,
 
483
                                             papszDSCO);
 
484
        }
 
485
    }
 
486
        
270
487
    CSLDestroy(papszDSCO);
271
488
    if (Ogr_ds == NULL)
272
489
        G_fatal_error(_("Unable to open OGR data source '%s'"),
273
 
                      dsn_opt->answer);
274
 
 
275
 
    /* parse layer creation options */
276
 
    i = 0;
277
 
    while (lco->answers[i]) {
278
 
        tokens = G_tokenize(lco->answers[i], "=");
279
 
        if (G_number_of_tokens(tokens))
280
 
            papszLCO = CSLSetNameValue(papszLCO, tokens[0], tokens[1]);
281
 
        G_free_tokens(tokens);
282
 
        i++;
283
 
    }
284
 
 
 
490
                      options.dsn->answer);
 
491
    
 
492
    /* check if OGR layer exists */
 
493
    overwrite = G_check_overwrite(argc, argv);
 
494
    found = FALSE;
 
495
    for (i = 0; i < OGR_DS_GetLayerCount(Ogr_ds); i++) {
 
496
        Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
 
497
        Ogr_field = OGR_L_GetLayerDefn(Ogr_layer);
 
498
        if (G_strcasecmp(OGR_FD_GetName(Ogr_field), options.layer->answer))
 
499
            continue;
 
500
        
 
501
        found = TRUE;
 
502
        if (!overwrite && !flags.append->answer) {
 
503
            G_fatal_error(_("Layer <%s> already exists in OGR data source '%s'"),
 
504
                          options.layer->answer, options.dsn->answer);
 
505
        }
 
506
        else if (overwrite) {
 
507
            G_warning(_("OGR layer <%s> already exists and will be overwritten"),
 
508
                      options.layer->answer);
 
509
            OGR_DS_DeleteLayer(Ogr_ds, i);
 
510
            break;
 
511
        }
 
512
    }
 
513
    if (flags.append->answer && !found) {
 
514
        G_warning(_("OGR layer <%s> doesn't exists, "
 
515
                    "creating new OGR layer instead"),
 
516
                  options.layer->answer);
 
517
        flags.append->answer = FALSE;
 
518
    }
 
519
    
 
520
    /* Automatically append driver options for 3D output to layer
 
521
       creation options if '2' is not given.*/
 
522
    if (!flags.force2d->answer &&
 
523
        Vect_is_3d(&In) && 
 
524
        strcmp(options.format->answer, "ESRI_Shapefile") == 0) {
 
525
        /* find right option */
 
526
        char shape_geom[20];
 
527
        if ((otype & GV_POINTS) || (otype & GV_KERNEL))
 
528
            sprintf(shape_geom, "POINTZ");
 
529
        if ((otype & GV_LINES))
 
530
            sprintf(shape_geom, "ARCZ");
 
531
        if ((otype & GV_AREA) || (otype & GV_FACE))
 
532
            sprintf(shape_geom, "POLYGONZ");
 
533
        /* check if the right LCO is already present */
 
534
        const char *shpt;
 
535
        shpt = CSLFetchNameValue(papszLCO, "SHPT");
 
536
        if ((!shpt)) {
 
537
            /* Not set at all? Good! */
 
538
            papszLCO = CSLSetNameValue(papszLCO, "SHPT", shape_geom);
 
539
        } else {
 
540
            if (strcmp(shpt, shape_geom) != 0) {
 
541
                /* Set but to a different value? Override! */
 
542
                G_warning(_("Overriding existing user-defined 'SHPT=' LCO."));
 
543
            }
 
544
            /* Set correct LCO for this geometry type */
 
545
            papszLCO = CSLSetNameValue(papszLCO, "SHPT", shape_geom);
 
546
        }
 
547
    }
 
548
    
285
549
    /* check if the map is 3d */
286
550
    if (Vect_is_3d(&In)) {
287
 
        /* specific check for shp */
288
 
        if (strcmp(frmt_opt->answer, "ESRI_Shapefile") == 0) {
 
551
        /* specific check for ESRI ShapeFile */
 
552
        if (strcmp(options.format->answer, "ESRI_Shapefile") == 0) {
289
553
            const char *shpt;
290
554
 
291
555
            shpt = CSLFetchNameValue(papszLCO, "SHPT");
292
556
            if (!shpt || shpt[strlen(shpt) - 1] != 'Z') {
293
557
                G_warning(_("Vector map <%s> is 3D. "
294
 
                            "Use format specific layer creation options (parameter 'lco') "
295
 
                            "to export in 3D rather than 2D (default)"),
296
 
                          in_opt->answer);
 
558
                            "Use format specific layer creation options SHPT (parameter 'lco') "
 
559
                            "or '-z' flag to export in 3D rather than 2D (default)"),
 
560
                          options.input->answer);
 
561
            }
 
562
        }
 
563
        /* specific check for PostgreSQL */
 
564
        else if (strcmp(options.format->answer, "PostgreSQL") == 0) {
 
565
            const char *dim;
 
566
 
 
567
            dim = CSLFetchNameValue(papszLCO, "DIM");
 
568
            if (!dim || strcmp(dim, "3") != 0) {
 
569
                G_warning(_("Vector map <%s> is 3D. "
 
570
                            "Use format specific layer creation options DIM (parameter 'lco') "
 
571
                            "to export in 3D rather than 2D (default)."),
 
572
                          options.input->answer);
297
573
            }
298
574
        }
299
575
        else {
300
576
            G_warning(_("Vector map <%s> is 3D. "
301
577
                        "Use format specific layer creation options (parameter 'lco') "
302
 
                        "to export in 3D rather than 2D (default)"),
303
 
                      in_opt->answer);
 
578
                        "to export <in 3D rather than 2D (default)."),
 
579
                      options.input->answer);
304
580
        }
305
581
    }
306
582
 
307
583
    G_debug(1, "Create OGR layer");
308
 
    Ogr_layer =
309
 
        OGR_DS_CreateLayer(Ogr_ds, layer_opt->answer, Ogr_projection, wkbtype,
310
 
                           papszLCO);
 
584
    if (flags.append->answer)
 
585
        Ogr_layer = OGR_DS_GetLayerByName(Ogr_ds, options.layer->answer);
 
586
    else 
 
587
        Ogr_layer = OGR_DS_CreateLayer(Ogr_ds, options.layer->answer, Ogr_projection, wkbtype,
 
588
                                       papszLCO);
 
589
    
311
590
    CSLDestroy(papszLCO);
312
 
    if (Ogr_layer == NULL)
313
 
        G_fatal_error(_("Unable to create OGR layer"));
314
 
 
 
591
    if (Ogr_layer == NULL) {
 
592
        if (flags.append->answer)
 
593
            G_fatal_error(_("OGR layer <%s> not found"), options.layer->answer);
 
594
        else
 
595
            G_fatal_error(_("Unable to create OGR layer"));
 
596
    }
 
597
    
315
598
    db_init_string(&dbstring);
316
599
 
317
600
    /* Vector attributes -> OGR fields */
320
603
        doatt = 1;              /* do attributes */
321
604
        Fi = Vect_get_field(&In, field);
322
605
        if (Fi == NULL) {
 
606
            char create_field = TRUE;
323
607
            G_warning(_("No attribute table found -> using only category numbers as attributes"));
324
 
 
325
 
            Ogr_field = OGR_Fld_Create("cat", OFTInteger);
326
 
            OGR_L_CreateField(Ogr_layer, Ogr_field, 0);
327
 
            OGR_Fld_Destroy(Ogr_field);
328
 
 
329
 
            doatt = 0;
330
 
        }
331
 
        else {
332
 
            Driver = db_start_driver(Fi->driver);
333
 
            if (Driver == NULL)
334
 
                G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
335
 
 
336
 
            db_init_handle(&handle);
337
 
            db_set_handle(&handle, Fi->database, NULL);
338
 
            if (db_open_database(Driver, &handle) != DB_OK)
339
 
                G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
340
 
                              Fi->database, Fi->driver);
341
 
 
342
 
            db_set_string(&dbstring, Fi->table);
343
 
            if (db_describe_table(Driver, &dbstring, &Table) != DB_OK)
344
 
                G_fatal_error(_("Unable to describe table <%s>"), Fi->table);
345
 
 
346
 
            ncol = db_get_table_number_of_columns(Table);
347
 
            G_debug(2, "ncol = %d", ncol);
348
 
            keycol = -1;
349
 
            for (i = 0; i < ncol; i++) {
350
 
                Column = db_get_table_column(Table, i);
351
 
                colsqltype = db_get_column_sqltype(Column);
352
 
                G_debug(2, "col %d: %s (%s)", i, db_get_column_name(Column),
353
 
                        db_sqltype_name(colsqltype));
354
 
                colctype = db_sqltype_to_Ctype(colsqltype);
355
 
 
356
 
                switch (colctype) {
357
 
                case DB_C_TYPE_INT:
358
 
                    ogr_ftype = OFTInteger;
359
 
                    break;
360
 
                case DB_C_TYPE_DOUBLE:
361
 
                    ogr_ftype = OFTReal;
362
 
                    break;
363
 
                case DB_C_TYPE_STRING:
364
 
                    ogr_ftype = OFTString;
365
 
                    break;
366
 
                case DB_C_TYPE_DATETIME:
367
 
                    ogr_ftype = OFTString;
368
 
                    break;
369
 
                }
370
 
                G_debug(2, "ogr_ftype = %d", ogr_ftype);
371
 
 
372
 
                strcpy(key1, Fi->key);
373
 
                G_tolcase(key1);
374
 
                strcpy(key2, db_get_column_name(Column));
375
 
                G_tolcase(key2);
376
 
                if (strcmp(key1, key2) == 0)
377
 
                    keycol = i;
378
 
                G_debug(2, "%s x %s -> %s x %s -> keycol = %d", Fi->key,
379
 
                        db_get_column_name(Column), key1, key2, keycol);
380
 
 
381
 
                Ogr_field =
382
 
                    OGR_Fld_Create(db_get_column_name(Column), ogr_ftype);
 
608
            /* if we have no more than a 'cat' column, then that has to
 
609
               be exported in any case */
 
610
            if (flags.nocat->answer) {
 
611
                G_warning(_("Exporting 'cat' anyway, as it is the only attribute table field"));
 
612
                flags.nocat->answer = FALSE;
 
613
            }
 
614
            
 
615
            if (flags.append->answer) {
 
616
                Ogr_field = OGR_L_GetLayerDefn(Ogr_layer);
 
617
                if (OGR_FD_GetFieldIndex(Ogr_field, GV_KEY_COLUMN) > -1)
 
618
                    create_field = FALSE;
 
619
                else 
 
620
                    G_warning(_("New attribute column <%s> added to the table"),
 
621
                              GV_KEY_COLUMN);
 
622
            }
 
623
            
 
624
            if (create_field) {
 
625
                Ogr_field = OGR_Fld_Create(GV_KEY_COLUMN, OFTInteger);
383
626
                OGR_L_CreateField(Ogr_layer, Ogr_field, 0);
384
627
                OGR_Fld_Destroy(Ogr_field);
385
628
            }
386
 
            if (keycol == -1)
387
 
                G_fatal_error(_("Key column '%s' not found"), Fi->key);
388
 
        }
389
 
 
 
629
            
 
630
            doatt = 0;
 
631
         }
 
632
         else {
 
633
             Driver = db_start_driver_open_database(Fi->driver, Fi->database);
 
634
             if (!Driver)
 
635
                 G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
 
636
                               Fi->database, Fi->driver);
 
637
 
 
638
             db_set_string(&dbstring, Fi->table);
 
639
             if (db_describe_table(Driver, &dbstring, &Table) != DB_OK)
 
640
                 G_fatal_error(_("Unable to describe table <%s>"), Fi->table);
 
641
 
 
642
             ncol = db_get_table_number_of_columns(Table);
 
643
             G_debug(2, "ncol = %d", ncol);
 
644
             colctype = G_malloc(ncol * sizeof(int));
 
645
             colname = G_malloc(ncol * sizeof(char *));
 
646
             keycol = -1;
 
647
             for (i = 0; i < ncol; i++) {
 
648
                 Column = db_get_table_column(Table, i);
 
649
                 colname[i] =  G_store(db_get_column_name(Column));
 
650
                 colsqltype = db_get_column_sqltype(Column);
 
651
                 colctype[i] = db_sqltype_to_Ctype(colsqltype);
 
652
                 colwidth = db_get_column_length(Column);
 
653
                 G_debug(3, "col %d: %s sqltype=%d ctype=%d width=%d",
 
654
                         i, colname[i], colsqltype, colctype[i], colwidth);
 
655
                 
 
656
                 switch (colctype[i]) {
 
657
                 case DB_C_TYPE_INT:
 
658
                     ogr_ftype = OFTInteger;
 
659
                     break;
 
660
                 case DB_C_TYPE_DOUBLE:
 
661
                     ogr_ftype = OFTReal;
 
662
                     break;
 
663
                 case DB_C_TYPE_STRING:
 
664
                     ogr_ftype = OFTString;
 
665
                     break;
 
666
                 case DB_C_TYPE_DATETIME:
 
667
                     ogr_ftype = OFTString;
 
668
                     break;
 
669
                 }
 
670
                 G_debug(2, "ogr_ftype = %d", ogr_ftype);
 
671
 
 
672
                 strcpy(key1, Fi->key);
 
673
                 G_tolcase(key1);
 
674
                 strcpy(key2, colname[i]);
 
675
                 G_tolcase(key2);
 
676
                 if (strcmp(key1, key2) == 0)
 
677
                     keycol = i;
 
678
                 G_debug(2, "%s x %s -> %s x %s -> keycol = %d", Fi->key,
 
679
                         colname[i], key1, key2, keycol);
 
680
 
 
681
                 if (flags.nocat->answer &&
 
682
                     strcmp(Fi->key, colname[i]) == 0)
 
683
                     /* skip export of 'cat' field */
 
684
                     continue;
 
685
 
 
686
                 if (flags.append->answer) {
 
687
                     Ogr_field = OGR_L_GetLayerDefn(Ogr_layer);
 
688
                     if (OGR_FD_GetFieldIndex(Ogr_field, colname[i]) > -1)
 
689
                         /* skip existing fields */
 
690
                         continue;
 
691
                     else
 
692
                         G_warning(_("New attribute column <%s> added to the table"),
 
693
                                   colname[i]);
 
694
                 }
 
695
                 
 
696
                 Ogr_field = OGR_Fld_Create(colname[i], ogr_ftype);
 
697
                 if (ogr_ftype == OFTString && colwidth > 0)
 
698
                     OGR_Fld_SetWidth(Ogr_field, colwidth);
 
699
                 OGR_L_CreateField(Ogr_layer, Ogr_field, 0);
 
700
                 
 
701
                 OGR_Fld_Destroy(Ogr_field);
 
702
             }
 
703
             if (keycol == -1)
 
704
                 G_fatal_error(_("Key column <%s> not found"), Fi->key);
 
705
         }
390
706
    }
391
 
 
 
707
    
392
708
    Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
393
 
    Ogr_feature = OGR_F_Create(Ogr_featuredefn);
394
 
 
395
 
    fout = fskip = nocat = noatt = nocatskip = 0;
396
 
 
397
 
    /* check what users wants to export and what's present in the map */
398
 
    if (Vect_get_num_primitives(&In, GV_POINT) > 0 && !(otype & GV_POINTS))
399
 
        G_warning(_("%d point(s) found, but not requested to be exported. "
400
 
                    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
401
 
                                                                         GV_POINT));
402
 
 
403
 
    if (Vect_get_num_primitives(&In, GV_LINE) > 0 && !(otype & GV_LINES))
404
 
        G_warning(_("%d line(s) found, but not requested to be exported. "
405
 
                    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
406
 
                                                                         GV_LINE));
407
 
 
408
 
    if (Vect_get_num_primitives(&In, GV_BOUNDARY) > 0 &&
409
 
        !(otype & GV_BOUNDARY) && !(otype & GV_AREA))
410
 
        G_warning(_("%d boundary(ies) found, but not requested to be exported. "
411
 
                   "Verify 'type' parameter."), Vect_get_num_primitives(&In,
412
 
                                                                        GV_BOUNDARY));
413
 
 
414
 
    if (Vect_get_num_primitives(&In, GV_CENTROID) > 0 &&
415
 
        !(otype & GV_CENTROID) && !(otype & GV_AREA))
416
 
        G_warning(_("%d centroid(s) found, but not requested to be exported. "
417
 
                   "Verify 'type' parameter."), Vect_get_num_primitives(&In,
418
 
                                                                        GV_CENTROID));
419
 
 
420
 
    if (Vect_get_num_primitives(&In, GV_AREA) > 0 && !(otype & GV_AREA))
421
 
        G_warning(_("%d areas found, but not requested to be exported. "
422
 
                    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
423
 
                                                                         GV_AREA));
424
 
 
425
 
    if (Vect_get_num_primitives(&In, GV_FACE) > 0 && !(otype & GV_FACE))
426
 
        G_warning(_("%d faces found, but not requested to be exported. "
427
 
                    "Verify 'type' parameter."), Vect_get_num_primitives(&In,
428
 
                                                                         GV_FACE));
429
 
 
430
 
    /* add? GV_KERNEL */
431
 
 
 
709
 
 
710
    n_feat = n_nocat = n_noatt = 0;
 
711
 
 
712
    if (OGR_L_TestCapability(Ogr_layer, OLCTransactions))
 
713
        OGR_L_StartTransaction(Ogr_layer);
 
714
    
432
715
    /* Lines (run always to count features of different type) */
433
 
    if ((otype & GV_POINTS) || (otype & GV_LINES)) {
434
 
        G_message(_("Exporting %i points/lines..."), Vect_get_num_lines(&In));
435
 
        for (i = 1; i <= Vect_get_num_lines(&In); i++) {
436
 
 
437
 
            G_percent(i, Vect_get_num_lines(&In), 1);
438
 
 
439
 
            type = Vect_read_line(&In, Points, Cats, i);
440
 
            G_debug(2, "line = %d type = %d", i, type);
441
 
            if (!(otype & type)) {
442
 
                G_debug(2, "type %d not specified -> skipping", type);
443
 
                fskip++;
444
 
                continue;
445
 
            }
446
 
 
447
 
            Vect_cat_get(Cats, field, &cat);
448
 
            if (cat < 0 && !donocat) {  /* Do not export not labeled */
449
 
                nocatskip++;
450
 
                continue;
451
 
            }
452
 
 
453
 
 
454
 
            /* Geometry */
455
 
            if (type == GV_LINE && poly_flag->answer) {
456
 
                OGRGeometryH ring;
457
 
 
458
 
                ring = OGR_G_CreateGeometry(wkbLinearRing);
459
 
                Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
460
 
 
461
 
                /* Area */
462
 
                for (j = 0; j < Points->n_points; j++) {
463
 
                    OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
464
 
                                   Points->z[j]);
465
 
                }
466
 
                if (Points->x[Points->n_points - 1] != Points->x[0] ||
467
 
                    Points->y[Points->n_points - 1] != Points->y[0] ||
468
 
                    Points->z[Points->n_points - 1] != Points->z[0]) {
469
 
                    OGR_G_AddPoint(ring, Points->x[0], Points->y[0],
470
 
                                   Points->z[0]);
471
 
                }
472
 
 
473
 
                OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
474
 
            }
475
 
            else if (type & GV_POINTS) {  /* GV_POINT or GV_CENTROID */
476
 
                Ogr_geometry = OGR_G_CreateGeometry(wkbPoint);
477
 
                OGR_G_AddPoint(Ogr_geometry, Points->x[0], Points->y[0],
478
 
                               Points->z[0]);
479
 
            }
480
 
            else {              /* GV_LINE or GV_BOUNDARY */
481
 
 
482
 
                Ogr_geometry = OGR_G_CreateGeometry(wkbLineString);
483
 
                for (j = 0; j < Points->n_points; j++) {
484
 
                    OGR_G_AddPoint(Ogr_geometry, Points->x[j], Points->y[j],
485
 
                                   Points->z[j]);
486
 
                }
487
 
            }
488
 
            OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
489
 
 
490
 
            /* Output one feature for each category */
491
 
            for (j = -1; j < Cats->n_cats; j++) {
492
 
                if (j == -1) {
493
 
                    if (cat >= 0)
494
 
                        continue;       /* cat(s) exists */
495
 
                }
496
 
                else {
497
 
                    if (Cats->field[j] == field)
498
 
                        cat = Cats->cat[j];
499
 
                    else
500
 
                        continue;
501
 
                }
502
 
 
503
 
                mk_att(cat, Fi, Driver, ncol, doatt, Ogr_feature);
504
 
                OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
505
 
            }
506
 
            OGR_G_DestroyGeometry(Ogr_geometry);
507
 
        }
 
716
    if (otype & (GV_POINTS | GV_LINES | GV_KERNEL | GV_FACE)) {
 
717
        G_message(_n("Exporting %d feature...",
 
718
                     "Exporting %d features...",
 
719
                     Vect_get_num_primitives(&In, otype)),
 
720
                 Vect_get_num_primitives(&In, otype));
 
721
 
 
722
        n_feat += export_lines(&In, field, otype, flags.multi->answer ? TRUE : FALSE,
 
723
                               donocat, ftype == GV_BOUNDARY ? TRUE : FALSE,
 
724
                               Ogr_featuredefn, Ogr_layer,
 
725
                               Fi, Driver, ncol, colctype, 
 
726
                               colname, doatt, flags.nocat->answer ? TRUE : FALSE,
 
727
                               &n_noatt, &n_nocat);
508
728
    }
509
729
 
510
730
    /* Areas (run always to count features of different type) */
511
 
    if (otype & GV_AREA) {
512
 
        G_message(_("Exporting %i areas (may take some time)..."),
 
731
    if (Vect_get_num_areas(&In) > 0 && (otype & GV_AREA)) {
 
732
        G_message(_n("Exporting %d area (may take some time)...",
 
733
                     "Exporting %d areas (may take some time)...",
 
734
                     Vect_get_num_areas(&In)),
513
735
                  Vect_get_num_areas(&In));
514
 
        for (i = 1; i <= Vect_get_num_areas(&In); i++) {
515
 
            OGRGeometryH ring;
516
 
 
517
 
            G_percent(i, Vect_get_num_areas(&In), 1);
518
 
 
519
 
            centroid = Vect_get_area_centroid(&In, i);
520
 
            cat = -1;
521
 
            if (centroid > 0) {
522
 
                Vect_read_line(&In, NULL, Cats, centroid);
523
 
                Vect_cat_get(Cats, field, &cat);
524
 
            }
525
 
            G_debug(3, "area = %d centroid = %d ncats = %d", i, centroid,
526
 
                    Cats->n_cats);
527
 
            if (cat < 0 && !donocat) {  /* Do not export not labeled */
528
 
                nocatskip++;
529
 
                continue;
530
 
            }
531
 
 
532
 
            Vect_get_area_points(&In, i, Points);
533
 
 
534
 
            /* Geometry */
535
 
            Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
536
 
 
537
 
            ring = OGR_G_CreateGeometry(wkbLinearRing);
538
 
 
539
 
            /* Area */
540
 
            for (j = 0; j < Points->n_points; j++) {
541
 
                OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
542
 
                               Points->z[j]);
543
 
            }
544
 
 
545
 
            OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
546
 
 
547
 
            /* Isles */
548
 
            for (k = 0; k < Vect_get_area_num_isles(&In, i); k++) {
549
 
                Vect_get_isle_points(&In, Vect_get_area_isle(&In, i, k),
550
 
                                     Points);
551
 
 
552
 
                ring = OGR_G_CreateGeometry(wkbLinearRing);
553
 
                for (j = 0; j < Points->n_points; j++) {
554
 
                    OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
555
 
                                   Points->z[j]);
556
 
                }
557
 
                OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
558
 
            }
559
 
 
560
 
            OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
561
 
 
562
 
            /* Output one feature for each category */
563
 
            for (j = -1; j < Cats->n_cats; j++) {
564
 
                if (j == -1) {
565
 
                    if (cat >= 0)
566
 
                        continue;       /* cat(s) exists */
567
 
                }
568
 
                else {
569
 
                    if (Cats->field[j] == field)
570
 
                        cat = Cats->cat[j];
571
 
                    else
572
 
                        continue;
573
 
                }
574
 
 
575
 
                mk_att(cat, Fi, Driver, ncol, doatt, Ogr_feature);
576
 
                OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
577
 
            }
578
 
            OGR_G_DestroyGeometry(Ogr_geometry);
579
 
        }
580
 
    }
581
 
 
582
 
    /* Faces (run always to count features of different type)  - Faces are similar to lines */
583
 
    if (otype & GV_FACE) {
584
 
        G_message(_("Exporting %i faces (may take some time) ..."),
585
 
                  Vect_get_num_faces(&In));
586
 
        for (i = 1; i <= Vect_get_num_faces(&In); i++) {
587
 
            OGRGeometryH ring;
588
 
 
589
 
            G_percent(i, Vect_get_num_faces(&In), 1);
590
 
 
591
 
            type = Vect_read_line(&In, Points, Cats, i);
592
 
            G_debug(3, "line type = %d", type);
593
 
 
594
 
            cat = -1;
595
 
            Vect_cat_get(Cats, field, &cat);
596
 
 
597
 
            G_debug(3, "face = %d ncats = %d", i, Cats->n_cats);
598
 
            if (cat < 0 && !donocat) {  /* Do not export not labeled */
599
 
                nocatskip++;
600
 
                continue;
601
 
            }
602
 
 
603
 
            if (type & GV_FACE) {
604
 
 
605
 
                /* Geometry */
606
 
                Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon25D);
607
 
                ring = OGR_G_CreateGeometry(wkbLinearRing);
608
 
 
609
 
                /* Face */
610
 
                for (j = 0; j < Points->n_points; j++) {
611
 
                    OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
612
 
                                   Points->z[j]);
613
 
                }
614
 
 
615
 
                OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
616
 
 
617
 
                OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
618
 
 
619
 
                /* Output one feature for each category */
620
 
                for (j = -1; j < Cats->n_cats; j++) {
621
 
                    if (j == -1) {
622
 
                        if (cat >= 0)
623
 
                            continue;   /* cat(s) exists */
624
 
                    }
625
 
                    else {
626
 
                        if (Cats->field[j] == field)
627
 
                            cat = Cats->cat[j];
628
 
                        else
629
 
                            continue;
630
 
                    }
631
 
 
632
 
                    mk_att(cat, Fi, Driver, ncol, doatt, Ogr_feature);
633
 
                    OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
634
 
                }
635
 
 
636
 
                OGR_G_DestroyGeometry(Ogr_geometry);
637
 
            }                   /* if type & GV_FACE */
638
 
 
639
 
        }                       /* for */
640
 
    }
641
 
 
642
 
 
643
 
    OGR_F_Destroy(Ogr_feature);
 
736
 
 
737
        n_feat += export_areas(&In, field, flags.multi->answer ? TRUE : FALSE, donocat, 
 
738
                               Ogr_featuredefn, Ogr_layer,
 
739
                               Fi, Driver, ncol, colctype, 
 
740
                               colname, doatt, flags.nocat->answer ? TRUE : FALSE,
 
741
                               &n_noatt, &n_nocat);
 
742
    }
 
743
 
 
744
    /*
 
745
       TODO: Volumes. Do not export kernels here, that's already done.
 
746
       We do need to worry about holes, though. NOTE: We can probably
 
747
       just merge this with faces export function. Except for GRASS,
 
748
       which output format would know the difference?
 
749
     */
 
750
    if (Vect_get_num_volumes(&In) > 0 && (otype & GV_VOLUME)) {
 
751
        G_message(_n("Exporting %d volume...",
 
752
                     "Exporting %d volumes...",
 
753
                     Vect_get_num_volumes(&In)),
 
754
                  Vect_get_num_volumes(&In));
 
755
        G_warning(_("Export of volumes not implemented yet. Skipping."));
 
756
    }
 
757
 
 
758
    if (OGR_L_TestCapability(Ogr_layer, OLCTransactions))
 
759
        OGR_L_CommitTransaction(Ogr_layer);
 
760
 
644
761
    OGR_DS_Destroy(Ogr_ds);
645
762
 
646
763
    Vect_close(&In);
651
768
    }
652
769
 
653
770
    /* Summary */
654
 
    G_message(_("%d features written"), fout);
655
 
    if (nocat > 0)
656
 
        G_warning(_("%d features without category were written"), nocat);
657
 
    if (noatt > 0)
658
 
        G_warning(_("%d features without attributes were written"), noatt);
659
 
    if (nocatskip > 0)
660
 
        G_warning(_("%d features found without category were skipped"),
661
 
                nocatskip);
662
 
 
663
 
    /* Enable this? May be confusing that for area type are not reported
664
 
     *    all boundaries/centroids.
665
 
     *  OTOH why should be reported? */
 
771
    if (n_noatt > 0)
 
772
        G_important_message(_n("%d feature without attributes was written",
 
773
                               "%d features without attributes were written",
 
774
                               n_noatt), n_noatt);
 
775
 
 
776
    if (n_nocat > 0) {
 
777
        if (donocat)
 
778
            G_important_message(_n("%d feature without category was written",
 
779
                                   "%d features without category were written",
 
780
                                   n_nocat), n_nocat);
 
781
        else
 
782
            G_warning(_n("%d feature without category was skipped. "
 
783
                         "Features without category are written only when -%c flag is given.",
 
784
                         "%d features without category were skipped. "
 
785
                         "Features without category are written only when -%c flag is given.",
 
786
                         n_nocat), n_nocat, flags.cat->key);
 
787
    }
 
788
 
 
789
    /* Enable this? May be confusing that for area type are not
 
790
     * reported all boundaries/centroids. OTOH why should be
 
791
     * reported? */
666
792
    /*
667
 
       if ( ((otype & GV_POINTS) || (otype & GV_LINES)) && fskip > 0 ) 
668
 
       G_warning ( "%d features of different type skip", fskip);
 
793
       if (((otype & GV_POINTS) || (otype & GV_LINES)) && fskip > 0)
 
794
       G_warning ("%d features of different type skip", fskip);
669
795
     */
670
796
 
 
797
    if (n_feat < 1)
 
798
        G_warning(_("Output layer is empty, no features written"));
 
799
    G_done_msg(_n("%d feature (%s type) written to <%s> (%s format).",
 
800
                  "%d features (%s type) written to <%s> (%s format).",
 
801
                  n_feat), n_feat,
 
802
               OGRGeometryTypeToName(wkbtype),
 
803
               options.layer->answer, options.format->answer);
 
804
 
671
805
    exit(EXIT_SUCCESS);
672
806
}
673
 
 
674
 
 
675
 
int mk_att(int cat, struct field_info *Fi, dbDriver *Driver, int ncol,
676
 
       int doatt, OGRFeatureH Ogr_feature)
677
 
{
678
 
    int j, ogrfieldnum;
679
 
    char buf[2000];
680
 
    int colsqltype, colctype, more;
681
 
    dbTable *Table;
682
 
    dbString dbstring;
683
 
    dbColumn *Column;
684
 
    dbCursor cursor;
685
 
    dbValue *Value;
686
 
 
687
 
    G_debug(2, "mk_att() cat = %d, doatt = %d", cat, doatt);
688
 
    db_init_string(&dbstring);
689
 
 
690
 
    /* Attributes */
691
 
    /* Reset */
692
 
    if (!doatt) {
693
 
        ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, "cat");
694
 
        OGR_F_UnsetField(Ogr_feature, ogrfieldnum);
695
 
    /* doatt reset moved into have cat loop as the table needs to be
696
 
        open to know the OGR field ID. Hopefully this has no ill consequences */
697
 
    }
698
 
 
699
 
    /* Read & set attributes */
700
 
    if (cat >= 0) {             /* Line with category */
701
 
        if (doatt) {
702
 
            sprintf(buf, "SELECT * FROM %s WHERE %s = %d", Fi->table, Fi->key,
703
 
                    cat);
704
 
            G_debug(2, "SQL: %s", buf);
705
 
            db_set_string(&dbstring, buf);
706
 
            if (db_open_select_cursor
707
 
                (Driver, &dbstring, &cursor, DB_SEQUENTIAL) != DB_OK) {
708
 
                G_fatal_error(_("Cannot select attributes for cat = %d"),
709
 
                              cat);
710
 
            }
711
 
            else {
712
 
                if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
713
 
                    G_fatal_error(_("Unable to fetch data from table"));
714
 
                if (!more) {
715
 
                    /* G_warning ("No database record for cat = %d", cat); */
716
 
                    /* Set at least key column to category */
717
 
                    ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, Fi->key);
718
 
                    OGR_F_SetFieldInteger(Ogr_feature, ogrfieldnum, cat);
719
 
                    noatt++;
720
 
                }
721
 
                else {
722
 
                    Table = db_get_cursor_table(&cursor);
723
 
                    for (j = 0; j < ncol; j++) {
724
 
                        Column = db_get_table_column(Table, j);
725
 
                        Value = db_get_column_value(Column);
726
 
                        db_convert_column_value_to_string(Column, &dbstring);   /* for debug only */
727
 
                        G_debug(2, "col %d : val = %s", j,
728
 
                                db_get_string(&dbstring));
729
 
 
730
 
                        colsqltype = db_get_column_sqltype(Column);
731
 
                        colctype = db_sqltype_to_Ctype(colsqltype);
732
 
                        G_debug(2, "  colctype = %d", colctype);
733
 
 
734
 
                        ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature,
735
 
                                                          db_get_column_name(Column));
736
 
 
737
 
                        /* Reset */
738
 
                        OGR_F_UnsetField(Ogr_feature, ogrfieldnum);
739
 
 
740
 
                        /* prevent writing NULL values */
741
 
                        if (!db_test_value_isnull(Value)) {
742
 
                                switch (colctype) {
743
 
                                case DB_C_TYPE_INT:
744
 
                                        OGR_F_SetFieldInteger(Ogr_feature, ogrfieldnum,
745
 
                                                        db_get_value_int(Value));
746
 
                                        break;
747
 
                                case DB_C_TYPE_DOUBLE:
748
 
                                        OGR_F_SetFieldDouble(Ogr_feature, ogrfieldnum,
749
 
                                                        db_get_value_double(Value));
750
 
                                        break;
751
 
                                case DB_C_TYPE_STRING:
752
 
                                        OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
753
 
                                                        db_get_value_string(Value));
754
 
                                        break;
755
 
                                case DB_C_TYPE_DATETIME:
756
 
                                        db_convert_column_value_to_string(Column,
757
 
                                                                        &dbstring);
758
 
                                        OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
759
 
                                                        db_get_string(&dbstring));
760
 
                                        break;
761
 
                                }
762
 
                        }
763
 
                    }
764
 
                }
765
 
            }
766
 
 
767
 
        }
768
 
        else {                  /* Use cat only */
769
 
            ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, "cat");
770
 
            OGR_F_SetFieldInteger(Ogr_feature, ogrfieldnum, cat);
771
 
        }
772
 
    }
773
 
    else {
774
 
        /* G_warning ( "Line without cat of layer %d", field); */
775
 
        nocat++;
776
 
    }
777
 
    fout++;
778
 
 
779
 
    return 1;
780
 
}
781
 
 
782
 
 
783
 
/* to print available drivers in help text */
784
 
char *OGR_list_write_drivers(void)
785
 
{
786
 
    int drn, i;
787
 
    OGRSFDriverH Ogr_driver;
788
 
    char buf[2000];
789
 
 
790
 
    /* Open OGR DSN */
791
 
    OGRRegisterAll();
792
 
    G_debug(2, "driver count = %d", OGRGetDriverCount());
793
 
    drn = -1;
794
 
    for (i = 0; i < OGRGetDriverCount(); i++) {
795
 
        /* only fetch read/write drivers */
796
 
        if (OGR_Dr_TestCapability(OGRGetDriver(i), ODrCCreateDataSource)) {
797
 
            Ogr_driver = OGRGetDriver(i);
798
 
            G_debug(2, "driver %d/%d : %s", i, OGRGetDriverCount(),
799
 
                    OGR_Dr_GetName(Ogr_driver));
800
 
            /* chg white space to underscore in OGR driver names */
801
 
            sprintf(buf, "%s", OGR_Dr_GetName(Ogr_driver));
802
 
            G_strchg(buf, ' ', '_');
803
 
            strcat(OGRdrivers, buf);
804
 
            if (i < OGRGetDriverCount() - 1)
805
 
                strcat(OGRdrivers, ",");
806
 
        }
807
 
    }
808
 
    G_debug(2, "all drivers: %s", OGRdrivers);
809
 
    return OGRdrivers;
810
 
}