Example #1
0
void ossimVpfTable::reset()const
{
   if(theTableInformation &&
      (theTableInformation->status!=CLOSED))
   {
      long fpos;

      fpos = index_pos(0, *theTableInformation);
      fseek(theTableInformation->fp, fpos, SEEK_SET);
   }
}
Example #2
0
/*************************************************************************
 *
 *N  read_row
 *
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Purpose:
 *P
 *     This function reads a specified row from the table.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Parameters:
 *A
 *    row_number <input> == (ossim_int32) row number.
 *    table      <input> == (vpf_table_type) vpf table structure.
 *    return    <output> == (row_type) row that was read in.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   History:
 *H
 *    Barry Michaels   May 1991      DOS Turbo C
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   External Variables:
 *X
 *    None
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Functions Called:
 *F
 *    ossim_int32 index_pos()                             VPFTABLE.C
 *    row_type read_next_row()                         VPFTABLE.C
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Portability:
 *O
 *    This module should be ANSI C compatible.
 *E
 *************************************************************************/
row_type read_row( ossim_int32 row_number,
		   vpf_table_type table )
{
   ossim_int32 fpos;

   fpos = index_pos(row_number,table);

   fseek(table.fp,fpos,SEEK_SET);

   return read_next_row(table);
}
Example #3
0
bool ossimVpfTable::goToRow(long row)const
{
   if(theTableInformation &&
      (theTableInformation->status!=CLOSED))
   {
      long fpos;

      fpos = index_pos(row, *theTableInformation);
      if(fpos < 0)
      {
         return false;
      }
      fseek(theTableInformation->fp, fpos, SEEK_SET);
   }

   return true;
}
Example #4
0
/*************************************************************************
 *
 *N  query_table
 *
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Purpose:
 *P
 *     This function returns the set of selected rows of a VPF table
 *     based upon the evaluation of the given selection expression string.
 *
 *     The expression is strictly evaluated left to right.  No nesting
 *     is supported, so parentheses are not allowed.  The expression
 *     must match the form:
 *        <field><log op><value> [ <join> <field><log op><value>]
 *     where,
 *        <field> is a valid field name of the table.
 *        <log op> is one of the following: =, <, >, <=, >=, <> (not equal).
 *        <value> is a valid value for the field.
 *        <join> is either " AND " or " OR ".
 *     Any number of clauses (<field><log op><value>) may be joined
 *     together with AND or OR to form the expression.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Parameters:
 *A
 *    expression <input>==(char *) selection expression string.
 *    table      <input>==(vpf_table_type) VPF table structure.
 *    return    <output>==(set_type) set of selected rows.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   History:
 *H
 *    Barry Michaels    May 1991                          DOS Turbo C
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   External Variables:
 *X
 *    None
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Functions Called:
 *F
 *    set_type set_init( rspf_int32 n ) SET.C
 *    void set_insert( rspf_int32 element, set_type set ) SET.C
 *    linked_list_type parse_expression( char *expression,
 *                     vpf_table_type table ) VPFQUERY.C
 *    row_type read_next_row( vpf_table_type table ) VPFREAD.C
 *    position_type ll_first( linked_list_type list ) LINKLIST.C
 *    int ll_end( position_type position ) LINKLIST.C
 *    void ll_element( position_type position, void *element ) LINKLIST.C
 *    void *get_table_element( rspf_int32 field_number,
 * 			 row_type row,
 *			 vpf_table_type table,
 *			 void *value,
 *			 rspf_int32  *count ) VPFREAD.C
 *    void display_message( char *info ) USER DEFINED
 *    static int strcompare( char *val1, char *val2, char op ) VPFQUERY.C
 *    static int icompare( rspf_int32 val1, rspf_int32 val2, char op ) VPFQUERY.C
 *    static int fcompare( float val1, float val2, char op ) VPFQUERY.C
 *    void ll_reset( linked_list_type list ) LINKLIST.C
      void free_row( row_type row, vpf_table_type table) VPFREAD.C
 *E
 *************************************************************************/
set_type query_table( char *expression, vpf_table_type table )
{
   row_type row;
   position_type pos;
   expr_type expr;
   register rspf_int32 i;
   int boolval=FALSE, booltemp=0, join = OR;
   rspf_int32 lval, lval2, count;
   float fval, fval2;
   char tval, tval2, *tptr;
   linked_list_type exprlist;
   set_type select_set;

   select_set = set_init(table.nrows+1);

   if (strcmp(expression,"*")==0) {
      set_on(select_set);
      return select_set;
   }

   exprlist = parse_expression( expression, table );

   if (!exprlist) return select_set;

   if (table.storage == DISK)
      fseek( table.fp, index_pos(1,table), SEEK_SET );

   for (i=1;i<=table.nrows;i++) {

      if (table.storage == DISK)
	 row = read_next_row(table);
      else
	 row = get_row( i, table );

      pos = ll_first(exprlist);
      while (!ll_end(pos)) {
	 ll_element( pos, &expr );
	 switch (table.header[expr.field].type) {
	    case 'I':
	       if (table.header[expr.field].count == 1) {
		  get_table_element( expr.field, row, table, &lval, &count );
		  lval2 = atol(expr.value);
		  booltemp = icompare( lval, lval2, expr.op );
	       } else {
		  display_message(
		     "Selection may not be performed upon arrays");
		  i=table.nrows+1;
	       }
	       break;
	    case 'T':
	       if (table.header[expr.field].count == 1) {
		  get_table_element( expr.field, row, table, &tval, &count );
		  tval2 = expr.value[0];
		  booltemp = comp( &tval, &tval2, sizeof(tval), expr.op );
	       } else {
		  tptr = (char *)get_table_element( expr.field, row, table,
				   NULL, &count );
		  booltemp = strcompare( tptr, expr.value, expr.op );
		  free(tptr);
	       }
	       break;
	    case 'F':
	       if (table.header[expr.field].count == 1) {
		  get_table_element( expr.field, row, table, &fval, &count );
		  if (!is_vpf_null_float(fval)) {
		     fval2 = (float)atof(expr.value);
		     booltemp = fcompare( fval, fval2, expr.op );
		  } else booltemp = FALSE;
	       } else {
		  display_message(
		     "Selection may not be performed upon arrays");
		  i=table.nrows+3;
	       }
	       break;
	    default:
	       display_message("Field type not supported for query");
	       i=table.nrows+3;
	       break;
	 }

	 if (i>table.nrows) break;

	 if (join==OR)
	    boolval = boolval || booltemp;
	 else
	    boolval = boolval && booltemp;

	 join = expr.join;

	 pos = pos->next;
      }
      free_row( row, table );
      if (boolval) set_insert(i,select_set);
      boolval = FALSE;
      join = OR;

      if (i==table.nrows+3) break;

   }

   ll_reset(exprlist);

   return select_set;
}
Example #5
0
/*************************************************************************
 *
 *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;
}
Example #6
0
/*************************************************************************
 *
 *N  get_selected_tile_primitives
 *
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Purpose:
 *P
 *    This function determines all of the selected primitive rows from
 *    the selected features of a given tile.
 *
 *    This function expects a feature class relationship structure that
 *    has been successfully created with select_feature_class_relate()
 *    from the feature table to the primitive.  The primitive table in
 *    the feature class relate structure must have been successfully
 *    opened for the given tile.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Parameters:
 *A
 *     library   <input>==(library_type *) VPF library structure.
 *     fcnum     <input>==(int) feature class number of the feature table.
 *     fcrel     <input>==(fcrel_type) feature class relate structure.
 *     feature_rows <input>==(set_type) set of selected features.
 *     mapenv    <input>==(map_environment_type *) map environment.
 *     tile      <input>==(rspf_int32) tile number.
 *     tiledir   <input>==(char *) path to the tile directory.
 *     status   <output>==(int *) status of the function:
 *                         1 if completed, 0 if user escape.
 *     return   <output>==(set_type) set of primitives for the features
 *                         in the corresponding tile.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   History:
 *H
 *    Barry Michaels   May 1991                           DOS Turbo C
 *E
 *************************************************************************/
set_type get_selected_tile_primitives( library_type *library,
				       int fcnum,
				       fcrel_type fcrel,
				       set_type feature_rows,
				       map_environment_type *mapenv,
				       rspf_int32 tile,
				       char *tiledir,
				       int *status )
{
   int cov, degree;
   int feature, prim;
   row_type row;
   char *spxname[] = {"","esi","fsi","tsi","nsi","csi"};
   char *brname[] = {"","ebr","fbr","tbr","nbr","cbr"};
   set_type primitive_rows, tile_features;
   set_type primitives;
   rspf_int32 prim_rownum;
   register rspf_int32 i,pclass, start,end;
   char path[255], covpath[255];
   linked_list_type primlist;
   position_type p;
   vpf_relate_struct rcell;
   ThematicIndex idx;

   feature = 0;
   prim = fcrel.nchain-1;

   /* Assume that fcrel.table[prim] has been opened */

   primitives.size = 0;
   primitives.buf = NULL;

   cov = library->fc[fcnum].coverage;
   strcpy( covpath, library->cover[cov].path );

   p = ll_previous(ll_last(fcrel.relate_list),fcrel.relate_list);
   ll_element(p,&rcell);
   degree = rcell.degree;

   for (pclass=EDGE;pclass<=CONNECTED_NODE;pclass++) {

      if ((pclass != library->fc[fcnum].primclass) &&
	  (library->fc[fcnum].primclass != COMPLEX_FEATURE)) continue;

      primitives = set_init(fcrel.table[prim].nrows+1);

      /* Get the set of primitive rows within the map extent */

      /* Look for the spatial index file to weed out primitives in the */
      /* given tile but outside of the viewing area.  If a projection  */
      /* other than plate-carree (rectangular) is on, or if the extent */
      /* crosses the meridian, the quick check is no longer valid.     */

      primitive_rows.size = 0;

      if (mapenv->projection == PLATE_CARREE &&
	  mapenv->mapextent.x1 < mapenv->mapextent.x2) {
	 sprintf(path,"%s%s%s",covpath,tiledir,spxname[pclass]);
	 /* 20 (below) is a fairly arbitrary cutoff of the number of */
	 /* primitives that make a spatial index search worth while. */
	 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)&&(fcrel.table[prim].nrows > 20)) {
	       primitive_rows = bounding_select(path,mapenv->mapextent,
						library->dec_degrees);
	    }
	 }
      }
      if (primitive_rows.size == 0) {
	 /* Search through all the primitives */
	 primitive_rows=set_init(fcrel.table[prim].nrows+1);
	 set_on(primitive_rows);
      }

      if (strcmp(tiledir,"") != 0) {
	 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);
	 }
      } else {
	 tile_features = set_init(fcrel.table[feature].nrows+1);
	 set_on(tile_features);
      }
      set_delete(0,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;
      }

      start = set_min(tile_features);
      end = set_max(tile_features);

      /* 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[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);
	    }
	 } 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);
	       }
	       p = ll_next(p);
	    }
	 }

	 if (primlist) ll_reset(primlist);

	 if (kbhit()) {
	    if (getch()==27) {
	       *status = 0;
	       break;
	    }
	 }
      }

      set_nuke(&primitive_rows);

      set_nuke(&tile_features);

      if (idx.fp) close_thematic_index(&idx);

      *status = 1;

      if (kbhit()) {
	 if (getch()==27) {
	    *status = 0;
	    break;
	 }
      }
   }

   return primitives;
}
Example #7
0
/*************************************************************************
 *
 *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;
}
Example #8
0
/*************************************************************************
 *
 *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;
}