grass  7.8.6
About: GRASS (Geographic Resources Analysis Support System) is a raster- and vector-based GIS, image processing system, graphics production system and spatial modeling system.
  Fossies Dox: grass-7.8.6.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ascii.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/Vlib/ascii.c
3
4 \brief Vector library - GRASS ASCII vector format
5
6 Higher level functions for reading/writing/manipulating vectors.
7
8 (C) 2001-2015 by the GRASS Development Team
9
10 This program is free software under the GNU General Public License
11 (>=v2). Read the file COPYING that comes with GRASS for details.
12
13 \author Original author CERL
14 \author Updated for GRASS 7 (SF support) by Martin Landa <landa.martin gmail.com>
15*/
16#include <stdlib.h>
17#include <stdio.h>
18#include <string.h>
19
20#include <grass/vector.h>
21#include <grass/dbmi.h>
22#include <grass/glocale.h>
23
24#define BUFFSIZE 128
25
26static int srch(const void *, const void *);
27static int get_cat(const struct line_cats *, const struct cat_list *,
28 const int *, int, int, int *);
29static void free_col_arrays(int *, char *, char **);
30
31/*!
32 \brief Read data in GRASS ASCII vector format
33
34 \param ascii pointer to the input ASCII file
35 \param[out] Map pointer to the output Map_info structure
36
37 \return number of read features
38 \return -1 on error
39*/
40int Vect_read_ascii(FILE *ascii, struct Map_info *Map)
41{
42 char ctype;
43 char buff[BUFFSIZE];
44 char east_str[256], north_str[256];
45 double *xarray;
46 double *yarray;
47 double *zarray;
48 double *x, *y, *z;
49 int i, n_points, n_coors, n_cats, n_lines;
50 int type, with_z, skip_feat, nskipped_3d;
51 int alloc_points;
52 struct line_pnts *Points;
53 struct line_cats *Cats;
54 int catn, cat;
55
56 /* Must always use this to create an initialized line_pnts structure */
58 Cats = Vect_new_cats_struct();
59
60 /*alloc_points = 1000 ; */
61 alloc_points = 1;
62 xarray = (double *)G_calloc(alloc_points, sizeof(double));
63 yarray = (double *)G_calloc(alloc_points, sizeof(double));
64 zarray = (double *)G_calloc(alloc_points, sizeof(double));
65
66 n_lines = nskipped_3d = 0;
67
68 with_z = Vect_is_3d(Map);
69
70 while (G_getl2(buff, BUFFSIZE - 1, ascii) != 0) {
71 n_cats = 0;
72 skip_feat = FALSE;
73 if (buff[0] == '\0') {
74 G_debug(3, "a2b: skipping blank line");
75 continue;
76 }
77
78 if (sscanf(buff, "%1c%d%d", &ctype, &n_coors, &n_cats) < 2 ||
79 n_coors < 0 || n_cats < 0) {
80 if (ctype == '#') {
81 G_debug(2, "a2b: skipping commented line");
82 continue;
83 }
84 G_warning(_("Error reading ASCII file: (bad type) [%s]"),
85 buff);
86 return -1;
87 }
88 if (ctype == '#') {
89 G_debug(2, "a2b: Skipping commented line");
90 continue;
91 }
92
93 switch (ctype) {
94 case 'A':
96 break;
97 case 'B':
99 break;
100 case 'C':
102 break;
103 case 'L':
104 type = GV_LINE;
105 break;
106 case 'P':
107 type = GV_POINT;
108 break;
109 case 'F':
110 type = GV_FACE;
111 break;
112 case 'K':
113 type = GV_KERNEL;
114 break;
115 case 'a':
116 case 'b':
117 case 'c':
118 case 'l':
119 case 'p':
120 type = 0; /* dead -> ignore */
121 break;
122 default: {
123 G_warning(_("Error reading ASCII file: (unknown type) [%s]"),
124 buff);
125 return -1;
126 }
127 }
128 G_debug(5, "feature type = %d", type);
129
130 if ((type & (GV_FACE | GV_KERNEL)) && !with_z) {
131 skip_feat = TRUE;
132 nskipped_3d++;
133 }
134
135 n_points = 0;
136 x = xarray;
137 y = yarray;
138 z = zarray;
139
140 /* Collect the points */
141 for (i = 0; i < n_coors; i++) {
142 if (G_getl2(buff, BUFFSIZE - 1, ascii) == 0) {
143 G_warning(_("End of ASCII file reached before end of coordinates"));
144 return -1;
145 }
146 if (buff[0] == '\0') {
147 G_debug(3, "a2b: skipping blank line while reading vertices");
148 i--;
149 continue;
150 }
151
152 *z = 0;
153 if (sscanf(buff, "%lf%lf%lf", x, y, z) < 2) {
154 if (sscanf(buff, " %s %s %lf", east_str, north_str, z) < 2) {
155 G_warning(_("Error reading ASCII file: (bad point) [%s]"),
156 buff);
157 return -1;
158 } else {
159 if (!G_scan_easting(east_str, x, G_projection())) {
160 G_warning(_("Unparsable longitude value: [%s]"),
161 east_str);
162 return -1;
163 }
164 if (!G_scan_northing(north_str, y, G_projection())) {
165 G_warning(_("Unparsable latitude value: [%s]"),
166 north_str);
167 return -1;
168 }
169 }
170 }
171
172 G_debug(5, "coor in: %s -> x = %f y = %f z = %f", G_chop(buff),
173 *x, *y, *z);
174
175 n_points++;
176 x++;
177 y++;
178 z++;
179
180 if (n_points >= alloc_points) {
181 alloc_points = n_points + 1000;
182 xarray =
183 (double *)G_realloc((void *)xarray,
184 alloc_points * sizeof(double));
185 yarray =
186 (double *)G_realloc((void *)yarray,
187 alloc_points * sizeof(double));
188 zarray =
189 (double *)G_realloc((void *)zarray,
190 alloc_points * sizeof(double));
191 x = xarray + n_points;
192 y = yarray + n_points;
193 z = zarray + n_points;
194 }
195 }
196
197 /* Collect the cats */
198 Vect_reset_cats(Cats);
199 for (i = 0; i < n_cats; i++) {
200 if (G_getl2(buff, BUFFSIZE - 1, ascii) == 0) {
201 G_warning(_("End of ASCII file reached before end of categories"));
202 return -1;
203 }
204 if (buff[0] == '\0') {
205 G_debug(3,
206 "a2b: skipping blank line while reading category info");
207 i--;
208 continue;
209 }
210
211 if (sscanf(buff, "%u%u", &catn, &cat) != 2) {
212 G_warning(_("Error reading categories: [%s]"), buff);
213 return -1;
214 }
215
216 Vect_cat_set(Cats, catn, cat);
217 }
218
219 if (skip_feat)
220 continue;
221
222 /* Allocation is handled for line_pnts */
223 if (0 >
224 Vect_copy_xyz_to_pnts(Points, xarray, yarray, zarray, n_points)) {
225 G_warning(_("Unable to copy points"));
226 return -1;
227 }
228
229 if (type > 0) {
230 if (-1 == Vect_write_line(Map, type, Points, Cats)) {
231 return -1;
232 }
233 n_lines++;
234 }
235 }
236
237 if (nskipped_3d > 0)
238 G_warning(_("Vector map <%s> is 2D. %d 3D features (faces or kernels) skipped."),
239 Vect_get_name(Map), nskipped_3d);
240
243
244 return n_lines;
245}
246
247/*!
248 \brief Read header of GRASS ASCII vector format
249
250 \param dascii pointer to the ASCII file
251 \param Map pointer to Map_info structure
252
253 \return 0 on success
254 \return -1 on error
255*/
256int Vect_read_ascii_head(FILE *dascii, struct Map_info *Map)
257{
258 char buff[1024];
259 char *ptr;
260
261 for (;;) {
262 if (0 == G_getl2(buff, sizeof(buff) - 1, dascii))
263 return (0);
264
265 /* Last line of header */
266 if (strncmp(buff, "VERTI:", 6) == 0)
267 return (0);
268
269 if (!(ptr = strchr(buff, ':'))) {
270 G_warning(_("Unexpected data in vector header:\n[%s]"), buff);
271 return -1;
272 }
273
274 ptr++; /* Search for the start of text */
275 while (*ptr == ' ')
276 ptr++;
277
278 if (strncmp(buff, "ORGANIZATION:", 13) == 0)
279 Vect_set_organization(Map, ptr);
280 else if (strncmp(buff, "DIGIT DATE:", 11) == 0)
281 Vect_set_date(Map, ptr);
282 else if (strncmp(buff, "DIGIT NAME:", 11) == 0)
283 Vect_set_person(Map, ptr);
284 else if (strncmp(buff, "MAP NAME:", 9) == 0)
285 Vect_set_map_name(Map, ptr);
286 else if (strncmp(buff, "MAP DATE:", 9) == 0)
287 Vect_set_map_date(Map, ptr);
288 else if (strncmp(buff, "MAP SCALE:", 10) == 0)
289 Vect_set_scale(Map, atoi(ptr));
290 else if (strncmp(buff, "OTHER INFO:", 11) == 0)
291 Vect_set_comment(Map, ptr);
292 else if (strncmp(buff, "ZONE:", 5) == 0 ||
293 strncmp(buff, "UTM ZONE:", 9) == 0)
294 Vect_set_zone(Map, atoi(ptr));
295 else if (strncmp(buff, "WEST EDGE:", 10) == 0) {
296 }
297 else if (strncmp(buff, "EAST EDGE:", 10) == 0) {
298 }
299 else if (strncmp(buff, "SOUTH EDGE:", 11) == 0) {
300 }
301 else if (strncmp(buff, "NORTH EDGE:", 11) == 0) {
302 }
303 else if (strncmp(buff, "MAP THRESH:", 11) == 0)
304 Vect_set_thresh(Map, atof(ptr));
305 else {
306 G_warning(_("Unknown keyword <%s> in vector head"), buff);
307 }
308 }
309 /* NOTREACHED */
310}
311
312/*!
313 \brief Write data to GRASS ASCII vector format
314
315 Prints message if some features without category are skipped.
316
317 \param[out] ascii pointer to the output ASCII file
318 \param[out] att att file (< version 5 only)
319 \param Map pointer to Map_info structure
320 \param ver version number 4 or 5
321 \param format format GV_ASCII_FORMAT_POINT or GV_ASCII_FORMAT_STD
322 \param dp number of significant digits
323 \param fs field separator
324 \param region_flag check region
325 \param type feature type filter
326 \param field field number
327 \param Clist list of categories to filter features or NULL
328 \param where SQL select where statement to filter features or NULL
329 \param column_names array of columns to be included to the output or NULL
330 "*" as the first item in the array indicates all columns
331 \param header TRUE to print also header
332
333 \return number of written features
334 \return -1 on error
335*/
336int Vect_write_ascii(FILE *ascii,
337 FILE *att, struct Map_info *Map, int ver,
338 int format, int dp, char *fs, int region_flag, int type,
339 int field, const struct cat_list *Clist, const char* where,
340 const char **column_names, int header)
341{
342 int ltype, ctype, i, cat, line, left, right, found;
343 double *xptr, *yptr, *zptr, x, y;
344 static struct line_pnts *Points;
345 struct line_cats *Cats, *ACats;
346 char *xstring, *ystring, *zstring;
347 size_t xsize, ysize, zsize;
348 struct Cell_head window;
349 struct ilist *fcats;
350 int count, n_skipped;
351
352 /* where || columns */
353 struct field_info *Fi;
355 dbValue value;
356 dbHandle handle;
357 int *cats, ncats, more;
358 dbTable *Table;
359 dbString dbstring;
360 dbColumn *Column;
361 dbValue *Value;
362 char *buf;
363 size_t bufsize;
364 dbCursor cursor;
365 /* columns */
366 char **columns;
367 int *coltypes;
368 char *all_columns;
369
370 Fi = NULL;
371 driver = NULL;
372 columns = NULL;
373 coltypes = NULL;
374 all_columns = NULL;
375
376 G_zero(&value, sizeof(dbValue));
377 db_init_string(&dbstring);
378
379 xstring = NULL;
380 ystring = NULL;
381 zstring = NULL;
382 xsize = 0;
383 ysize = 0;
384 zsize = 0;
385 buf = NULL;
386 bufsize = 0;
387
388 /* get the region */
390
391 count = ncats = 0;
392 xstring = ystring = zstring = NULL;
393 cats = NULL;
394
395 if (field > 0 && (where || column_names)) {
396 Fi = Vect_get_field(Map, field);
397 if (!Fi) {
398 G_fatal_error(_("Database connection not defined for layer %d"),
399 field);
400 }
401
403 if (!driver)
404 G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
405
406 db_init_handle(&handle);
407 db_set_handle(&handle, Fi->database, NULL);
408
409 if (db_open_database(driver, &handle) != DB_OK)
410 G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
411 Fi->database, Fi->driver);
412
413 /* select cats (sorted array) */
414 ncats = db_select_int(driver, Fi->table, Fi->key, where, &cats);
415 G_debug(3, "%d categories selected from table <%s>", ncats, Fi->table);
416
417 if (!column_names) {
420 }
421 else {
422 int icol, ncols;
423 const char *col_name;
424 int len_all = 0;
425
426 db_set_string(&dbstring, Fi->table);
427 if (db_describe_table(driver, &dbstring, &Table) != DB_OK) {
428 G_warning(_("Unable to describe table <%s>"), Fi->table);
429 return -1;
430 }
431
433 columns = (char **) G_malloc((ncols + 1) * sizeof(char *));
434
435 if (column_names[0] && strcmp(column_names[0], "*") == 0) {
436
437 /* all columns */
438 icol = 0;
439 for (i = 0; i < ncols; i++) {
440 col_name = db_get_column_name(db_get_table_column(Table, i));
441 /* key column skipped */
442 if (strcmp(Fi->key, col_name) != 0)
443 columns[icol++] = G_store(col_name);
444 }
445 columns[icol] = NULL;
446 }
447 else {
448 int j;
449
450 icol = 0;
451 i = 0;
452 while (column_names[i]) {
453 /* key column skipped */
454 if (strcmp(Fi->key, column_names[i]) != 0) {
455 found = 0;
456 for (j = 0; j < ncols; j++) {
457 col_name = db_get_column_name(db_get_table_column(Table, j));
458 if (strcmp(col_name, column_names[i]) == 0) {
459 columns[icol++] = G_store(col_name);
460 found = 1;
461 break;
462 }
463 }
464 if (!found) {
465 G_warning(_("Column <%s> does not exist"),
466 column_names[i]);
467 G_important_message(_("Available columns:"));
468 for (j = 0; j < ncols; j++) {
469 col_name = db_get_column_name(db_get_table_column(Table, j));
470 G_important_message("%s", col_name);
471 }
472 G_warning(_("Export cancelled"));
475 return -1;
476 }
477 }
478 i++;
479 }
480 columns[icol] = NULL;
481 }
482
483 db_zero_string(&dbstring);
484 db_free_table(Table);
485 Table = NULL;
486
487 if (columns[0]) {
488 /* selected columns only */
489 i = 0;
490 while (columns[i])
491 len_all += strlen(columns[i++]);
492
493 coltypes = G_malloc(i * sizeof(int));
494
495 all_columns = G_malloc(len_all + i + 2);
496
497 i = 0;
498 strcpy(all_columns, columns[0]);
499 while (columns[i]) {
500 /* get column types */
501 coltypes[i] = db_column_Ctype(driver, Fi->table, columns[i]);
502 if (coltypes[i] < 0) {
505 G_warning(_("Unknown type of column <%s>, export cancelled"),
506 columns[i]);
507 return -1;
508 }
509 if (i > 0) {
510 strcat(all_columns, ",");
511 strcat(all_columns, columns[i]);
512 }
513 i++;
514 }
515 }
516 else {
517 /* no column or only key column selected */
519 columns = NULL;
520
523 }
524 }
525 }
526
527 if (format == GV_ASCII_FORMAT_POINT && header) {
528
529 /* print header */
530 if (Map->head.with_z)
531 fprintf(ascii, "east%snorth%sheight%scat", fs, fs, fs);
532 else
533 fprintf(ascii, "east%snorth%scat", fs, fs);
534 if (columns) {
535 for (i = 0; columns[i]; i++) {
537 (driver, Fi->table, Fi->key, cat,
538 columns[i], &value) < 0)
539 G_fatal_error(_("Unable to select record from table <%s> (key %s, column %s)"),
540 Fi->table, Fi->key, columns[i]);
541 if (columns[i])
542 fprintf(ascii, "%s%s", fs, columns[i]);
543 else
544 fprintf(ascii, "%s", columns[i]); /* can not happen */
545 }
546 }
547 fprintf(ascii, "%s", HOST_NEWLINE);
548 }
549
551 Cats = Vect_new_cats_struct();
552 ACats = Vect_new_cats_struct();
553 fcats = Vect_new_list();
554
555 /* by default, read_next_line will NOT read Dead lines */
556 /* but we can override that (in Level I only) by specifying */
557 /* the type -1, which means match all line types */
558
559 Vect_rewind(Map);
560
561 count = n_skipped = line = 0;
562 while (TRUE) {
563 ltype = Vect_read_next_line(Map, Points, Cats);
564 if (ltype == -1 ) { /* failure */
565 if (columns) {
568
569 free_col_arrays(coltypes, all_columns,
570 column_names && strcmp(column_names[0], "*") == 0 ? columns : NULL);
571 }
572
573 return -1;
574 }
575
576 if (ltype == -2) { /* EOF */
577 if (columns) {
580
581 free_col_arrays(coltypes, all_columns,
582 column_names && strcmp(column_names[0], "*") == 0 ? columns : NULL);
583 }
584 break;
585 }
586
587 line++;
588
589 if (!(ltype & type))
590 continue;
591
592 if (format == GV_ASCII_FORMAT_POINT && !(ltype & GV_POINTS))
593 continue;
594
595 found = get_cat(Cats, Clist, cats, ncats, field, &cat);
596
597 if (!found && field > 0 && ltype == GV_BOUNDARY &&
598 type & GV_AREA && Vect_level(Map) > 1) {
599 Vect_get_line_areas(Map, line, &left, &right);
600 if (left < 0)
601 left = Vect_get_isle_area(Map, abs(left));
602 if (left > 0) {
603 Vect_get_area_cats(Map, left, ACats);
604 found = get_cat(ACats, Clist, cats, ncats, field, &cat);
605 }
606 if (right < 0)
607 right = Vect_get_isle_area(Map, abs(right));
608 if (!found && right > 0) {
609 Vect_get_area_cats(Map, right, ACats);
610 found = get_cat(ACats, Clist, cats, ncats, field, &cat);
611 }
612 }
613
614 if (!found) {
615 if (Cats->n_cats < 1)
616 n_skipped++;
617
618 continue;
619 }
620
621 if (ver < 5) {
622 Vect_cat_get(Cats, 1, &cat);
623 }
624
625 switch (ltype) {
626 case GV_BOUNDARY:
627 if (ver == 5)
628 ctype = 'B';
629 else
630 ctype = 'A';
631 break;
632 case GV_CENTROID:
633 if (ver < 5) {
634 if (att != NULL) {
635 if (cat > 0) {
636 G_rasprintf(&xstring, &xsize, "%.*f", dp, Points->x[0]);
637 G_trim_decimal(xstring);
638 G_rasprintf(&ystring, &ysize, "%.*f", dp, Points->y[0]);
639 G_trim_decimal(ystring);
640 fprintf(att, "A %s %s %d%s", xstring, ystring, cat, HOST_NEWLINE);
641 }
642 }
643 continue;
644 }
645 ctype = 'C';
646 break;
647 case GV_LINE:
648 ctype = 'L';
649 break;
650 case GV_POINT:
651 ctype = 'P';
652 break;
653 case GV_FACE:
654 ctype = 'F';
655 break;
656 case GV_KERNEL:
657 ctype = 'K';
658 break;
659 default:
660 ctype = 'X';
661 G_warning(_("Unknown feature type %d"), (int)ltype);
662 break;
663 }
664
666 if (region_flag) {
667 if ((window.east < Points->x[0]) ||
668 (window.west > Points->x[0]))
669 continue;
670 }
671 G_rasprintf(&xstring, &xsize, "%.*f", dp, Points->x[0]);
672 G_trim_decimal(xstring);
673
674 if (region_flag) {
675 if ((window.north < Points->y[0]) ||
676 (window.south > Points->y[0]))
677 continue;
678 }
679 G_rasprintf(&ystring, &ysize, "%.*f", dp, Points->y[0]);
680 G_trim_decimal(ystring);
681
682 Vect_field_cat_get(Cats, field, fcats);
683
684 if (Map->head.with_z && ver == 5) {
685 if (region_flag) {
686 if ((window.top < Points->z[0]) ||
687 (window.bottom > Points->z[0]))
688 continue;
689 }
690 G_rasprintf(&zstring, &zsize, "%.*f", dp, Points->z[0]);
691 G_trim_decimal(zstring);
692 fprintf(ascii, "%s%s%s%s%s", xstring, fs, ystring, fs,
693 zstring);
694 }
695 else {
696 fprintf(ascii, "%s%s%s", xstring, fs, ystring);
697 }
698
699 if (fcats->n_values > 0 && cat > -1) {
700 if (fcats->n_values > 1) {
701 G_warning(_("Feature has more categories. Only one category (%d) "
702 "is exported."), cat);
703 }
704 fprintf(ascii, "%s%d", fs, cat);
705
706 /* print attributes */
707 if (columns) {
708
709 G_rasprintf(&buf, &bufsize, "SELECT %s FROM %s WHERE %s = %d",
710 all_columns, Fi->table, Fi->key, cat);
711 G_debug(2, "SQL: %s", buf);
712 db_set_string(&dbstring, buf);
713
715 (driver, &dbstring, &cursor, DB_SEQUENTIAL) != DB_OK) {
718 G_fatal_error(_("Cannot select attributes for cat = %d"),
719 cat);
720 }
721 if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
724 G_fatal_error(_("Unable to fetch data from table"));
725 }
726
727 Table = db_get_cursor_table(&cursor);
728
729
730 for (i = 0; columns[i]; i++) {
731 Column = db_get_table_column(Table, i);
732 Value = db_get_column_value(Column);
733
734 if (db_test_value_isnull(Value)) {
735 fprintf(ascii, "%s", fs);
736 }
737 else {
738 switch(coltypes[i])
739 {
740 case DB_C_TYPE_INT: {
741 fprintf(ascii, "%s%d", fs, db_get_value_int(Value));
742 break;
743 }
744 case DB_C_TYPE_DOUBLE: {
745 fprintf(ascii, "%s%.*f", fs, dp, db_get_value_double(Value));
746 break;
747 }
748 case DB_C_TYPE_STRING: {
749 fprintf(ascii, "%s%s", fs, db_get_value_string(Value));
750 break;
751 }
752 case DB_C_TYPE_DATETIME: {
753 break;
754 }
755 case -1:
756 G_fatal_error(_("Column <%s> not found in table <%s>"),
757 columns[i], Fi->table);
758 default: G_fatal_error(_("Column <%s>: unsupported data type"),
759 columns[i]);
760 }
761 }
762 }
763 db_close_cursor(&cursor);
764 }
765 }
766
767 fprintf(ascii, "%s", HOST_NEWLINE);
768 }
769 else if (format == GV_ASCII_FORMAT_STD) {
770 /* FORMAT_STANDARD */
771 if (ver == 5 && Cats->n_cats > 0)
772 fprintf(ascii, "%c %d %d%s", ctype, Points->n_points,
773 Cats->n_cats, HOST_NEWLINE);
774 else
775 fprintf(ascii, "%c %d%s", ctype, Points->n_points, HOST_NEWLINE);
776
777 xptr = Points->x;
778 yptr = Points->y;
779 zptr = Points->z;
780
781 while (Points->n_points--) {
782
783 G_rasprintf(&xstring, &xsize, "%.*f", dp, *xptr++);
784 G_trim_decimal(xstring);
785 G_rasprintf(&ystring, &ysize, "%.*f", dp, *yptr++);
786 G_trim_decimal(ystring);
787
788 if (ver == 5) {
789 if (Map->head.with_z) {
790 G_rasprintf(&zstring, &zsize, "%.*f", dp, *zptr++);
791 G_trim_decimal(zstring);
792 fprintf(ascii, " %-12s %-12s %-12s%s", xstring,
793 ystring, zstring, HOST_NEWLINE);
794 }
795 else {
796 fprintf(ascii, " %-12s %-12s%s", xstring, ystring, HOST_NEWLINE);
797 }
798 } /*Version 4 */
799 else {
800 fprintf(ascii, " %-12s %-12s%s", ystring, xstring, HOST_NEWLINE);
801 }
802 }
803
804 if (ver == 5) {
805 for (i = 0; i < Cats->n_cats; i++) {
806 fprintf(ascii, " %-5d %-10d%s", Cats->field[i],
807 Cats->cat[i], HOST_NEWLINE);
808 }
809 }
810 else {
811 if (cat > -1) {
812 if (ltype == GV_POINT) {
813 G_rasprintf(&xstring, &xsize, "%.*f", dp, Points->x[0]);
814 G_trim_decimal(xstring);
815 G_rasprintf(&ystring, &ysize, "%.*f", dp, Points->y[0]);
816 G_trim_decimal(ystring);
817 fprintf(att, "P %s %s %d%s", xstring, ystring, cat, HOST_NEWLINE);
818 }
819 else {
820 x = (Points->x[1] + Points->x[0]) / 2;
821 y = (Points->y[1] + Points->y[0]) / 2;
822
823 G_rasprintf(&xstring, &xsize, "%.*f", dp, x);
824 G_trim_decimal(xstring);
825 G_rasprintf(&ystring, &ysize, "%.*f", dp, y);
826 G_trim_decimal(ystring);
827 fprintf(att, "L %s %s %d%s", xstring, ystring, cat, HOST_NEWLINE);
828 }
829 }
830 }
831 }
832 else if (format == GV_ASCII_FORMAT_WKT) {
833 if (ltype & (GV_BOUNDARY | GV_CENTROID | GV_FACE | GV_KERNEL))
834 continue;
835 /* Well-Known Text */
836 Vect_sfa_line_astext(Points, ltype, Vect_is_3d(Map), dp, ascii);
837 count++;
838 }
839 else {
840 G_fatal_error(_("Unknown format"));
841 }
842 count++;
843 }
844
846 /* process areas - topology required */
847 int i, area, nareas, isle, nisles;
848
849 if (Vect_level(Map) < 2) {
850 G_warning(_("Topology not available, unable to process areas"));
851 nareas = 0;
852 }
853 else {
854 nareas = Vect_get_num_areas(Map);
855 }
856 for (area = 1; area <= nareas; area++) {
857 if (!Vect_area_alive(Map, area)) /* skip dead areas */
858 continue;
859 if (Vect_get_area_cat(Map, area, field) < 0)
860 continue;
861 /* get boundary -> linearring */
862 if (Vect_get_area_points(Map, area, Points) < 0) {
863 G_warning(_("Unable to get boundary of area id %d"), area);
864 continue;
865 }
866 fprintf(ascii, "POLYGON(");
867 /* write outter ring */
868 Vect_sfa_line_astext(Points, GV_BOUNDARY, 0, dp, ascii); /* boundary is always 2D */
869 /* get isles (holes) -> inner rings */
870 nisles = Vect_get_area_num_isles(Map, area);
871 for (i = 0; i < nisles; i++) {
872 /* get isle boundary -> linearring */
873 isle = Vect_get_area_isle(Map, area, i);
874 if (Vect_get_isle_points(Map, isle, Points) < 0) {
875 G_warning(_("Unable to get boundary of isle id %d (area id %d)"), isle, area);
876 continue;
877 }
878 fprintf(ascii, ", ");
879 /* write inner ring */
880 Vect_sfa_line_astext(Points, GV_BOUNDARY, 0, dp, ascii); /* boundary is always 2D */
881 }
882 fprintf(ascii, ")%s", HOST_NEWLINE);
883
884 count++;
885 }
886 }
887
888 if (n_skipped > 0)
889 G_important_message(_("%d features without category skipped. To export also "
890 "features without category use '%s=-1'."), n_skipped, "layer");
891
895
896 return count;
897}
898
899int srch(const void *pa, const void *pb)
900{
901 int *p1 = (int *)pa;
902 int *p2 = (int *)pb;
903
904 if (*p1 < *p2)
905 return -1;
906 if (*p1 > *p2)
907 return 1;
908 return 0;
909}
910
911/*!
912 \brief Write data to GRASS ASCII vector format
913
914 \param[out] dascii pointer to the output ASCII file
915 \param Map pointer to Map_info structure
916*/
917void Vect_write_ascii_head(FILE *dascii, struct Map_info *Map)
918{
919 fprintf(dascii, "ORGANIZATION: %s%s",
921 fprintf(dascii, "DIGIT DATE: %s%s",
923 fprintf(dascii, "DIGIT NAME: %s%s",
925 fprintf(dascii, "MAP NAME: %s%s",
927 fprintf(dascii, "MAP DATE: %s%s",
929 fprintf(dascii, "MAP SCALE: %d%s",
931 fprintf(dascii, "OTHER INFO: %s%s",
933 fprintf(dascii, "ZONE: %d%s",
935 fprintf(dascii, "MAP THRESH: %f%s",
937}
938
939/* check category */
940int get_cat(const struct line_cats *Cats, const struct cat_list *Clist,
941 const int *cats, int ncats, int field, int *cat)
942{
943 int i;
944
945 *cat = -1;
946
947 if (field < 1)
948 return TRUE;
949
950 if (Clist && Clist->field == field) {
951 for (i = 0; i < Cats->n_cats; i++) {
952 if (Cats->field[i] == field &&
953 Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
954 *cat = Cats->cat[i];
955 return TRUE;
956 }
957 }
958 return FALSE;
959 }
960 if (cats) {
961 int *found;
962
963 for (i = 0; i < Cats->n_cats; i++) {
964 if (Cats->field[i] == field) {
965 found = (int *)bsearch((void *) &(Cats->cat[i]), cats,
966 ncats, sizeof(int), srch);
967 if (found) {
968 /* found */
969 *cat = *found;
970 return TRUE;
971 }
972 }
973 }
974 return FALSE;
975 }
976 if (!Clist && !cats && field > 0) {
977 Vect_cat_get(Cats, field, cat);
978 if (*cat > -1)
979 return TRUE;
980 }
981
982 return FALSE;
983}
984
985/* free column arrays, see Vect_write_ascii() */
986void free_col_arrays(int *coltypes, char *all_columns, char **columns)
987{
988 G_free(coltypes);
989 G_free(all_columns);
990 if (columns) {
991 int i = 0;
992
993 while (columns[i])
994 G_free(columns[i++]);
996 }
997}
static int get_cat(const struct line_cats *, const struct cat_list *, const int *, int, int, int *)
Definition: ascii.c:940
int Vect_write_ascii(FILE *ascii, FILE *att, struct Map_info *Map, int ver, int format, int dp, char *fs, int region_flag, int type, int field, const struct cat_list *Clist, const char *where, const char **column_names, int header)
Write data to GRASS ASCII vector format.
Definition: ascii.c:336
#define BUFFSIZE
Definition: ascii.c:24
int Vect_read_ascii_head(FILE *dascii, struct Map_info *Map)
Read header of GRASS ASCII vector format.
Definition: ascii.c:256
void Vect_write_ascii_head(FILE *dascii, struct Map_info *Map)
Write data to GRASS ASCII vector format.
Definition: ascii.c:917
static int srch(const void *, const void *)
Definition: ascii.c:899
int Vect_read_ascii(FILE *ascii, struct Map_info *Map)
Read data in GRASS ASCII vector format.
Definition: ascii.c:40
static void free_col_arrays(int *, char *, char **)
Definition: ascii.c:986
int G_rasprintf(char **out, size_t *size, const char *fmt,...)
Reallocating version of asprintf().
Definition: asprintf.c:101
static struct line_pnts * Points
Definition: build_nat.c:22
int db_close_cursor(dbCursor *cursor)
Close cursor.
Definition: c_close_cur.c:27
int db_close_database(dbDriver *driver)
Close database connection.
Definition: c_closedb.c:26
int db_describe_table(dbDriver *driver, dbString *name, dbTable **table)
Describe table.
Definition: c_desc_table.c:28
int db_fetch(dbCursor *cursor, int position, int *more)
Fetch data from open cursor.
Definition: c_fetch.c:28
int db_open_database(dbDriver *driver, dbHandle *handle)
Open database connection.
Definition: c_opendb.c:27
int db_open_select_cursor(dbDriver *driver, dbString *select, dbCursor *cursor, int mode)
Open select cursor.
Definition: c_openselect.c:37
int columns
Definition: calc.c:12
#define NULL
Definition: ccmath.h:32
dbTable * db_get_cursor_table(dbCursor *cursor)
Get table allocated by cursor.
Definition: cursor.c:67
int db_select_int(dbDriver *driver, const char *tab, const char *col, const char *where, int **pval)
Select array of ordered integers from table/column.
Definition: select.c:103
int db_select_value(dbDriver *driver, const char *tab, const char *key, int id, const char *col, dbValue *val)
Select one (first) value from table/column for key/id.
Definition: select.c:204
#define DB_C_TYPE_INT
Definition: dbmi.h:108
#define DB_SEQUENTIAL
Definition: dbmi.h:123
#define DB_C_TYPE_STRING
Definition: dbmi.h:107
#define DB_C_TYPE_DOUBLE
Definition: dbmi.h:109
#define DB_OK
Definition: dbmi.h:71
#define DB_C_TYPE_DATETIME
Definition: dbmi.h:110
#define DB_NEXT
Definition: dbmi.h:114
dbValue * db_get_column_value(dbColumn *column)
Returns column value for given column structure.
Definition: column.c:27
const char * db_get_column_name(dbColumn *column)
Returns column name for given column.
Definition: column.c:418
int db_get_table_number_of_columns(dbTable *table)
Return the number of columns of the table.
Definition: table.c:138
void db_free_table(dbTable *table)
Free the table.
Definition: table.c:68
dbColumn * db_get_table_column(dbTable *table, int idx)
Returns column structure for given table and column number.
Definition: table.c:307
int db_column_Ctype(dbDriver *driver, const char *tab, const char *col)
Get column ctype.
Definition: column.c:99
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
#define GV_ASCII_FORMAT_WKT
GRASS ASCII vector format - well-known-text format.
Definition: dig_defines.h:228
#define GV_CENTROID
Definition: dig_defines.h:185
#define GV_LINE
Definition: dig_defines.h:183
#define GV_POINT
Feature types used in memory on run time (may change)
Definition: dig_defines.h:182
#define GV_ASCII_FORMAT_STD
GRASS ASCII vector format - standard format.
Definition: dig_defines.h:226
#define GV_BOUNDARY
Definition: dig_defines.h:184
#define GV_FACE
Definition: dig_defines.h:186
#define GV_POINTS
Definition: dig_defines.h:191
#define GV_ASCII_FORMAT_POINT
GRASS ASCII vector format - point format.
Definition: dig_defines.h:224
#define GV_AREA
Definition: dig_defines.h:188
#define GV_KERNEL
Definition: dig_defines.h:187
static struct @14 window
const struct driver * driver
Definition: init.c:25
struct field_info * Vect_get_field(const struct Map_info *Map, int field)
Get information about link to database (by layer number)
Definition: field.c:506
static int type
Definition: fpxdr.c:101
void G_get_window(struct Cell_head *window)
Get the current region.
Definition: get_window.c:47
int G_getl2(char *buf, int n, FILE *fd)
Gets a line of text from a file of any pedigree.
Definition: getl.c:64
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
void G_important_message(const char *msg,...)
Print a message to stderr even in brief mode (verbosity=1)
Definition: error.c:131
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: error.c:160
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: error.c:204
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: zero.c:23
#define HOST_NEWLINE
Definition: gis.h:77
#define TRUE
Definition: gis.h:59
#define FALSE
Definition: gis.h:63
#define _(str)
Definition: glocale.h:13
void db_init_handle(dbHandle *handle)
Initialize handle (i.e database/schema)
Definition: handle.c:23
int db_set_handle(dbHandle *handle, const char *dbName, const char *dbSchema)
Set handle (database and schema name)
Definition: handle.c:39
static void line(double m[2][3], double x0, double y0, double x1, double y1)
Definition: icon.c:20
int count
int Vect_level(const struct Map_info *Map)
Returns level that Map is opened at.
Definition: level.c:29
int Vect_get_line_areas(const struct Map_info *Map, int line, int *left, int *right)
Get area id on the left and right side of the boundary.
Definition: level_two.c:350
plus_t Vect_get_num_areas(const struct Map_info *Map)
Get number of areas in vector map.
Definition: level_two.c:86
int Vect_copy_xyz_to_pnts(struct line_pnts *Points, const double *x, const double *y, const double *z, int n)
Copy points from array to line_pnts structure.
Definition: line.c:99
struct line_pnts * Vect_new_line_struct()
Creates and initializes a line_pnts structure.
Definition: line.c:45
void Vect_destroy_line_struct(struct line_pnts *p)
Frees all memory associated with a line_pnts structure, including the structure itself.
Definition: line.c:77
static void format(char *, int, int, double, char)
Definition: ll_format.c:87
static int ncols
Definition: raster.c:29
int G_projection(void)
Query cartographic projection.
Definition: proj1.c:32
static int more(const char **)
Definition: scan.c:477
int db_shutdown_driver(dbDriver *driver)
Closedown the driver, and free the driver structure.
Definition: shutdown.c:36
int Vect_sfa_line_astext(const struct line_pnts *Points, int type, int with_z, int precision, FILE *file)
Export geometry to Well-Known Text.
dbDriver * db_start_driver(const char *name)
Initialize a new dbDriver for db transaction.
Definition: start.c:50
void db_zero_string(dbString *x)
Zero string.
Definition: string.c:79
void db_init_string(dbString *x)
Initialize dbString.
Definition: string.c:25
int db_set_string(dbString *x, const char *s)
Inserts string to dbString (enlarge string)
Definition: string.c:41
char * G_chop(char *line)
Chop leading and trailing white spaces.
Definition: strings.c:286
char * G_store(const char *s)
Copy string to allocated memory.
Definition: strings.c:86
2D/3D raster map header (used also for region)
Definition: gis.h:414
Vector map info.
Definition: dig_structs.h:1260
struct dig_head head
Header info.
Definition: dig_structs.h:1403
Category list.
Definition: dig_structs.h:1724
int field
Category layer (field)
Definition: dig_structs.h:1728
int with_z
2D/3D vector data
Definition: dig_structs.h:347
Definition: driver.h:23
Layer (old: field) information.
Definition: dig_structs.h:135
char * table
Name of DB table.
Definition: dig_structs.h:155
char * driver
Name of DB driver ('sqlite', 'dbf', ...)
Definition: dig_structs.h:147
char * database
Definition: dig_structs.h:151
char * key
Name of key column (usually 'cat')
Definition: dig_structs.h:159
List of integers.
Definition: gis.h:691
int n_values
Number of values in the list.
Definition: gis.h:699
Feature category info.
Definition: dig_structs.h:1703
int * field
Array of layers (fields)
Definition: dig_structs.h:1707
int * cat
Array of categories.
Definition: dig_structs.h:1711
int n_cats
Number of categories attached to element.
Definition: dig_structs.h:1715
Feature geometry info - coordinates.
Definition: dig_structs.h:1676
double * y
Array of Y coordinates.
Definition: dig_structs.h:1684
double * x
Array of X coordinates.
Definition: dig_structs.h:1680
int n_points
Number of points.
Definition: dig_structs.h:1692
double * z
Array of Z coordinates.
Definition: dig_structs.h:1688
void G_trim_decimal(char *buf)
Removes trailing zeros from decimal number.
Definition: trim_dec.c:24
int db_get_value_int(dbValue *value)
Get integer value.
Definition: value.c:38
const char * db_get_value_string(dbValue *value)
Get string value.
Definition: value.c:92
double db_get_value_double(dbValue *value)
Get double precision value.
Definition: value.c:50
int db_test_value_isnull(dbValue *value)
Check of value is null.
Definition: value.c:26
int Vect_get_area_cats(const struct Map_info *Map, int area, struct line_cats *Cats)
Get area categories.
Definition: area.c:424
int Vect_get_area_num_isles(const struct Map_info *Map, int area)
Returns number of isles for given area.
Definition: area.c:208
int Vect_get_area_isle(const struct Map_info *Map, int area, int isle)
Returns isle id for area.
Definition: area.c:237
int Vect_get_isle_points(const struct Map_info *Map, int isle, struct line_pnts *BPoints)
Returns polygon array of points for given isle.
Definition: area.c:68
int Vect_get_area_points(const struct Map_info *Map, int area, struct line_pnts *BPoints)
Returns polygon array of points (outer ring) of given area.
Definition: area.c:37
int Vect_get_area_cat(const struct Map_info *Map, int area, int field)
Find FIRST category of given field and area.
Definition: area.c:452
int Vect_get_isle_area(const struct Map_info *Map, int isle)
Returns area id for isle.
Definition: area.c:264
void Vect_destroy_cats_struct(struct line_cats *p)
Frees all memory associated with line_cats structure, including the struct itself.
Definition: cats.c:80
int Vect_cat_get(const struct line_cats *Cats, int field, int *cat)
Get first found category of given field.
Definition: cats.c:156
int Vect_reset_cats(struct line_cats *Cats)
Reset category structure to make sure cats structure is clean to be re-used.
Definition: cats.c:294
int Vect_cat_in_cat_list(int cat, const struct cat_list *list)
Check if category number is in list.
Definition: cats.c:544
int Vect_field_cat_get(const struct line_cats *Cats, int field, struct ilist *cats)
Get list of categories of given field.
Definition: cats.c:192
struct line_cats * Vect_new_cats_struct()
Creates and initializes line_cats structure.
Definition: cats.c:40
int Vect_cat_set(struct line_cats *Cats, int field, int cat)
Add new field/cat to category structure if doesn't exist yet.
Definition: cats.c:104
int Vect_is_3d(const struct Map_info *Map)
Check if vector map is 3D.
Definition: header.c:255
double Vect_get_thresh(const struct Map_info *Map)
Get threshold used for digitization from map header.
Definition: header.c:582
int Vect_set_person(struct Map_info *Map, const char *str)
Set name of user who digitized the map in map header.
Definition: header.c:327
int Vect_get_zone(const struct Map_info *Map)
Get projection zone from map header.
Definition: header.c:480
const char * Vect_get_map_date(const struct Map_info *Map)
Get date when the source map was originally produced from map header.
Definition: header.c:398
int Vect_set_map_date(struct Map_info *Map, const char *str)
Set date when the source map was originally produced in map header.
Definition: header.c:383
const char * Vect_get_map_name(const struct Map_info *Map)
Get map name from map header.
Definition: header.c:370
const char * Vect_get_date(const struct Map_info *Map)
Get date of digitization from map header.
Definition: header.c:314
int Vect_set_organization(struct Map_info *Map, const char *str)
Set organization string in map header.
Definition: header.c:268
const char * Vect_get_name(const struct Map_info *Map)
Get name of vector map.
Definition: header.c:190
int Vect_set_thresh(struct Map_info *Map, double thresh)
Set threshold used for digitization in map header.
Definition: header.c:568
int Vect_set_map_name(struct Map_info *Map, const char *str)
Set map name in map header.
Definition: header.c:355
int Vect_get_scale(const struct Map_info *Map)
Get map scale from map header.
Definition: header.c:425
int Vect_set_comment(struct Map_info *Map, const char *str)
Set comment or other info string in map header.
Definition: header.c:438
int Vect_set_scale(struct Map_info *Map, int scale)
Set map scale in map header.
Definition: header.c:411
int Vect_set_zone(struct Map_info *Map, int zone)
Set projection zone in map header.
Definition: header.c:466
const char * Vect_get_comment(const struct Map_info *Map)
Get comment or other info string from map header.
Definition: header.c:453
int Vect_set_date(struct Map_info *Map, const char *str)
Set date of digitization in map header.
Definition: header.c:299
const char * Vect_get_person(const struct Map_info *Map)
Get user name string who digitized the map from map header.
Definition: header.c:342
const char * Vect_get_organization(const struct Map_info *Map)
Get organization string from map header.
Definition: header.c:283
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
Definition: list.c:32
int Vect_area_alive(const struct Map_info *Map, int area)
Check if area is alive or dead (topological level required)
Definition: read.c:245
int Vect_read_next_line(const struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c)
Read next vector feature.
Definition: read.c:121
int Vect_rewind(struct Map_info *Map)
Rewind vector map to cause reads to start at beginning.
Definition: rewind.c:66
off_t Vect_write_line(struct Map_info *Map, int type, const struct line_pnts *points, const struct line_cats *cats)
Writes a new feature.
Definition: write.c:178
int G_scan_northing(const char *buf, double *northing, int projection)
ASCII northing to double.
Definition: wind_scan.c:38
int G_scan_easting(const char *buf, double *easting, int projection)
ASCII easting to double.
Definition: wind_scan.c:69
#define x