home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume5 / mapper < prev    next >
Text File  |  1989-02-03  |  21KB  |  803 lines

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