#include #include #include #include #include #include #include #include "local_proto.h" /* Determine if the string is integer, e.g. 123, +123, -123 * return 1 if integer, 0 otherwise */ int is_int ( char *str ) { int i = -1; while ( str[++i] != '\0' ) { if ( i == 0 && (str[i] == '+' || str[i] == '-') ) continue; if ( !isdigit(str[i]) ) return 0; } return 1; } /* Determine if the string is double, e.g. 123.456, +123.456, -123.456 * return 1 if double, 0 otherwise */ int is_double ( char *str ) { int i = -1, ndots = 0; while ( str[++i] != '\0' ) { if ( i == 0 && (str[i] == '+' || str[i] == '-') ) continue; if ( str[i] == '.' ) { if ( ndots > 0 ) return 0; /* > 1 dot */ ndots++; continue; } if ( !isdigit(str[i]) ) return 0; } return 1; } /* Analyse points ascii file. Determine number of columns and column types. * ascii_tmp: write copy of tempfile to ascii_tmp: * rowlength: maximum row length * ncolumns: number of columns * minncolumns: minimum number of columns * column_type: column types * column_length: column lengths (string only) */ int points_analyse ( FILE *ascii_in, FILE *ascii, char *fs, int *rowlength, int *ncolumns, int *minncolumns, int **column_type, int **column_length, int skip_lines, int xcol, int ycol ) { int i; int buflen; /* buffer length */ char *buf; /* buffer */ int row = 1; /* line number, first is 1 */ int ncols = 0; /* number of columns */ int minncols = -1; int *coltype = NULL; /* column types */ int *collen = NULL; /* column lengths */ char **tokens; int ntokens; /* number of tokens */ int len, rowlen = 0; /* maximum row length */ struct Cell_head window; double northing=.0; double easting=.0; char *coorbuf, *tmp_token, *sav_buf; buflen = 1000; buf = (char *) G_malloc ( buflen ); coorbuf=(char *) G_malloc(256); tmp_token=(char *) G_malloc(256); sav_buf = NULL; /* fetch projection for LatLong test */ G_get_window(&window); while (1) { len = 0; /* not really needed, but what the heck */ if( G_getl2(buf, buflen-1, ascii_in) == 0 ) break; /* EOF */ if(row <= skip_lines) { G_debug (3, "skipping header row %d : %d chars", row, strlen(buf)); /* this fn is read-only, write to hist with points_to_bin() */ fprintf(ascii, "%s\n", buf); len = strlen ( buf ) + 1; if (len > rowlen ) rowlen = len; row++; continue; } if(buf[0] == '#') { G_debug (3, "skipping comment row %d : %d chars", row, strlen(buf)); continue; } /* no G_chop() as first/last column may be empty fs=tab value */ G_debug (3, "row %d : %d chars", row, strlen(buf)); fprintf(ascii, "%s\n", buf); len = strlen ( buf ) + 1; if (len > rowlen ) rowlen = len; tokens = G_tokenize (buf, fs); ntokens = G_number_of_tokens ( tokens ); if ( ntokens > ncols ) { int c; coltype = (int *) G_realloc ( coltype, ntokens * sizeof(int) ); collen = (int *) G_realloc ( collen, ntokens * sizeof(int) ); for ( c = ncols; c < ntokens; c++ ) { coltype[c] = DB_C_TYPE_INT; /* default type */ collen[c] = 0; } ncols = ntokens; } if ( minncols == -1 || minncols > ntokens ) minncols = ntokens; /* Determine column types */ for ( i = 0; i < ntokens; i++ ) { if ((G_projection() == PROJECTION_LL)){ if (i==xcol || i==ycol ){ if(i==0){ /* Save position of original internal token buffer */ /* Prevent memory leaks */ sav_buf=tokens[0]; } /* check if coordinates are DMS or decimal or not latlong at all */ sprintf(coorbuf,"%s", tokens[i]); G_debug (4, "token: %s", coorbuf); if (G_scan_northing ( coorbuf, &northing, window.proj) ){ G_debug (4, "is_latlong north: %f", northing); sprintf(tmp_token, "%f", northing); /* replace current DMS token by decimal degree */ tokens[i]=tmp_token; }else{ if (G_scan_easting ( coorbuf, &easting, window.proj) ){ G_debug (4, "is_latlong east: %f", easting); sprintf(tmp_token, "%f", easting); /* replace current DMS token by decimal degree */ tokens[i]=tmp_token; } else{ /* maybe do nothing here */ G_warning("Unparsable LatLong value found: %s", tokens[i]); } } /* G_scan_northing else */ } if(i==ntokens-1 && sav_buf != NULL){ /* Restore original token buffer so free_tokens works */ /* Only do this if tokens[0] was re-assigned */ tokens[0]=sav_buf; sav_buf = NULL; } } /* PROJECTION_LL */ G_debug (4, "row %d col %d: '%s' is_int = %d is_double = %d", row, i, tokens[i], is_int(tokens[i]), is_double(tokens[i]) ); if ( is_int(tokens[i]) ) continue; /* integer */ if ( is_double(tokens[i]) ) { /* double */ if ( coltype[i] == DB_C_TYPE_INT ) { coltype[i] = DB_C_TYPE_DOUBLE; } continue; } /* string */ coltype[i] = DB_C_TYPE_STRING; len = strlen (tokens[i]); if ( len > collen[i] ) collen[i] = len; } G_free_tokens(tokens); row++; } *rowlength = rowlen; *ncolumns = ncols; *minncolumns = minncols; *column_type = coltype; *column_length = collen; G_free(buf); G_free(coorbuf); G_free(tmp_token); return 0; } /* Import points from ascii file. * * fs: field separator * xcol, ycol, zcol, catcol: x,y,z,cat column in input file, first column is 1, * zcol and catcol may be 0 (do not use) * rowlen: maximum row length * Note: column types (both in header or coldef) must be supported by driver */ int points_to_bin( FILE *ascii, int rowlen, struct Map_info *Map, dbDriver *driver, char *table, char *fs, int ncols, int *coltype, int xcol, int ycol, int zcol, int catcol, int skip_lines ) { char *buf, buf2[1000]; int cat = 0; int row = 1; struct line_pnts *Points; struct line_cats *Cats; dbString sql, val; struct Cell_head window; /* fetch projection for LatLong test */ G_get_window(&window); rewind(ascii); Points = Vect_new_line_struct (); Cats = Vect_new_cats_struct (); buf = (char *) G_malloc ( rowlen + 1 ); db_init_string (&sql); db_init_string (&val); if(skip_lines > 0) { sprintf(buf2, "HEADER: (%d lines)\n", skip_lines); Vect_hist_write(Map, buf2); } while ( G_getl2(buf, rowlen, ascii) != 0 ) { int i, len; double x, y, z; char **tokens; int ntokens; /* number of tokens */ if(row <= skip_lines) { G_debug (4, "writing skip line %d to hist : %d chars", row, strlen(buf)); Vect_hist_write(Map, buf); Vect_hist_write(Map, "\n"); row++; continue; } len = strlen(buf); if ( len == 0 ) continue; /* should not happen */ G_debug (4, "row: %s", buf ); tokens = G_tokenize (buf, fs); ntokens = G_number_of_tokens ( tokens ); if ((G_projection() == PROJECTION_LL)){ G_scan_easting ( tokens[xcol], &x, window.proj); G_scan_northing ( tokens[ycol], &y, window.proj); }else{ x = atof ( tokens[xcol] ); y = atof ( tokens[ycol] ); } G_debug (4, "x: %f, y: %f", x, y); if ( zcol >= 0 ) z = atof ( tokens[zcol] ); else z = 0.0; if ( catcol >= 0 ) cat = atof ( tokens[catcol] ); else cat++; Vect_reset_line ( Points ); Vect_reset_cats ( Cats ); Vect_append_point ( Points, x, y, z); Vect_cat_set ( Cats, 1, cat ); Vect_write_line ( Map, GV_POINT, Points, Cats ); /* Attributes */ if ( driver ) { sprintf ( buf2, "insert into %s values ( ", table); db_set_string (&sql, buf2 ); if ( catcol < 0 ) { sprintf ( buf2, "%d, ", cat ); db_append_string (&sql, buf2 ); } for ( i = 0; i < ntokens; i++ ) { if ( i > 0 ) db_append_string (&sql, ", " ); if ( strlen(tokens[i]) > 0 ) { if ( coltype[i] == DB_C_TYPE_INT || coltype[i] == DB_C_TYPE_DOUBLE ) { sprintf ( buf2, "%s", tokens[i] ); } else { db_set_string (&val, tokens[i]); /* TODO: strip leading and trailing "quotes" from input string */ db_double_quote_string ( &val ); sprintf ( buf2, "'%s'", db_get_string ( &val ) ); } } else { sprintf ( buf2, "null" ); } db_append_string (&sql, buf2 ); } db_append_string (&sql, ")" ); G_debug ( 3, db_get_string ( &sql ) ); if (db_execute_immediate (driver, &sql) != DB_OK ) { G_fatal_error ( "Cannot insert values: %s", db_get_string ( &sql ) ); } } G_free_tokens(tokens); } return 0; }