home *** CD-ROM | disk | FTP | other *** search
/ GRIPS 2: Government Rast…rocessing Software & Data / GRIPS_2.cdr / dos / tv / demo.c < prev    next >
C/C++ Source or Header  |  1991-01-18  |  25KB  |  752 lines

  1. /* DEMO.c -- TerraView Toolkit Demo Program */
  2.  
  3. /**************************************************************************/
  4. /*               Copyright (c) 1988, 1989 TerraLogics, Inc.               */
  5. /*                           All Rights Reserved                          */
  6. /*    THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF TERRALOGICS, INC.    */
  7. /*            The copyright notice above does not evidence any            */
  8. /*           actual or intended publication of such source code.          */
  9. /**************************************************************************/
  10.  
  11. /* Include files */
  12.  
  13. #include <stdio.h>
  14. #include <math.h>
  15.  
  16. #include "TvTypes.h"
  17. #include "Tv.h"
  18.  
  19.  
  20. /* Global variables */
  21.  
  22. double    zoom_factor = 2.0;
  23. int     grid_up     = 0;
  24.  
  25. char txtbuf[132];
  26.  
  27. #define MAX_OVERLAYS        (8)
  28. int overlays = 0;
  29.  
  30. static TvOverlayID       overlay_user[MAX_OVERLAYS],
  31.                          overlay_tmp  = 0,
  32.                          locator      = 0,
  33.                          grid         = 0,
  34.                          compass      = 0,
  35.                          scale        = 0;
  36.  
  37. static double proj_data[16];
  38. static LONG   proj_type = 0;
  39.  
  40. #define CENTER(MAP,ROW,COLOR,STRING)                                \
  41.   {                                                                           \
  42.   int        len = strlen(STRING), center;                                    \
  43.   double     min_row, min_col, max_row, max_col;                              \
  44.   TvInquireVisible( MAP, TvRowCol, &min_row, &max_row, &min_col, &max_col );  \
  45.   center = (max_col - min_col + 1) / 2 + 1;                                   \
  46.   TvText(MAP,TvRowCol,((double) ROW),((double) center - len/2),COLOR,STRING );\
  47.   }
  48. int            first_screen = 1;
  49.  
  50.  
  51. /* Button/function handling global variable */
  52.  
  53. struct
  54.   {
  55.   int    symbol;
  56.   int    button;
  57.   } functions[20];
  58.  
  59. /* The following examples of functions are included in this demo program */
  60.  
  61. #define    FUNCTION_ZOOM_IN        (1)
  62. #define    FUNCTION_ZOOM_OUT        (2)
  63. #define    FUNCTION_GRID            (3)
  64. #define    FUNCTION_IDENTIFY        (4)
  65. #define    FUNCTION_UP            (5)
  66. #define    FUNCTION_DOWN            (6)
  67. #define    FUNCTION_LEFT            (7)
  68. #define    FUNCTION_RIGHT            (8)
  69. #define    FUNCTION_QUIT            (9)
  70. #define    FUNCTION_QUAD_INSET        (10)
  71. #define    FUNCTION_ROTATE            (11)
  72. #define    FUNCTION_RECENTER        (12)
  73. #define    FUNCTION_ADDRESS_LOCATOR    (13)
  74. #define    FUNCTION_PRINT            (14)
  75. #define    FUNCTION_ADD_SYMBOL        (15)
  76. #define    FUNCTION_RESET            (16)
  77. #define    FUNCTION_HELP            (17)
  78.  
  79. #define    BUTTON(SYM,FNC)    functions[FNC].symbol   = SYM;        \
  80.                            functions[FNC].button   = ++button;
  81.  
  82.  
  83. /* This function binds a button number to a symbol 
  84.    (graphic representation) and a function */
  85.  
  86. setup_buttons( map )
  87.  TvMapID     map;
  88.   {
  89.   int  button=0, i;
  90.  
  91. /*      SYMBOL        FUNCTION            BUTTON
  92.     ------        --------            ------
  93. /*                                */
  94.   BUTTON( 31,         FUNCTION_ZOOM_IN )        /* 01     */
  95.   BUTTON( 30,         FUNCTION_ZOOM_OUT )        /* 02     */
  96.   BUTTON( 19,         FUNCTION_RECENTER )        /* 03     */
  97.   BUTTON( 21,         FUNCTION_ROTATE )        /* 04     */
  98.   BUTTON( 24,         FUNCTION_IDENTIFY )        /* 05    */
  99.   BUTTON( 18,         FUNCTION_ADDRESS_LOCATOR )    /* 06     */
  100.   BUTTON( 23,         FUNCTION_GRID )            /* 07     */
  101.   BUTTON( 16,         FUNCTION_ADD_SYMBOL )        /* 08     */
  102.   BUTTON( 22,         FUNCTION_QUAD_INSET )        /* 09     */
  103.   BUTTON( 14,         FUNCTION_RESET )             /* 10     */
  104.   BUTTON( 15,         FUNCTION_HELP )            /* 11     */
  105.   BUTTON( 25,         FUNCTION_QUIT )            /* 12     */
  106.  
  107.   for( i=1; i < 20; i++ ) 
  108.    if ( functions[i].button )
  109.     TvMapPanelButton( map, functions[i].button, functions[i].symbol, i );
  110.   }
  111.  
  112.  
  113. /************************/
  114. /*     Main Program     */
  115. /************************/
  116.  
  117. TvMain( argc, argv )
  118.  int argc;
  119.  char *argv[];
  120.   {
  121.   TvMapID        map;
  122.   int i;
  123.  
  124.   /* Create an empty map */
  125.   if ( !(map = TvCreateMap( TvDefaultWindow, "Map Demo Application" )) )
  126.     {
  127.     printf( "Cannot create map!\n" );
  128.     TvExit( 0 );
  129.     }
  130.  
  131.   /* Enough command-line arguments? */
  132.   if ( argc < 2 )
  133.     {
  134.     TvPrompt( map, "Usage:  DEMO overlay-1.TV overlay-2.TV ...", txtbuf );
  135.     TvExit( 0 );
  136.     }
  137.  
  138.   /* Read overlays from command-line */
  139.   while( (overlays < MAX_OVERLAYS) && (overlays < (argc-1)) )
  140.     if ( (overlay_user[overlays] = TvReadOverlay( argv[overlays+1] )) != TvStatusError )
  141.       overlays++;
  142.     else
  143.       {
  144.       sprintf( txtbuf, "Cannot open overlay %s.  Press ENTER to exit.", argv[overlays+1] );
  145.       TvPrompt( map, txtbuf, txtbuf );
  146.       TvExit( 0 );
  147.       }
  148.  
  149.   /* Clear window, create map control panel, and load the buttons */
  150.   TvClearWindow( TvInquireMapWindow( map ) );
  151.   TvCreateMapPanel( map, TvPanelStyleRight, 12, 1 );
  152.   setup_buttons( map );
  153.  
  154.   /* Now add the overlays to the map */
  155.   for( i = 0; i < overlays; i++ ) TvAddOverlay( map, overlay_user[i] );
  156.   proj_type = TvInqOverlayProjection( overlay_user[0], 16, proj_data );
  157.  
  158.   /* Generate a grid, compass, and scale overlays */
  159.   grid    = TvGenerateGrid( TvDefaultGridStyle );
  160.   compass = TvGenerateCompass( 0 );
  161.   TvAddOverlay( map, compass );
  162.   scale = TvGenerateScale( 0 );
  163.   TvAddOverlay( map, scale );
  164.  
  165.   /* Select the types of features to display */
  166.   do_features( map );
  167.  
  168.   /* Set size of pick aperture as twice the default */
  169.   TvSetMapPickAperture( map, 2 * TvDefaultPickAperture );
  170.  
  171.   /* Display the map on the screen */
  172.   TvRefresh( map , TvAllOverlays );
  173.  
  174.   CENTER(map,2,TvColorGrid,"Welcome to the TerraView Toolkit(tm) Demonstration program")
  175.   CENTER(map,6,TvColorGrid,"To proceed, use your mouse and click on a button")
  176.   CENTER(map,8,TvColorGrid,"OR")
  177.   CENTER(map,10,TvColorGrid,"Press F1 for more help")
  178.   CENTER(map,14,TvColorGrid,"If you have any questions, please call us at (603) 889-1800")
  179.   CENTER(map,16,TvColorGrid,"Monday to Friday between 9AM and 5PM Eastern Time")
  180.  
  181.   /****************************************/
  182.   /* Process user input in a loop forever */
  183.   /****************************************/
  184.   while( 1 )  nxtfnc( );
  185.   }
  186.  
  187.  
  188. /**********************************************/
  189. /* Function to get user input, and process it */
  190. /**********************************************/
  191.  
  192. nxtfnc()
  193.   {
  194.   TvMapID                cur;
  195.   TvEventID              event,  event2;
  196.   long int               code,   code2;
  197.   char                   wild[255];
  198.   static char            line[132];
  199.   static double          latitude, longitude;
  200.   double                 rescale = 0.0;
  201.   LONG             num, refresh = 0, button;
  202.   static LONG            prev_button = -1;
  203.   static int         hl_color = TvColorHighlight;
  204.  
  205.   /* Wait for the user to do something */
  206.   event = TvGetEvent( TvAnyMap );
  207.  
  208.   /* Which map?  What event?  Change to upper case, if necessary.  */
  209.   cur     = TvEventMap( event);
  210.   button  = TvEventData(event );
  211.   code    = TvEventCode(event);
  212.   if ( (code >= 'a') && (code <= 'z') ) code -= 'a' - 'A';
  213.  
  214.   /* Skip mouse or button UP click */
  215.   if ( !(code & KBD_MASK_DOWN) &&
  216.        ( ((code & KBD_MASK_CLASS) == KBD_LOCATOR) ||
  217.          ((code & KBD_MASK_CLASS) == KBD_SELECTOR) ) )
  218.     {
  219.     TvReplyEvent( event );
  220.     return;
  221.     }
  222.  
  223.   /* Default mouse click becomes same function as previous button */
  224.   if ( (code & KBD_MASK_CLASS) == KBD_LOCATOR )
  225.     switch( prev_button )
  226.       {
  227.     case FUNCTION_ZOOM_IN:
  228.     case FUNCTION_ZOOM_OUT:
  229.     case FUNCTION_RECENTER:
  230.     case FUNCTION_IDENTIFY:
  231.     case FUNCTION_ADD_SYMBOL:
  232.       button = prev_button;
  233.       code   = KBD_SELECTOR;
  234.       break;
  235.  
  236.     default:
  237.       TvReplyEvent( event );
  238.       return;
  239.       }
  240.  
  241.   /* If the user clicked a button... */
  242.   if ( (code & KBD_MASK_CLASS) == KBD_SELECTOR )
  243.     {
  244.     TvMapPanelArm(  cur, functions[button].button, 0, TvColorGreen );
  245.     TvMapPanelRefresh( cur );
  246.  
  247.     /* Process the button */
  248.     prev_button = button;
  249.     switch( button )
  250.       {
  251.  
  252. /* Note:    In the following call, TvFWS specifies the coordinate mode 
  253.         "Fractional Window Size", which indicates a "fraction" of 
  254.         the current window */
  255.  
  256.         case FUNCTION_UP:
  257.               /* Scroll up 1/4 of screen. */
  258.               TvScrollMap( cur, TvFWS,   0.00,   0.25 );
  259.               refresh++;
  260.               break;
  261.  
  262.         case FUNCTION_DOWN:
  263.               /* Scroll down 1/4 of screen. */
  264.               TvScrollMap( cur, TvFWS,   0.00,  -0.25 );
  265.               refresh++;
  266.               break;
  267.  
  268.         case FUNCTION_LEFT:
  269.               /* Scroll left 1/4 of screen. */
  270.               TvScrollMap( cur, TvFWS,  -0.25,   0.00 );
  271.               refresh++;
  272.               break;
  273.  
  274.         case FUNCTION_RIGHT:
  275.               /* Scroll right 1/4 of screen. */
  276.               TvScrollMap( cur, TvFWS,   0.25,   0.00 );
  277.               refresh++;
  278.               break;
  279.  
  280.         case FUNCTION_ROTATE:
  281.                 {
  282.                 double angle;
  283.                 TvPrompt( cur, "Rotate map:  Enter rotation angle from North (degrees): ",
  284.                           line );
  285.                 sscanf( line, "%lf", &angle );
  286.                 TvSetMapRotation( cur, angle );
  287.                 }
  288.               refresh++;
  289.               break;
  290.  
  291.         case FUNCTION_GRID:
  292.               if ( !grid_up )
  293.                 {
  294.                 TvAddOverlay( cur, grid );
  295.                 if ( first_screen )
  296.                   {
  297.                   first_screen = 0;
  298.                   TvRefresh( cur, TvAllOverlays );
  299.                   }
  300.                 else
  301.                   TvRefresh( cur, grid );
  302.                 TvRemoveOverlay( cur, grid );
  303.                 grid_up = 1;
  304.                 }
  305.               else
  306.                 {
  307.                 grid_up = 0;
  308.                 refresh++;
  309.                 }
  310.               break;
  311.  
  312.         case FUNCTION_ZOOM_OUT:
  313.               TvSetMapZoom( cur, (rescale = (1.0 / zoom_factor)) );
  314.               refresh++;
  315.               break;
  316.  
  317.         case FUNCTION_ZOOM_IN:
  318.         case FUNCTION_RECENTER:
  319.               if ( button == FUNCTION_ZOOM_IN )
  320.                CENTER( cur, 4, TvColorHighlight,
  321.                  "Zoom in: Move mouse to desired center and click")
  322.               else
  323.                CENTER( cur, 4, TvColorHighlight,
  324.                  "Recenter: Move mouse to desired center and click")
  325.  
  326.               TvSetMouseTracking( cur, 1 );
  327.               while( 1 )
  328.                 {
  329.                 event2 = TvGetEvent( cur );
  330.                 switch( code2  = TvEventCode( event2 ) )
  331.                   {
  332.                   case KBD_MOUSE1_UP:
  333.                   case KBD_MOUSE2_UP:
  334.                       break;
  335.  
  336.                   case KBD_MOUSE_MOVED:    
  337.                       TvInquireEventPosition( event2, TvLatLong, &latitude,  
  338.                                                                  &longitude );
  339.                       tell_position( cur, latitude, longitude );
  340.                       TvReplyEvent( event2 );
  341.               continue;
  342.  
  343.                   default:
  344.                       if ( ((code2 & KBD_MASK_CLASS) == KBD_SELECTOR) &&
  345.                            (button                   == FUNCTION_ZOOM_IN) &&
  346.                            (code2 & KBD_MASK_DOWN) )
  347.                         break;
  348.                       TvReplyEvent( event2 );
  349.               continue;
  350.                   }
  351.                 break;
  352.                 }
  353.               TvReplyEvent( event2 );
  354.               TvSetMouseTracking( cur, 0 );
  355.               if ( (code2 & KBD_MASK_CLASS) != KBD_SELECTOR )
  356.                 {
  357.                 TvInquireLastPosition(cur, TvLatLong, &latitude, &longitude);
  358.                 TvSetMapCenter( cur, TvLatLong, latitude, longitude );
  359.                 }
  360.               if ( button == FUNCTION_ZOOM_IN )
  361.                 TvSetMapZoom( cur, (rescale = zoom_factor) );
  362.               refresh++;
  363.               break;
  364.  
  365.  
  366.         case FUNCTION_ADD_SYMBOL:
  367.               TvMessage(cur, "Add Symbol: Point to location and click");
  368.                 {
  369.         TvOverlayID     legend;
  370.                 double          coord[2];
  371.                 char         name[132];
  372.           
  373.                 while( 1 )
  374.                   {
  375.                   event2 = TvGetEvent( cur );
  376.                   code2  = TvEventCode( event2 );
  377.                   if ( ((code2 & KBD_MASK_CLASS) == KBD_LOCATOR) )
  378.                     break;
  379.                   TvReplyEvent( event2 );
  380.                   }
  381.  
  382.                 TvInquireEventPosition(event2, TvLatLong, &coord[0], &coord[1]);
  383.                 TvReplyEvent( event2 );
  384.                 TvPrompt(cur,"Add Symbol: Enter description of feature: ",name);
  385.         if ( !strlen( name ) )
  386.           {
  387.           TvMessage( cur, TvClearMessage );
  388.           break;
  389.           }
  390.         legend = TvGenerateLegend( "Some Symbols to Choose From:" );
  391.         TvLegendFile( legend, "TvLegend.DEM", TvColorGreen, 0 );
  392.         TvAddOverlay( cur, legend );
  393.                 TvPrompt(cur, "Add Symbol: Enter symbol number: ", line);
  394.         TvRemoveOverlay( cur, legend );
  395.         TvDeleteOverlay( legend );
  396.                 num = atoi( line );
  397.                 if ( (num < 0) || (num > 31) )
  398.                   {
  399.               TvMessage(cur,"Unrecognized Symbol Code.  Please retry.");
  400.                   break;
  401.                   }
  402.                 if ( overlay_tmp == 0 )
  403.                   {
  404.                   if ( !(overlay_tmp = TvCreateOverlay( 0 )) )
  405.                     TvExit( 0 );
  406.           TvSetOverlayProjection(overlay_tmp,proj_type,16,proj_data);
  407.                   TvAddOverlay( cur, overlay_tmp );
  408.                   }
  409.                 TvBeginFeature(overlay_tmp,0,0,name,"");
  410.                 TvInsertSymbol(overlay_tmp, num, 1, coord );
  411.                 TvEndFeature( overlay_tmp );
  412.                 }
  413.               break;
  414.  
  415.         case FUNCTION_QUAD_INSET:
  416.                 {
  417.                 TvWindowID         window1, window2;
  418.                 TvMapID            maps[4], pmap=cur;
  419.                 int                i;
  420.                 TvDeviceID         device;
  421.                 double             x_base, y_base, x_size, y_size;
  422.  
  423.                 for( i=0; i < 4; maps[i++] = TvStatusError );
  424.  
  425.                 window1 = TvInquireMapWindow( cur );
  426.                 TvInquireWindow( window1, &device,
  427.                                  &x_base, &y_base,
  428.                                  &x_size, &y_size );
  429.                 if ( (x_size < 0.15) || ((y_size -= 0.1) < 0.15) ) break;
  430.  
  431.                 TvClearWindow( window1 );
  432.                 TvMessage( cur, "Displaying current scale in a small window" );
  433.                 for( i=0; i < 4; pmap = maps[i++] )
  434.                   {
  435.                   double  xo = (( !(i & 1) ) ? .04 : .52) * x_size;
  436.                   double  yo = (( !(i & 2) ) ? 0.0 : 0.5) * y_size;
  437.           
  438.                   if ( !(window2 = TvCreateWindow( TvDefaultDevice,
  439.                    xo + x_base, yo + y_base + 0.1, .44*x_size, .44*y_size )) )
  440.                     break;
  441.             
  442.                   if ( !(maps[i] = TvDupMap( window2, pmap )) )
  443.                     {
  444.                     TvDeleteWindow( window2 );
  445.                     break;
  446.                     }
  447.                   TvSetMapWindowDelete( maps[i] );
  448.                   if ( i != 0 ) TvSetMapZoom( maps[i], 0.2 );
  449.             
  450.                   do_features( maps[i] );
  451.                   TvRefresh( maps[i], TvAllOverlays );
  452.                   grid_up = 0;
  453.  
  454.                   TvMessage( cur, TvClearMessage   );
  455.                   TvMessage( cur, "Zooming out 5X" );
  456.                   }
  457.           
  458.                 TvMessage( cur, "ANY KEY to resume" );
  459.  
  460.                 while( 1 )
  461.                   {
  462.                   event2 = TvGetEvent( TvAnyMap );
  463.                   code2  = TvEventCode( event2 );
  464.                   TvReplyEvent( event2 );
  465.                   if ( ((code2 & KBD_MASK_CLASS) != KBD_SELECTOR) &&
  466.                        ((code2 & KBD_MASK_CLASS) != KBD_LOCATOR) )
  467.                     break;
  468.                   else if ( code2 & KBD_MASK_DOWN )
  469.                     break;
  470.                   }
  471.  
  472.                 for( i=0; i < 4; pmap = maps[i++] )
  473.                  if ( maps[i] != TvStatusError )
  474.                   TvDeleteMap( maps[i] );
  475.                 }
  476.               break;
  477.  
  478.         case FUNCTION_ADDRESS_LOCATOR:
  479.                 {
  480.                 LONG               addr = -1, zipcode = -1, atol();
  481.           
  482.                 if ( locator )
  483.                   {
  484.                   TvRemoveOverlay( cur, locator );
  485.                   TvDeleteOverlay( locator );
  486.                   locator = 0;
  487.                   }
  488.                 TvPrompt( cur, "Address Locator: Enter street NAME: ", line );
  489.                 if ( line[0] == '\0' ) break;
  490.                 strcpy( wild, line );  strcat( wild, "*" );
  491.           
  492.                 TvPrompt( cur, "Address Locator: Enter street NUMBER: ", line );
  493.                 if ( line[0] ) addr = atol(line);
  494.           
  495.                 TvPrompt( cur, "Address Locator: Enter ZIPCODE: ", line );
  496.                 if ( line[0] ) zipcode = atol(line);
  497.           
  498.                 if ( zipcode == -1 )
  499.                   sprintf(line,"Searching for [ %ld %s ]...",
  500.                      addr, wild );
  501.                 else
  502.                   sprintf(line,"Searching for [ %05ld: %ld %s ]...",
  503.                      zipcode, addr, wild );
  504.                 TvMessage( cur, line );
  505.           
  506.                 if ( (locator = TvStreetLocator( cur, TvAllOverlays, 
  507.                                                  zipcode, wild, addr, 1 )) 
  508.                      != TvStatusError )
  509.                   {
  510.                   TvAddOverlay( cur, locator );
  511.                   TvResetReference( cur );
  512.                   }
  513.                 else
  514.                   TvPrompt(cur,"Location not found!  ENTER to continue.", line);
  515.                 }
  516.               refresh++;
  517.               break;
  518.  
  519.         case FUNCTION_PRINT:
  520.               TvPrompt(cur,"Enter print file name (ENTER to abort):", line);
  521.               if ( strlen(line) ) 
  522.                 {
  523.                 TvMessage( cur, "Please wait..." );
  524.                 TvScreenDump( cur , line );
  525.                 TvMessage( cur, TvClearMessage );
  526.                 }
  527.               break;
  528.  
  529.         case FUNCTION_RESET:
  530.               TvResetReference( cur );
  531.               if ( overlay_tmp != 0 )
  532.                 {
  533.                 TvRemoveOverlay( cur, overlay_tmp );
  534.                 TvDeleteOverlay( overlay_tmp );
  535.                 overlay_tmp = 0;
  536.                 }
  537.               if ( locator )
  538.                 {
  539.                 TvRemoveOverlay( cur, locator );
  540.                 TvDeleteOverlay( locator );
  541.                 locator = 0;
  542.                 }
  543.               refresh++;
  544.               break;
  545.  
  546.         case FUNCTION_HELP:
  547.               tell_help( cur );
  548.               refresh++;
  549.               break;
  550.  
  551.  
  552.         case FUNCTION_IDENTIFY:
  553.               TvMessage(cur, "Identify: Point to unknown feature and click");
  554.               while( 1 )
  555.                 {
  556.                 event2 = TvGetEvent( cur );
  557.                 code2  = TvEventCode( event2 );
  558.                 if ( (code2 & KBD_MASK_CLASS) == KBD_LOCATOR )
  559.                   break;
  560.                 TvReplyEvent( event2 );
  561.                 }
  562.               TvInquireEventPosition(event2, TvLatLong, &latitude, &longitude);
  563.               TvReplyEvent( event2 );
  564.               TvPickByPosition( cur, TvLatLong, latitude, longitude );
  565.               TvMessage( cur, "In progress..." );
  566.               while ( (code2 != KBD_QUIT) && (code2 != KBD_WINDOW_EXIT) &&
  567.                   (code2 != 0177) && (TvPickNext(cur) == TvStatusOK) )
  568.                 {
  569.                 char   name[80];
  570.           
  571.                 TvDisplayPickedFeature( cur, hl_color );
  572.                 TvInquirePickedFeature( cur, 0, name, 0 );
  573.                 sprintf( line, "<%s> ANY KEY for next", name );
  574.                 TvMessage( cur, line );
  575.                 while( 1 )
  576.                   {
  577.                   event2 = TvGetEvent( TvAnyMap );
  578.                   code2  = TvEventCode( event2 );
  579.                   TvReplyEvent( event2 );
  580.                   if ( ((code2 & KBD_MASK_CLASS) != KBD_LOCATOR) &&
  581.                        ((code2 & KBD_MASK_CLASS) != KBD_SELECTOR) )
  582.                     break;
  583.                   else if ( (code2 & KBD_MASK_DOWN) )
  584.                     break;
  585.                   }
  586.                 TvMessage( cur, "In progress..." );
  587.                 TvHighlightPickedFeature( cur, 0 );
  588.                 }
  589.               TvMessage( cur, TvClearMessage );
  590.               break;
  591.  
  592.         case FUNCTION_QUIT:
  593.               TvReplyEvent( event );
  594.               TvClearWindow( TvInquireMapWindow( cur ) );
  595.               CENTER( cur, 05, TvColorGrid,
  596.                 "Thanks for using the TerraView Demonstration program" )
  597.               CENTER( cur, 10, TvColorGrid,
  598.                 "Comments and suggestions are greatly appreciated" )
  599.               CENTER( cur, 15, TvColorGrid,
  600.                 "Please call us 9-5 EST M-F at (603) 889-1800" )
  601.               CENTER( cur, 20, TvColorGrid,
  602.                 "We look forward to hearing from you!" )
  603.               TvMessage( cur, "ANY key to exit" );
  604.               event = TvGetEvent( TvAnyMap );
  605.               TvReplyEvent( event );
  606.               TvExit( 1 );
  607.               break;
  608.  
  609.       }    /* end switch( button ) */
  610.       
  611.     TvMapPanelArm(  cur, functions[button].button, 0, TvColorWhite );
  612.     }        /* end if SELECTOR */
  613.  
  614.   else switch ( code )
  615.     {
  616.   case KBD_HELP:
  617.   case KBD_F1:
  618.   case 'H':
  619.     tell_help( cur );
  620.     refresh++;
  621.     break;
  622.  
  623.   case KBD_QUIT:
  624.     TvPrompt( cur , "Really Exit ? (Y/N) [N]: ", line );
  625.     if ( (line[0] != 'Y') && (line[0] != 'y') ) break;
  626.   case 'Q':
  627.   case 'E':
  628.   case 'X':
  629.     TvReplyEvent( event );
  630.     TvExit( 1 );
  631.     break;
  632.  
  633.   case KBD_F2:
  634.     TvSetMapZoom( cur, (rescale = zoom_factor) );
  635.     refresh++;
  636.     break;
  637.  
  638.   case KBD_F3:
  639.     TvSetMapZoom( cur, (rescale = (1.0 / zoom_factor)) );
  640.     refresh++;
  641.     break;
  642.  
  643.   case KBD_UP:
  644.     TvScrollMap( cur, TvFWS,   0.00,   0.25 );
  645.     refresh++;
  646.     break;
  647.  
  648.   case KBD_DOWN:
  649.     TvScrollMap( cur, TvFWS,   0.00,  -0.25 );
  650.     refresh++;
  651.     break;
  652.  
  653.   case KBD_LEFT:
  654.     TvScrollMap( cur, TvFWS,  -0.25,   0.00 );
  655.     refresh++;
  656.     break;
  657.  
  658.   case KBD_RIGHT:
  659.     TvScrollMap( cur, TvFWS,   0.25,   0.00 );
  660.     refresh++;
  661.     break;
  662.  
  663.   case KBD_WINDOW_RESIZE:
  664.     refresh++;
  665.     break;
  666.     }   /* switch( code ) */
  667.  
  668.   if ( refresh ) 
  669.     {
  670.     do_features( cur );
  671.     if ( !TvRefresh( cur, TvAllOverlays ) && (rescale != 0.0) )
  672.       {
  673.       /* No data displayed!  Reset zoom and re-display */
  674.       TvSetMapZoom( cur, (1.0 / rescale) );
  675.       do_features( cur );
  676.       TvRefresh( cur, TvAllOverlays );
  677.       TvMessage( cur,"No Additional Data Available!");
  678.       }
  679.     rescale = 0.0;
  680.     first_screen = grid_up = 0;
  681.     }
  682.   else
  683.     TvMapPanelRefresh( cur );
  684.  
  685.   if ( event   ) TvReplyEvent( event );
  686.  
  687.   return;
  688.   }
  689.  
  690. /***************************************/
  691. /* Function to tell the user the mouse */ 
  692. /* position in Latitude and Longitude  */
  693. /***************************************/
  694. tell_position( cur, latitude, longitude )
  695.  TvMapID  cur;
  696.  double   latitude, longitude;
  697.   {
  698.   char msg[255];
  699.   double lat_deg,  lat_min,  lat_sec;
  700.   double long_deg, long_min, long_sec;
  701.  
  702.   TvDegDMS( latitude,  &lat_deg,  &lat_min,  &lat_sec  );
  703.   TvDegDMS( longitude, &long_deg, &long_min, &long_sec );
  704.   sprintf( msg, "%3.0lf %2.0lf'%5.2lf\" %3.0lf %2.0lf'%5.2lf\"",
  705.            lat_deg,  lat_min,  lat_sec, long_deg, long_min, long_sec );
  706.   TvMessage( cur, msg );
  707.   }
  708.  
  709.  
  710. /*************************************/
  711. /* Function to display the help file */
  712. /*************************************/
  713. tell_help( cur )
  714.  TvMapID   cur;
  715.   {
  716.   char       line[132];
  717.   FILE      *help;
  718.   int        line_number=4;
  719.   TvEventID  event2;
  720.   LONG       code2;
  721.  
  722.   if ( (help = fopen( "readme.txt", "r" )) == NULL ) return;
  723.   TvClearWindow( TvInquireMapWindow( cur ) );
  724.   while( fgets( line, 132, help ) != NULL )
  725.     CENTER( cur, line_number++, TvColorHighlight, line )
  726.  
  727.   TvMessage( cur, "ANY KEY to resume" );
  728.   while( 1 )
  729.     {
  730.     event2 = TvGetEvent( TvAnyMap );
  731.     code2 = TvEventCode( event2 );
  732.     TvReplyEvent( event2 );
  733.     if ( ((code2 & KBD_MASK_CLASS) != KBD_SELECTOR) &&
  734.          ((code2 & KBD_MASK_CLASS) != KBD_LOCATOR) )
  735.       break;
  736.     else if ( code2 & KBD_MASK_DOWN )
  737.       break;
  738.     }
  739.   }
  740.  
  741.  
  742. /*****************************************************/
  743. /* Function to enable selected features in overlays */
  744. /*****************************************************/
  745. do_features( cur )
  746.  TvMapID   cur;
  747.   {
  748.   TvSelectFeature(cur, TvAllOverlays, "DYNAMAP", "A", 1);
  749.   TvSelectFeature(cur, TvAllOverlays, "DYNAMAP", "0", 1);
  750.   TvSelectFeature(cur, TvAllOverlays, "DYNAMAP", "4", 1);
  751.   }
  752.