source: grass/trunk/vector/v.in.ascii/main.c

Last change on this file was 74209, checked in by mmetz, 5 years ago

v.in.ascii: no default answer for text, needed to import geonames

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id
  • Property svn:mime-type set to text/x-csrc
File size: 16.9 KB
Line 
1
2/****************************************************************************
3 *
4 * MODULE: v.in.ascii
5 *
6 * AUTHOR(S): Original authors Michael Higgins, James Westervelt (CERL)
7 * Updated to GRASS 5.7 Radim Blazek, ITC-Irst, Trento, Italy
8 * PURPOSE: Converts a vector map in ASCII format to a vector map
9 * in binary format
10 *
11 * COPYRIGHT: (C) 2000-2014 by the GRASS Development Team
12 *
13 * This program is free software under the GNU General Public
14 * License (>=v2). Read the file COPYING that comes with GRASS
15 * for details.
16 *
17 *****************************************************************************/
18#include <stdio.h>
19#include <string.h>
20#include <unistd.h>
21#include <stdlib.h>
22#include <grass/gis.h>
23#include <grass/dbmi.h>
24#include <grass/vector.h>
25#include <grass/glocale.h>
26#include "local_proto.h"
27
28#define A_DIR "dig_ascii"
29
30static char *get_td(const struct Option *option)
31{
32 char* sep;
33
34 if (option->answer == NULL)
35 return NULL;
36
37 if (strcmp(option->answer, "doublequote") == 0)
38 sep = G_store("\"");
39 else if (strcmp(option->answer, "singlequote") == 0)
40 sep = G_store("\'");
41 else if (strcmp(option->answer, "none") == 0)
42 sep = NULL;
43 else
44 sep = G_store(option->answer);
45
46 return sep;
47}
48
49
50int main(int argc, char *argv[])
51{
52 FILE *ascii;
53 struct GModule *module;
54 struct Option *old, *new, *delim_opt, *tdelim_opt, *columns_opt,
55 *xcol_opt, *ycol_opt, *zcol_opt, *catcol_opt,
56 *format_opt, *skip_opt;
57 int xcol, ycol, zcol, catcol, format, skip_lines;
58 struct Flag *zcoorf, *t_flag, *e_flag, *noheader_flag, *notopol_flag,
59 *region_flag, *ignore_flag;
60 char *table;
61 char *fs, *td;
62 char *desc;
63 int zcoor = WITHOUT_Z, make_table;
64
65 struct Map_info Map;
66
67 G_gisinit(argv[0]);
68
69 module = G_define_module();
70 G_add_keyword(_("vector"));
71 G_add_keyword(_("import"));
72 G_add_keyword("ASCII");
73 G_add_keyword(_("level1"));
74
75 module->description =
76 _("Creates a vector map from an ASCII points file or ASCII vector file.");
77
78 /************************** Command Parser ************************************/
79 old = G_define_standard_option(G_OPT_F_INPUT);
80 old->label = _("Name of input file to be imported");
81 old->description = ("'-' for standard input");
82
83 new = G_define_standard_option(G_OPT_V_OUTPUT);
84
85 format_opt = G_define_option();
86 format_opt->key = "format";
87 format_opt->type = TYPE_STRING;
88 format_opt->required = NO;
89 format_opt->multiple = NO;
90 format_opt->options = "point,standard";
91 desc = NULL;
92 G_asprintf(&desc,
93 "point;%s;standard;%s",
94 _("simple x,y[,z] list"),
95 _("GRASS vector ASCII format"));
96 format_opt->descriptions = desc;
97 format_opt->answer = "point";
98 format_opt->description = _("Input file format");
99 format_opt->guisection = _("Input format");
100
101 delim_opt = G_define_standard_option(G_OPT_F_SEP);
102 delim_opt->guisection = _("Input format");
103
104 tdelim_opt = G_define_standard_option(G_OPT_F_SEP);
105 tdelim_opt->key = "text";
106 tdelim_opt->label = "Text delimiter";
107 tdelim_opt->answer = NULL;
108 tdelim_opt->description = _("Special characters: doublequote, singlequote, none");
109 tdelim_opt->guisection = _("Input format");
110
111 skip_opt = G_define_option();
112 skip_opt->key = "skip";
113 skip_opt->type = TYPE_INTEGER;
114 skip_opt->required = NO;
115 skip_opt->multiple = NO;
116 skip_opt->answer = "0";
117 skip_opt->description =
118 _("Number of header lines to skip at top of input file (points mode)");
119 skip_opt->guisection = _("Points");
120
121 columns_opt = G_define_option();
122 columns_opt->key = "columns";
123 columns_opt->type = TYPE_STRING;
124 columns_opt->required = NO;
125 columns_opt->multiple = NO;
126 columns_opt->guisection = _("Points");
127 columns_opt->label = _("Column definition in SQL style (points mode)");
128 columns_opt->description = _("For example: "
129 "'x double precision, y double precision, cat int, "
130 "name varchar(10)'");
131
132 xcol_opt = G_define_option();
133 xcol_opt->key = "x";
134 xcol_opt->type = TYPE_INTEGER;
135 xcol_opt->required = NO;
136 xcol_opt->multiple = NO;
137 xcol_opt->answer = "1";
138 xcol_opt->guisection = _("Points");
139 xcol_opt->label = ("Number of column used as x coordinate (points mode)");
140 xcol_opt->description = _("First column is 1");
141
142 ycol_opt = G_define_option();
143 ycol_opt->key = "y";
144 ycol_opt->type = TYPE_INTEGER;
145 ycol_opt->required = NO;
146 ycol_opt->multiple = NO;
147 ycol_opt->answer = "2";
148 ycol_opt->guisection = _("Points");
149 ycol_opt->label = _("Number of column used as y coordinate (points mode)");
150 ycol_opt->description = _("First column is 1");
151
152 zcol_opt = G_define_option();
153 zcol_opt->key = "z";
154 zcol_opt->type = TYPE_INTEGER;
155 zcol_opt->required = NO;
156 zcol_opt->multiple = NO;
157 zcol_opt->answer = "0";
158 zcol_opt->guisection = _("Points");
159 zcol_opt->label = _("Number of column used as z coordinate (points mode)");
160 zcol_opt->description = _("First column is 1. If 0, z coordinate is not used");
161
162 catcol_opt = G_define_option();
163 catcol_opt->key = "cat";
164 catcol_opt->type = TYPE_INTEGER;
165 catcol_opt->required = NO;
166 catcol_opt->multiple = NO;
167 catcol_opt->answer = "0";
168 catcol_opt->guisection = _("Points");
169 catcol_opt->label =
170 _("Number of column used as category (points mode)");
171 catcol_opt->description =
172 _("First column is 1. If 0, unique category is assigned to each row and written to new column 'cat'");
173
174 zcoorf = G_define_flag();
175 zcoorf->key = 'z';
176 zcoorf->description = _("Create 3D vector map");
177
178 e_flag = G_define_flag();
179 e_flag->key = 'e';
180 e_flag->description =
181 _("Create a new empty vector map and exit. Nothing is read from input.");
182
183 noheader_flag = G_define_flag();
184 noheader_flag->key = 'n';
185 noheader_flag->description =
186 _("Do not expect a header when reading in standard format");
187 noheader_flag->guisection = _("Input format");
188
189 t_flag = G_define_flag();
190 t_flag->key = 't';
191 t_flag->description = _("Do not create table in points mode");
192 t_flag->guisection = _("Points");
193
194 notopol_flag = G_define_standard_flag(G_FLG_V_TOPO);
195 notopol_flag->description = _("Do not build topology in points mode");
196 notopol_flag->guisection = _("Points");
197
198 region_flag = G_define_flag();
199 region_flag->key = 'r';
200 region_flag->description =
201 _("Only import points falling within current region (points mode)");
202 region_flag->guisection = _("Points");
203
204 ignore_flag = G_define_flag();
205 ignore_flag->key = 'i';
206 ignore_flag->description = _("Ignore broken line(s) in points mode");
207 ignore_flag->guisection = _("Points");
208
209 if (G_parser(argc, argv))
210 exit(EXIT_FAILURE);
211
212
213 if (format_opt->answer[0] == 'p')
214 format = GV_ASCII_FORMAT_POINT;
215 else
216 format = GV_ASCII_FORMAT_STD;
217
218 skip_lines = atoi(skip_opt->answer);
219 if (skip_lines < 0)
220 G_fatal_error(_("Please specify reasonable number of lines to skip"));
221
222 if (zcoorf->answer && format == GV_ASCII_FORMAT_POINT && !zcol_opt->answer)
223 G_fatal_error(_("Please specify z column"));
224
225 xcol = atoi(xcol_opt->answer) - 1;
226 ycol = atoi(ycol_opt->answer) - 1;
227 zcol = atoi(zcol_opt->answer) - 1;
228
229 /* specifying zcol= implies that a 3D map is needed */
230 if (zcol >= 0 && !zcoorf->answer)
231 zcoorf->answer = TRUE;
232
233 if (zcoorf->answer && format == GV_ASCII_FORMAT_POINT && zcol < 0)
234 G_fatal_error(_("Please specify reasonable z column"));
235
236 catcol = atoi(catcol_opt->answer) - 1;
237
238 if (xcol < 0 || ycol < 0 || zcol + 1 < 0 || catcol + 1 < 0)
239 G_fatal_error(_("Column numbers must not be negative"));
240
241 ascii = G_open_option_file(old);
242 fs = G_option_to_separator(delim_opt);
243 td = get_td(tdelim_opt);
244
245 /* check dimension */
246 if (zcoorf->answer) {
247 zcoor = 1;
248 }
249
250 if (Vect_open_new(&Map, new->answer, zcoor) < 0)
251 G_fatal_error(_("Unable to create vector map <%s>"), new->answer);
252
253 Vect_set_error_handler_io(NULL, &Map);
254 Vect_hist_command(&Map);
255
256 if (e_flag->answer) {
257 Vect_build(&Map);
258 Vect_close(&Map);
259 exit(EXIT_SUCCESS);
260 }
261
262 if (format == GV_ASCII_FORMAT_POINT) {
263 int i, rowlen, ncols, minncols, *coltype, *coltype2, *collen, nrows;
264 int n_int = 0, n_double = 0, n_string = 0;
265 char buf[1000];
266 struct field_info *Fi;
267 char *tmp, *key;
268 dbDriver *driver;
269 dbString sql;
270 FILE *tmpascii;
271
272 /* Open temporary file */
273 tmp = G_tempfile();
274 if (NULL == (tmpascii = fopen(tmp, "w+"))) {
275 G_fatal_error(_("Unable to open temporary file <%s>"), tmp);
276 }
277 unlink(tmp);
278
279 points_analyse(ascii, tmpascii, fs, td, &rowlen, &ncols, &minncols,
280 &nrows, &coltype, &collen, skip_lines, xcol, ycol,
281 zcol, catcol, region_flag->answer, ignore_flag->answer);
282
283 G_verbose_message(_("Maximum input row length: %d"), rowlen);
284 if (ncols != minncols) {
285 G_message(_("Maximum number of columns: %d"), ncols);
286 G_message(_("Minimum number of columns: %d"), minncols);
287 }
288 else {
289 G_message(_("Number of columns: %d"), ncols);
290 }
291
292 G_message(_("Number of rows: %d"), nrows);
293
294 /* check column numbers */
295 if (xcol >= minncols) {
296 G_fatal_error(_("'%s' column number > minimum last column number "
297 "(incorrect field separator or format?)"), "x");
298 }
299 if (ycol >= minncols) {
300 G_fatal_error(_("'%s' column number > minimum last column number "
301 "(incorrect field separator or format?)"), "y");
302
303 }
304 if (zcol >= minncols) {
305 G_fatal_error(_("'%s' column number > minimum last column number "
306 "(incorrect field separator or format?)"), "z");
307
308 }
309 if (catcol >= minncols) {
310 G_fatal_error(_("'%s' column number > minimum last column number "
311 "(incorrect field separator or format?)"), "cat");
312 }
313
314 if (coltype[xcol] == DB_C_TYPE_STRING) {
315 G_fatal_error(_("'%s' column is not of number type"), "x");
316 }
317 if (coltype[ycol] == DB_C_TYPE_STRING) {
318 G_fatal_error(_("'%s' column is not of number type"), "y");
319 }
320 if (zcol >= 0 && coltype[zcol] == DB_C_TYPE_STRING) {
321 G_fatal_error(_("'%s' column is not of number type"), "z");
322 }
323 if (catcol >= 0 && coltype[catcol] == DB_C_TYPE_STRING) {
324 G_fatal_error(_("'%s' column is not of number type"), "cat");
325 }
326
327 /* Create table */
328 make_table = FALSE;
329 for (i = 0; i < ncols; i++) {
330 if (xcol != i && ycol != i && zcol != i && catcol != i) {
331 make_table = TRUE;
332 break;
333 }
334 }
335 if (t_flag->answer) {
336 make_table = FALSE;
337 }
338
339 coltype2 = NULL;
340
341 if (make_table) {
342 Fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);
343 driver =
344 db_start_driver_open_database(Fi->driver,
345 Vect_subst_var(Fi->database,
346 &Map));
347 if (driver == NULL) {
348 G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
349 Vect_subst_var(Fi->database, &Map), Fi->driver);
350 }
351 db_begin_transaction(driver);
352
353 db_init_string(&sql);
354 sprintf(buf, "create table %s ( ", Fi->table);
355 db_append_string(&sql, buf);
356
357 if (catcol < 0) {
358 db_append_string(&sql, "cat integer, ");
359 }
360
361 for (i = 0; i < ncols; i++) {
362 if (i > 0 && !columns_opt->answer) {
363 db_append_string(&sql, ", ");
364 }
365 if (catcol == i && coltype[i] != DB_C_TYPE_INT) {
366 G_fatal_error(_("Category column is not of integer type"));
367 }
368
369 switch (coltype[i]) {
370 case DB_C_TYPE_INT:
371 G_verbose_message("Column: %d type: integer", i + 1);
372 if (!columns_opt->answer) {
373 sprintf(buf, "int_%d integer", n_int + 1);
374 db_append_string(&sql, buf);
375 if (catcol == i) {
376 sprintf(buf, "int_%d", n_int + 1);
377 key = G_store(buf);
378 }
379 }
380 n_int++;
381 break;
382 case DB_C_TYPE_DOUBLE:
383 G_verbose_message("Column: %d type: double", i + 1);
384 if (!columns_opt->answer) {
385 sprintf(buf, "dbl_%d double precision", n_double + 1);
386 db_append_string(&sql, buf);
387 }
388 n_double++;
389 break;
390 case DB_C_TYPE_STRING:
391 G_verbose_message("Column: %d type: string length: %d",
392 i + 1, collen[i]);
393 if (!columns_opt->answer) {
394 sprintf(buf, "str_%d varchar(%d)", n_string + 1,
395 collen[i]);
396 db_append_string(&sql, buf);
397 }
398 n_string++;
399 break;
400 }
401 }
402 if (columns_opt->answer) {
403 db_append_string(&sql, columns_opt->answer);
404 }
405 db_append_string(&sql, " )");
406
407 /* this link is added with default 'cat' key, later deleted and replaced by true key name,
408 * otherwise if module crashes when the table exists but link is not written it makes troubles */
409 Vect_map_add_dblink(&Map, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
410 Fi->driver);
411
412 /* Create table */
413 G_debug(3, "%s", db_get_string(&sql));
414 if (db_execute_immediate(driver, &sql) != DB_OK) {
415 G_fatal_error(_("Unable to create table: %s"),
416 db_get_string(&sql));
417 }
418
419 /* Grant */
420 if (db_grant_on_table
421 (driver, Fi->table, DB_PRIV_SELECT,
422 DB_GROUP | DB_PUBLIC) != DB_OK) {
423 G_fatal_error(_("Unable to grant privileges on table <%s>"),
424 Fi->table);
425 }
426
427 /* Check column types */
428 if (columns_opt->answer) {
429 int nc;
430 dbTable *table;
431 dbColumn *column;
432
433 db_set_string(&sql, Fi->table);
434 if (db_describe_table(driver, &sql, &table) != DB_OK) {
435 G_fatal_error(_("Unable to describe table <%s>"),
436 Fi->table);
437 }
438
439 nc = db_get_table_number_of_columns(table);
440
441 if ((catcol >= 0 && nc != ncols) ||
442 (catcol < 0 && (nc - 1) != ncols)) {
443 G_fatal_error(_("Number of columns defined (%d) does not match number "
444 "of columns (%d) in input"),
445 catcol < 0 ? nc - 1 : nc, ncols);
446 }
447
448 coltype2 = (int *)G_malloc(ncols * sizeof(int));
449
450 for (i = 0; i < ncols; i++) {
451 int dbcol, ctype, length;
452
453 if (catcol < 0)
454 dbcol = i + 1; /* first is category */
455 else
456 dbcol = i;
457
458 column = db_get_table_column(table, dbcol);
459 ctype =
460 db_sqltype_to_Ctype(db_get_column_sqltype(column));
461 length = db_get_column_length(column);
462 coltype2[i] = ctype;
463
464 if (catcol == i) { /* if catcol == -1 it cannot be tru */
465 key = G_store(db_get_column_name(column));
466 }
467
468 switch (coltype[i]) {
469 case DB_C_TYPE_INT:
470 if (ctype == DB_C_TYPE_DOUBLE) {
471 G_warning(_("Column number %d <%s> defined as double "
472 "has only integer values"), i + 1,
473 db_get_column_name(column));
474 }
475 else if (ctype == DB_C_TYPE_STRING) {
476 G_warning(_("Column number %d <%s> defined as string "
477 "has only integer values"), i + 1,
478 db_get_column_name(column));
479 }
480 break;
481 case DB_C_TYPE_DOUBLE:
482 if (ctype == DB_C_TYPE_INT) {
483 G_fatal_error(_("Column number %d <%s> defined as integer "
484 "has double values"), i + 1,
485 db_get_column_name(column));
486 }
487 else if (ctype == DB_C_TYPE_STRING) {
488 G_warning(_("Column number %d <%s> defined as string "
489 "has double values"), i + 1,
490 db_get_column_name(column));
491 }
492 break;
493 case DB_C_TYPE_STRING:
494 if (ctype == DB_C_TYPE_INT) {
495 G_fatal_error(_("Column number %d <%s> defined as integer "
496 "has string values"), i + 1,
497 db_get_column_name(column));
498 }
499 else if (ctype == DB_C_TYPE_DOUBLE) {
500 G_fatal_error(_("Column number %d <%s> defined as double "
501 "has string values"), i + 1,
502 db_get_column_name(column));
503 }
504 if (length < collen[i]) {
505 G_fatal_error(_("Length of column %d <%s> (%d) is less than "
506 "maximum value " "length (%d)"),
507 i + 1, db_get_column_name(column),
508 length, collen[i]);
509 }
510 break;
511 }
512 }
513 }
514 else {
515 coltype2 = coltype;
516 }
517
518 if (catcol < 0) {
519 key = GV_KEY_COLUMN;
520 }
521
522 if (db_create_index2(driver, Fi->table, key) != DB_OK)
523 G_warning(_("Unable to create index for table <%s>, key <%s>"),
524 Fi->table, key);
525
526 Vect_map_del_dblink(&Map, 1);
527 Vect_map_add_dblink(&Map, 1, NULL, Fi->table, key, Fi->database,
528 Fi->driver);
529
530 table = Fi->table;
531 }
532 else {
533 driver = NULL;
534 table = NULL;
535 }
536
537 points_to_bin(tmpascii, rowlen, &Map, driver, table, fs, td, nrows,
538 coltype2, xcol, ycol, zcol, catcol, skip_lines);
539
540 if (driver) {
541 G_message(_("Populating table..."));
542 db_commit_transaction(driver);
543 if (db_close_database_shutdown_driver(driver) == DB_FAILED)
544 G_fatal_error(_("Unable to close attribute table. The DBMI driver did not accept all attributes"));
545 }
546 fclose(tmpascii);
547 }
548
549 else { /* FORMAT_ALL (standard mode) */
550 if (!noheader_flag->answer)
551 if (Vect_read_ascii_head(ascii, &Map) == -1)
552 G_fatal_error(_("Import failed"));
553
554 if (Vect_read_ascii(ascii, &Map) == -1)
555 G_fatal_error(_("Import failed"));
556 }
557
558 G_close_option_file(ascii);
559
560 if (notopol_flag->answer) {
561 Vect_close(&Map);
562 }
563 else {
564 Vect_build(&Map);
565 Vect_close(&Map);
566 }
567
568 exit(EXIT_SUCCESS);
569}
Note: See TracBrowser for help on using the repository browser.