home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume05 / mapper < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  20.5 KB

  1. From decwrl!labrea!rutgers!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery Sun Dec 11 17:12:00 PST 1988
  2. Article 747 of comp.sources.misc:
  3. Path: granite!decwrl!labrea!rutgers!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery
  4. From: sampson@killer.DALLAS.TX.US (Steve Sampson)
  5. Newsgroups: comp.sources.misc
  6. Subject: v05i072: CGA/EGA Perspective Map Program
  7. Keywords: Source, Doc
  8. Message-ID: <6335@killer.DALLAS.TX.US>
  9. Date: 7 Dec 88 00:30:44 GMT
  10. Sender: allbery@ncoast.UUCP
  11. Reply-To: sampson@killer.DALLAS.TX.US (Steve Sampson)
  12. Organization: The Unix(R) Connection, Dallas, Texas
  13. Lines: 789
  14. Approved: allbery@ncoast.UUCP
  15.  
  16. Posting-number: Volume 5, Issue 72
  17. Submitted-by: "Steve Sampson" <sampson@killer.DALLAS.TX.US>
  18. Archive-name: mapper
  19.  
  20. This is for Turbo-C users, no binaries included.  Easily modified for
  21. other compilers.
  22.  
  23.  
  24. #! /bin/sh
  25. # Contents:  mapper.doc mapper.c
  26. # Wrapped by sampson on Mon Dec 05 15:07:18 1988
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f mapper.doc -a "${1}" != "-c" ; then 
  29.   echo shar: Will not over-write existing file \"mapper.doc\"
  30. else
  31. echo shar: Extracting \"mapper.doc\" \(4532 characters\)
  32. sed "s/^X//" >mapper.doc <<'END_OF_mapper.doc'
  33. X
  34. X                             The Mapper Program
  35. X
  36. X                                 Version 1.7
  37. X
  38. X                              22 November 1988
  39. X
  40. X
  41. X         I was interested in techniques  for producing maps, and  found
  42. X      the article by William D. Johnston in the May and June 1979  Byte
  43. X      Magazine.    This   two  part  article   provided  an   excellent
  44. X      introduction and source  code in Basic  Language.   His code  was
  45. X      restricted to the algorithms and  did not get involved with  user
  46. X      interface.  To evaluate his algorithms and try out the displays I
  47. X      coded the program and a simple interface in Turbo-C Version  1.5.
  48. X      The program in its current form is highly based on Mr. Johnston's
  49. X      algorithms and provides no significant additional capabilities.
  50. X
  51. X      I also found  a high resolution database  called the Micro  World
  52. X      Data Bank II (MWDBII).   This database was  1 megabyte in  length
  53. X      and good down  to minutes  of a degree.   See the  C source  code
  54. X      comments for availability.
  55. X
  56. X      To run the  program and receive  help you  use the DOS  common
  57. X      method of the question option "/?".  Just type "mapper/?" and the
  58. X      following usage help will be displayed:
  59. X
  60. X              Usage: mapper [/bcdgilmrsx]
  61. X
  62. X                /b   Boundaries Off
  63. X                /c   Countries On
  64. X                /dn  Database ('MWDBII' Default)
  65. X                /g   Grid lines On
  66. X                /i   Islands Off
  67. X                /l   Lakes Off
  68. X                /mn  Map Resolution (5 Default)
  69. X                /r   Rivers On
  70. X                /s   States On
  71. X                /x   Colors On
  72. X
  73. X              Defaults to Boundaries and Islands On
  74. X
  75. X      The defaults are what I thought should be fairly common.  The map
  76. X      database has  5 resolutions,  and can  be selected  with the  'm'
  77. X      option.  5 is the  lowest resolution and 1  is the greatest.   If
  78. X      you have several different databases  you can use the 'd'  option
  79. X      and provide the path and filename (128 Characters max).  The  'm'
  80. X      and 'd' options  should be placed at  the end.   They can be  put
  81. X      anywhere  but  it's  a  little  easier  at  the  end.    Example:
  82. X      mapper/glrsm1.  If you use the option in the middle you will need
  83. X      to put a  space between it  and the  remaining options.  Example:
  84. X      mapper/glddata /rs.  These are the most foolproof methods.  Note:
  85. X      The level 5 database included doesn't really use the options yet.
  86. X      The program works as advertised on level 1. There are some errors
  87. X      with the database as you'll see.  I've converted the database  to
  88. X      ASCII, and am working on cleaning up the errors and redundancies.
  89. X
  90. X         A little about the speed of the result.  The program is  quite
  91. X      slow on an 8088 without a math coprocessor, and speed is  getting
  92. X      acceptable on  an 80286.   The  C language  standard uses  double
  93. X      precision math.    This is  a  waste  with the  current  database
  94. X      resolution.  An integer version  of the math routines would  sure
  95. X      speed up  the program  quite  a bit.    The mapper  program  uses
  96. X      Turbo-C auto detect  of a  math coprocessor  and graphics  device
  97. X      type (CGA, EGA, and VGA).
  98. X
  99. X         If you want to quit the  plotting on the screen, just hit  any
  100. X      key and the bell will  sound and exit you back  to DOS.  You  can
  101. X      also use Control-C to get out.
  102. X
  103. X         The C program  lists three sources  for the  Micro World  Data
  104. X      Bank II database.  The  database is 1 Megabyte (800K  Compressed)
  105. X      and is just too much data for reasonable downloading.   To see if
  106. X      the program  would  be  useful  for you  I  included  a  level  5
  107. X      resolution map (the lowest resolution).  This particular database
  108. X      has all  the data  thrown together  so the  command line  options
  109. X      aren't fully functional.  They  become functional at about  level
  110. X      3 I believe.
  111. X
  112. X         This program was tested  on a PC XT  Clone, 640K, and NSI  EGA
  113. X      board.  Also a Zenith Z-248 with 512k and CGA was tested.   Other
  114. X      configurations will need to be tested.
  115. X
  116. X      Due to  the  grid  method used,  it  shouldn't  be used  with  an
  117. X      Azimuthal Equidistant map.   You can  try it once  to see what  I
  118. X      mean.  There's lots of room for improvements, "Handle It!".
  119. X
  120. X      Thanks to Mr. Johnston for his article and algorithms.
  121. X
  122. X      USMail: Steve R. Sampson, Box 45668, Tinker AFB, Oklahoma, 73145
  123. X      Compuserve: 75136,626  Unix: sampson@killer.dallas.tx
  124. END_OF_mapper.doc
  125. if test 4532 -ne `wc -c <mapper.doc`; then
  126.     echo shar: \"mapper.doc\" unpacked with wrong size!
  127. fi
  128. # end of overwriting check
  129. fi
  130. if test -f mapper.c -a "${1}" != "-c" ; then 
  131.   echo shar: Will not over-write existing file \"mapper.c\"
  132. else
  133. echo shar: Extracting \"mapper.c\" \(13949 characters\)
  134. sed "s/^X//" >mapper.c <<'END_OF_mapper.c'
  135. X/*
  136. X *    mapper.c
  137. X *
  138. X *    Version 1.7 by Steven R. Sampson, November 1988
  139. X *
  140. X *    Based on a program and article by William D. Johnston
  141. X *    Copyright (c) May-June 1979 BYTE, All Rights Reserved
  142. X *
  143. X *    This program draws three types of map projections:
  144. X *    Perspective, Modified Perspective, and Azimuthal Equidistant.
  145. X *
  146. X *    Compiled with Turbo-C V1.5
  147. X */
  148. X
  149. X#include <dos.h>
  150. X#include <math.h>
  151. X#include <stdio.h>
  152. X#include <conio.h>
  153. X#include <string.h>
  154. X#include <stdlib.h>
  155. X#include <graphics.h>
  156. X
  157. Xtypedef int    bool;
  158. X
  159. X/* Program Constants */
  160. X
  161. X#define    FALSE    (bool) 0
  162. X#define    TRUE    (bool) ~FALSE
  163. X
  164. X#define    PI    (3.141593F)
  165. X#define    HALFPI    (1.570796F)
  166. X#define    TWOPI    (2.0F * PI)        /* Two Pi alias 360 Degrees         */
  167. X
  168. X#define    RADIAN    (180.0F / PI )        /* One radian                 */
  169. X#define    TWO    (2.0F / RADIAN)        /* 2 degrees in radians             */
  170. X#define    TEN    (10.0F / RADIAN)    /* 10 degrees in radians         */
  171. X#define    EIGHTY    (80.0F / RADIAN)    /* 80 degrees in radians         */
  172. X#define    EARTH    (6378.0F)        /* Mean radius of earth (Kilometers) */
  173. X
  174. X/* Program Globals */
  175. X
  176. XFILE    *fp;
  177. X
  178. Xfloat    angle, maxplot, center_lat, center_lon, lat, lon, distance,
  179. X    sin_of_distance, cos_of_distance, sin_of_center_lat, cos_of_center_lat,
  180. X    scale, g, h2, facing_azimuth, aspect;
  181. X
  182. Xint    option, center_x, center_y, grid_color, level = 5;
  183. Xint    GraphDriver = DETECT, GraphMode;
  184. X
  185. Xchar    optstring[] = "bcd:gilm:rsx?";
  186. Xchar    database[128] = "mwdbii";    /* default name 'MWDBII'         */
  187. X                    /* leave room for pathname!         */
  188. Xbool    boundaries = TRUE,        /* defaults to Boundaries, Islands   */
  189. X    countries  = FALSE,
  190. X    grids      = FALSE,
  191. X    islands    = TRUE,
  192. X    lakes      = FALSE,
  193. X    rivers     = FALSE,
  194. X    states     = FALSE,
  195. X    colors     = FALSE;
  196. X
  197. X/* Forward Declarations, Prototypes */
  198. X
  199. Xextern    int    getopt(int, char **, char *);
  200. Xextern    int    optind, opterr;
  201. Xextern    char    *optarg;
  202. X
  203. Xfloat    parse(char *);
  204. Xvoid    grid(void), plotmap(void), prompts(void), quit(void);
  205. Xbool    compute(float *, float *, int *, int *);
  206. X
  207. X
  208. Xmain(argc, argv)
  209. Xint    argc;
  210. Xchar    *argv[];
  211. X{
  212. X    register int    i;
  213. X    int        err, xasp, yasp;
  214. X
  215. X    registerbgidriver(EGAVGA_driver);
  216. X    registerbgidriver(CGA_driver);
  217. X
  218. X    setcbrk(TRUE);        /* Allow Control-C checking             */
  219. X    ctrlbrk(quit);        /* Execute quit() if Control-C detected         */
  220. X
  221. X    while ((i = getopt(argc, argv, optstring)) != -1)  {
  222. X        switch (i)  {
  223. X        case 'b':
  224. X            boundaries = FALSE;
  225. X            break;
  226. X        case 'c':
  227. X            countries = TRUE;
  228. X            break;
  229. X        case 'd':
  230. X            strcpy(database, optarg);
  231. X            break;
  232. X        case 'g':
  233. X            grids = TRUE;
  234. X            break;
  235. X        case 'i':
  236. X            islands = FALSE;
  237. X            break;
  238. X        case 'l':
  239. X            lakes = TRUE;
  240. X            break;
  241. X        case 'm':
  242. X            level = atoi(optarg);
  243. X            break;
  244. X        case 'r':
  245. X            rivers = TRUE;
  246. X            break;
  247. X        case 's':
  248. X            states = TRUE;
  249. X            break;
  250. X        case 'x':
  251. X            colors = FALSE;
  252. X            break;
  253. X        case '?':
  254. X        default:
  255. X              printf("Usage: mapper [/bcdgilmrsx]\n\n");
  256. X              printf("  /b   Boundaries Off\n");
  257. X              printf("  /c   Countries On\n");
  258. X              printf("  /dn  Database ('MWDBII' Default)\n");
  259. X              printf("  /g   Grid lines On\n");
  260. X              printf("  /i   Islands Off\n");
  261. X              printf("  /l   Lakes On\n");
  262. X              printf("  /mn  Map Resolution (5 Default)\n");
  263. X              printf("  /r   Rivers On\n");
  264. X              printf("  /s   States On\n");
  265. X              printf("  /x   Colors On\n\n");
  266. X              printf("Defaults to Boundaries and Islands On\n");
  267. X              exit(0);
  268. X        }
  269. X    }
  270. X
  271. X    if ((fp = fopen(database, "rb")) == (FILE *)NULL)  {
  272. X        printf("\007Error: Can't locate Database '%s'\n", database);
  273. X        exit(1);
  274. X    }
  275. X
  276. X    initgraph(&GraphDriver, &GraphMode, "");/* initialize graphics         */
  277. X    err = graphresult();
  278. X
  279. X    restorecrtmode();            /* get back to text mode     */
  280. X
  281. X    if (err < 0)  {
  282. X        printf("Graphics Error - %s\n", grapherrormsg(err));
  283. X        exit(-1);
  284. X    }
  285. X
  286. X    center_x = getmaxx() / 2;        /* get screen size for x, y  */
  287. X    center_y = getmaxy() / 2;
  288. X    getaspectratio(&xasp, &yasp);        /* squish factor for y axis  */
  289. X    aspect = (float)xasp / (float)yasp;
  290. X
  291. X    prompts();                /* get the basic map info    */
  292. X    setgraphmode(GraphMode);        /*  and go to graphics mode  */
  293. X
  294. X    if (GraphMode != CGAHI)  {
  295. X        setbkcolor(BLACK);        /* must be EGA or VGA then   */
  296. X        if (colors)
  297. X            grid_color = EGA_LIGHTRED;
  298. X        else
  299. X            grid_color = EGA_LIGHTGRAY;
  300. X    } else
  301. X        grid_color = LIGHTGRAY;        /* CGA only has two colors   */
  302. X
  303. X    setcolor(LIGHTGRAY);
  304. X
  305. X    /*
  306. X     *    See if data plotting is even needed
  307. X     */
  308. X
  309. X    if (boundaries || countries || islands || lakes || rivers || states)
  310. X        plotmap();            /* display map on screen     */
  311. X
  312. X    if (grids)
  313. X        grid();                /* draw lat & long ref lines */
  314. X
  315. X    if (print)
  316. X        printscreen();            /* relay screen to printer   */
  317. X
  318. X    sound(800);                /* 800 Hz for 1/4 a second   */
  319. X    delay(125);
  320. X    nosound();
  321. X
  322. X    getch();                /* pause until key pressed   */
  323. X    closegraph();                /* graphics off             */
  324. X    fclose(fp);                /* close database file         */
  325. X
  326. X    exit(0);
  327. X}
  328. X
  329. X/*
  330. X *    Return to operator following Control-C
  331. X */
  332. X
  333. Xvoid quit()
  334. X{
  335. X    closegraph();
  336. X    fclose(fp);
  337. X
  338. X    exit(0);
  339. X}
  340. X
  341. X/*
  342. X *    Operator prompts and input.
  343. X */
  344. X
  345. Xvoid prompts()
  346. X{
  347. X    char    temp[16];
  348. X    float    ret, altitude;
  349. X
  350. X    printf("West Longitudes and South Lattitudes are negative\n");
  351. X
  352. X    /* input the world Lat & Long that is to be centered on */
  353. X    /*   then convert the human notation to radians         */
  354. X
  355. X    do  {
  356. X        printf("\nLatitude of the map center [+-]dd.mm : ");
  357. X        scanf("%s", temp);
  358. X        ret = parse(temp);
  359. X    } while (ret > 90.0F || ret < -90.0F);
  360. X
  361. X    /* the arcosine function has trouble at 90 degrees */
  362. X
  363. X    if (ret == 90.0F)
  364. X        ret = 89.9F;
  365. X
  366. X    if (ret == -90.0F)
  367. X        ret = -89.9F;
  368. X
  369. X    center_lat = ret / RADIAN;
  370. X    sin_of_center_lat = sin(center_lat);
  371. X    cos_of_center_lat = cos(center_lat);
  372. X
  373. X    do  {
  374. X        printf("Longitude of the map center [+-]ddd.mm : ");
  375. X        scanf("%s", temp);
  376. X        ret = parse(temp);
  377. X    } while (ret > 180.0F || ret < -180.0F);
  378. X
  379. X    center_lon = ret / RADIAN;
  380. X
  381. X    do  {
  382. X        printf("\nSelect from the following options:\n\n");
  383. X        printf("  1 - Perspective Projection\n");
  384. X        printf("  2 - Modified Perspective Projection\n");
  385. X        printf("  3 - Azimuthal Equidistant Projection\n\n");
  386. X        printf("Choice : ");
  387. X        scanf("%d", &option);
  388. X    } while (option < 1 || option > 3);
  389. X
  390. X    if (option == 3)  {
  391. X        maxplot = PI;        /* use HALFPI for less area        */
  392. X        scale = (float)center_y / maxplot;
  393. X        return;
  394. X    }
  395. X
  396. X    /* input the height above the terrain */
  397. X
  398. X    printf("\nObserver altitude (km) : ");
  399. X    scanf("%f", &altitude);
  400. X
  401. X    h2 = EARTH + altitude;
  402. X    maxplot = acos(EARTH / h2);
  403. X
  404. X    /* the operator can orient the world upside down if they want */
  405. X
  406. X    do  {
  407. X        printf("Observer facing azimuth (0 - 359 degrees) : ");
  408. X        scanf("%f", &facing_azimuth);
  409. X    } while (facing_azimuth < 0.0F || facing_azimuth > 360.0F);
  410. X
  411. X    facing_azimuth = -facing_azimuth / RADIAN;
  412. X
  413. X    /* calculate the scale for the polar coordinates */
  414. X
  415. X    scale = (float)center_y / (EARTH * sin(maxplot));
  416. X
  417. X    /* for the perspective projection */
  418. X
  419. X    g = EARTH * (h2 - EARTH * cos(maxplot));
  420. X}
  421. X
  422. X
  423. X/*
  424. X *    Convert the database to the desired projection by computation.
  425. X *
  426. X *    This code is a hand translation from BASIC to C based on Mr. Johnstons
  427. X *    code.  It is a non-mathematicians idea of what he meant.
  428. X *
  429. X *    Return TRUE if offscale else FALSE.
  430. X */
  431. X
  432. Xbool compute(lat, lon, x, y)
  433. Xregister float    *lat, *lon;
  434. Xregister int    *x, *y;
  435. X{
  436. X    float    sin_of_lat,
  437. X        cos_of_lat,
  438. X        abs_delta_lon,            /* absolute value         */
  439. X        delta_lon,            /* x distance from center    */
  440. X        delta_lat,            /* y distance from center    */
  441. X        temp;                /* temporary storage         */
  442. X
  443. X    /* normalize the longitude to +/- PI */
  444. X
  445. X    delta_lon = *lon - center_lon;
  446. X
  447. X    if (delta_lon < -PI)
  448. X        delta_lon = delta_lon + TWOPI;
  449. X
  450. X    if (delta_lon > PI)
  451. X        delta_lon = delta_lon - TWOPI;
  452. X
  453. X    abs_delta_lon = fabs(delta_lon);
  454. X
  455. X    /*
  456. X     *    If the delta_lon is within .00015 radians of 0 then
  457. X     *    the difference is considered exactly zero.
  458. X     *
  459. X     *    This also simplifys the great circle bearing calculation.
  460. X     */
  461. X
  462. X    if (abs_delta_lon <= 0.00015F)  {
  463. X        delta_lat = fabs(center_lat - *lat);
  464. X
  465. X        if (delta_lat > maxplot)
  466. X            return TRUE;        /* offscale             */
  467. X
  468. X        if (*lat < center_lat)
  469. X            angle = PI;
  470. X        else
  471. X            angle = 0.0F;
  472. X
  473. X        sin_of_distance = sin(delta_lat);
  474. X        cos_of_distance = cos(delta_lat);
  475. X    }
  476. X
  477. X    /*
  478. X     *    Check if delta_lon is within .00015 radians of PI.
  479. X     */
  480. X
  481. X    else if (fabs(PI - abs_delta_lon) <= 0.00015F)  {
  482. X        delta_lat = PI - center_lat - *lat;
  483. X
  484. X        if (delta_lat > PI)  {
  485. X            delta_lat = TWOPI - delta_lat;
  486. X            angle = PI;
  487. X        } else
  488. X            angle = 0.0F;
  489. X
  490. X        if (delta_lat > maxplot)
  491. X            return TRUE;        /* offscale             */
  492. X
  493. X        sin_of_distance = sin(delta_lat);
  494. X        cos_of_distance = cos(delta_lat);
  495. X    }
  496. X
  497. X    /*
  498. X     *    Simple calculations are out, now get cosmic.
  499. X     */
  500. X
  501. X    else  {
  502. X        sin_of_lat = sin(*lat);
  503. X        cos_of_lat = cos(*lat);
  504. X
  505. X        cos_of_distance = sin_of_center_lat * sin_of_lat +
  506. X                    cos_of_center_lat * cos_of_lat *
  507. X                      cos(delta_lon);
  508. X
  509. X        distance = acos(cos_of_distance);
  510. X
  511. X        if (distance > maxplot)
  512. X            return TRUE;        /* offscale             */
  513. X
  514. X        sin_of_distance = sin(distance);
  515. X
  516. X        temp = (sin_of_lat - sin_of_center_lat * cos_of_distance) /
  517. X            (cos_of_center_lat * sin_of_distance);
  518. X
  519. X        if (temp < -1.0F || temp > 1.0F)
  520. X            return TRUE;        /* offscale             */
  521. X
  522. X        angle = acos(temp);
  523. X
  524. X        if (delta_lon < 0.0F)
  525. X            angle = TWOPI - angle;
  526. X    }
  527. X
  528. X    if (facing_azimuth != 0.0F)  {
  529. X        angle = angle - facing_azimuth;
  530. X        if (angle < 0.0F)
  531. X            angle = TWOPI + angle;
  532. X    }
  533. X
  534. X    angle = HALFPI - angle;
  535. X
  536. X    if (angle < -PI)
  537. X        angle = angle + TWOPI;
  538. X
  539. X    switch (option)  {
  540. X    case 1:
  541. X        temp  = (scale * (g * sin_of_distance)) /
  542. X                (h2 - EARTH * cos_of_distance);
  543. X        break;
  544. X    case 2:
  545. X        temp = scale * EARTH * sin_of_distance;
  546. X        break;
  547. X    case 3:
  548. X        temp = scale * distance;
  549. X    }
  550. X
  551. X    /* convert polar to rectangular, correct for screen aspect */
  552. X
  553. X    *x = center_x + (int)(temp * cos(angle));
  554. X    *y = center_y - (int)(temp * sin(angle) * aspect);
  555. X
  556. X    return FALSE;
  557. X}
  558. X
  559. X/*
  560. X *    Read the database and plot points or lines.
  561. X *
  562. X *    The database is Micro World Data Bank II.  It's based on the
  563. X *    CIA WDB-II tape available from NTIS.  Micro WDB-II was created
  564. X *    by Micro Doc.  Placed in the public domain by Fred Pospeschil
  565. X *    and Antonio Riveria.  Check on availability at:
  566. X *    1-402-291-0795  (6-9 PM Central)
  567. X *
  568. X *    Austin Code Works has something called: The World Digitized
  569. X *    that sounds like the same thing ($30.00), 1-512-258-0785
  570. X *
  571. X *    Lone Star Software has something called: The World Digitized
  572. X *    that sounds like the same thing ($6.00), 1-800-445-6172.
  573. X *
  574. X *    Database is in Intel word order:
  575. X *    code_lsb, code_msb, lat_lsb, lat_msb, lon_lsb, lon_msb
  576. X *
  577. X *    Code:    Integer, two meanings:
  578. X *        1.  Detail Level (1 Highest - 5 Lowest)
  579. X *
  580. X *        2.  Header (1xxx - 7xxx)    Command Line Options
  581. X *
  582. X *            1xxx    Boundaries        /b
  583. X *            2xxx    Countries        /c
  584. X *    (decimal)    4xxx    States            /s
  585. X *            5xxx    Islands            /i
  586. X *            6xxx    Lakes            /l
  587. X *            7xxx    Rivers            /r
  588. X *
  589. X *    Lat & Long:  Integer
  590. X *        Representing Minutes of degree
  591. X */
  592. X
  593. Xvoid plotmap()
  594. X{
  595. X    struct    { short code, lat, lon; } coord;
  596. X    float    lat, lon;
  597. X    int    x, y;
  598. X    bool    point;
  599. X
  600. X    point = TRUE;
  601. X    while (fread(&coord, sizeof coord, 1, fp) > 0)  {
  602. X
  603. X        if (kbhit())  {
  604. X            grids = print = FALSE;
  605. X            getch();
  606. X            return;
  607. X        }
  608. X            
  609. X        /*
  610. X         *    Skip data that has been optioned out.
  611. X         */
  612. X
  613. X        if (coord.code < level)
  614. X            continue;
  615. X
  616. X        if (coord.code > 5)  {        /* must be a header         */
  617. X
  618. X            point = TRUE;
  619. X
  620. X            switch (coord.code / 1000)  {
  621. X            case 1:
  622. X                if (boundaries)  {
  623. X                    if (colors)
  624. X                        setcolor(EGA_LIGHTGRAY);
  625. X                    break;
  626. X                }
  627. X                else
  628. X                    continue;
  629. X            case 2:
  630. X                if (countries)  {
  631. X                    if (colors)
  632. X                        setcolor(EGA_BROWN);
  633. X                    break;
  634. X                }
  635. X                else
  636. X                    continue;
  637. X            case 4:
  638. X                if (states)  {
  639. X                    if (colors)
  640. X                        setcolor(EGA_BROWN);
  641. X                    break;
  642. X                }
  643. X                else
  644. X                    continue;
  645. X            case 5:
  646. X                if (islands)  {
  647. X                    if (colors)
  648. X                        setcolor(EGA_LIGHTGRAY);
  649. X                    break;
  650. X                }
  651. X                else
  652. X                    continue;
  653. X            case 6:
  654. X                if (lakes)  {
  655. X                    if (colors)
  656. X                        setcolor(EGA_BLUE);
  657. X                    break;
  658. X                }
  659. X                else
  660. X                    continue;
  661. X            case 7:
  662. X                if (rivers)  {
  663. X                    if (colors)
  664. X                        setcolor(EGA_GREEN);
  665. X                    break;
  666. X                }
  667. X                else
  668. X                    continue;
  669. X            }
  670. X        }
  671. X
  672. X        /*  Convert database minutes of a degree to radians */
  673. X
  674. X        lat =  (float) coord.lat / 60.0F / RADIAN;
  675. X        lon =  (float) coord.lon / 60.0F / RADIAN;
  676. X
  677. X        if (compute(&lat, &lon, &x, &y))  {
  678. X            point = TRUE;        /* offscale             */
  679. X            continue;
  680. X        }
  681. X
  682. X        if (point)  {
  683. X            putpixel(x, y, getcolor());/* put down a dot         */
  684. X            moveto(x, y);
  685. X            point = FALSE;
  686. X        }
  687. X        else
  688. X            lineto(x, y);        /* connect the dots         */
  689. X    }
  690. X}
  691. X
  692. X/*
  693. X *    parse +-ddd.mm
  694. X *
  695. X *    Change human degrees, and minutes to computer decimal.
  696. X *    Probably designed a monster for a simple solution here...
  697. X */
  698. X
  699. Xfloat parse(string)
  700. Xchar    *string;
  701. X{
  702. X    char    *ptr, degrees[8], minutes[8];
  703. X    float    num;
  704. X
  705. X    strcpy(degrees, "       ");        /* pre-load with blanks      */
  706. X    strcpy(minutes, "       ");
  707. X
  708. X    /* if no decimal point we assume a whole number */
  709. X
  710. X    if ( (ptr = strchr(string, '.')) == (char *)NULL )
  711. X        return atof(string);
  712. X
  713. X    /* else use the decimal point to offset */
  714. X
  715. X    *ptr++ = '\0';
  716. X
  717. X    strcpy(degrees, string);
  718. X    num = atof(degrees);
  719. X
  720. X    switch (strlen(ptr))  {
  721. X    case 0:
  722. X        return atof(string);
  723. X    case 1:
  724. X    case 2:
  725. X        strcpy(minutes, ptr);
  726. X        break;
  727. X    default:
  728. X        return 361.0F;    /* This will produce an error             */
  729. X    }
  730. X
  731. X    if (num >= 0.0F)
  732. X        num += atof(minutes) / 60.0F;
  733. X    else
  734. X        num -= atof(minutes) / 60.0F;
  735. X
  736. X    return num;
  737. X}
  738. X
  739. X
  740. X/*
  741. X *    Draw grid lines from -180 to +180 Degrees (Longitude Lines),
  742. X *    as well as +80 to -80 Degrees (Lattitude Lines).
  743. X */
  744. X
  745. Xvoid grid()
  746. X{
  747. X    float    lat, lon;
  748. X    int    x, y, pass1;
  749. X
  750. X    setcolor(grid_color);
  751. X
  752. X    for (lon = -PI; lon <= PI; lon += TEN)  {
  753. X        pass1 = TRUE;
  754. X        for (lat = EIGHTY; lat > -EIGHTY; lat -= TEN)  {
  755. X            if (!compute(&lat, &lon, &x, &y))  {
  756. X                if (pass1)  {
  757. X                    putpixel(x, y, grid_color);
  758. X                    moveto(x, y);
  759. X                    pass1 = FALSE;
  760. X                } else
  761. X                    lineto(x, y);
  762. X            } else
  763. X                pass1 = TRUE;
  764. X        }
  765. X
  766. X        if (kbhit())  {
  767. X            print = FALSE;
  768. X            getch();
  769. X            return;
  770. X        }
  771. X    }
  772. X
  773. X    for (lat = EIGHTY; lat > -EIGHTY; lat -= TEN)  {
  774. X        pass1 = TRUE;
  775. X        for (lon = -PI; lon <= PI; lon += TEN)  {
  776. X            if (!compute(&lat, &lon, &x, &y))  {
  777. X                if (pass1)  {
  778. X                    putpixel(x, y, grid_color);
  779. X                    moveto(x, y);
  780. X                    pass1 = FALSE;
  781. X                } else
  782. X                    lineto(x, y);
  783. X            } else
  784. X                pass1 = TRUE;
  785. X
  786. X        }
  787. X
  788. X        if (kbhit())  {
  789. X            print = FALSE;
  790. X            getch();
  791. X            return;
  792. X        }
  793. X    }
  794. X}
  795. X
  796. X/* EOF */
  797. END_OF_mapper.c
  798. if test 13949 -ne `wc -c <mapper.c`; then
  799.     echo shar: \"mapper.c\" unpacked with wrong size!
  800. fi
  801. # end of overwriting check
  802. fi
  803. echo shar: End of shell archive.
  804. exit 0
  805.  
  806.  
  807.