static void not_a_vpf_table( char *path ) { char *buf,*filename,*tempstr,ch; buf = (char *)vpfmalloc(255); filename = (char *)vpfmalloc(255); /* Not a VPF table - try to determine what type of file it is */ if (strstr(path,"\\asi") || strstr(path,"\\lsi") || strstr(path,"\\nsi") || strstr(path,"\\csi") || strstr(path,"\\tsi")) { sprintf(filename,"%s is a spatial index file.",path); displaymessage(filename, "It is not a VPF table and cannot be viewed directly", NULL); } else if (strstr(path,".ati") || strstr(path,".lti") || strstr(path,".pti") || strstr(path,".tti")) { sprintf(filename,"%s is a thematic index file.",path); displaymessage(filename, "It is not a VPF table and cannot be viewed directly", NULL); } else if (path[strlen(path)-1] == 'x') { /* Need to determine what file it is the index for */ sprintf(buf,"%s is a variable-length index file",path); strcpy(filename,path); for (ch='a';ch <= 'z';ch++) { if (ch=='x') continue; filename[strlen(path)-1] = ch; if (access(filename,0) == 0) { tempstr = strdup(filename); sprintf(filename,"for %s.",tempstr); free(tempstr); break; } } if (strcmp(path,filename)==0) { displaymessage(buf, "It is not a VPF table and cannot be viewed directly.", NULL); } else { displaymessage(buf, filename, "It is not a VPF table and cannot be viewed directly.", NULL); } } else { /* Not a VPF type of file */ sprintf(filename,"%s: Not a VPF table",path); display_message(filename); } free(filename); free(buf); }
/************************************************************************* * *N dms_string * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function converts a coordinate in degrees-minutes-seconds format * to a character string. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * coord <input> == (dms_type) degrees-minutes-seconds coordinate. * seconds <input> == (int) flag to indicate if seconds are to be * displayed. * return <output> == (char *) character string. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels April 1990 Original Version DOS Turbo C *E *************************************************************************/ char *dms_string( dms_type coord, int seconds ) { char *str,deg[5],min[3],sec[3]; str = (char *)vpfmalloc( (20*sizeof(char))+ sizeof(deg)+sizeof(min)+sizeof(sec) ); itoa( coord.degrees, deg, 10 ); itoa( abs(coord.minutes), min, 10 ); if (seconds) itoa( ((int)floor(coord.seconds)), sec, 10 ); if ((coord.degrees==0)&&(coord.minutes < 0)) { strcpy(str,"-0"); coord.minutes *= -1; } else { strcpy(str,deg); } strcat(str," deg "); strcat(str,min); strcat(str," min "); if (seconds) { strcat(str,sec); strcat(str," sec"); } return(str); }
/* * currently being used by the converter routines, not by the vpfview * routines */ static char * get_line (FILE *fp) { ossim_int32 CurrentChar, /* This is an int because fgetc returns an int */ count , NextBlock = 256 , LineAllocation = 0 ; char *CurrentLine = (char *) NULL ; /* This forever loop searches past all lines beginning with #, indicating comments. */ for (;;) { CurrentChar = fgetc(fp); if ( CurrentChar == COMMENT ) /* skip past comment line */ for (;CurrentChar != NEW_LINE; ) { if (CurrentChar == EOF) return (char *) NULL ; CurrentChar = fgetc (fp) ; } else break ; } /* end of forever loop */ if (CurrentChar == EOF ) return (char *) NULL ; for(count = 0; CurrentChar != EOF; CurrentChar = fgetc(fp), count++) { /* Allocate space for output line, if needed */ if (! ( count < LineAllocation )) { LineAllocation += NextBlock ; if ( CurrentLine ) CurrentLine = (char *) realloc ( CurrentLine, LineAllocation ); else CurrentLine = (char *) vpfmalloc ( LineAllocation ); if (!CurrentLine) { return (char *) NULL ; } } if ( ( CurrentChar == (ossim_int32) LINE_CONTINUE ) ) { CurrentChar = fgetc(fp ) ; /* read character after backslash */ /* A newline will be ignored and thus skipped over */ if ( CurrentChar == (ossim_int32) SPACE ) /* Assume line continue error */ while ( fgetc (fp) != (ossim_int32) SPACE ) ; else if (CurrentChar != (ossim_int32) NEW_LINE ) { /* copy it if not new line */ CurrentLine[count++] = (char) LINE_CONTINUE ; CurrentLine[count] = (char) CurrentChar ; } else count -- ; /* Decrement the counter on a newline character */ } else if (CurrentChar == (ossim_int32) NEW_LINE ) /* We're done */ break; else CurrentLine[count] = (char)CurrentChar; } /* end of for count */ CurrentLine[count] = '\0'; /* terminate string */ return CurrentLine ; }
/*************************************************************************** * *N point_in_face_table * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * Test whether a point is inside a face or not. Must have a valid path- * name to a valid VPF Face file, or else be in graphics mode for the error * message that will result. Filename must have all directory seperators * escapes; eg. c:\\vpf NOT c:\vpf *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * Parameters: *A * x <input> == (float) given point x coordinate. * y <input> == (float) given point y coordinate. * face_id <input> == (rspf_int32) face. * fname <input> == (char *) pathname to VPF face file. * point_in_face_table <output> == VPF_BOOLEAN: * 1 --> point is inside * 0 --> point is not inside *E **************************************************************************/ int point_in_face_table( float x, float y, rspf_int32 face_id, char *fname ) { vpf_table_type facetable, ringtable, edgetable; char *name; int result; name = (char *)vpfmalloc( 255*sizeof(char) ); facetable = vpf_open_table(fname,disk, "rb", NULL ); strupr(fname); strcpy( name, fname ); dirpath( name ); strcat( name, "RNG" ); ringtable = vpf_open_table( name, disk , "rb", NULL ); strcpy( name, fname ); dirpath( name ); strcat( name, "EDG" ); edgetable = vpf_open_table( name, disk , "rb", NULL ); free( name ); result = point_in_face( x, y, face_id, facetable, ringtable, edgetable ); vpf_close_table(&facetable); vpf_close_table(&ringtable); vpf_close_table(&edgetable); return result; }
/************************************************************************* * *N displaymessage * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function displays a list of text strings in a * popup text window. The list must be NULL-terminated. Must be in * graphics mode to call this function. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * string <input> == (char *) first text string to be displayed. * ... <input> == (char *) variable list of text strings to be displayed. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels August 1991 DOS Turbo C *E *************************************************************************/ void displaymessage( char *string, ... ) { int i,maxw,height,x,y,pad, nlines; panel_type panel; char **text; va_list arglist; va_start(arglist,string); nlines = 1; while (va_arg(arglist,char *)) nlines++; va_end(arglist); text = (char **)vpfmalloc((nlines+1)*sizeof(char *)); text[0] = string; va_start(arglist,string); for (i=1;i<nlines;i++) { text[i] = va_arg(arglist,char *); } va_end(arglist); settextstyle( SMALL_FONT, HORIZ_DIR, 4 ); maxw = 0; height = 0; for (i=0;i<nlines;i++) { if (textwidth(text[i]) > maxw) maxw = textwidth(text[i]); height = height + textheight(text[i]) + 5; } if (maxw < (textwidth("Continue") + 10)) maxw = textwidth("Continue") + 10; pad = (maxw*10)/100; maxw = maxw + (2*pad); if (maxw > getmaxx()) maxw = getmaxx() - 8; height = height + 2*(textheight("Continue") + 5) + 5; create_panel( &panel, maxw, height, menucolor, menubordercolor ); x = pad; y = 0; for (i=0;i<nlines;i++) { y = y + textheight(text[i]) + 5; create_label( text[i], x, y, SMALL_FONT, 4, menutextcolor, &panel ); } y = height - (textheight("Continue") + 6); x = (maxw - (textwidth("Continue") + 10))/2; create_button( 27, "Continue", x, y, SMALL_FONT, 4, menutextcolor, menucolor, menubordercolor, RELIEVED, &panel ); get_display_position( &x, &y, panel.window ); display_panel( &panel, x, y ); i = process_panel( &panel, i ); destroy_panel( &panel ); close_panel( &panel ); free(text); }
/************************************************************************* * *N display_message * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function displays a one-line informational message to the * screen and waits for the user to continue. Must be in graphics mode * to call this function. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * str <input> == (char *) message to be displayed. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels July 1990 Original Version DOS Turbo C *E *************************************************************************/ void display_message(char *str) { char **txt; txt = (char **)vpfmalloc( (unsigned long)(1*sizeof(char **)) ); txt[0] = strdup(str); displayinfo( txt, 1 ); free(txt[0]); free(txt); }
/************************************************************************* * *N create_row * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function creates a null row for the given table. * The parameter table must be a valid table and initialized prior to * this function, by vpf_open_table. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * table <input> == (vpf_table_type) vpf table structure. * return <output> == (row_type) row of the table. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels Oct 1991 *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * External Variables: *X * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Functions Called: *F * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Portability: *O * This module should be ANSI C compatible. *E *************************************************************************/ row_type create_row( vpf_table_type table ) { long int i; row_type row; row = (row_type)vpfmalloc(table.nfields*sizeof(column_type)); for (i=0;i<table.nfields;i++) { row[i].count = table.header[i].count; row[i].ptr = NULL; } return row; }
/************************************************************************** * *N display_library_contents * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * List the tables in the Library level directory and display their * contents if selected. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * library <input> == (library_type) VPF library structure. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels DOS Turbo C *E *************************************************************************/ void display_library_contents( library_type library ) { char *filename, *libpath, *path, *libstr; libstr = (char *)vpfmalloc(128); libpath = (char *)vpfmalloc(255); filename = (char *)vpfmalloc(128); path = (char *)vpfmalloc(255); strcpy( libstr, "Library: " ); strcat( libstr, library.name ); strcpy(libpath,library.path); strcat(libpath,"*.*"); do { strcpy(filename,pickfile(libpath,0,libstr)); if (strcmp(filename,"")==0) break; strcpy( path, library.path ); strcat( path, filename ); rightjust(path); leftjust(path); strlwr(path); if (is_vpf_table(path)) { strlwr(path); if (strstr(path,".doc")) vpf_dump_doc_table(path,"temp.out"); else vpf_dump_table(path,"temp.out"); viewfile("temp.out", getmaxy()/3); unlink("temp.out"); } else { not_a_vpf_table(path); } } while (strcmp(filename,"") != 0); free(path); free(filename); free(libpath); free(libstr); }
/* * currently being used by converter routines, not by vpfview * routines */ int add_null_values ( char *name, vpf_table_type table, FILE * fpout ) { FILE *nullfp; ossim_int32 i , ptr ; char *cval, *line, *field ; nullfp = fopen( name, "r"); if ( !nullfp ) return 0; /* Now read nulls from file and populate table structure */ while ( (line = get_line ( nullfp )) ) { ptr = 0 ; field = get_string ( &ptr, line, FIELD_SEPERATOR ) ; i = table_pos ( field, table ) ; switch ( table.header[i].type ) { case 'T': cval = get_string ( &ptr, line, FIELD_SEPERATOR ) ; free ( table.header[i].nullval.Char ) ; /* get rid of default */ table.header[i].nullval.Char = (char *) vpfmalloc ( (unsigned long)strlen (cval)+1) ; strcpy ( table.header[i].nullval.Char, cval ) ; free (cval) ; break ; case 'I': table.header[i].nullval.Int = get_number ( &ptr, line, FIELD_SEPERATOR ); break ; case 'S': table.header[i].nullval.Short = (short int) get_number ( &ptr, line, FIELD_SEPERATOR ); break ; case 'R': cval = get_string ( &ptr, line, FIELD_SEPERATOR ) ; table.header[i].nullval.Double = atof ( cval ) ; free ( cval ) ; break ; case 'F': cval = get_string ( &ptr, line, FIELD_SEPERATOR ) ; table.header[i].nullval.Float = (float) atof ( cval ) ; free ( cval ) ; break ; default: return 0 ; break ; } } return 1 ; }
/************************************************************************** * *N display_database_contents * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * List the tables in the Database level directory and display their * contents if selected. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * database <input> == (database_type) VPF database. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels DOS Turbo C *E *************************************************************************/ void display_database_contents( database_type database ) { char *filename, *dbpath, *path, *dbstr; dbstr = (char *)vpfmalloc(128); dbpath = (char *)vpfmalloc(255); filename = (char *)vpfmalloc(128); path = (char *)vpfmalloc(255); strcpy( dbstr, "Database: " ); strcat( dbstr, database.name ); strcpy(dbpath,database.path); strcat(dbpath,"*.*"); do { strcpy(filename,pickfile(dbpath,0,dbstr)); if (strcmp(filename,"")==0) break; strcpy( path, database.path ); strcat( path, filename ); rightjust(path); strlwr(path); if (is_vpf_table(path)) { if (strstr(path,".doc")) vpf_dump_doc_table(path,"temp.out"); else vpf_dump_table(path,"temp.out"); viewfile("temp.out", getmaxy()/3); unlink("temp.out"); } else { not_a_vpf_table(path); } } while (strcmp(filename,"") != 0); free(path); free(filename); free(dbpath); free(dbstr); }
void displaymessage( char *s, ... ) { int i, nlines; char **text; va_list arglist; va_start(arglist,s); nlines = 1; while (va_arg(arglist,char *)) nlines++; va_end(arglist); text = (char **)vpfmalloc((nlines+1)*sizeof(char *)); text[0] = s; va_start(arglist,s); for (i=1;i<nlines;i++) { text[i] = va_arg(arglist,char *); } va_end(arglist); for (i=0;i<nlines;i++) { fprintf(stderr, "%s", text[i]); } free(text); }
/************************************************************************* * *N outline_face_table * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function outlines the specified face from a previously unopened * face primitive table in the given color. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * face_id <input>==(ossim_int32) id of the face to be outlined. * fname <input>==(char *) file name of the face primitive table. * color <input>==(int) color to outline the face. * inner <input>==(int) if TRUE, draw inner rings; * if FALSE, only draw outer ring. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels May 1991 DOS Turbo C *E *************************************************************************/ void outline_face_table( ossim_int32 face_id, char *fname, int color, int inner ) { vpf_table_type facetable, ringtable, edgetable; char *name; name = (char *)vpfmalloc( 255*sizeof(char) ); gpsetlinecolor( color ); facetable = vpf_open_table(fname,disk, "rb", (char *)NULL); strupr(fname); strcpy( name, facetable.path ); strcat( name, "RNG" ); ringtable = vpf_open_table( name, disk, "rb", (char *)NULL ); strcpy( name, facetable.path ); strcat( name, "EDG" ); edgetable = vpf_open_table( name, disk, "rb", (char *)NULL ); free( name ); hidemousecursor(); outline_face( face_id, facetable, ringtable, edgetable, color, inner ); showmousecursor(); vpf_close_table(&facetable); vpf_close_table(&ringtable); vpf_close_table(&edgetable); }
/************************************************************************* * *N parse_data_def * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function parses a table's data definition and creates a header * in memory that is associated with the table. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * table <inout> == (vpf_table_type *) vpf table structure. * ddlen <input> == (ossim_int32) length of the table's data definition. * * return value is the record length if all items are fixed length, or * -1 if the record contains variable length items *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels April 1991 DOS Turbo C * Mody Buchbinder May 1991 - Modified for new table header. * Dave Flinn July 1991 - updated for UNIX *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * External Variables: *X * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Functions Called: *F * void *vpfmalloc() VPFMISC.C *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Portability: *O * This module should be ANSI C compatible. *E *************************************************************************/ ossim_int32 parse_data_def( vpf_table_type *table ) { register ossim_int32 n,i; ossim_int32 p, k; char *buf,*des,*nar,*vdt, *tdx, *doc, byte ;/*temporary storage */ char end_of_rec; int status; ossim_int32 ddlen; ossim_int32 reclen = 0; #if UNIX /* just for backward compat check */ ossim_int32 bkcompat = 1 ; #endif if ( table->mode == Read ) { fread(&ddlen,sizeof(ddlen),1,table->fp); /* Check the next byte to see if the byte order is specified */ fread(&byte,1,1,table->fp); p=0; table->byte_order = LEAST_SIGNIFICANT; /* default */ switch (toupper(byte)) { case 'L': p++; break; case 'M': table->byte_order = MOST_SIGNIFICANT; p++; break; } if (MACHINE_BYTE_ORDER != table->byte_order) { k = ddlen; swap_four((char *)&k,(char *)&ddlen); } if ( ddlen < 0 ) { return (ossim_int32)0 ; } STORAGE_BYTE_ORDER = table->byte_order; /* header without first 4 bytes */ table->ddlen = ddlen + sizeof (ossim_int32) ; buf = (char *)vpfmalloc((ddlen+3)*sizeof(char)); buf[0] = byte; /* already have the first byte of the buffer */ Read_Vpf_Char(&buf[1],table->fp,ddlen-1) ; } else { table->ddlen = (long)strlen ( table->defstr ) ; ddlen = table->ddlen ; buf = (char *)vpfmalloc((ddlen+3)*sizeof(char)); strncpy ( buf, table->defstr, ddlen ) ; p=0; table->byte_order = LEAST_SIGNIFICANT; /* default */ byte = buf[0]; switch (toupper(byte)) { case 'L': p++; break; case 'M': table->byte_order = MOST_SIGNIFICANT; p++; break; } STORAGE_BYTE_ORDER = table->byte_order; } buf[ddlen-1] = '\0'; /* mark end of string for reading functions */ if ( buf[p] == ';' ) p++; /* buf[p] is semi-colon */ des = get_string(&p,buf,COMPONENT_SEPERATOR ); strncpy(table->description,des,80); free(des); nar = get_string(&p,buf,COMPONENT_SEPERATOR ); strncpy(table->narrative ,nar,12); free(nar); n = 0 ; /* get number of fields */ for (i=p; i < ddlen;i++) if ( buf[i] == LINE_CONTINUE ) i++ ; /* skip past line continue, and next character */ else if (buf[i] == END_OF_FIELD ) /* Found end of field */ n++; /* increment nfields */ else if (buf[i] == COMMENT ) /* skip past comments */ while ( buf[i] != LINE_CONTINUE && buf[i] != END_OF_FIELD && buf[i] != '\0') i++ ; /* increment i */ table->nfields = n ; table->header = (header_type)vpfmalloc((n+1)*sizeof(header_cell)); for(i=0;i<n;i++) { end_of_rec = FALSE; table->header[i].name = get_string(&p,buf, FIELD_COUNT); /*****/ rightjust(table->header[i].name); table->header[i].type = toupper(vpf_get_char (&p,buf)); table->header[i].count = get_number(&p,buf,FIELD_SEPERATOR ); if ( i == 0 ) if ( ossim_strcasecmp ( table->header[0].name, "ID" ) ) { free(buf); return (ossim_int32)0 ; } if(table->header[i].count == -1) reclen = -1; /* set reclen to variable len flag */ /* Now set null values and add up record length, if fixed length */ status = 0; switch (table->header[i].type) { case 'I': if ( reclen >= 0 ) reclen += (sizeof(ossim_int32)*table->header[i].count); table->header[i].nullval.Int = NULLINT ; break; case 'S': if ( reclen >= 0 ) reclen += (sizeof(short int)*table->header[i].count); table->header[i].nullval.Short = NULLSHORT ; break; case 'F': if ( reclen >= 0 ) reclen += (sizeof(float)*table->header[i].count); table->header[i].nullval.Float = NULLFLOAT ; break; case 'R': if ( reclen >= 0 ) reclen += (sizeof(double)*table->header[i].count); table->header[i].nullval.Double = NULLDOUBLE ; break; case 'T': if ( reclen >= 0 ) { /* if fixed length */ reclen += (sizeof(char)*table->header[i].count); table->header[i].nullval.Char = (char *) vpfmalloc ( table->header[i].count + 1 ) ; for ( k=0; k < table->header[i].count; k++ ) table->header[i].nullval.Char[k] = NULLCHAR ; table->header[i].nullval.Char[k] = '\0'; } else { /* variable length */ table->header[i].nullval.Char = (char *) vpfmalloc ( VARIABLE_STRING_NULL_LENGTH + 1 ) ; for ( k=0; k < VARIABLE_STRING_NULL_LENGTH ; k++ ) table->header[i].nullval.Char[k] = NULLCHAR ; table->header[i].nullval.Char[k] = '\0'; } break; case 'C': if ( reclen >= 0 ) reclen += (sizeof(coordinate_type)*table->header[i].count); table->header[i].nullval.Other = '\0'; break; case 'Z': if ( reclen >= 0 ) reclen += (sizeof(tri_coordinate_type)*table->header[i].count); table->header[i].nullval.Other = '\0' ; break; case 'B': if ( reclen >= 0 ) reclen += (sizeof(double_coordinate_type)*table->header[i].count); table->header[i].nullval.Other = '\0' ; break; case 'Y': if ( reclen >= 0 ) reclen += (sizeof(double_tri_coordinate_type)*table->header[i].count); table->header[i].nullval.Other ='\0'; break; case 'D': if ( reclen >= 0 ) reclen += ((sizeof(date_type)-1)*table->header[i].count); strcpy ( table->header[i].nullval.Date, NULLDATE ) ; break; case 'K': reclen = -1; table->header[i].nullval.Other = '\0' ; break; case 'X': /* do nothing */ table->header[i].nullval.Other = '\0' ; break ; default: status = 1; break ; } /** switch type **/ if (status) { free(buf); return (ossim_int32)0; } table->header[i].keytype = vpf_get_char (&p,buf); des = get_string(&p,buf, FIELD_SEPERATOR ); rightjust(des); strncpy(table->header[i].description,des,80); free(des); vdt = get_string(&p,buf, FIELD_SEPERATOR ); strncpy(table->header[i].vdt,vdt,12); free(vdt); #if UNIX /* This is for backward compatability qc checking */ if ( bkcompat && buf[p] == END_OF_FIELD ) { bkcompat= 0 ; } #endif tdx = get_string(&p,buf, FIELD_SEPERATOR ) ; if ( ! strcmp ( tdx, "" ) ) { table->header[i].tdx = (char *) NULL ; if (buf[p] == ':') end_of_rec = TRUE; } else { if (strcmp(tdx,"-") != 0) { table->header[i].tdx =(char*) vpfmalloc ( (unsigned long)strlen ( tdx ) +1 ) ; strcpy (table->header[i].tdx, tdx ); } else table->header[i].tdx = (char *)NULL; } free(tdx); if (!end_of_rec) { doc = get_string(&p,buf, FIELD_SEPERATOR ) ; if ( ! strcmp ( doc, "" ) ) { table->header[i].narrative = (char *) NULL ; end_of_rec = TRUE; } else { if (strcmp(doc,"-") != 0) { table->header[i].narrative = (char*)vpfmalloc ( (unsigned long)strlen(doc) +1) ; strcpy (table->header[i].narrative, doc ); } else table->header[i].narrative = (char *)NULL; } free(doc); } else table->header[i].narrative = (char *)NULL; p += 1; /** eat semicolon **/ } free(buf); return reclen; }
/************************************************************************* * *N vpf_open_table * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function opens a vpf table and either loads it into RAM or sets * up the structure to read off of disk. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * tablename <input> == (const char *) file name of the table. * storage <input> == (storage_type) table storage mode - * either ram or disk. * mode <input> == (const char *) file mode for opening the table - * same as fopen() mode in C. * defstr <input> == (char *) table definition string used for * creating a writable table. * vpf_open_table <output> == (vpf_table_type) VPF table structure. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels April 1991 DOS Turbo C * Dave Flinn July 1991 UNIX compatable *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * External Variables: *X * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Functions Called: *F *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Portability: *O * This module should be ANSI C compatible. *E *************************************************************************/ vpf_table_type vpf_open_table( const char * tablename, storage_type storage , const char * mode, char * defstr ) { vpf_table_type table; char tablepath[255], * idxname; ossim_int32 i, j; ossim_int32 tablesize, idxsize, memsize; ossim_uint32 ulval; char * diskname = "VPF data disc"; strcpy(tablepath,tablename); rightjust(tablepath); /* Parse out name and path */ j = -1; i=(long)strlen(tablepath); while (i>0) { #ifdef __MSDOS__ if (tablepath[i] == '\\') { #else if (tablepath[i] == '/') { #endif j = i; break; } i--; } strncpy(table.name,&(tablepath[j+1]),12); rightjust(table.name); strupr(table.name); table.path = (char *)vpfmalloc(((unsigned long)strlen(tablepath)+5)*(unsigned long)sizeof(char)); strcpy(table.path, tablepath); table.path[j+1] = '\0'; /* Establish a read or write table operation */ if ( mode[0] == 'r' ) table.mode = Read ; else table.mode = Write ; /*fprintf(stderr, "vpf_open_table opening %s\n", tablepath);*/ table.fp = vpfopencheck(tablepath,mode,diskname); if (table.fp == NULL) { perror(tablepath); /* #if __MSDOS__ perror(tablepath); getch(); if (getgraphmode() >= 0) closegraph(); exit(0); #endif */ free(table.path); if (table.fp) { fclose(table.fp); table.fp = NULL; } return table; } /* If file is to be created, copy the def string ptr into header for now */ if ( table.mode == Write ) table.defstr = defstr ; #ifdef __MSDOS__ tablesize = (filelength(fileno(table.fp))); #else { /* UNIX doesn't have a filelength function, so this is the best */ struct stat statbuf ; if ( stat ( tablepath, &statbuf ) < 0 ) { fprintf (stderr, "vpf_open_table: can't stat file\n" ) ; free(table.path); fclose(table.fp); table.fp = NULL; return table; } tablesize = statbuf.st_size ; } #endif /* Populate table structure with correct data, either for read or write */ table.reclen = parse_data_def(&table); if ( table.mode == Write ) { /* write out header */ rewind ( table.fp ) ; Write_Vpf_Int ( &table.ddlen, table.fp, 1 ) ; Write_Vpf_Char ( table.defstr, table.fp, table.ddlen ) ; free ( table.defstr ) ; table.defstr = (char *) NULL ; table.nrows = 0 ; } if (table.reclen > 0) { /* Index file */ table.xstorage = (storage_type)COMPUTE; if (table.mode != Write) table.nrows = (tablesize - table.ddlen)/table.reclen; table.xfp = (FILE *) NULL ; } else { idxname = strdup( tablepath ); #ifdef __MSDOS__ idxname[strlen(tablepath)-1] = 'x'; #else if (idxname[strlen(tablepath)-1] == '.') idxname[strlen(tablepath)-2] = 'x'; else idxname[strlen(tablepath)-1] = 'x'; #endif table.xfp = fopen(idxname, mode); if ((!table.xfp) && (table.mode == Read)) { perror(idxname); fprintf(stderr, "hit RETURN to continue..."); i=getc(stdin); free(idxname); for (i = 0; i < table.nfields; i++) free(table.header[i].name); free(table.header); free(table.path); fclose(table.fp); table.fp = NULL; return table; } free(idxname); /*#ifdef __MSDOS__*/ table.xstorage = (storage_type)DISK; /* Worst case default */ /*#endif*/ /* Only read in index if file is read only */ if (table.xfp && ( table.mode == Read ) ) { Read_Vpf_Int (&(table.nrows), table.xfp, 1 ) ; Read_Vpf_Int (&ulval, table.xfp, 1 ) ; idxsize = table.nrows*sizeof(index_cell) + 10L; #ifdef __MSDOS__ if ( (idxsize < (farcoreleft()/2)) && (idxsize < __64K) ) #else if (0) #endif { table.xstorage = (storage_type)RAM; table.index = (index_type)vpfmalloc(idxsize); for (i=0;i<table.nrows;i++) { Read_Vpf_Int (&(table.index[i].pos), table.xfp, 1) ; Read_Vpf_Int (&(table.index[i].length),table.xfp,1 ) ; } fclose(table.xfp); } } else if (table.mode == Write) { /* Write out dummy header record for index file. vpf_close_table finishes the job. */ Write_Vpf_Int ( &(table.ddlen), table.xfp, 1 ) ; Write_Vpf_Int ( &(table.ddlen), table.xfp, 1 ) ; table.xstorage = (storage_type)DISK; table.index = (index_type) NULL ; } } /* end of if table .reclen */ table.storage = (storage_type)DISK; #ifdef __MSDOS__ memsize = (ossim_int32)min(farcoreleft(),__64K); #else memsize = MAXINT; #endif if ( (storage != disk) && ( table.mode == Read ) ) { if (tablesize + table.nrows * table.nfields * HEAP_OVERHEAD < memsize) { fseek(table.fp,index_pos(1,table),SEEK_SET); table.row = (row_type *)vpfmalloc((table.nrows+1)*sizeof(row_type)); for (i=0;i<table.nrows;i++) { table.row[i] = read_next_row(table); } fclose(table.fp); table.storage = (storage_type)RAM; } } table.status = OPENED; return table; } /************************************************************************* * *N vpf_close_table * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function frees an entire table from memory. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * table <inout> == (vpf_table_type) VPF table structure. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels May 1991 DOS Turbo C *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * External Variables: *X * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Functions Called: *F * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Portability: *O * This module should be ANSI C compatible. *E *************************************************************************/ void vpf_close_table( vpf_table_type *table ) { register ossim_int32 i; if (table->status != OPENED) { return; } /*fprintf(stderr, "vpf_close_table closing %s%s\n", table->path, table->name);*/ /* If the table is writable, write out the final record count */ if ( table->mode == Write && table->xfp ) { rewind ( table->xfp ) ; Write_Vpf_Int ( &table->nrows, table->xfp, 1 ) ; Write_Vpf_Int ( &table->ddlen, table->xfp, 1 ) ; } for (i=0;i<table->nfields;i++) { free(table->header[i].name); /* free up null text string */ if ( table->header[i].type == 'T') free(table->header[i].nullval.Char); /* free up index file string */ if (table->header[i].tdx!=(char *)NULL) free ( table->header[i].tdx ) ; /* free up narrative table string */ if (table->header[i].narrative!=(char *)NULL) { free ( table->header[i].narrative ) ; } } free(table->header); switch (table->storage) { case RAM: for (i=0;i<table->nrows;i++) free_row(table->row[i],*table); free(table->row); break; case DISK: fclose(table->fp); break; default: printf("%s%s: unknown storage flag: %d\n",table->path,table->name, table->storage); break; } switch (table->xstorage) { case RAM: free(table->index); break; case DISK: fclose(table->xfp); break; case COMPUTE: break; default: printf("%s%s: unknown index storage flag: %d\n", table->path,table->name,table->storage); break; } table->nfields = 0; free(table->path); table->status = CLOSED; } ossim_int32 is_vpf_table( const char *fname ) { FILE *fp; ossim_int32 n, ok; fp = fopen( fname, "rb" ); if (!fp) { return FALSE; } Read_Vpf_Int ( &n, fp, 1 ) ; fseek( fp, n-1, SEEK_CUR ); if (fgetc(fp) == ';') ok = TRUE; else ok = FALSE; fclose(fp); return ok; }
/************************************************************************* * *N put_table_element * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * Copies one element into the designated field. * The parameter row must be initialized prior to this functional, either * buy being read in from an existing table or set to valid values. The * parameter table must be a valid table and initialized prior to this * function, by vpf_open_table. Note that if errorfp is used, it must * be opened prior to this function. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * field <input> == (long int) column offset. * row <in-out> == (row_type) row containing target field. * table <in-out> == (vpf_table_type) VPF table owning row. * value <in> == (void *) source field element. * count <in> == (long int) number of items in value. * put_table_element <output> == (long int) * 0 --> element write succeeded * 1 --> unknown element type or * invalid column offset *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * RDF 7/91 original * JTB 10/91 removed call to exit(); * guaranteed function always returns value * 0: element write succeeded * -1: unknown element type or invalid column (field) offset *E *************************************************************************/ long int put_table_element( long int field, row_type row, vpf_table_type table, void * value, long int count ) { long int i, len, stat; char *str; stat=0; if ((count != table.header[field].count) && (table.header[field].count > 0)) { printf("Invalid element count! (%ld, %ld)\n", count,table.header[field].count); return -1; } if (field < 0 || field >= table.nfields) return -1; row[field].count = count; if (row[field].ptr) { free(row[field].ptr); row[field].ptr = NULL; } switch ( table.header[field].type ) { case 'T': len = (long int)max(count,table.header[field].count); str = (char *) vpfmalloc( len + 1 ); row[field].ptr = (char *) vpfmalloc ( len + 1 ) ; strcpy( (char*)str, (char*)value ); for ( i = (long)strlen((char*)value) ; i < table.header[field].count; i++ ) str[i] = SPACE ; str[len] = '\0'; memcpy(row[field].ptr, str, len+1); free(str); break ; case 'D': row[field].ptr = (date_type *) vpfmalloc (count*sizeof(date_type)); memcpy ( row[field].ptr, value, sizeof (date_type) * count ) ; break; case 'I' : row[field].ptr = (long int *) vpfmalloc (count*sizeof(long int)); memcpy ( row[field].ptr, value, sizeof (long int) * count ) ; break; case 'S' : row[field].ptr = (short int *) vpfmalloc (count*sizeof(short int)); memcpy ( row[field].ptr, value, sizeof (short int) * count ) ; break; case 'F': row[field].ptr = (float *) vpfmalloc (count*sizeof(float)); memcpy ( row[field].ptr, value, sizeof (float) * count ) ; break; case 'R': row[field].ptr = (double *) vpfmalloc (count*sizeof(double)); memcpy ( row[field].ptr, value, sizeof (double) * count ) ; break; case 'K': row[field].ptr = (id_triplet_type *) vpfmalloc ( count*sizeof(id_triplet_type )); memcpy ( row[field].ptr, value, sizeof(id_triplet_type)*count ) ; break; case 'C': if (value) { row[field].ptr = (coordinate_type *) malloc ( count * sizeof( coordinate_type )); if (row[field].ptr) memcpy ( row[field].ptr, value, sizeof(coordinate_type)*count ) ; } else { row[field].ptr = NULL; } break; case 'Z': if (value) { row[field].ptr = (tri_coordinate_type *) malloc ( count * sizeof( tri_coordinate_type )); if (row[field].ptr) memcpy ( row[field].ptr, value, sizeof(tri_coordinate_type)*count ) ; } else { row[field].ptr = NULL; } break; case 'B': if (value) { row[field].ptr = (double_coordinate_type *) malloc ( count * sizeof( double_coordinate_type )); if (row[field].ptr) memcpy ( row[field].ptr, value, sizeof(double_coordinate_type)*count ) ; } else { row[field].ptr = NULL; } break; case 'Y': if (value) { row[field].ptr = (double_tri_coordinate_type *) malloc ( count * sizeof( double_tri_coordinate_type )); if (row[field].ptr) memcpy( row[field].ptr, value, sizeof(double_tri_coordinate_type)*count); } else { row[field].ptr = NULL; } break; default: stat = -1; break ; } return stat; }
/* get string until delimeter */ static char *cpy_del(char *src, char delimiter, ossim_int32 *ind ) { ossim_int32 i, skipchar ; char *temp, *tempstr ; /* remove all blanks ahead of good data */ skipchar = 0 ; while ( src[skipchar] == SPACE || src[skipchar] == TAB ) skipchar++ ; temp = &src[skipchar]; /* If t he first character is a COMMENT, goto LINE_CONTINUE */ if ( *temp == COMMENT ) { while ( *temp != LINE_CONTINUE && *temp != END_OF_FIELD && *temp != '\0'){ temp++ ; skipchar ++ ; } skipchar++ ; temp++ ; /* skip past LC, EOF, or NULL */ } /* Start with temporary string value */ tempstr = (char *)vpfmalloc ( (unsigned long)strlen ( temp ) + 10 ) ; if ( *temp == '"' ) { /* If field is quoted, do no error checks */ temp++ ; /* skip past quote character */ skipchar++ ; /* update the position pointer */ for ( i=0 ; *temp != '\0'; temp++,i++) { if ( *temp == LINE_CONTINUE || *temp == TAB ) { temp++ ; skipchar++ ; } else if ( *temp == '"' ) break ; /* Now copy the char into the output string */ tempstr[i] = *temp ; } tempstr[i] = '\0'; /* terminate string */ *ind += ( i + skipchar + 2) ; /* Increment position locate past */ return tempstr ; /* quote and semicolon */ } /* search for delimiter to end, or end of string */ i=0 ; /* initialize */ if ( *temp != END_OF_FIELD ) { /* backward compatability check */ for ( i=0; *temp != '\0';temp++,i++){/* Stop on NULL*/ if ( ( *temp == LINE_CONTINUE && *(temp+1) == '\n') || *temp == TAB ) { temp++ ; skipchar++ ; } else if ( *temp == delimiter ) break ; /* break for delimiter */ /* Now copy the char into the output string */ tempstr[i] = *temp ; } /* Eat the delimiter from ind also */ *ind += ( i + skipchar + 1) ; /* Increment position locate */ } tempstr[i] = '\0'; /* terminate string */ return tempstr; }
/************************************************************************* * *N write_next_row * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function writes the next row of the table. * The parameter row must be initialized prior to this functional, either * by being read in from an existing table or set to valid values. * A row with any empty columns should not be written out. * The parameter table must be a valid table and initialized prior to * this function, by vpf_open_table. It is assumed that there is * enough free disk space to write to the file. It is also assumed that * the file pointer (table->fp) is already opened for writing. The * variable count, set to the values in row, must be greater than 0, * otherwise, if count is -1 the vpf_write functions will lock up * (row[].count should never have a value of 0). Note that if errorfp * is used, it must be opened prior to this function. * *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * row <input> == (row_type) the row to write to the table. * table <input> == (vpf_table_type *) vpf table structure. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Dave Flinn July 1991 Based on read_next_row. * Barry Michaels Oct 1991 Added row as a parameter. * JTB 10/91 guaranteed function always * returns a value: * 0: record written * -1: unknown field type *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * External Variables: *X * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Functions Called: *F * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Portability: *O * This module should be ANSI C compatible. *E *************************************************************************/ long int write_next_row(row_type row, vpf_table_type * table ) { register long int i, j; char * tptr, * output ; long int recordsize = 0; long int count; id_triplet_type * keys; unsigned long int pos_for_ndx, length; int retn_val = 0; coordinate_type dummycoord = {0.0,0.0}; STORAGE_BYTE_ORDER = table->byte_order; table->nrows++; fseek(table->fp, 0L, SEEK_END); pos_for_ndx = ftell(table->fp); /* begining of new row */ for (i = 0; i < table->nfields; i++) { /* for each column */ count = row[i].count ; /* Retrieve count from row. Should be 0 if variable length null */ /* In case this column is variable length, write out count */ if (count == 0) count = 1; if ( table->header[i].count < 0 ) { Write_Vpf_Int ( &count, table->fp, 1 ) ; recordsize += sizeof ( long int ) ; } /* Now write out the data type */ switch (table->header[i].type) { case 'T': if ( count == 0 ) /* Assume this is variable length text and don't do anything */ break ; /* This loop insures that the exact number of characters are written out to disk. */ output = (char *) vpfmalloc ( count + 1 ) ; /* include null byte */ for (j = 0, tptr = (char*)row[i].ptr; j < count; j++, tptr++) if ( *tptr ) output[j] = *tptr ; else output[j] = SPACE ; output[count] = '\0' ; Write_Vpf_Char( output ,table->fp, count) ; free ( output ) ; recordsize += sizeof ( char ) * count ; break; case 'I': Write_Vpf_Int (row[i].ptr, table->fp, count ) ; recordsize += sizeof ( long int ) * count ; break; case 'S': Write_Vpf_Short (row[i].ptr, table->fp, count ) ; recordsize += sizeof ( short int ) * count ; break; case 'F': Write_Vpf_Float (row[i].ptr, table->fp, count ) ; recordsize += sizeof ( float ) * count ; break; case 'R': Write_Vpf_Double (row[i].ptr, table->fp, count ) ; recordsize += sizeof ( double ) * count ; break; case 'D': /* date has 21 chars in memory, not on disk */ Write_Vpf_Date (row[i].ptr, table->fp, count ) ; recordsize += ( sizeof ( date_type ) - 1 ) * count ; break; case 'C': if (row[i].ptr) { Write_Vpf_Coordinate(row[i].ptr,table->fp,count); } else { for (j=0;j<count;j++) Write_Vpf_Coordinate(&dummycoord,table->fp,count); } recordsize += sizeof ( coordinate_type ) * count ; break; case 'B': Write_Vpf_DoubleCoordinate(row[i].ptr,table->fp,count); recordsize += sizeof ( double_coordinate_type ) * count ; break; case 'Z': Write_Vpf_CoordinateZ(row[i].ptr,table->fp,count); recordsize += sizeof ( tri_coordinate_type ) * count ; break; case 'Y': Write_Vpf_DoubleCoordinateZ(row[i].ptr,table->fp,count); recordsize += sizeof ( double_tri_coordinate_type ) * count ; break; case 'K': keys = (id_triplet_type *) vpfmalloc (count*sizeof(id_triplet_type)) ; memcpy ( keys, row[i].ptr, count*sizeof(id_triplet_type) ) ; for (j=0;j<count;j++) recordsize += write_key ( keys[j], table->fp); free ( keys ) ; break; case 'X': /* do nothing */ break; default: return(-1); } } if ( table->xfp ) { /* only for variable length columns */ length = recordsize ; fseek( table->xfp, 0, SEEK_END ); Write_Vpf_Int ( &pos_for_ndx, table->xfp, 1 ) ; Write_Vpf_Int ( &length, table->xfp, 1 ) ; } return retn_val; }
/************************************************************************* * *N draw_selected_features * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function draws the selected features from a specified feature * class based upon a query (either an expression or the pre-compiled * results of an expression). *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * view <inout>==(view_type *) view structure. * themenum <input>==(int) theme number. * library <input>==(library_type *) VPF library structure. * mapenv <input>==(map_environment_type *) map environment structure. * return <output>==(int) completion status: * 1 if completed successfully, * 0 if an error occurred. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels August 1991 DOS Turbo C *E *************************************************************************/ int draw_selected_features( view_type *view, int themenum, library_type *library, map_environment_type *mapenv ) { int status, fcnum, finished, cov, tilecover, TILEPATH_, prim; int outline, color1, color2, color3, color4; vpf_table_type rngtable,edgtable,fbrtable, tile_table; row_type row; char *ptable[] = {"","edg","fac","txt","end","cnd"}; register rspf_int32 i, j, p, pclass, tile; int display_order[] = {FACE,EDGE,ENTITY_NODE,CONNECTED_NODE,TEXT}; register rspf_int32 starttile, endtile, startprim, endprim; rspf_int32 count; char path[255], covpath[255], tiledir[255], *buf, str[255]; char *drive, rngpath[255],edgpath[255],edxpath[255],fbrpath[255]; boolean rng_rdisk,edg_rdisk,fbr_rdisk; set_type primitives, feature_rows; fcrel_type fcrel; window_type info; struct viewporttype vp; getviewsettings(&vp); fcnum = view->theme[themenum].fcnum; sprintf(path,"%stileref\\tileref.aft",library->path); if (access(path,0) != 0) { tilecover = FALSE; } else { tile_table = vpf_open_table(path,disk,"rb",NULL); TILEPATH_ = table_pos("TILE_NAME",tile_table); tilecover = TRUE; } feature_rows = get_selected_features( view, themenum, *library ); for (p=0;p<5;p++) { pclass = display_order[p]; if ((pclass != library->fc[fcnum].primclass) && (library->fc[fcnum].primclass != COMPLEX_FEATURE)) continue; if ((library->fc[fcnum].primclass == COMPLEX_FEATURE) && (!library->fc[fcnum].cprim[pclass])) continue; /* Set up the feature class table relate chain. */ /* The feature table is fcrel.table[0]. */ /* The primitive table is the last table in the chain: */ /* fcrel.table[ fcrel.nchain-1 ]. */ j = 0; for (i=0;i<strlen(library->fc[fcnum].table);i++) if (library->fc[fcnum].table[i] == '\\') j = i+1; strcpy( str, &(library->fc[fcnum].table[j])); fcrel = select_feature_class_relate(fcnum, library, str, ptable[pclass]); prim = fcrel.nchain-1; /*** 'Tile' number 1 is the universe polygon for the tileref cover ***/ starttile = set_min(library->tile_set); if (starttile < 2) starttile = 2; endtile = set_max(library->tile_set); if (endtile < 2) endtile = 2; for (tile = starttile; tile <= endtile; tile++ ) { if (!set_member(tile,library->tile_set)) continue; if (tilecover) { row = get_row(tile,tile_table); buf = (char *)get_table_element(TILEPATH_,row,tile_table, NULL,&count); free_row(row,tile_table); strcpy(tiledir,buf); rightjust(tiledir); strcat(tiledir,"\\"); free(buf); } else { strcpy(tiledir,""); } cov = library->fc[fcnum].coverage; strcpy( covpath, library->cover[cov].path ); finished = TRUE; sprintf(path,"%s%s%s",covpath,tiledir,ptable[pclass]); if (access(path,0) != 0) continue; fcrel.table[prim] = vpf_open_table(path,disk,"rb",NULL); info = info_window("Searching..."); primitives = get_selected_tile_primitives( library, fcnum, fcrel, feature_rows, mapenv, tile, tiledir, &status ); delete_window(&info); setviewport(vp.left,vp.top,vp.right,vp.bottom,vp.clip); /* Reset plate-carree parameters (changed in */ /* get_selected_tile_primitives() ) */ if (mapenv->projection == PLATE_CARREE) set_plate_carree_parameters( central_meridian( mapenv->mapextent.x1, mapenv->mapextent.x2), 0.0, 1.0 ); if (primitives.size < 1) { vpf_close_table(&fcrel.table[prim]); continue; } if (!status) { set_nuke(&primitives); vpf_close_table(&fcrel.table[prim]); break; } if (pclass == FACE) { /* Must also open RNG, EDG, and FBR for drawing faces. */ /* If a RAM disk is specified, copy these to it and open */ /* them there. */ rng_rdisk = FALSE; edg_rdisk = FALSE; fbr_rdisk = FALSE; drive = getenv("TMP"); buf = (char *)vpfmalloc(255); sprintf(path,"%s%srng",covpath,tiledir); strcpy(rngpath,path); if (drive && filesize(path) < available_space(drive)) { sprintf(rngpath,"%s\\RNG",drive); sprintf(buf,"COPY %s %s > NUL",path,rngpath); system(buf); rng_rdisk = TRUE; } rngtable = vpf_open_table(rngpath,disk,"rb",NULL); sprintf(path,"%s%sedg",covpath,tiledir); strcpy(edgpath,path); sprintf(edxpath,"%s%sedx",covpath,tiledir); if (drive && (filesize(path)+filesize(edxpath))<available_space(drive)) { sprintf(edgpath,"%s\\EDG",drive); sprintf(buf,"COPY %s %s > NUL",path,edgpath); system(buf); sprintf(edxpath,"%s\\EDX",drive); sprintf(buf,"COPY %s%sedx %s > NUL",covpath,tiledir,edxpath); system(buf); edg_rdisk = TRUE; } edgtable = vpf_open_table(edgpath,disk,"rb",NULL); sprintf(path,"%s%sfbr",covpath,tiledir); strcpy(fbrpath,path); if (drive && filesize(path) < available_space(drive)) { sprintf(fbrpath,"%s\\FBR",drive); sprintf(buf,"COPY %s %s > NUL",path,fbrpath); system(buf); fbr_rdisk = TRUE; } fbrtable = vpf_open_table(fbrpath,disk,"rb",NULL); free(buf); } finished = 1; startprim = set_min(primitives); endprim = set_max(primitives); /* It turns out to be MUCH faster off of a CD-ROM to */ /* read each row and discard unwanted ones than to */ /* forward seek past them. It's about the same off */ /* of a hard disk. */ fseek(fcrel.table[prim].fp, index_pos(startprim,fcrel.table[prim]), SEEK_SET); for (i=startprim;i<=endprim;i++) { row = read_next_row(fcrel.table[prim]); if (set_member( i, primitives )) { /* Draw the primitive */ switch (pclass) { case EDGE: finished = draw_edge_row(row,fcrel.table[prim]); break; case ENTITY_NODE: case CONNECTED_NODE: finished = draw_point_row(row,fcrel.table[prim]); break; case FACE: gpgetlinecolor( &outline ); gpgetpattern( &color1, &color2, &color3, &color4 ); hidemousecursor(); draw_face_row( row,fcrel.table[prim], rngtable, edgtable, fbrtable, outline, color1, color2, color3, color4 ); showmousecursor(); finished = 1; if (kbhit()) { if (getch()==27) finished = 0; } break; case TEXT: finished = draw_text_row(row,fcrel.table[prim]); break; } } free_row(row,fcrel.table[prim]); if (!finished) { status = 0; break; } } if (pclass == FACE) { vpf_close_table(&rngtable); if (rng_rdisk) remove(rngpath); vpf_close_table(&edgtable); if (edg_rdisk) { remove(edgpath); remove(edxpath); } vpf_close_table(&fbrtable); if (fbr_rdisk) remove(fbrpath); } vpf_close_table(&fcrel.table[prim]); set_nuke(&primitives); if (!finished) { status = 0; break; } } if (!finished) { status = 0; deselect_feature_class_relate( &fcrel ); break; } status = 1; if (kbhit()) { if (getch()==27) { status = 0; deselect_feature_class_relate( &fcrel ); break; } } deselect_feature_class_relate(&fcrel); } if (tilecover) { vpf_close_table(&tile_table); } set_nuke(&feature_rows); return status; }
/************************************************************************** * *N select_feature_class_relate * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * Set up the relationships between features and primitives or between * primitives and features (one way only) for a specified feature class. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels DOS Turbo C *E *************************************************************************/ fcrel_type select_feature_class_relate( int fcnum, library_type *library, char *start_table, char *end_table ) { int storage, cov; vpf_table_type fcs; long int i; char path[255], covpath[255]; position_type p; vpf_relate_struct rcell; fcrel_type fcrel; fcrel.nchain = 0; fcrel.table = NULL; fcrel.relate_list = NULL; cov = library->fc[fcnum].coverage; strcpy(covpath,library->cover[cov].path); rightjust(covpath); sprintf( path, "%sfcs", covpath ); /* Feature Class Schema table */ fcs = vpf_open_table( path, disk, "rb", NULL ); fcrel.relate_list = fcs_relate_list( library->fc[fcnum].name, start_table,end_table, fcs ); if (ll_empty(fcrel.relate_list)) { ll_reset(fcrel.relate_list); displaymessage("ERROR in feature class relationship!", start_table,end_table,NULL); return fcrel; } /* Find the number of tables in the relate chain */ p = ll_first(fcrel.relate_list); fcrel.nchain = 0; while (!ll_end(p)) { fcrel.nchain++; p = ll_next(p); } /* Allow for last table2 */ fcrel.nchain++; fcrel.table = (vpf_table_type *) vpfmalloc((fcrel.nchain+1)* sizeof(vpf_table_type)); for (i=0;i<fcrel.nchain+1;i++) vpf_nullify_table( &(fcrel.table[i]) ); p = ll_first(fcrel.relate_list); for (i=0;i<fcrel.nchain-1;i++) { ll_element(p,&rcell); /** Can't open primitive table - may be several under tile **/ /** directories. Open all others **/ if (!is_primitive(rcell.table1)) { sprintf(path,"%s%s",covpath,rcell.table1); if (is_join(rcell.table1)) storage = ram; else storage = disk; fcrel.table[i] = vpf_open_table(path,(storage_type)storage,"rb",NULL); } if (!ll_end(p)) p = ll_next(p); } /* End of relate chain */ i = fcrel.nchain-1; if (!is_primitive(rcell.table2)) { sprintf(path,"%s%s",covpath,rcell.table2); storage = disk; fcrel.table[i] = vpf_open_table(path,(storage_type)storage,"rb",NULL); } vpf_close_table( &fcs ); return fcrel; }
/************************************************************************* * *N get_selected_primitives * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function determines all of the selected primitive rows from * the selected features. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * view <input> == (view_type *) view structure. * themenum <input> == (int) theme number. * library <input> == (library_type *) VPF library structure. * mapenv <input> == (map_environment_type *) map environment. * status <output> == (int *) status of the function: * 1 if completed, 0 if user escape. * get_selected_primitives <output> == (set_type *) array of sets, each position * representing the set of primitives for the * corresponding tile in the tileref.aft table. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels May 1991 DOS Turbo C *E *************************************************************************/ set_type *get_selected_primitives( view_type *view, int themenum, library_type *library, map_environment_type *mapenv, int *status ) { int fcnum, finished, found, cov, tilecover, TILEPATH_, degree; int feature, prim; vpf_table_type tile_table; row_type row; char *ptable[] = {"","edg","fac","txt","end","cnd"}; char *spxname[] = {"","esi","fsi","tsi","nsi","csi"}; char *brname[] = {"","ebr","fbr","tbr","nbr","cbr"}; set_type feature_rows, primitive_rows, tile_features; set_type *primitives; rspf_int32 prim_rownum, count, tile; register rspf_int32 i,j, pclass, start,end; char path[255], covpath[255], tiledir[255], *buf, str[255]; fcrel_type fcrel; linked_list_type primlist; position_type p; vpf_relate_struct rcell; ThematicIndex idx; primitives = (set_type *)vpfmalloc((library->ntiles+1)*sizeof(set_type)); for (i=0;i<=library->ntiles;i++) { primitives[i].size = 0; primitives[i].buf = NULL; } fcnum = view->theme[themenum].fcnum; feature_rows = get_selected_features( view, themenum, *library ); /* Open the tile reference table, if present */ sprintf(path,"%stileref\\tileref.aft",library->path); if (access(path,0) != 0) { tilecover = FALSE; } else { tile_table = vpf_open_table(path,disk,"rb",NULL); TILEPATH_ = table_pos("TILE_NAME",tile_table); tilecover = TRUE; } for (pclass=EDGE;pclass<=CONNECTED_NODE;pclass++) { if ((pclass != library->fc[fcnum].primclass) && (library->fc[fcnum].primclass != COMPLEX_FEATURE)) continue; /* Set up the feature class table relate chain. */ /* The feature table is fcrel.table[0]. */ /* The primitive table is the last table in the chain: */ /* fcrel.table[ fcrel.nchain-1 ]. */ j = 0; for (i=0;i<strlen(library->fc[fcnum].table);i++) if (library->fc[fcnum].table[i] == '\\') j = i+1; strcpy( str, &(library->fc[fcnum].table[j])); fcrel = select_feature_class_relate(fcnum, library, str, ptable[pclass]); feature = 0; prim = fcrel.nchain-1; p = ll_previous(ll_last(fcrel.relate_list),fcrel.relate_list); ll_element(p,&rcell); degree = rcell.degree; /*** 'Tile' number 1 is the universe polygon for the tileref cover ***/ for (tile = 2; tile <= library->ntiles; tile++ ) { if (!set_member(tile,library->tile_set)) continue; if (tilecover) { row = get_row(tile,tile_table); buf = (char *)get_table_element(TILEPATH_,row,tile_table, NULL,&count); free_row(row,tile_table); strcpy(tiledir,buf); rightjust(tiledir); strcat(tiledir,"\\"); free(buf); } else { strcpy(tiledir,""); } cov = library->fc[fcnum].coverage; strcpy( covpath, library->cover[cov].path ); finished = 1; found = 0; /* Open primitive table in tile */ sprintf(path,"%s%s%s",covpath,tiledir,ptable[pclass]); if (access(path,0) != 0) continue; found = 1; fcrel.table[prim] = vpf_open_table(path,disk,"rb",NULL); if (primitives[tile].size > 0) { printf("Oops! size = %ld\n",primitives[tile].size); exit(1); } primitives[tile] = set_init(fcrel.table[prim].nrows+1); /* Get the set of primitive rows within the map extent */ /* Look for spatial index file */ primitive_rows.size = 0; if (mapenv->projection == PLATE_CARREE && mapenv->mapextent.x1 < mapenv->mapextent.x2) { sprintf(path,"%s%s%s",covpath,tiledir,spxname[pclass]); if ((access(path,0)==0)&&(fcrel.table[prim].nrows > 20)) { primitive_rows = spatial_index_search(path, mapenv->mapextent.x1,mapenv->mapextent.y1, mapenv->mapextent.x2,mapenv->mapextent.y2); } else { /* Next best thing - bounding rectangle table */ sprintf(path,"%s%s%s",covpath,tiledir,brname[pclass]); if (access(path,0)==0) { primitive_rows = bounding_select(path,mapenv->mapextent, library->dec_degrees); } } } /* projection check */ if (primitive_rows.size == 0) { /* Search through all the primitives */ primitive_rows=set_init(fcrel.table[prim].nrows+1); set_on(primitive_rows); } tile_thematic_index_name(fcrel.table[feature], path); if ( (strcmp(path,"") != 0) && (access(path,4)==0) ) { /* Tile thematic index for feature table present, */ tile_features = read_thematic_index( path, (char *)&tile ); } else { tile_features = set_init(fcrel.table[feature].nrows+1); set_on(tile_features); } idx.fp = NULL; i = table_pos(rcell.key2,fcrel.table[prim]); if (i >= 0) { if (fcrel.table[prim].header[i].tdx) { sprintf(path,"%s%s",fcrel.table[prim].path, fcrel.table[prim].header[i].tdx); if (access(path,0)==0) idx = open_thematic_index(path); } if (fcrel.table[prim].header[i].keytype == 'U') degree = R_ONE; if (fcrel.table[prim].header[i].keytype == 'N') degree = R_MANY; if (fcrel.table[prim].header[i].keytype == 'P') degree = R_ONE; } finished = 1; start = set_min(tile_features); end = set_max(tile_features); fseek(fcrel.table[feature].fp, index_pos(start,fcrel.table[feature]), SEEK_SET); for (i=start;i<=end;i++) { row = read_next_row(fcrel.table[feature]); if (!set_member( i, feature_rows )) { free_row(row,fcrel.table[feature]); continue; } if (!set_member( i, tile_features )) { free_row(row,fcrel.table[feature]); continue; } if (degree == R_ONE) { prim_rownum = fc_row_number( row, fcrel, tile ); primlist = NULL; p = NULL; } else { primlist = fc_row_numbers( row, fcrel, tile, &idx ); } free_row( row, fcrel.table[feature] ); if (!primlist) { if ((prim_rownum<1)|| (prim_rownum>fcrel.table[prim].nrows)) continue; if (set_member( prim_rownum, primitive_rows )) { set_insert(prim_rownum,primitives[tile]); } } else { p = ll_first(primlist); while (!ll_end(p)) { ll_element(p,&prim_rownum); if ((prim_rownum<1)|| (prim_rownum>fcrel.table[prim].nrows)) continue; if (set_member( prim_rownum, primitive_rows )) { set_insert(prim_rownum,primitives[tile]); } p = ll_next(p); } } if (kbhit()) { if (getch()==27) { *status = 0; finished = 0; break; } } } if (idx.fp) close_thematic_index(&idx); vpf_close_table(&(fcrel.table[prim])); set_nuke(&primitive_rows); set_nuke(&tile_features); if (set_empty(primitives[tile])) { set_nuke(&primitives[tile]); primitives[tile].size = 0; primitives[tile].buf = NULL; } if (!finished) { *status = 0; break; } } if (!finished) { *status = 0; deselect_feature_class_relate( &fcrel ); break; } if (found) *status = 1; if (kbhit()) { if (getch()==27) { *status = 0; deselect_feature_class_relate( &fcrel ); break; } } deselect_feature_class_relate( &fcrel ); } set_nuke(&feature_rows); if (tilecover) { vpf_close_table(&tile_table); } return primitives; }
/************************************************************************* * *N get_table_element * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function returns the element in the given row in the given * column. If the element is a single element (count=1), the value * is passed back via the void pointer *value; otherwise, an array * is allocated and passed back as the return value. * NOTE: If an array is allocated in this function, it should be freed * when no longer needed. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * field_number <input> == (ossim_int32) field column number. * row <input> == (row_type) vpf table row. * table <input> == (vpf_table_type) VPF table structure. * value <output> == (void *) pointer to a single element value. * count <output> == (ossim_int32 *) pointer to the array size for a * multiple element value. * return <output> == (void *) returned multiple element value. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels May 1991 DOS Turbo C *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * External Variables: *X * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Functions Called: *F * void *vpfmalloc() *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Portability: *O * This module should be ANSI C compatible. *E *************************************************************************/ void *get_table_element( ossim_int32 field_number, row_type row, vpf_table_type table, void *value, ossim_int32 *count ) { ossim_int32 col; char * tptr; void * retvalue; retvalue = NULL; col = field_number; if ((col < 0) || (col >= table.nfields)) { fprintf(stderr,"%s: Invalid field number %d\n", table.name,(int)field_number); return NULL; } if (!row) return NULL; switch (table.header[col].type) { case 'X': retvalue = NULL; break; case 'T': if (table.header[col].count == 1) { memcpy(value,row[col].ptr,sizeof(char)); } else { retvalue = (char *)vpfmalloc((row[col].count+1)*sizeof(char)); tptr = (char *)vpfmalloc((row[col].count+1)*sizeof(char)); memcpy(tptr,row[col].ptr,row[col].count*sizeof(char)); tptr[row[col].count] = '\0'; strcpy((char *)retvalue,tptr); free(tptr); } break; case 'I': if (table.header[col].count == 1) { memcpy(value,row[col].ptr,sizeof(ossim_int32)); } else { retvalue = (ossim_int32 *)vpfmalloc(row[col].count* sizeof(ossim_int32)); memcpy(retvalue,row[col].ptr,row[col].count*sizeof(ossim_int32)); } break; case 'S': if (table.header[col].count == 1) { memcpy(value,row[col].ptr,sizeof(short int)); } else { retvalue = (short int *)vpfmalloc(row[col].count* sizeof(short int)); memcpy(retvalue,row[col].ptr,row[col].count*sizeof(short int)); } break; case 'F': if (table.header[col].count == 1) { memcpy(value,row[col].ptr,sizeof(float)); } else { retvalue = (float *)vpfmalloc(row[col].count*sizeof(float)); memcpy(retvalue,row[col].ptr,row[col].count*sizeof(float)); } break; case 'R': if (table.header[col].count == 1) { memcpy(value,row[col].ptr,sizeof(double)); } else { retvalue = (double *)vpfmalloc(row[col].count*sizeof(double)); memcpy(retvalue,row[col].ptr,row[col].count*sizeof(double)); } break; case 'C': if (table.header[col].count == 1) { memcpy(value,row[col].ptr,sizeof(coordinate_type)); } else { if (row[col].ptr) { retvalue = (coordinate_type *)malloc(row[col].count* sizeof(coordinate_type)); if (retvalue) memcpy(retvalue,row[col].ptr,row[col].count* sizeof(coordinate_type)); } else { retvalue = NULL; } } break; case 'Z': if (table.header[col].count == 1) { memcpy(value,row[col].ptr,sizeof(tri_coordinate_type)); } else { retvalue = (tri_coordinate_type *)vpfmalloc(row[col].count* sizeof(tri_coordinate_type)); memcpy(retvalue,row[col].ptr,row[col].count* sizeof(tri_coordinate_type)); } break; case 'B': if (table.header[col].count == 1) { memcpy(value,row[col].ptr,sizeof(double_coordinate_type)); } else { retvalue = (double_coordinate_type *)vpfmalloc(row[col].count* sizeof(double_coordinate_type)); memcpy(retvalue,row[col].ptr,row[col].count* sizeof(double_coordinate_type)); } break; case 'Y': if (table.header[col].count == 1) { memcpy(value,row[col].ptr,sizeof(double_tri_coordinate_type)); } else { retvalue = (double_tri_coordinate_type *)vpfmalloc(row[col].count* sizeof(double_tri_coordinate_type)); memcpy(retvalue,row[col].ptr,row[col].count* sizeof(double_tri_coordinate_type)); } break ; case 'D': if (table.header[col].count == 1) { memcpy(value,row[col].ptr,sizeof(date_type)); } else { retvalue = (date_type *)vpfmalloc(row[col].count* sizeof(date_type)); memcpy(retvalue,row[col].ptr,row[col].count* sizeof(date_type)); } break; case 'K': /* ID Triplet */ if (table.header[col].count == 1) { memcpy(value,row[col].ptr,sizeof(id_triplet_type)); } else { retvalue = (id_triplet_type *)vpfmalloc(row[col].count* sizeof(id_triplet_type)); memcpy(retvalue,row[col].ptr,row[col].count* sizeof(id_triplet_type)); } break; } *count = row[col].count; return retvalue; }
/************************************************************************* * *N read_next_row * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function reads the next row of the table. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * table <input> == (vpf_table_type) vpf table structure. * return <output> == (row_type) the next row in the table. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels May 1991 Original Version DOS Turbo C * Dave Flinn July 1991 Updated for UNIX *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * External Variables: *X * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Functions Called: *F * void *vpfmalloc() *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Portability: *O * This module should be ANSI C compatible. *E *************************************************************************/ row_type read_next_row( vpf_table_type table ) { register ossim_int32 i,j; ossim_int32 status; char *tptr; ossim_int32 size,count; row_type row; id_triplet_type * keys; coordinate_type dummycoord; if (feof(table.fp)) { return NULL; } STORAGE_BYTE_ORDER = table.byte_order; row = (row_type)vpfmalloc((table.nfields+1) * sizeof(column_type)); for (i=0;i<table.nfields;i++) row[i].ptr = NULL; for (i=0;i<table.nfields;i++) { if (table.header[i].count < 0) { Read_Vpf_Int (&count,table.fp,1) ; } else { count = table.header[i].count; } row[i].count = count; status = 0; switch (table.header[i].type) { case 'T': if (count == 1) { row[i].ptr = (char *)vpfmalloc(sizeof(char)); Read_Vpf_Char(row[i].ptr, table.fp, 1) ; } else { size = count*sizeof(char); row[i].ptr = (char *)vpfmalloc(size+2); tptr = (char *)vpfmalloc(size+2); Read_Vpf_Char(tptr,table.fp,count) ; tptr[count] = '\0'; strcpy((char*)row[i].ptr,(char*)tptr); free(tptr); } break; case 'I': row[i].ptr = (ossim_int32 *)vpfmalloc(count*sizeof(ossim_int32)); Read_Vpf_Int (row[i].ptr, table.fp, count ) ; break; case 'S': row[i].ptr = (short int *)vpfmalloc(count*sizeof(short int)); Read_Vpf_Short (row[i].ptr, table.fp, count ) ; break; case 'F': row[i].ptr = (float *)vpfmalloc(count*sizeof(float)); Read_Vpf_Float (row[i].ptr, table.fp, count ) ; break; case 'R': row[i].ptr = (double *)vpfmalloc(count*sizeof(double)); Read_Vpf_Double (row[i].ptr, table.fp, count ) ; break; case 'D': row[i].ptr = (date_type *)vpfmalloc(count*sizeof(date_type)); Read_Vpf_Date (row[i].ptr, table.fp, count ) ; break; case 'C': /* Coordinate strings may be quite large. */ /* Allow for null coordinate string pointer if */ /* not enough memory that can be handled one */ /* coordinate at a time in higher level functions. */ row[i].ptr = (coordinate_type *)malloc(count* sizeof(coordinate_type)); if (row[i].ptr) Read_Vpf_Coordinate(row[i].ptr,table.fp,count); else for (j=0;j<count;j++) Read_Vpf_Coordinate(&dummycoord,table.fp,1); break; case 'Z': row[i].ptr = (tri_coordinate_type *)vpfmalloc(count* sizeof(tri_coordinate_type)); Read_Vpf_CoordinateZ(row[i].ptr,table.fp,count); break; case 'B': row[i].ptr = (double_coordinate_type *)vpfmalloc(count* sizeof(double_coordinate_type)); Read_Vpf_DoubleCoordinate(row[i].ptr,table.fp,count); break; case 'Y': row[i].ptr = (double_tri_coordinate_type *)vpfmalloc(count* sizeof(double_tri_coordinate_type)); Read_Vpf_DoubleCoordinateZ(row[i].ptr,table.fp,count); break; case 'K': /* ID Triplet */ row[i].ptr = (id_triplet_type *)vpfmalloc(count* sizeof(id_triplet_type)); keys = (id_triplet_type *)vpfmalloc(count* sizeof(id_triplet_type)); for (j=0;j<count;j++) { keys[j] = read_key(table); } memcpy(row[i].ptr,keys,count*sizeof(id_triplet_type)); free(keys); break; case 'X': row[i].ptr = NULL; break; default: fprintf(stderr,"\n%s%s >>> read_next_row: no such type < %c >", table.path,table.name,table.header[i].type ) ; status = 1; break ; } /* end of switch */ if (status == 1) { free_row ( row, table ) ; return (row_type) NULL; } } return row; }
/************************************************************************* * *N rowcpy * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function returns a copy of the specified row. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * origrow <input> == (row_type) row to copy. * table <input> == (vpf_table_type) vpf table structure. * return <output> == (row_type) copy of the row. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels May 1991 DOS Turbo C *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * External Variables: *X * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Functions Called: *F * void *vpfmalloc() VPFMISC.C *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Portability: *O * This module should be ANSI C compatible. *E *************************************************************************/ row_type rowcpy( row_type origrow, vpf_table_type table ) { register ossim_int32 i; ossim_int32 count; ossim_int32 size; row_type row; row = (row_type)vpfmalloc(table.nfields * sizeof(column_type)); for (i=0;i<table.nfields;i++) { count = origrow[i].count; row[i].count = count; switch (table.header[i].type) { case 'T': if (count==1) { row[i].ptr = (char *)vpfmalloc(1); memcpy(row[i].ptr,origrow[i].ptr,sizeof(char)); } else { size = count*sizeof(char); row[i].ptr = (char *)vpfmalloc(size+1); strcpy((char*)row[i].ptr,(char*)origrow[i].ptr); } break; case 'I': size = count*sizeof(ossim_int32); row[i].ptr = (ossim_int32 *)vpfmalloc(size); memcpy(row[i].ptr,origrow[i].ptr,size); break; case 'S': size = count*sizeof(short int); row[i].ptr = (short int *)vpfmalloc(size); memcpy(row[i].ptr,origrow[i].ptr,size); break; case 'F': size = count*sizeof(float); row[i].ptr = (float *)vpfmalloc(size); memcpy(row[i].ptr,origrow[i].ptr,size); break; case 'R': size = count*sizeof(double); row[i].ptr = (double *)vpfmalloc(size); memcpy(row[i].ptr,origrow[i].ptr,size); break; case 'C': size = count*sizeof(coordinate_type); row[i].ptr = (coordinate_type *)malloc(size); if (row[i].ptr && origrow[i].ptr) memcpy(row[i].ptr,origrow[i].ptr,size); else row[i].ptr = NULL; break; case 'Z': size = count*sizeof(tri_coordinate_type); row[i].ptr = (tri_coordinate_type *)vpfmalloc(size); memcpy(row[i].ptr,origrow[i].ptr,size); break; case 'B': size = count*sizeof(double_coordinate_type); row[i].ptr = (double_coordinate_type *)vpfmalloc(size); memcpy(row[i].ptr,origrow[i].ptr,size); break; case 'Y': size = count*sizeof(double_tri_coordinate_type); row[i].ptr = (double_tri_coordinate_type *)vpfmalloc(size); memcpy(row[i].ptr,origrow[i].ptr,size); break; case 'D': /* Date */ size = count*sizeof(date_type); row[i].ptr = (date_type *)vpfmalloc(size); memcpy(row[i].ptr,origrow[i].ptr,size); break; case 'K': /* ID Triplet */ size = count*sizeof(id_triplet_type); row[i].ptr = (id_triplet_type *)vpfmalloc(size); memcpy(row[i].ptr,origrow[i].ptr,size); break; case 'X': row[i].ptr = NULL; break; default: fprintf (stderr,"\nrow_cpy: error in data type < %c >", table.header[i].type ) ; abort () ; break ; } /* end of switch */ } /* end of table.nfields */ return row; }
/************************************************************************* * *N displayerror * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function displays an error message when a disk error is detected. * It displays the given lines of text in a popup panel and waits for * the user to click on either retry or cancel. It returns 1 for retry * and 0 for cancel. Must be in graphics mode to call this function. * * text strings may contain embedded newlines, in which case text to the * right of the newline will be displayed on (what else?) a new line. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * text[] <input> == (char *) array of text strings to be displayed. * nlines <input> == (int) number of lines of text (this count ignores * newline characters embedded in the text * strings * return <output> == (VPF_BOOLEAN) 1 => retry, * 0 => cancel. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels July 1990 Prototype 3 DOS Turbo C *E *************************************************************************/ VPF_BOOLEAN displayerror( char *text[], int nlines ) { register int i; int maxw, height, x, y, pad, choice, n_real_lines; panel_type panel; int retry_button = 'r', cancel_button = 'c', msg_ar_sz = 10; char * walker, ** msgs; struct viewporttype view; getviewsettings( &view ); setviewport(0,0,getmaxx(),getmaxy(),1); settextstyle( SMALL_FONT, HORIZ_DIR, 4 ); msgs = (char **) vpfmalloc(msg_ar_sz * sizeof(char *)); maxw = height = 0; for (n_real_lines = i = 0; i < nlines; i++) { walker = text[i]; while (1) { size_t substr_len = strcspn(walker, "\n"); char plug; maxw = max(maxw, textwidth(walker)); height = height + textheight(walker) + 5; plug = walker[substr_len]; walker[substr_len] = '\0'; msgs[n_real_lines++] = strdup(walker); if (n_real_lines == msg_ar_sz) msgs = (char **) realloc(msgs, (msg_ar_sz += 5) * sizeof(char *)); if (plug == 0) break; walker[substr_len] = plug; walker += substr_len + 1; } } if (maxw < (textwidth("Retry") + textwidth("Cancel") + 20)) maxw = textwidth("Retry") + textwidth("Cancel") + 20; pad = (maxw*10)/100; maxw = maxw + (2*pad); height = height + 2*(textheight("Retry") + 5) + 1; maxw = min(getmaxx(), maxw); height = min(getmaxy()-10, height); create_panel( &panel, maxw, height, menucolor, menubordercolor ); for (y = i = 0; i < n_real_lines; i++) { create_label(msgs[i], pad, y, SMALL_FONT, 4, menutextcolor, &panel ); y += textheight(msgs[i]) + 3; } y = height-15; create_button( retry_button, "Retry", 3, y, SMALL_FONT, 4, menutextcolor, menucolor, menubordercolor, RELIEVED, &panel ); create_button( cancel_button, "Cancel", maxw - (textwidth("Cancel") + 13), y, SMALL_FONT, 4, menutextcolor, menucolor, menubordercolor, RELIEVED, &panel ); get_display_position( &x, &y, panel.window ); display_panel( &panel, x,y ); showmousecursor(); arrow_cursor(); choice = process_panel( &panel, 0 ); hidemousecursor(); destroy_panel( &panel ); close_panel( &panel ); setviewport(view.left,view.top,view.right,view.bottom,view.clip); for (i = 0; i < n_real_lines; i++) free(msgs[i]); free(msgs); return (choice == retry_button) ? 1 : 0; }
/************************************************************************* * *N vpf_display_record * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function displays all of the fields of a particular VPF * record, including the descriptions of the fields and their * values. It accesses the online data dictionary metadata * contained in the specified Value Description Tables. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * row <input> == (row_type) vpf table row structure. * table <input> == (vpf_table_type) vpf table. * fp <input> == (FILE *) pointer to the output file. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels Sept 1991 DOS Turbo C *E *************************************************************************/ void vpf_display_record( row_type row, vpf_table_type table, FILE *fp ) { register int i,j; char *buf,*num, path[128], *tablename; char *attr,*val,*descr, vdtpath[128], fmtdate[40]; vpf_table_type vdt; row_type vdtrow; int found; ossim_int32 l, lval, count, *lptr; short int s,sval,*sptr; float f,*fptr; date_type date; int TABLE_ = 1, ATTR_ = 2, VAL_ = 3, DESCR_ = 4; num = (char *)vpfmalloc(20*sizeof(char)); strcpy( vdtpath, "" ); /* Display all secondary attributes */ for (i=0;i<table.nfields;i++) { switch (table.header[i].type) { case 'T': buf = (char *)get_table_element(i,row,table, NULL,&count); rightjust(buf); if (strcmp( buf, "" ) != 0) { fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": ",fp); fputs(buf,fp); strcpy( path, table.path ); strcat( path, table.header[i].vdt ); if ( (access(path,4)==0) && (strcmp(table.header[i].vdt,"") != 0) ) { if (strcmp(vdtpath,path) != 0) { if (strcmp(vdtpath,"") != 0) { vpf_close_table(&vdt); } vdt = vpf_open_table( path, disk, "rb", NULL ); } strcpy( vdtpath, path ); for (j=1;j<=vdt.nrows;j++) { vdtrow = read_row( j, vdt ); tablename = (char *)get_table_element( TABLE_, vdtrow, vdt, NULL, &count ); rightjust(tablename); strupr2(tablename); attr = (char *)get_table_element( ATTR_, vdtrow, vdt, NULL, &count ); rightjust(attr); val = (char *)get_table_element( VAL_, vdtrow, vdt, NULL, &count ); rightjust(val); found = FALSE; if ( (strstr(table.name,tablename)) && (ossim_strcasecmp(attr,table.header[i].name)==0) && (ossim_strcasecmp(val,buf)==0) ) { descr = (char *)get_table_element(DESCR_,vdtrow,vdt, NULL, &count); rightjust(descr); fputs(" (",fp); fputs(descr,fp); fputs(")",fp); free(descr); found = TRUE; } free(tablename); free(attr); free(val); free_row( vdtrow, vdt ); if (found) break; } } fputc('\n',fp); } free(buf); break; case 'I': if (table.header[i].count==1) { get_table_element(i,row,table,&l,&count); if (l != NULLINT) { fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": ",fp); ltoa((int)l,num,10); fputs(num,fp); strcpy( path, table.path ); strcat( path, table.header[i].vdt ); if ( (access(path,4)==0) && (strcmp(table.header[i].vdt,"") != 0) ) { if (strcmp(vdtpath,path) != 0) { if (strcmp(vdtpath,"") != 0) { vpf_close_table(&vdt); } vdt = vpf_open_table( path, disk, "rb", NULL ); } strcpy( vdtpath, path ); for (j=1;j<=vdt.nrows;j++) { vdtrow = read_row( j, vdt ); tablename = (char *)get_table_element( TABLE_, vdtrow, vdt, NULL, &count ); rightjust(tablename); strupr2(tablename); attr = (char *)get_table_element( ATTR_, vdtrow, vdt, NULL, &count ); rightjust(attr); get_table_element( VAL_, vdtrow, vdt, &lval, &count ); found = FALSE; if ( (strstr(table.name,tablename)) && (ossim_strcasecmp(attr,table.header[i].name)==0) && (lval==l) ) { descr = (char *)get_table_element(DESCR_,vdtrow, vdt, NULL, &count); rightjust(descr); fputs(" (",fp); fputs(descr,fp); fputs(")",fp); free(descr); found = TRUE; } free(tablename); free(attr); free_row( vdtrow, vdt ); if (found) break; } } fputc('\n',fp); } } else { get_table_element(i,row,table,&lptr,&count); fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": (",fp); for (j=0;j<count;j++) { ltoa((int)lptr[j],num,10); fputs(num,fp); if (j<count-1) fputs(", ",fp); } fputs(")\n",fp); } break; case 'S': if (table.header[i].count==1) { get_table_element(i,row,table,&s,&count); if (s != NULLSHORT) { fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": ",fp); itoa(s,num,10); fputs(num,fp); strcpy( path, table.path ); strcat( path, table.header[i].vdt ); if ( (access(path,4)==0) && (strcmp(table.header[i].vdt,"") != 0) ) { if (strcmp(vdtpath,path) != 0) { if (strcmp(vdtpath,"") != 0) { vpf_close_table(&vdt); } vdt = vpf_open_table( path, disk, "rb", NULL ); } strcpy( vdtpath, path ); for (j=1;j<=vdt.nrows;j++) { vdtrow = read_row( j, vdt ); tablename = (char *)get_table_element( TABLE_, vdtrow, vdt, NULL, &count ); rightjust(tablename); strupr2(tablename); attr = (char *)get_table_element( ATTR_, vdtrow, vdt, NULL, &count ); rightjust(attr); get_table_element( VAL_, vdtrow, vdt, &sval, &count ); found = FALSE; if ( (strstr(table.name,tablename)) && (ossim_strcasecmp(attr,table.header[i].name)==0) && (sval==s) ) { descr = (char *)get_table_element(DESCR_,vdtrow, vdt, NULL, &count); rightjust(descr); fputs(" (",fp); fputs(descr,fp); fputs(")",fp); free(descr); found = TRUE; } free(tablename); free(attr); free_row( vdtrow, vdt ); if (found) break; } } fputc('\n',fp); } } else { get_table_element(i,row,table,&sptr,&count); fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": (",fp); for (j=0;j<count;j++) { itoa(sptr[j],num,10); fputs(num,fp); if (j<count-1) fputs(", ",fp); } fputs(")\n",fp); } break; case 'F': if (table.header[i].count==1) { get_table_element(i,row,table,&f,&count); if (!is_vpf_null_float(f)) { fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": ",fp); #if !defined(__APPLE__) && !defined(__FreeBSD__) gcvt(f,6,num); #endif fputs(num,fp); fputc('\n',fp); } } else { get_table_element(i,row,table,&fptr,&count); fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": (",fp); for (j=0;j<count;j++) { if (is_vpf_null_float(fptr[j])) { fputs("(null)",fp); } else { #if !defined(__APPLE__) && !defined(__FreeBSD__) gcvt(fptr[j],6,num); #endif fputs(num,fp); } if (j<count-1) fputs(", ",fp); } fputs(")\n",fp); } break; case 'D': if (table.header[i].count==1) { get_table_element(i,row,table,date,&count); fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": ",fp); format_date(date,fmtdate); fputs(fmtdate,fp); fputc('\n',fp); } break; } } if (strcmp(vdtpath,"") != 0) vpf_close_table( &vdt ); free(num); }