123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830 |
- /*!
- \file lib/vector/Vlib/ascii.c
-
- \brief Vector library - GRASS ASCII vector format
-
- Higher level functions for reading/writing/manipulating vectors.
-
- (C) 2001-2009, 2011 by the GRASS Development Team
-
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
-
- \author Original author CERL
- \author Updated for GRASS 7 (SF support) by Martin Landa <landa.martin gmail.com>
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <grass/vector.h>
- #include <grass/dbmi.h>
- #include <grass/glocale.h>
- #define BUFFSIZE 128
- static int srch(const void *, const void *);
- static int check_cat(const struct line_cats *, const struct cat_list *,
- const int *, int);
- /*!
- \brief Read data in GRASS ASCII vector format
- \param ascii pointer to the ASCII file
- \param Map pointer to Map_info structure
- \return number of read features
- \return -1 on error
- */
- int Vect_read_ascii(FILE *ascii, struct Map_info *Map)
- {
- char ctype;
- char buff[BUFFSIZE];
- char east_str[256], north_str[256];
- double *xarray;
- double *yarray;
- double *zarray;
- double *x, *y, *z;
- int i, n_points, n_coors, n_cats, n_lines;
- int type;
- int alloc_points;
- struct line_pnts *Points;
- struct line_cats *Cats;
- int catn, cat;
- /* Must always use this to create an initialized line_pnts structure */
- Points = Vect_new_line_struct();
- Cats = Vect_new_cats_struct();
- /*alloc_points = 1000 ; */
- alloc_points = 1;
- xarray = (double *)G_calloc(alloc_points, sizeof(double));
- yarray = (double *)G_calloc(alloc_points, sizeof(double));
- zarray = (double *)G_calloc(alloc_points, sizeof(double));
- n_lines = 0;
- while (G_getl2(buff, BUFFSIZE - 1, ascii) != 0) {
- n_cats = 0;
- if (buff[0] == '\0') {
- G_debug(3, "a2b: skipping blank line");
- continue;
- }
- if (sscanf(buff, "%1c%d%d", &ctype, &n_coors, &n_cats) < 2 ||
- n_coors < 0 || n_cats < 0) {
- if (ctype == '#') {
- G_debug(2, "a2b: skipping commented line");
- continue;
- }
- G_fatal_error(_("Error reading ASCII file: (bad type) [%s]"),
- buff);
- }
- if (ctype == '#') {
- G_debug(2, "a2b: Skipping commented line");
- continue;
- }
- switch (ctype) {
- case 'A':
- type = GV_BOUNDARY;
- break;
- case 'B':
- type = GV_BOUNDARY;
- break;
- case 'C':
- type = GV_CENTROID;
- break;
- case 'L':
- type = GV_LINE;
- break;
- case 'P':
- type = GV_POINT;
- break;
- case 'F':
- type = GV_FACE;
- break;
- case 'K':
- type = GV_KERNEL;
- break;
- case 'a':
- case 'b':
- case 'c':
- case 'l':
- case 'p':
- type = 0; /* dead -> ignore */
- break;
- default:
- G_fatal_error(_("Error reading ASCII file: (unknown type) [%s]"),
- buff);
- }
- G_debug(5, "feature type = %d", type);
- n_points = 0;
- x = xarray;
- y = yarray;
- z = zarray;
- /* Collect the points */
- for (i = 0; i < n_coors; i++) {
- if (G_getl2(buff, BUFFSIZE - 1, ascii) == 0)
- G_fatal_error(_("End of ASCII file reached before end of coordinates"));
- if (buff[0] == '\0') {
- G_debug(3, "a2b: skipping blank line while reading vertices");
- i--;
- continue;
- }
- *z = 0;
- if (sscanf(buff, "%lf%lf%lf", x, y, z) < 2) {
- if (sscanf(buff, " %s %s %lf", east_str, north_str, z) < 2) {
- G_fatal_error(_("Error reading ASCII file: (bad point) [%s]"),
- buff);
- } else {
- if( ! G_scan_easting(east_str, x, G_projection()) )
- G_fatal_error(_("Unparsable longitude value: [%s]"),
- east_str);
- if( ! G_scan_northing(north_str, y, G_projection()) )
- G_fatal_error(_("Unparsable latitude value: [%s]"),
- north_str);
- }
- }
- G_debug(5, "coor in: %s -> x = %f y = %f z = %f", G_chop(buff),
- *x, *y, *z);
- n_points++;
- x++;
- y++;
- z++;
- if (n_points >= alloc_points) {
- alloc_points = n_points + 1000;
- xarray =
- (double *)G_realloc((void *)xarray,
- alloc_points * sizeof(double));
- yarray =
- (double *)G_realloc((void *)yarray,
- alloc_points * sizeof(double));
- zarray =
- (double *)G_realloc((void *)zarray,
- alloc_points * sizeof(double));
- x = xarray + n_points;
- y = yarray + n_points;
- z = zarray + n_points;
- }
- }
- /* Collect the cats */
- for (i = 0; i < n_cats; i++) {
- if (G_getl2(buff, BUFFSIZE - 1, ascii) == 0)
- G_fatal_error(_("End of ASCII file reached before end of categories"));
- if (buff[0] == '\0') {
- G_debug(3,
- "a2b: skipping blank line while reading category info");
- i--;
- continue;
- }
- if (sscanf(buff, "%u%u", &catn, &cat) != 2)
- G_fatal_error(_("Error reading categories: [%s]"), buff);
- Vect_cat_set(Cats, catn, cat);
- }
- /* Allocation is handled for line_pnts */
- if (0 >
- Vect_copy_xyz_to_pnts(Points, xarray, yarray, zarray, n_points))
- G_fatal_error(_("Out of memory"));
- if (type > 0) {
- if (-1 == Vect_write_line(Map, type, Points, Cats)) {
- G_warning(_("Unable to write new feature"));
- return -1;
- }
- n_lines++;
- }
-
- Vect_reset_cats(Cats);
- }
- Vect_destroy_line_struct(Points);
- Vect_destroy_cats_struct(Cats);
- return n_lines;
- }
- /*!
- \brief Read header of GRASS ASCII vector format
- \param dascii pointer to the ASCII file
- \param Map pointer to Map_info structure
- \return 0 on success
- \return -1 on error
- */
- int Vect_read_ascii_head(FILE *dascii, struct Map_info *Map)
- {
- char buff[1024];
- char *ptr;
- for (;;) {
- if (0 == G_getl2(buff, sizeof(buff) - 1, dascii))
- return (0);
- /* Last line of header */
- if (strncmp(buff, "VERTI:", 6) == 0)
- return (0);
- if (!(ptr = strchr(buff, ':')))
- G_fatal_error(_("Unexpected data in vector head:\n[%s]"), buff);
- ptr++; /* Search for the start of text */
- while (*ptr == ' ')
- ptr++;
- if (strncmp(buff, "ORGANIZATION:", 12) == 0)
- Vect_set_organization(Map, ptr);
- else if (strncmp(buff, "DIGIT DATE:", 11) == 0)
- Vect_set_date(Map, ptr);
- else if (strncmp(buff, "DIGIT NAME:", 11) == 0)
- Vect_set_person(Map, ptr);
- else if (strncmp(buff, "MAP NAME:", 9) == 0)
- Vect_set_map_name(Map, ptr);
- else if (strncmp(buff, "MAP DATE:", 9) == 0)
- Vect_set_map_date(Map, ptr);
- else if (strncmp(buff, "MAP SCALE:", 10) == 0)
- Vect_set_scale(Map, atoi(ptr));
- else if (strncmp(buff, "OTHER INFO:", 11) == 0)
- Vect_set_comment(Map, ptr);
- else if (strncmp(buff, "ZONE:", 5) == 0 ||
- strncmp(buff, "UTM ZONE:", 9) == 0)
- Vect_set_zone(Map, atoi(ptr));
- else if (strncmp(buff, "WEST EDGE:", 10) == 0) {
- }
- else if (strncmp(buff, "EAST EDGE:", 10) == 0) {
- }
- else if (strncmp(buff, "SOUTH EDGE:", 11) == 0) {
- }
- else if (strncmp(buff, "NORTH EDGE:", 11) == 0) {
- }
- else if (strncmp(buff, "MAP THRESH:", 11) == 0)
- Vect_set_thresh(Map, atof(ptr));
- else {
- G_warning(_("Unknown keyword <%s> in vector head"), buff);
- }
- }
- /* NOTREACHED */
- }
- /*!
- \brief Write data to GRASS ASCII vector format
- \param dascii pointer to the ASCII file
- \param Map pointer to Map_info structure
- \param ver version number 4 or 5
- \param format format GV_ASCII_FORMAT_POINT or GV_ASCII_FORMAT_STD
- \param dp number of significant digits
- \param fs field separator
- \param region_flag check region
- \param type feature type filter
- \param field field number
- \param Clist list of categories to filter features or NULL
- \param where SQL select where statement to filter features or NULL
- \param columns array of columns to be included to the output or NULL
- \param header non-zero to print also header
- \return number of written features
- \return -1 on error
- */
- 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 **columns, int header)
- {
- int ltype, ctype, i, cat, n_lines, line, left, right, found;
- double *xptr, *yptr, *zptr, x, y;
- static struct line_pnts *Points;
- struct line_cats *Cats, *ACats;
- char *xstring, *ystring, *zstring;
- size_t xsize, ysize, zsize;
- struct Cell_head window;
- struct ilist *fcats;
- int count;
- /* where || columns */
- struct field_info *Fi = NULL;
- dbDriver *driver = NULL;
- dbValue value;
- dbHandle handle;
- int *cats, ncats, more;
- dbTable *Table;
- dbString dbstring;
- dbColumn *Column;
- dbValue *Value;
- char buf[2000];
- dbCursor cursor;
- int *coltypes = NULL;
- char *all_columns = NULL;
-
- G_zero(&value, sizeof(dbValue));
- db_init_string(&dbstring);
- /* TODO: free memory allocated by G_asprintf(),
- * this is a bad memory leak */
- xstring = NULL;
- ystring = NULL;
- zstring = NULL;
- xsize = 0;
- ysize = 0;
- zsize = 0;
- /* get the region */
- G_get_window(&window);
- count = n_lines = ncats = 0;
- xstring = ystring = zstring = NULL;
- cats = NULL;
-
- if (where || columns) {
- Fi = Vect_get_field(Map, field);
- if (!Fi) {
- G_fatal_error(_("Database connection not defined for layer %d"),
- field);
- }
- driver = db_start_driver(Fi->driver);
- if (!driver)
- G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
-
- db_init_handle(&handle);
- db_set_handle(&handle, Fi->database, NULL);
-
- if (db_open_database(driver, &handle) != DB_OK)
- G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
- Fi->database, Fi->driver);
-
- /* select cats (sorted array) */
- ncats = db_select_int(driver, Fi->table, Fi->key, where, &cats);
- G_debug(3, "%d categories selected from table <%s>", ncats, Fi->table);
- if (!columns) {
- db_close_database(driver);
- db_shutdown_driver(driver);
- }
- else {
- int len_all = 0;
- i = 0;
- while (columns[i])
- len_all += strlen(columns[i++]);
-
- coltypes = G_malloc(i * sizeof(int));
-
- all_columns = G_malloc(len_all + i + 2);
- i = 0;
- strcpy(all_columns, columns[0]);
- while (columns[i]) {
- /* get column types */
- coltypes[i] = db_column_Ctype(driver, Fi->table, columns[i]);
- if (coltypes[i] < 0) {
- db_close_database(driver);
- db_shutdown_driver(driver);
- G_warning(_("Unknown type of column <%s>, export cancelled"),
- columns[i]);
- return -1;
- }
- if (i > 0) {
- strcat(all_columns, ",");
- strcat(all_columns, columns[i]);
- }
- i++;
- }
- }
- }
-
- Points = Vect_new_line_struct();
- Cats = Vect_new_cats_struct();
- ACats = Vect_new_cats_struct();
- fcats = Vect_new_list();
- /* by default, read_next_line will NOT read Dead lines */
- /* but we can override that (in Level I only) by specifying */
- /* the type -1, which means match all line types */
- Vect_rewind(Map);
- line = 0;
- while (TRUE) {
- ltype = Vect_read_next_line(Map, Points, Cats);
- if (ltype == -1 ) { /* failure */
- if (columns) {
- db_close_database(driver);
- db_shutdown_driver(driver);
- G_free(coltypes);
- G_free(all_columns);
- }
-
- return -1;
- }
- if (ltype == -2) { /* EOF */
- if (columns) {
- db_close_database(driver);
- db_shutdown_driver(driver);
- G_free(coltypes);
- G_free(all_columns);
- }
- break;
- }
- line++;
- if (!(ltype & type))
- continue;
- if (format == GV_ASCII_FORMAT_POINT && !(ltype & GV_POINTS))
- continue;
- found = check_cat(Cats, Clist, cats, ncats);
- if (!found && ltype == GV_BOUNDARY &&
- type & GV_AREA && Vect_level(Map) > 1) {
- Vect_get_line_areas(Map, line, &left, &right);
- if (left < 0)
- left = Vect_get_isle_area(Map, abs(left));
- if (left > 0) {
- Vect_get_area_cats(Map, left, ACats);
- found = check_cat(ACats, Clist, cats, ncats);
- }
- if (right < 0)
- right = Vect_get_isle_area(Map, abs(right));
- if (!found && right > 0) {
- Vect_get_area_cats(Map, right, ACats);
- found = check_cat(ACats, Clist, cats, ncats);
- }
- }
-
- if (!found)
- continue;
-
- if (ver < 5) {
- Vect_cat_get(Cats, 1, &cat);
- }
- switch (ltype) {
- case GV_BOUNDARY:
- if (ver == 5)
- ctype = 'B';
- else
- ctype = 'A';
- break;
- case GV_CENTROID:
- if (ver < 5) {
- if (att != NULL) {
- if (cat > 0) {
- G_rasprintf(&xstring, &xsize, "%.*f", dp, Points->x[0]);
- G_trim_decimal(xstring);
- G_rasprintf(&ystring, &ysize, "%.*f", dp, Points->y[0]);
- G_trim_decimal(ystring);
- fprintf(att, "A %s %s %d\n", xstring, ystring, cat);
- }
- }
- continue;
- }
- ctype = 'C';
- break;
- case GV_LINE:
- ctype = 'L';
- break;
- case GV_POINT:
- ctype = 'P';
- break;
- case GV_FACE:
- ctype = 'F';
- break;
- case GV_KERNEL:
- ctype = 'K';
- break;
- default:
- ctype = 'X';
- G_warning(_("Unknown feature type %d"), (int)ltype);
- break;
- }
- if (format == GV_ASCII_FORMAT_POINT) {
- if (region_flag) {
- if ((window.east < Points->x[0]) ||
- (window.west > Points->x[0]))
- continue;
- }
- G_rasprintf(&xstring, &xsize, "%.*f", dp, Points->x[0]);
- G_trim_decimal(xstring);
- if (region_flag) {
- if ((window.north < Points->y[0]) ||
- (window.south > Points->y[0]))
- continue;
- }
- G_rasprintf(&ystring, &ysize, "%.*f", dp, Points->y[0]);
- G_trim_decimal(ystring);
- Vect_field_cat_get(Cats, field, fcats);
- /* print header */
- if (header && count < 1) {
- count++;
- if (Map->head.with_z)
- fprintf(ascii, "east%snorth%sheight%scat", fs, fs, fs);
- else
- fprintf(ascii, "east%snorth%scat", fs, fs);
- if (columns) {
- for (i = 0; columns[i]; i++) {
- if (db_select_value
- (driver, Fi->table, Fi->key, fcats->value[0],
- columns[i], &value) < 0)
- G_fatal_error(_("Unable to select record from table <%s> (key %s, column %s)"),
- Fi->table, Fi->key, columns[i]);
- if (columns[i])
- fprintf(ascii, "%s%s", fs, columns[i]);
- else
- fprintf(ascii, "%s", columns[i]); /* can not happen */
- }
- }
- fprintf(ascii, "\n");
- }
- if (Map->head.with_z && ver == 5) {
- if (region_flag) {
- if ((window.top < Points->z[0]) ||
- (window.bottom > Points->z[0]))
- continue;
- }
- G_rasprintf(&zstring, &zsize, "%.*f", dp, Points->z[0]);
- G_trim_decimal(zstring);
- fprintf(ascii, "%s%s%s%s%s", xstring, fs, ystring, fs,
- zstring);
- }
- else {
- fprintf(ascii, "%s%s%s", xstring, fs, ystring);
- }
-
- if (fcats->n_values > 0) {
- if (fcats->n_values > 1) {
- G_warning(_("Feature has more categories. Only first category (%d) "
- "is exported."), fcats->value[0]);
- }
- fprintf(ascii, "%s%d", fs, fcats->value[0]);
-
- /* print attributes */
- if (columns) {
- sprintf(buf, "SELECT %s FROM %s WHERE %s = %d",
- all_columns, Fi->table, Fi->key, fcats->value[0]);
- G_debug(2, "SQL: %s", buf);
- db_set_string(&dbstring, buf);
- if (db_open_select_cursor
- (driver, &dbstring, &cursor, DB_SEQUENTIAL) != DB_OK) {
- db_close_database(driver);
- db_shutdown_driver(driver);
- G_fatal_error(_("Cannot select attributes for cat = %d"),
- fcats->value[0]);
- }
- if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
- db_close_database(driver);
- db_shutdown_driver(driver);
- G_fatal_error(_("Unable to fetch data from table"));
- }
- Table = db_get_cursor_table(&cursor);
- for(i = 0; columns[i]; i++) {
- Column = db_get_table_column(Table, i);
- Value = db_get_column_value(Column);
- if (db_test_value_isnull(Value)) {
- fprintf(ascii, "%s", fs);
- }
- else {
- switch(coltypes[i])
- {
- case DB_C_TYPE_INT: {
- fprintf(ascii, "%s%d", fs, db_get_value_int(Value));
- break;
- }
- case DB_C_TYPE_DOUBLE: {
- fprintf(ascii, "%s%.*f", fs, dp, db_get_value_double(Value));
- break;
- }
- case DB_C_TYPE_STRING: {
- fprintf(ascii, "%s%s", fs, db_get_value_string(Value));
- break;
- }
- case DB_C_TYPE_DATETIME: {
- break;
- }
- case -1:
- G_fatal_error(_("Column <%s> not found in table <%s>"),
- columns[i], Fi->table);
- default: G_fatal_error(_("Column <%s>: unsupported data type"),
- columns[i]);
- }
- }
- }
- db_close_cursor(&cursor);
- }
- }
- fprintf(ascii, "\n");
- }
- else if (format == GV_ASCII_FORMAT_STD) {
- /* FORMAT_STANDARD */
- if (ver == 5 && Cats->n_cats > 0)
- fprintf(ascii, "%c %d %d\n", ctype, Points->n_points,
- Cats->n_cats);
- else
- fprintf(ascii, "%c %d\n", ctype, Points->n_points);
- xptr = Points->x;
- yptr = Points->y;
- zptr = Points->z;
- while (Points->n_points--) {
- G_rasprintf(&xstring, &xsize, "%.*f", dp, *xptr++);
- G_trim_decimal(xstring);
- G_rasprintf(&ystring, &ysize, "%.*f", dp, *yptr++);
- G_trim_decimal(ystring);
- if (ver == 5) {
- if (Map->head.with_z) {
- G_rasprintf(&zstring, &zsize, "%.*f", dp, *zptr++);
- G_trim_decimal(zstring);
- fprintf(ascii, " %-12s %-12s %-12s\n", xstring,
- ystring, zstring);
- }
- else {
- fprintf(ascii, " %-12s %-12s\n", xstring, ystring);
- }
- } /*Version 4 */
- else {
- fprintf(ascii, " %-12s %-12s\n", ystring, xstring);
- }
- }
- if (ver == 5) {
- for (i = 0; i < Cats->n_cats; i++) {
- fprintf(ascii, " %-5d %-10d\n", Cats->field[i],
- Cats->cat[i]);
- }
- }
- else {
- if (cat > 0) {
- if (ltype == GV_POINT) {
- G_rasprintf(&xstring, &xsize, "%.*f", dp, Points->x[0]);
- G_trim_decimal(xstring);
- G_rasprintf(&ystring, &ysize, "%.*f", dp, Points->y[0]);
- G_trim_decimal(ystring);
- fprintf(att, "P %s %s %d\n", xstring, ystring, cat);
- }
- else {
- x = (Points->x[1] + Points->x[0]) / 2;
- y = (Points->y[1] + Points->y[0]) / 2;
- G_rasprintf(&xstring, &xsize, "%.*f", dp, x);
- G_trim_decimal(xstring);
- G_rasprintf(&ystring, &ysize, "%.*f", dp, y);
- G_trim_decimal(ystring);
- fprintf(att, "L %s %s %d\n", xstring, ystring, cat);
- }
- }
- }
- }
- else if (format == GV_ASCII_FORMAT_WKT) {
- if (ltype & (GV_BOUNDARY | GV_CENTROID | GV_FACE | GV_KERNEL))
- continue;
- /* Well-Known Text */
- Vect_sfa_line_astext(Points, ltype, Vect_is_3d(Map), dp, ascii);
- }
- else {
- G_fatal_error(_("Unknown format"));
- }
- n_lines++;
- }
- if (format == GV_ASCII_FORMAT_WKT) {
- /* process areas - topology required */
- int i, area, nareas, isle, nisles;
- if (Vect_level(Map) < 2) {
- G_warning(_("Topology not available, unable to process areas"));
- nareas = 0;
- }
- else {
- nareas = Vect_get_num_areas(Map);
- }
- for (area = 1; area <= nareas; area++) {
- if (!Vect_area_alive(Map, area)) /* skip dead areas */
- continue;
- if (Vect_get_area_cat(Map, area, field) < 0)
- continue;
- /* get boundary -> linearring */
- if (Vect_get_area_points(Map, area, Points) < 0) {
- G_warning(_("Unable to get boundary of area id %d"), area);
- continue;
- }
- fprintf(ascii, "POLYGON(");
- /* write outter ring */
- Vect_sfa_line_astext(Points, GV_BOUNDARY, 0, dp, ascii); /* boundary is always 2D */
- /* get isles (holes) -> inner rings */
- nisles = Vect_get_area_num_isles(Map, area);
- for (i = 0; i < nisles; i++) {
- /* get isle boundary -> linearring */
- isle = Vect_get_area_isle(Map, area, i);
- if (Vect_get_isle_points(Map, isle, Points) < 0) {
- G_warning(_("Unable to get boundary of isle id %d (area id %d)"), isle, area);
- continue;
- }
- fprintf(ascii, ", ");
- /* write inner ring */
- Vect_sfa_line_astext(Points, GV_BOUNDARY, 0, dp, ascii); /* boundary is always 2D */
- }
- fprintf(ascii, ")\n");
- }
- }
- Vect_destroy_line_struct(Points);
- Vect_destroy_cats_struct(Cats);
- Vect_destroy_cats_struct(ACats);
-
- return n_lines;
- }
- int srch(const void *pa, const void *pb)
- {
- int *p1 = (int *)pa;
- int *p2 = (int *)pb;
-
- if (*p1 < *p2)
- return -1;
- if (*p1 > *p2)
- return 1;
- return 0;
- }
- /*!
- \brief Write data to GRASS ASCII vector format
- \param dascii pointer to the ASCII file
- \param Map pointer to Map_info structure
- */
- void Vect_write_ascii_head(FILE *dascii, struct Map_info *Map)
- {
- fprintf(dascii, "ORGANIZATION: %s\n", Vect_get_organization(Map));
- fprintf(dascii, "DIGIT DATE: %s\n", Vect_get_date(Map));
- fprintf(dascii, "DIGIT NAME: %s\n", Vect_get_person(Map));
- fprintf(dascii, "MAP NAME: %s\n", Vect_get_map_name(Map));
- fprintf(dascii, "MAP DATE: %s\n", Vect_get_map_date(Map));
- fprintf(dascii, "MAP SCALE: %d\n", Vect_get_scale(Map));
- fprintf(dascii, "OTHER INFO: %s\n", Vect_get_comment(Map));
- fprintf(dascii, "ZONE: %d\n", Vect_get_zone(Map));
- fprintf(dascii, "MAP THRESH: %f\n", Vect_get_thresh(Map));
- }
- /* check category */
- int check_cat(const struct line_cats *Cats, const struct cat_list *Clist,
- const int *cats, int ncats)
- {
- int i, cat;
-
- if (Clist) {
- Vect_cat_get(Cats, Clist->field, &cat);
- if (!Vect_cat_in_cat_list(cat, Clist))
- return FALSE;
- }
- if (cats) {
- for (i = 0; i < Cats->n_cats; i++) {
- if ((int *)bsearch((void *) &(Cats->cat[i]), cats, ncats, sizeof(int),
- srch)) {
- /* found */
- break;
- }
- }
-
- if (i == Cats->n_cats)
- return FALSE;
- }
-
- return TRUE;
- }
|