2
2
***************************************************************
6
6
* AUTHOR(S): Radim Blazek
7
* Some extensions: Markus Neteler
9
* PURPOSE: Category manipulations
11
* COPYRIGHT: (C) 2001 by the GRASS Development Team
13
* This program is free software under the
14
* GNU General Public License (>=v2).
15
* Read the file COPYING that comes with GRASS
7
* Some extensions: Markus Neteler, Benjamin Ducke
8
* Multi-features support by Martin Landa <landa.martin gmail.com>
10
* PURPOSE: Converts GRASS vector to one of supported OGR vector formats.
12
* COPYRIGHT: (C) 2001-2013 by the GRASS Development Team
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.
18
18
**************************************************************/
19
20
#include <stdlib.h>
20
21
#include <string.h>
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>
28
#include "cpl_string.h"
30
int fout, fskip; /* features written/ skip */
31
int nocat, noatt, nocatskip; /* number of features without cats/atts written/skip */
33
int mk_att(int cat, struct field_info *Fi, dbDriver *Driver,
34
int ncol, int doatt, OGRFeatureH Ogr_feature);
36
char *OGR_list_write_drivers();
37
char OGRdrivers[2000];
28
#include "local_proto.h"
30
#include "ogr_srs_api.h"
39
32
int main(int argc, char *argv[])
41
int i, j, k, centroid, otype, donocat;
34
int i, otype, ftype, donocat;
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;
49
char key1[200], key2[200];
50
struct Key_Value *projinfo, *projunits;
40
struct Options options;
43
char buf[SQL_BUFFER_SIZE];
44
char key1[SQL_BUFFER_SIZE], key2[SQL_BUFFER_SIZE];
51
45
struct Cell_head cellhd;
55
49
struct Map_info In;
56
struct line_pnts *Points;
57
struct line_cats *Cats;
61
int doatt = 0, ncol = 0, colsqltype, colctype, keycol = -1;
52
int doatt = 0, ncol = 0, colsqltype, colwidth, keycol = -1;
54
const char **colname = NULL;
62
55
struct field_info *Fi = NULL;
63
56
dbDriver *Driver = NULL;
61
int n_feat; /* number of written features */
62
int n_nocat, n_noatt; /* number of features without cats/atts written/skip */
70
int drn, ogr_ftype = OFTInteger;
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;
82
77
G_gisinit(argv[0]);
84
79
/* Module options */
85
80
module = G_define_module();
86
module->keywords = _("vector, export");
88
_("Converts to one of the supported OGR vector formats.");
90
in_opt = G_define_standard_option(G_OPT_V_INPUT);
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 "
98
type_opt->guisection = _("Input");
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");
108
layer_opt = G_define_option();
109
layer_opt->key = "olayer";
110
layer_opt->type = TYPE_STRING;
111
layer_opt->required = NO;
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");
117
field_opt = G_define_standard_option(G_OPT_V_FIELD);
118
field_opt->guisection = _("Input");
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");
130
dsco = G_define_option();
132
dsco->type = TYPE_STRING;
134
dsco->multiple = YES;
137
_("OGR dataset creation option (format specific, NAME=VALUE)");
138
dsco->guisection = _("Creation");
140
lco = G_define_option();
142
lco->type = TYPE_STRING;
147
_("OGR layer creation option (format specific, NAME=VALUE)");
148
lco->guisection = _("Creation");
150
cat_flag = G_define_flag();
152
cat_flag->description = _("Export features with category (labeled) only. "
153
"Otherwise all features are exported");
155
esristyle = G_define_flag();
156
esristyle->key = 'e';
157
esristyle->description = _("Use ESRI-style .prj file format "
158
"(applies to Shapefile output only)");
160
poly_flag = G_define_flag();
161
poly_flag->key = 'p';
162
poly_flag->description = _("Export lines as polygons");
164
if (G_parser(argc, argv))
169
field = atoi(field_opt->answer);
171
/* Check output type */
172
otype = Vect_option_to_types(type_opt);
174
if (!layer_opt->answer) {
175
char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
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"));
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;
90
/* parse & read options */
91
parse_args(argc, argv, &options, &flags);
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);
99
/* parse dataset creation options */
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);
109
/* parse layer creation options */
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);
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.
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);
132
if (strcmp(options.type->answer, "auto") == 0) {
133
G_debug(2, "Automatic type determination.");
135
options.type->answers = G_malloc(sizeof(char *) * 10);
136
G_zero(options.type->answers, sizeof(char *) * 10);
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.");
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.");
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.");
154
/* Faces and volumes:
155
For now, volumes will just be exported as sets of faces.
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.");
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.");
171
if (strcmp(options.type->answers[num_types - 1], "face")
173
/* only put faces on export list if that's not the case already */
174
options.type->answers[num_types++] =
176
G_debug(3, "Adding volumes to export list.");
181
if (num_types == 0) {
182
G_warning(_("Unable to determine input map's vector feature type(s)."));
187
field = Vect_get_field_number(&In, options.field->answer);
189
/* check output feature type */
190
otype = Vect_option_to_types(options.type);
191
ftype = Vect_option_to_types(options.otype);
193
if (!options.layer->answer) {
194
char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
196
if (flags.append->answer)
197
G_fatal_error(_("Appending to OGR layer requires option '%s'"),
200
if (G_name_is_fully_qualified(options.input->answer, xname, xmapset))
201
options.layer->answer = G_store(xname);
180
layer_opt->answer = G_store(in_opt->answer);
183
if (otype & GV_POINTS)
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;
192
if (poly_flag->answer)
193
wkbtype = wkbPolygon;
203
options.layer->answer = G_store(options.input->answer);
206
if (ftype == GV_BOUNDARY) {
207
if (!flags.multi->answer)
208
wkbtype = wkbPolygon;
210
wkbtype = wkbMultiPolygon;
212
else if (otype & GV_POINTS) {
213
if (!flags.multi->answer)
216
wkbtype = wkbMultiPoint;
218
else if (otype & GV_LINES || ftype == GV_LINE) {
219
if (!flags.multi->answer)
220
wkbtype = wkbLineString;
222
wkbtype = wkbMultiLineString;
224
else if (otype & GV_AREA) {
225
if (!flags.multi->answer)
226
wkbtype = wkbPolygon;
228
wkbtype = wkbMultiPolygon;
230
else if (otype & (GV_FACE | GV_VOLUME)) {
231
if (!flags.multi->answer)
232
wkbtype = wkbPolygon25D;
234
wkbtype = wkbMultiPolygon25D;
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))
201
252
G_warning(_("The combination of types is not supported"
202
253
" by all formats."));
203
254
wkbtype = wkbUnknown;
207
if (cat_flag->answer)
212
Points = Vect_new_line_struct();
213
Cats = Vect_new_cats_struct();
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);
220
Vect_set_open_level(2);
221
Vect_open_old(&In, in_opt->answer, mapset);
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"));
226
257
/* fetch PROJ info */
227
258
G_get_default_window(&cellhd);
228
if (cellhd.proj == PROJECTION_XY)
229
Ogr_projection = NULL;
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) {
263
Ogr_projection = NULL;
264
/* try EPSG code first */
265
epsg = G_database_epsg_code();
267
struct Key_Value *projinfo, *projunits;
269
projinfo = G_get_projinfo();
270
projunits = G_get_projunits();
271
Ogr_projection = GPJ_grass_to_osr(projinfo, projunits);
274
Ogr_projection = OSRNewSpatialReference(NULL);
275
if (OSRImportFromEPSG(Ogr_projection, atoi(epsg)) != OGRERR_NONE)
276
G_fatal_error(_("Unknown EPSG code %s"), epsg);
278
if (flags.esristyle->answer &&
279
(strcmp(options.format->answer, "ESRI_Shapefile") == 0))
236
280
OSRMorphToESRI(Ogr_projection);
283
/* create new OGR layer in datasource */
284
if (flags.new->answer) {
288
options.layer->answer ? options.layer->answer : options.input->
291
create_ogr_layer(options.dsn->answer, options.format->answer, name,
292
wkbtype, papszDSCO, papszLCO);
294
G_message(_("OGR layer <%s> created in datasource <%s> (format '%s')"),
295
name, options.dsn->answer, options.format->answer);
299
if (flags.cat->answer)
304
if ((GV_AREA & otype) && Vect_get_num_islands(&In) > 0 &&
306
G_warning(_("The map contains islands. With the -c flag, "
307
"islands will appear as filled areas, not holes in the output map."));
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));
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));
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));
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));
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));
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));
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));
369
/* warn and eventually abort if there is nothing to be exported */
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."));
376
if (otype & GV_POINT)
377
num_to_export += Vect_get_num_primitives(&In, GV_POINT);
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."));
386
num_to_export += Vect_get_num_primitives(&In, GV_LINE);
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."));
395
if (otype & GV_BOUNDARY)
396
num_to_export += Vect_get_num_primitives(&In, GV_BOUNDARY);
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."));
405
num_to_export += Vect_get_num_areas(&In);
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."));
414
if (otype & GV_CENTROID)
415
num_to_export += Vect_get_num_primitives(&In, GV_CENTROID);
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."));
424
num_to_export += Vect_get_num_primitives(&In, GV_FACE);
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."));
432
if (otype & GV_KERNEL)
433
num_to_export += Vect_get_num_primitives(&In, GV_KERNEL);
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."));
441
if (otype & GV_VOLUME)
442
num_to_export += Vect_get_num_volumes(&In);
445
G_debug(1, "Requested to export %d features", num_to_export);
239
447
/* Open OGR DSN */
240
/* OGRRegisterAll(); */ /* drivers are already registered */
241
448
G_debug(2, "driver count = %d", OGRGetDriverCount());
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) {
251
458
G_debug(2, " -> driver = %d", drn);
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);
258
/* parse dataset creation options */
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);
268
G_debug(1, "Create OGR data source");
269
Ogr_ds = OGR_Dr_CreateDataSource(Ogr_driver, dsn_opt->answer, papszDSCO);
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);
469
if (Ogr_ds == NULL) {
470
G_debug(1, "Create OGR data source");
471
Ogr_ds = OGR_Dr_CreateDataSource(Ogr_driver, options.dsn->answer,
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);
481
G_debug(1, "Create OGR data source");
482
Ogr_ds = OGR_Dr_CreateDataSource(Ogr_driver, options.dsn->answer,
270
487
CSLDestroy(papszDSCO);
271
488
if (Ogr_ds == NULL)
272
489
G_fatal_error(_("Unable to open OGR data source '%s'"),
275
/* parse layer creation options */
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);
490
options.dsn->answer);
492
/* check if OGR layer exists */
493
overwrite = G_check_overwrite(argc, argv);
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))
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);
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);
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;
520
/* Automatically append driver options for 3D output to layer
521
creation options if '2' is not given.*/
522
if (!flags.force2d->answer &&
524
strcmp(options.format->answer, "ESRI_Shapefile") == 0) {
525
/* find right option */
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 */
535
shpt = CSLFetchNameValue(papszLCO, "SHPT");
537
/* Not set at all? Good! */
538
papszLCO = CSLSetNameValue(papszLCO, "SHPT", shape_geom);
540
if (strcmp(shpt, shape_geom) != 0) {
541
/* Set but to a different value? Override! */
542
G_warning(_("Overriding existing user-defined 'SHPT=' LCO."));
544
/* Set correct LCO for this geometry type */
545
papszLCO = CSLSetNameValue(papszLCO, "SHPT", shape_geom);
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;
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)"),
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);
563
/* specific check for PostgreSQL */
564
else if (strcmp(options.format->answer, "PostgreSQL") == 0) {
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);
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)"),
578
"to export <in 3D rather than 2D (default)."),
579
options.input->answer);
307
583
G_debug(1, "Create OGR layer");
309
OGR_DS_CreateLayer(Ogr_ds, layer_opt->answer, Ogr_projection, wkbtype,
584
if (flags.append->answer)
585
Ogr_layer = OGR_DS_GetLayerByName(Ogr_ds, options.layer->answer);
587
Ogr_layer = OGR_DS_CreateLayer(Ogr_ds, options.layer->answer, Ogr_projection, wkbtype,
311
590
CSLDestroy(papszLCO);
312
if (Ogr_layer == NULL)
313
G_fatal_error(_("Unable to create OGR layer"));
591
if (Ogr_layer == NULL) {
592
if (flags.append->answer)
593
G_fatal_error(_("OGR layer <%s> not found"), options.layer->answer);
595
G_fatal_error(_("Unable to create OGR layer"));
315
598
db_init_string(&dbstring);
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"));
325
Ogr_field = OGR_Fld_Create("cat", OFTInteger);
326
OGR_L_CreateField(Ogr_layer, Ogr_field, 0);
327
OGR_Fld_Destroy(Ogr_field);
332
Driver = db_start_driver(Fi->driver);
334
G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
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);
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);
346
ncol = db_get_table_number_of_columns(Table);
347
G_debug(2, "ncol = %d", ncol);
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);
358
ogr_ftype = OFTInteger;
360
case DB_C_TYPE_DOUBLE:
363
case DB_C_TYPE_STRING:
364
ogr_ftype = OFTString;
366
case DB_C_TYPE_DATETIME:
367
ogr_ftype = OFTString;
370
G_debug(2, "ogr_ftype = %d", ogr_ftype);
372
strcpy(key1, Fi->key);
374
strcpy(key2, db_get_column_name(Column));
376
if (strcmp(key1, key2) == 0)
378
G_debug(2, "%s x %s -> %s x %s -> keycol = %d", Fi->key,
379
db_get_column_name(Column), key1, key2, keycol);
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;
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;
620
G_warning(_("New attribute column <%s> added to the table"),
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);
387
G_fatal_error(_("Key column '%s' not found"), Fi->key);
633
Driver = db_start_driver_open_database(Fi->driver, Fi->database);
635
G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
636
Fi->database, Fi->driver);
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);
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 *));
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);
656
switch (colctype[i]) {
658
ogr_ftype = OFTInteger;
660
case DB_C_TYPE_DOUBLE:
663
case DB_C_TYPE_STRING:
664
ogr_ftype = OFTString;
666
case DB_C_TYPE_DATETIME:
667
ogr_ftype = OFTString;
670
G_debug(2, "ogr_ftype = %d", ogr_ftype);
672
strcpy(key1, Fi->key);
674
strcpy(key2, colname[i]);
676
if (strcmp(key1, key2) == 0)
678
G_debug(2, "%s x %s -> %s x %s -> keycol = %d", Fi->key,
679
colname[i], key1, key2, keycol);
681
if (flags.nocat->answer &&
682
strcmp(Fi->key, colname[i]) == 0)
683
/* skip export of 'cat' field */
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 */
692
G_warning(_("New attribute column <%s> added to the table"),
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);
701
OGR_Fld_Destroy(Ogr_field);
704
G_fatal_error(_("Key column <%s> not found"), Fi->key);
392
708
Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
393
Ogr_feature = OGR_F_Create(Ogr_featuredefn);
395
fout = fskip = nocat = noatt = nocatskip = 0;
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,
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,
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,
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,
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,
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,
710
n_feat = n_nocat = n_noatt = 0;
712
if (OGR_L_TestCapability(Ogr_layer, OLCTransactions))
713
OGR_L_StartTransaction(Ogr_layer);
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++) {
437
G_percent(i, Vect_get_num_lines(&In), 1);
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);
447
Vect_cat_get(Cats, field, &cat);
448
if (cat < 0 && !donocat) { /* Do not export not labeled */
455
if (type == GV_LINE && poly_flag->answer) {
458
ring = OGR_G_CreateGeometry(wkbLinearRing);
459
Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
462
for (j = 0; j < Points->n_points; j++) {
463
OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
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],
473
OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
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],
480
else { /* GV_LINE or GV_BOUNDARY */
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],
488
OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
490
/* Output one feature for each category */
491
for (j = -1; j < Cats->n_cats; j++) {
494
continue; /* cat(s) exists */
497
if (Cats->field[j] == field)
503
mk_att(cat, Fi, Driver, ncol, doatt, Ogr_feature);
504
OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
506
OGR_G_DestroyGeometry(Ogr_geometry);
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));
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,
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++) {
517
G_percent(i, Vect_get_num_areas(&In), 1);
519
centroid = Vect_get_area_centroid(&In, i);
522
Vect_read_line(&In, NULL, Cats, centroid);
523
Vect_cat_get(Cats, field, &cat);
525
G_debug(3, "area = %d centroid = %d ncats = %d", i, centroid,
527
if (cat < 0 && !donocat) { /* Do not export not labeled */
532
Vect_get_area_points(&In, i, Points);
535
Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
537
ring = OGR_G_CreateGeometry(wkbLinearRing);
540
for (j = 0; j < Points->n_points; j++) {
541
OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
545
OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
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),
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],
557
OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
560
OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
562
/* Output one feature for each category */
563
for (j = -1; j < Cats->n_cats; j++) {
566
continue; /* cat(s) exists */
569
if (Cats->field[j] == field)
575
mk_att(cat, Fi, Driver, ncol, doatt, Ogr_feature);
576
OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
578
OGR_G_DestroyGeometry(Ogr_geometry);
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++) {
589
G_percent(i, Vect_get_num_faces(&In), 1);
591
type = Vect_read_line(&In, Points, Cats, i);
592
G_debug(3, "line type = %d", type);
595
Vect_cat_get(Cats, field, &cat);
597
G_debug(3, "face = %d ncats = %d", i, Cats->n_cats);
598
if (cat < 0 && !donocat) { /* Do not export not labeled */
603
if (type & GV_FACE) {
606
Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon25D);
607
ring = OGR_G_CreateGeometry(wkbLinearRing);
610
for (j = 0; j < Points->n_points; j++) {
611
OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
615
OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
617
OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
619
/* Output one feature for each category */
620
for (j = -1; j < Cats->n_cats; j++) {
623
continue; /* cat(s) exists */
626
if (Cats->field[j] == field)
632
mk_att(cat, Fi, Driver, ncol, doatt, Ogr_feature);
633
OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
636
OGR_G_DestroyGeometry(Ogr_geometry);
637
} /* if type & GV_FACE */
643
OGR_F_Destroy(Ogr_feature);
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,
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?
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."));
758
if (OGR_L_TestCapability(Ogr_layer, OLCTransactions))
759
OGR_L_CommitTransaction(Ogr_layer);
644
761
OGR_DS_Destroy(Ogr_ds);
654
G_message(_("%d features written"), fout);
656
G_warning(_("%d features without category were written"), nocat);
658
G_warning(_("%d features without attributes were written"), noatt);
660
G_warning(_("%d features found without category were skipped"),
663
/* Enable this? May be confusing that for area type are not reported
664
* all boundaries/centroids.
665
* OTOH why should be reported? */
772
G_important_message(_n("%d feature without attributes was written",
773
"%d features without attributes were written",
778
G_important_message(_n("%d feature without category was written",
779
"%d features without category were written",
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);
789
/* Enable this? May be confusing that for area type are not
790
* reported all boundaries/centroids. OTOH why should be
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);
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).",
802
OGRGeometryTypeToName(wkbtype),
803
options.layer->answer, options.format->answer);
671
805
exit(EXIT_SUCCESS);
675
int mk_att(int cat, struct field_info *Fi, dbDriver *Driver, int ncol,
676
int doatt, OGRFeatureH Ogr_feature)
680
int colsqltype, colctype, more;
687
G_debug(2, "mk_att() cat = %d, doatt = %d", cat, doatt);
688
db_init_string(&dbstring);
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 */
699
/* Read & set attributes */
700
if (cat >= 0) { /* Line with category */
702
sprintf(buf, "SELECT * FROM %s WHERE %s = %d", Fi->table, Fi->key,
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"),
712
if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
713
G_fatal_error(_("Unable to fetch data from table"));
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);
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));
730
colsqltype = db_get_column_sqltype(Column);
731
colctype = db_sqltype_to_Ctype(colsqltype);
732
G_debug(2, " colctype = %d", colctype);
734
ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature,
735
db_get_column_name(Column));
738
OGR_F_UnsetField(Ogr_feature, ogrfieldnum);
740
/* prevent writing NULL values */
741
if (!db_test_value_isnull(Value)) {
744
OGR_F_SetFieldInteger(Ogr_feature, ogrfieldnum,
745
db_get_value_int(Value));
747
case DB_C_TYPE_DOUBLE:
748
OGR_F_SetFieldDouble(Ogr_feature, ogrfieldnum,
749
db_get_value_double(Value));
751
case DB_C_TYPE_STRING:
752
OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
753
db_get_value_string(Value));
755
case DB_C_TYPE_DATETIME:
756
db_convert_column_value_to_string(Column,
758
OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
759
db_get_string(&dbstring));
768
else { /* Use cat only */
769
ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, "cat");
770
OGR_F_SetFieldInteger(Ogr_feature, ogrfieldnum, cat);
774
/* G_warning ( "Line without cat of layer %d", field); */
783
/* to print available drivers in help text */
784
char *OGR_list_write_drivers(void)
787
OGRSFDriverH Ogr_driver;
792
G_debug(2, "driver count = %d", OGRGetDriverCount());
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, ",");
808
G_debug(2, "all drivers: %s", OGRdrivers);