home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume32 / wmap2ps / part01 < prev    next >
Encoding:
Text File  |  1992-09-10  |  31.0 KB  |  1,115 lines

  1. Newsgroups: comp.sources.misc
  2. From: dockhorn@fzi.de (Patrick Dockhorn)
  3. Subject:  v32i033:  wmap2ps - WorldMap goes PostScript, Part01/01
  4. Message-ID: <1992Sep11.171436.17360@sparky.imd.sterling.com>
  5. X-Md4-Signature: cf6105d4ddd9b70a936825d0787ffaf3
  6. Date: Fri, 11 Sep 1992 17:14:36 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: dockhorn@fzi.de (Patrick Dockhorn)
  10. Posting-number: Volume 32, Issue 33
  11. Archive-name: wmap2ps/part01
  12. Environment: Postscript
  13.  
  14. Here's an excerpt from the README file:
  15.  
  16. WHAT IS wmap2ps ?
  17. =================
  18.  
  19. wmap2ps converts map files (MP1 format) from John B. Allisons
  20. 'The World Digitized' package to EPSF 2.0 conforming
  21. PostScript files. The latitude is usually projected using the
  22. mercator projection and the resulting figure may be scaled and
  23. positioned to the needs of the user.
  24. The MP1 format is described in the header of wmap2ps.c
  25.  
  26. THE WORLD DIGITIZED:
  27. ====================
  28.  
  29. The 'Digital World' data can be found on several 
  30. servers around the world; you might want to query
  31. archie for 'worldmap' or get the data for example from
  32.  
  33. nz20.rz.uni-karlsruhe.de
  34. in
  35. /pub/msdos/worldmap
  36.  
  37. If you decide to go there, you'll need the arc utility to extract the maps.
  38.  
  39. Have fun,
  40.  
  41.     Patsch
  42. -------------------------------------------------------------------------------
  43. #! /bin/sh
  44. # This is a shell archive.  Remove anything before this line, then feed it
  45. # into a shell via "sh file" or similar.  To overwrite existing files,
  46. # type "sh file -c".
  47. # Contents:  README Makefile wmap2ps.1 wmap2ps.c
  48. # Wrapped by kent@sparky on Fri Sep 11 12:09:56 1992
  49. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  50. echo If this archive is complete, you will see the following message:
  51. echo '          "shar: End of archive 1 (of 1)."'
  52. if test -f 'README' -a "${1}" != "-c" ; then 
  53.   echo shar: Will not clobber existing file \"'README'\"
  54. else
  55.   echo shar: Extracting \"'README'\" \(2480 characters\)
  56.   sed "s/^X//" >'README' <<'END_OF_FILE'
  57. XFILES
  58. X=====
  59. X
  60. XYou should have the following files:
  61. X
  62. XREADME        - that's me
  63. Xwmap2ps.c    - C source
  64. Xwmap2ps.1    - man page
  65. Xwmap2ps.man    - nroff'ed, i.e. human readable man page
  66. XMakefile    - genmake generated makefile to build wmap2ps
  67. X
  68. X
  69. XWHAT IS wmap2ps ?
  70. X=================
  71. X
  72. Xwmap2ps converts map files (MP1 format) from John B. Allisons
  73. X'The World Digitized' package to EPSF 2.0 conforming
  74. XPostScript files. The latitude is usually projected using the
  75. Xmercator projection and the resulting figure may be scaled and
  76. Xpositioned to the needs of the user.
  77. XThe MP1 format is described in the header of wmap2ps.c
  78. X
  79. X
  80. XHOW TO BUILD wmap2ps ?
  81. X======================
  82. X
  83. XThe Makefile was created using Edwin R. Carp's 'genmake' - nice program !
  84. XTo build wmap2ps simply do a 'make', provided that you have gcc installed.
  85. XOtherwise you'll need to change the CC macro in the makefile.
  86. X
  87. XThe program was developed using gcc and SunOS 4.1,
  88. Xbut there should be no problems in porting it to other platforms.
  89. X
  90. X
  91. XPROBLEMS:
  92. X=========
  93. X
  94. XI used old style function declarations and simple prototypes
  95. Xso the worst thing will be the strings that exceed one line, i.e.
  96. Xfprintf(stdout,"blablabla"
  97. X           "blubbblubbblubb"
  98. X        "yupyupyup");
  99. XI know that there are compilers that do not support this feature,
  100. Xbut it should be no problem to work around it.
  101. X
  102. X
  103. X
  104. XTHE WORLD DIGITIZED:
  105. X====================
  106. X
  107. XThe 'Digital World' data can be found on several 
  108. Xservers around the world; you might want to query
  109. Xarchie for 'worldmap' or get the data for example from
  110. X
  111. Xnz20.rz.uni-karlsruhe.de
  112. Xin
  113. X/pub/msdos/worldmap
  114. X
  115. XIf you decide to go there, you'll need the arc utility to extract the maps.
  116. X
  117. Xwmap2ps is in the Public Domain. You may use, copy and distribute it freely,
  118. Xas long as this README file is kept intact.
  119. XOn the contrary, the MP1 files you need to let it do something useful are not.
  120. XI suggest that you send a donation of $20 to the author of 
  121. X'The World Digitized', John B. Allison. His address is
  122. X
  123. XThe World Digitized
  124. XDept. PC SIG
  125. X166 Shady Lane
  126. XApollo, PA 15613
  127. X
  128. X
  129. XSTILL READING ?
  130. X===============
  131. X
  132. XThe reason for writing this program was the need of a map of Tassie -
  133. Xwell, I can promise that it is AT LEAST able to solve this problem.
  134. X
  135. XAny suggestions, bug reports etc. should be directed to dockhorn@fzi.de
  136. XAs this address is subject to change, do a 
  137. Xfinger dockhorn@keemun.fzi.de 
  138. Xor
  139. Xfinger dockhorn@141.21.4.77
  140. Xif your mail is not answered within a week.
  141. XI'll leave my new mail address in the finger info.
  142. X
  143. X    have fun
  144. X    
  145. X        Patsch
  146. END_OF_FILE
  147.   if test 2480 -ne `wc -c <'README'`; then
  148.     echo shar: \"'README'\" unpacked with wrong size!
  149.   fi
  150.   # end of 'README'
  151. fi
  152. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  153.   echo shar: Will not clobber existing file \"'Makefile'\"
  154. else
  155.   echo shar: Extracting \"'Makefile'\" \(1299 characters\)
  156.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  157. X#
  158. X# Makefile generated with genmake - version 1.1  08/22/92
  159. X#
  160. X# genmake is Copyright 1991 by Edwin R. Carp
  161. X#
  162. X# GENMAKE [files]
  163. X#
  164. X
  165. XCC = gcc -O
  166. XCFLAGS =  $(INCLUDE)
  167. XSOURCES = wmap2ps 
  168. XOBJECTS = wmap2ps.o 
  169. XPROGRAMS = wmap2ps 
  170. X
  171. Xall: $(PROGRAMS) 
  172. X
  173. Xwmap2ps: wmap2ps.o 
  174. X    $(CC) $(CFLAGS) -o wmap2ps wmap2ps.o $(LDFLAGS)  -lm -O
  175. X
  176. Xclean:
  177. X    /bin/rm -f $(OBJECTS) MAKELOG eddep makedep
  178. X
  179. Xclobber:
  180. X    /bin/rm -f $(OBJECTS) $(PROGRAMS) MAKELOG eddep makedep *~ *.bak *.BAK
  181. Xhidden:
  182. X    echo "make all > MAKELOG 2>&1 &"|/bin/sh
  183. X
  184. Xmakefile:
  185. X    genmake $(SOURCES) &
  186. X
  187. Xmakeall:
  188. X    genmake *.c &
  189. X
  190. X
  191. Xdepend:
  192. X    $(CC) -M ${INCLUDES} ${SOURCES} | \
  193. X    awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
  194. X        else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
  195. X               else rec = rec " " $$2 } } \
  196. X          END { print rec } ' > makedep
  197. X    echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
  198. X    echo '$$r makedep' >>eddep
  199. X    echo 'w' >>eddep
  200. X    cp Makefile Makefile.bak
  201. X    cat eddep | ed - Makefile
  202. X    rm eddep makedep
  203. X    echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
  204. X    echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
  205. X    echo '# see make depend above' >> Makefile
  206. X
  207. X# DO NOT DELETE THIS LINE -- make depend uses it
  208. X
  209. X
  210. X# DEPENDENCIES MUST END AT END OF FILE
  211. X# IF YOU PUT STUFF HERE IT WILL GO AWAY
  212. X# see make depend above
  213. END_OF_FILE
  214.   if test 1299 -ne `wc -c <'Makefile'`; then
  215.     echo shar: \"'Makefile'\" unpacked with wrong size!
  216.   fi
  217.   # end of 'Makefile'
  218. fi
  219. if test -f 'wmap2ps.1' -a "${1}" != "-c" ; then 
  220.   echo shar: Will not clobber existing file \"'wmap2ps.1'\"
  221. else
  222.   echo shar: Extracting \"'wmap2ps.1'\" \(3535 characters\)
  223.   sed "s/^X//" >'wmap2ps.1' <<'END_OF_FILE'
  224. X.TH WMAP2PS 1
  225. X.SH NAME
  226. Xwmap2ps \- convert a worldmap file to PostScript
  227. X.SH SYNOPSIS
  228. X.B wmap2ps [ -u unit ]
  229. X.nf
  230. X                [ -o x y ] 
  231. X.nf
  232. X                [ -w width ] 
  233. X.nf
  234. X                [ -h height ] 
  235. X.nf
  236. X                [ -nomercat ]
  237. X.nf
  238. X                [ -unconnect ]
  239. X.nf
  240. X                [ -drawsegs ]
  241. X.nf
  242. X                [ -showbox ]
  243. X.nf
  244. X                [ -debug ]
  245. X.sp
  246. X.SH DESCRIPTION
  247. X.I wmap2ps
  248. Xconverts map files (MP1 format) from the
  249. X.I Digitized World
  250. Xpackage by John B. Allison to an EPSF 2.0 conforming 
  251. X.B PostScript
  252. Xfile. This is done by reading map data from stdin and piping
  253. Xthe resulting PostScript code to stdout, taking user desired
  254. Xscaling and change of origin into account. The problem of
  255. Xmapping a three-dimensional surface to a two-dimensional plane
  256. Xis handled using the mercator projection, if this is desired.
  257. XUsing this transformation, distortions at extreme latitudes are
  258. Xavoided.
  259. X.SH OPTIONS
  260. X.TP
  261. X.B \-u unit
  262. Xdefines the unit in which the other scalar values will be given.
  263. XThe default is
  264. X.I cm
  265. X, other possible values are
  266. X.I pt
  267. Xor
  268. X.I in
  269. X.TP
  270. X.B \-o x y 
  271. XSets the origin of the figure. The values are given in the current unit,
  272. Xdefault is the lower left corner of the page.
  273. X.TP
  274. X.B \-w width
  275. XSpecify the desired width of the figure using the current unit.
  276. X.TP
  277. X.B \-h height
  278. XSpecify the desired height of the figure using the current unit. Only one
  279. Xof -h and -w may be used so that the original image ratio is preserved.
  280. XIf neither -w nor -h is given, the image is left in its original size.
  281. X.TP
  282. X.B \-nomercat
  283. XDon't use mercator projection. You may still achieve nice pictures if
  284. Xyour favourite country is close to the equator.
  285. X.TP
  286. X.B \-unconnect
  287. XThe MP1 files include comments, usually to give some information about the
  288. Xarea that is described by the following data. If one concatenates several
  289. Xmaps to form a bigger one, this may result in lines that interconnect the
  290. Xpreviously separate maps. If the maps are described by comments, wmap2ps
  291. Xis able to detect such interconnection points and, if you specify this
  292. Xoption, unconnects them.
  293. X.TP
  294. X.B \-drawsegs
  295. XUsually the lines drawn are stroked when the map is completed.
  296. XBut if your PostScript device is not able to handle all the 
  297. Xline segments at once, i.e. you get an error message like
  298. X.nf
  299. X%%[ Error: limitcheck; OffendingCommand: lineto ]%%
  300. X.nf
  301. X%%[ Flushing: rest of job (to end-of-file) will be ignored ]%%
  302. X.nf
  303. Xyou can force the program to stroke every single segment 
  304. Ximmediately after it is drawn by giving it this option.
  305. X.TP
  306. X.B \-showbox
  307. XThe bounding box of the figure is drawn too.
  308. X.TP
  309. X.B \-debug
  310. XWrite some additional information to stderr.
  311. X.SH EXAMPLES
  312. Xcat AU?.MP1 | wmap2ps -unconnect -o 1 1 -w 6 > au.ps
  313. X
  314. XThis would create a PostScript file that draws
  315. Xthe map of Australia, its seas and its islands
  316. Xwith an origin that lies 1 cm to the right and 1 cm
  317. Xabove the lower left corner of the page. The mercator
  318. Xprojection will be used and the resulting picture is
  319. Xscaled so that it's exactly 6 cm wide.
  320. X
  321. X.SH BUGS
  322. XIf, like in the above example, several map files are
  323. Xconcatenated, the
  324. Xresulting
  325. X.B PostScript
  326. Xfile may include visible lines that connect the partial maps. 
  327. XTo fix this bug, simply add a separator line (blank line)
  328. Xat the end of the map files. If possible, wmap2ps detects
  329. Xsuch problems and offers help through the '-unconnect' option.
  330. X.SH FILES
  331. Xwmap2ps.tmp - temporary, needed as wmap2ps acts as a pipe
  332. X.SH AUTHOR
  333. XPatrick Dockhorn (dockhorn@fzi.de).
  334. X.nf
  335. XForschungszentrum Informatik, Karlsruhe, Germany.
  336. X.nf
  337. X(Address is subject to change, do a 'finger dockhorn@keemun.fzi.de'
  338. X.nf
  339. Xto find out about the author's present address)
  340. X
  341. END_OF_FILE
  342.   if test 3535 -ne `wc -c <'wmap2ps.1'`; then
  343.     echo shar: \"'wmap2ps.1'\" unpacked with wrong size!
  344.   fi
  345.   # end of 'wmap2ps.1'
  346. fi
  347. if test -f 'wmap2ps.c' -a "${1}" != "-c" ; then 
  348.   echo shar: Will not clobber existing file \"'wmap2ps.c'\"
  349. else
  350.   echo shar: Extracting \"'wmap2ps.c'\" \(19844 characters\)
  351.   sed "s/^X//" >'wmap2ps.c' <<'END_OF_FILE'
  352. X/*
  353. X   wmap2ps
  354. X
  355. X   Description: converts files from the WORLDMAP package 
  356. X                (MP1 format) by John B. Allison to PostScript
  357. X
  358. X   The program expects input from stdin in WORLDMAP format
  359. X   as described below and writes a corresponding PostScript 
  360. X   file to stdout.
  361. X
  362. X   Written by Patsch in September 1992 (I needed the map of Tassie...)
  363. X
  364. X   This program is in the Public Domain, as
  365. X   long as the README file is kept intact.
  366. X
  367. X   =====================================================================
  368. X
  369. X   Usage :
  370. X
  371. X          wmap2ps [ -u unit     ]   %% one from { cm, in, pt }     
  372. X              [ -o x y      ]   %% lower left corner of image  
  373. X              [ -w width    ]   %% desired target width/height 
  374. X              [ -h height   ]   %% using the current unit      
  375. X          [ -nomercat   ]   %% don't use mercator projection
  376. X          [ -unconnect  ]   %% if multiple maps are concatenated
  377. X                    %% this may be detected by the presence of
  378. X                    %% a comment. if you activate this option,
  379. X                    %% every block of comments that appears implies
  380. X                    %% that the first pair of data points in the block
  381. X                    %% should be treaten as the beginning of a new line.
  382. X              [ -showbox    ]   %% draw the bounding box       
  383. X          [ -drawsegs   ]   %% do a 'stroke' after every line segment
  384. X              [ -debug      ]   %% print additional information
  385. X
  386. X      NOTES:  - If you specify both width and height this will result
  387. X                in a change of the image ratio, i.e. a distortion.
  388. X              - default unit is cm"
  389. X              - default origin is 0 0"
  390. X              - default width is original width\n"
  391. X   
  392. X   =====================================================================
  393. X
  394. X   Compiled successfully on a SPARCstation running SunOS 4.1.1 with:
  395. X   gcc -O -o wmap2ps wmap2ps.c
  396. X   
  397. X   If you have problems compiling the program, you might need to change
  398. X   the lines where strings are concatenated over more than one line.
  399. X   I know that many compilers are not able to do that.
  400. X
  401. X   =====================================================================
  402. X
  403. X   .MP1 File Format:  variable length ASCII records
  404. X
  405. X       Data Records
  406. X           field
  407. X             1     latitude        floating point number
  408. X
  409. X             2     blank           field separator
  410. X
  411. X             3     longitude       floating point number
  412. X
  413. X            [4]    optional        begining with a blank
  414. X                      comment
  415. X
  416. X             5     line feed       end of record (LF - 10)
  417. X
  418. X      Separator Records
  419. X           field
  420. X            [1]    optional blanks[s]
  421. X
  422. X             2     line feed       end of record (LF - 10)
  423. X
  424. X
  425. X   All you have to do is
  426. X   - to draw a line from (x0,y0) to (x1,y1); the from (x1,y1) to (x2,y2) etc.
  427. X   - if a separator line (blank line) is read, break the connection,
  428. X
  429. X     You may have noticed distortion in the maps displayed in the
  430. X     previous programs, epecially at extreme latitudes.  This
  431. X     distortion is caused by an attempt to map the curved surface
  432. X     of a three dimensional globe onto a two dimensional plane.  As
  433. X     you travel toward the poles, the 360 degrees of longitude are
  434. X     squeezed into less and less space on the globe, but not on the
  435. X     plane.
  436. X
  437. X     There are many ways to compensate for the distortion problem.
  438. X     Probably the solution most widely recognized is the Mercator
  439. X     projection, named for a famous early map maker.  Mercator's
  440. X     projection has the characteristics that both lines of latitude
  441. X     and longitude are straight and at right angles to each other
  442. X     (orthogonal).  In addition, if a small area is viewed, there
  443. X     is no distortion of form: areas have the right shape although
  444. X     the vertical scale and total area is distorted as you move from
  445. X     the equator.
  446. X     
  447. X     The formula for the Mercator projection is
  448. X
  449. X             y = ln{tan[45 deg + latitude/2)/deg_per_radian]}
  450. X
  451. X     Check out the Encyclopedia Britannica under Map for all this
  452. X     good stuff and more.
  453. X
  454. X   ========================================================================
  455. X
  456. X   The data you may use with this tool can be found for example on host
  457. X
  458. X   nz20.rz.uni-karlsruhe.de
  459. X
  460. X   in the directory
  461. X
  462. X   /pub/msdos/worldmap
  463. X
  464. X   Just use archie and look for 'worldmap' in EXACT mode.
  465. X
  466. X
  467. X   =======================================================================
  468. X
  469. X   As wmap2ps acts as a pipe, you may do the following
  470. X
  471. X   cat AU0.MP1 AU1.MP1 AU2.MP1 | wmap2ps -unconnect -o 1 1 -w 6 > au.ps
  472. X
  473. X   This would create a PostScript file that draws
  474. X   the map of Australia, its seas and its islands.
  475. X    
  476. X   If you glue together different maps in such a way, this may result in
  477. X   a map where the parts are connected by visible lines - to fix this 
  478. X   problem you may want to add an extra separator line (blank line) 
  479. X   at the end of the map files.
  480. X
  481. X   =====================================================================
  482. X               cookies to RCS
  483. X   =====================================================================
  484. X
  485. X   $Author: dockhorn $
  486. X   $Revision: 1.0 $
  487. X   $Log:    wmap2ps.c,v $
  488. X * Revision 1.0  92/09/05  18:06:07  dockhorn
  489. X * Initial revision
  490. X * 
  491. X*/
  492. X
  493. X#include <stdio.h>
  494. X#include <math.h>
  495. X
  496. Xstatic char rcsid[] = "$Header: /disk/DBS0S3-2H/home/dockhorn/TOOLS/SRC/WMAP2PS/RCS/wmap2ps.c,v 1.0 92/09/05 18:06:07 dockhorn Exp Locker: dockhorn $";
  497. X
  498. X#define TEMPFILE "wmap2ps.tmp"
  499. X
  500. X#define Key(x) if (!(strcmp(argv[i],x)))
  501. X
  502. X
  503. X/* primitive prototyping */
  504. Xvoid hints();
  505. Xint main();
  506. Xshort rvalues();
  507. Xint check_arguments();
  508. X
  509. X/* print out the command line format */
  510. X
  511. Xvoid hints(void)
  512. X{
  513. X  fprintf(stderr,
  514. X          "\n\nwmap2ps [ -u unit     ]   /* one from { cm, in, pt }       */"
  515. X      "\n        [ -o x y      ]   /* lower left corner of image    */"
  516. X      "\n        [ -w width    ]   /* desired target width/height   */"
  517. X      "\n        [ -h height   ]   /* using the current unit        */"
  518. X      "\n        [ -nomercat   ]   /* don't use mercator projection */"
  519. X      "\n        [ -unconnect  ]   /* don't draw illegal connections*/"
  520. X      "\n        [ -showbbox   ]   /* draw the bounding box         */"
  521. X      "\n        [ -debug      ]   /* print additional information  */\n"
  522. X      "\nNOTES:  - If you specify both width and height this will result"
  523. X      "\n          in a change of the image ratio, i.e. a distortion."
  524. X      "\n        - default unit is cm"
  525. X      "\n        - default origin is 0 0"
  526. X      "\n        - default width is original width\n"
  527. X      "\nSee the manpage for more information.\n");
  528. X
  529. X  
  530. X}
  531. X
  532. X/* ok, ok, too many global variables, 
  533. X   but here speed is more important than style
  534. X   and I lose enough speed by letting the
  535. X   program act as a pipe            */
  536. X
  537. X#define BUFSIZE 80
  538. Xstatic int linecnt = 0;            /* number of lines read        */
  539. Xstatic short debug = 0;            /* several flags        */
  540. X
  541. Xstatic float minlong = 1e10,minlat = 1e10,   /* to compute bounding box     */
  542. X             maxlong = -1e10, maxlat = -1e10,
  543. X         miny = 1e10, maxy = -1e10;
  544. X
  545. Xstatic float llx = 0.0,lly = 0.0;       /* user desired object origin      */
  546. X
  547. Xstatic char *unitnames[] = { "cm" , "in" , "pt" };
  548. Xstatic float unitfacts[] = { 28.34646, 72.0, 1.0 };
  549. X
  550. X
  551. X
  552. X
  553. X/*
  554. X   read in two values from stdin.
  555. X   I use a procedure rather than fscanf to be able to cope with
  556. X   additional comments after the values, i.e. lines like
  557. X   -40.723 144.912 The World Digitized
  558. X   -40.781 144.891 Islands of Australia
  559. X   -40.801 144.896 Copyright 1986 John B. Allison
  560. X
  561. X   the returned value tells me whether I should break the line
  562. X   connection or not.
  563. X*/
  564. X
  565. X
  566. Xshort rvalues(ftmp,x,y,mercat)
  567. XFILE *ftmp;
  568. Xfloat *x;    /* longitude     */
  569. Xfloat *y;    /* latitude    */
  570. Xshort mercat;    /* do conversion?*/
  571. X{
  572. X  static unsigned char buf[BUFSIZE];        /* buffer for line read from file*/
  573. X  unsigned char c = (unsigned char) 0;    /* current char read        */
  574. X  unsigned char *tmp;
  575. X  float latitude,longitude;
  576. X  short idx = 0;
  577. X
  578. X  c = fgetc(stdin);
  579. X  while ((!(feof(stdin))) && (c != '\n') && (idx < BUFSIZE))
  580. X    {
  581. X      buf[idx++] = c;
  582. X      c = (unsigned char) fgetc(stdin);
  583. X    }
  584. X  
  585. X  /* separator line ? */
  586. X  while ((idx > 0) && 
  587. X     ((buf[idx-1] == ' ') || 
  588. X      (buf[idx-1] == '\011') ||
  589. X      (buf[idx-1] == '\015')))
  590. X    buf[--idx] = (unsigned char) 0;
  591. X
  592. X  if (!(feof(stdin)))
  593. X    {
  594. X      linecnt++;
  595. X      if (!(idx < BUFSIZE))
  596. X    fprintf(stderr,"\nSorry, line %d is too long.",linecnt);
  597. X      else
  598. X    {
  599. X      if (idx == 0) return(0);    /* break line connection */
  600. X      buf[idx] = (unsigned char) 0;
  601. X      tmp = &buf[0];
  602. X      /* discard any control characters at the beginning of the buffer */
  603. X      while ((*tmp) && (*tmp < ' ')) tmp++;
  604. X      sscanf(tmp,"%g %g",&latitude,&longitude);
  605. X
  606. X      if (latitude < miny) miny = latitude;
  607. X      if (latitude > maxy) maxy = latitude;
  608. X
  609. X      if (mercat)
  610. X        {
  611. X          /*  too close to pole -> don't project */
  612. X          if (!((fabs(latitude-90.0) < 1) ||  
  613. X            (fabs(latitude-270.0) < 1)))
  614. X        latitude = (float) log(tan((45.0 + 
  615. X                        0.5*(double)latitude)*M_PI/180.0));
  616. X        }
  617. X
  618. X      /* bounding box changed ? */
  619. X      if (longitude < minlong) minlong = longitude;
  620. X      if (longitude > maxlong) maxlong = longitude;
  621. X      if (latitude < minlat) minlat = latitude;
  622. X      if (latitude > maxlat) maxlat = latitude;
  623. X
  624. X      /* control output            */
  625. X      if ((debug) && ((linecnt % 200) == 0))
  626. X        {
  627. X          fputc('.',stderr);
  628. X          fflush(stderr);
  629. X        }
  630. X
  631. X      /* if there is a comment, print it to the output file */
  632. X      tmp = &buf[0];
  633. X      while ((*tmp) && (!(((*tmp >= 'a') && (*tmp <= 'z')) ||
  634. X                  ((*tmp >= 'A') && (*tmp <= 'Z'))))) tmp++;
  635. X
  636. X      *y = latitude;
  637. X      *x = longitude;
  638. X
  639. X
  640. X      if (*tmp)
  641. X        {
  642. X          fprintf(ftmp,"\n%% %s",tmp);
  643. X          return(2);    /* comment encountered */
  644. X        }
  645. X    }
  646. X    }
  647. X  return(1);
  648. X}
  649. X
  650. X/*
  651. X   parse command line arguments
  652. X*/
  653. X
  654. Xint check_arguments(argc,argv,
  655. X            p_unitstr,p_unitfactor,
  656. X            p_width,p_height,
  657. X            p_mercat,p_unconnect,
  658. X            p_showbox,p_drawsegs)
  659. Xint argc;
  660. Xchar *argv[];
  661. Xchar **p_unitstr;
  662. Xfloat *p_unitfactor;
  663. Xfloat *p_width;
  664. Xfloat *p_height;
  665. Xshort *p_mercat;
  666. Xshort *p_unconnect;
  667. Xshort *p_showbox;
  668. Xshort *p_drawsegs;
  669. X{
  670. X  int i,j;
  671. X  short hit;
  672. X
  673. X  /* check for command line params */
  674. X  for (i = 1 ; i < argc ; i++)
  675. X    {
  676. X      if (*argv[i] != '-')
  677. X    {
  678. X      fprintf(stderr,
  679. X          "\nUnknown command line argument '%s' - abort.",
  680. X          argv[i]);
  681. X      hints();
  682. X      return(-1);
  683. X    }
  684. X      else
  685. X    switch(*(argv[i]+1))
  686. X      {
  687. X      case 'u':
  688. X        if (!(strcmp(argv[i]+1,"unconnect"))) *p_unconnect = 1;
  689. X        else
  690. X          {
  691. X        if (*(argv[i]+2) != (char) 0)
  692. X          {
  693. X            fprintf(stderr,
  694. X                "\nUnknown option '%s' - maybe '-u' was intended.",
  695. X                argv[i]);
  696. X            hints();
  697. X            return(-1); 
  698. X          }
  699. X        
  700. X        i++;
  701. X        for (j = 0 , hit = 0; j < 3 ; j++)
  702. X          {
  703. X            Key(unitnames[j])
  704. X              {
  705. X            hit = 1;
  706. X            *p_unitstr = &unitnames[j][0];
  707. X            *p_unitfactor = unitfacts[j];
  708. X              }
  709. X          }
  710. X        
  711. X        if (!(hit))
  712. X          {
  713. X            fprintf(stderr,"\nUnknown unit '%s' requested.",argv[i]);
  714. X            hints();
  715. X            return(-1);
  716. X          }
  717. X          }
  718. X        break;
  719. X
  720. X      case 'w' :
  721. X      case 'W':
  722. X        if (*(argv[i]+2) != (char) 0)
  723. X          {
  724. X        fprintf(stderr,
  725. X            "\nUnknown option '%s' - maybe '-w' was intended.",
  726. X            argv[i]);
  727. X        hints();
  728. X        return(-1); 
  729. X          }
  730. X
  731. X        if ((i+1) < argc)
  732. X          sscanf(argv[++i],"%g",p_width);
  733. X        else
  734. X          {
  735. X        fprintf(stderr,"\nMissing value after -w option - abort.");
  736. X        hints();
  737. X        return(-1);
  738. X          }
  739. X        break;
  740. X
  741. X      case 'h' :
  742. X      case 'H':
  743. X        if (*(argv[i]+2) != (char) 0) 
  744. X          {
  745. X        fprintf(stderr,
  746. X            "\nUnknown option '%s' - maybe '-w' was intended.",
  747. X            argv[i]);
  748. X        hints();
  749. X        return(-1); 
  750. X          };
  751. X          
  752. X        if ((i+1) < argc)
  753. X          sscanf(argv[++i],"%g",p_height);
  754. X        else
  755. X          {
  756. X        fprintf(stderr,"\nMissing value after -h option - abort.");
  757. X        hints();
  758. X        return(-1);
  759. X          }
  760. X        break;
  761. X
  762. X      case 'n':
  763. X        if (!(strcmp(argv[i]+1,"nomercat"))) *p_mercat = 0;        
  764. X        else
  765. X          {
  766. X        fprintf(stderr,
  767. X            "\nUnknown option '%s' - maybe '-nomercat' was intended.",
  768. X            argv[i]);
  769. X        hints();
  770. X        return(-1); 
  771. X          };
  772. X        break;
  773. X
  774. X      case 's':
  775. X        if (!(strcmp(argv[i]+1,"showbox"))) *p_showbox = 1;        
  776. X        else
  777. X          {
  778. X        fprintf(stderr,
  779. X            "\nUnknown option '%s' - maybe '-showbox' was intended.",
  780. X            argv[i]);
  781. X        hints();
  782. X        return(-1); 
  783. X          };
  784. X        break;
  785. X
  786. X      case 'd':
  787. X        if (!(strcmp(argv[i]+1,"debug"))) debug = 1;
  788. X        else
  789. X          {
  790. X        if (!(strcmp(argv[i]+1,"drawsegs")))
  791. X          *p_drawsegs = 1;
  792. X        else
  793. X          {
  794. X            fprintf(stderr,
  795. X                "\nUnknown option '%s'"
  796. X                "\n - maybe '-debug' or '-drawsegs' have been intended.",
  797. X                argv[i]);
  798. X            hints();
  799. X            return(-1);
  800. X          }
  801. X          }
  802. X          
  803. X        break;
  804. X
  805. X      case 'o':
  806. X        if (*(argv[i]+2) != (char) 0) 
  807. X          {
  808. X        fprintf(stderr,
  809. X            "\nUnknown option '%s' - maybe '-o' was intended.",
  810. X            argv[i]);
  811. X        hints();
  812. X        return(-1); 
  813. X          }
  814. X        else
  815. X          {
  816. X        if ((i+2) < argc)    /* arguments given ? */
  817. X          {
  818. X            sscanf(argv[++i],"%g",&llx);
  819. X            sscanf(argv[++i],"%g",&lly);
  820. X          }
  821. X        else
  822. X          {
  823. X            fprintf(stderr,
  824. X                "\nMissing values after '-o' - abort.");
  825. X            hints();
  826. X            return(-1);
  827. X          }
  828. X          }
  829. X        break;
  830. X
  831. X        default :
  832. X          fprintf(stderr,
  833. X              "\nUnknown command line argument '%s' - abort.",
  834. X              argv[i]);
  835. X        hints();
  836. X        return(-1);
  837. X        
  838. X      }    /* end switch */
  839. X    }    /* end loop over command line options */
  840. X
  841. X  return(0);
  842. X  /* ------------------ end of command line parsing------------------- */
  843. X}    /* end check_arguments()    */
  844. X
  845. X
  846. X/***********************************************************************/
  847. X/***********************************************************************/
  848. X/*            M    A    I    N               */
  849. X/***********************************************************************/
  850. X/***********************************************************************/
  851. X   
  852. Xint main(argc, argv)
  853. Xint argc;
  854. Xchar *argv[];
  855. X{
  856. X  /* ============================= VARIABLES ========================== */
  857. X
  858. X  float y,x,lx,ly;            /* temporary location variables */
  859. X  float bwidth,bheight,blat;        /* natural object size        */
  860. X  float width = -1.0, height = -1.0;    /* user desired object size    */
  861. X
  862. X  char *unitstr = unitnames[0];
  863. X  float unitfactor = unitfacts[0];
  864. X
  865. X  short mercat = 1, showbox = 0, status, 
  866. X        oldstatus = 0, drawsegs = 0, unconnect = 0;
  867. X  short isdrawn;
  868. X
  869. X  FILE *ftmp = fopen(TEMPFILE,"w");    /* handle for temporary file    */
  870. X
  871. X  char c;
  872. X
  873. X  /* possible units and their conversion values    */
  874. X
  875. X  /* =============================== CODE ============================= */
  876. X
  877. X  if (check_arguments(argc,argv,
  878. X              &unitstr,&unitfactor,
  879. X              &width,&height,
  880. X              &mercat,&unconnect,
  881. X              &showbox,&drawsegs)) return(-1);
  882. X
  883. X  llx*=unitfactor;  /* convert origin to current unit    */
  884. X  lly*=unitfactor;
  885. X
  886. X  /* read stdin and write the data to a temporary 
  887. X     file while looking for the bounding box    */
  888. X
  889. X  if (ftmp == (FILE *) NULL)
  890. X    {
  891. X      fprintf(stderr,
  892. X          "\nCouldn't open temporary file %s for writing - abort.\n",
  893. X          TEMPFILE);
  894. X      return(-1);
  895. X    }
  896. X
  897. X
  898. X  if (debug)
  899. X    {
  900. X      fprintf(stderr,
  901. X          mercat ? "\nUsing mercator projection." : "\nNo projection.");
  902. X      fprintf(stderr,"\nscanning");
  903. X    }
  904. X
  905. X  /* -------------------------- conversion --------------------------- */
  906. X  
  907. X  rvalues(ftmp,&lx,&ly,mercat);
  908. X  fprintf(ftmp,"\n%g %g M",lx,ly);
  909. X
  910. X  while (!(feof(stdin)))
  911. X    {
  912. X      status = rvalues(ftmp,&x,&y,mercat);
  913. X      isdrawn = 0;
  914. X
  915. X      if ((status == 2) && (oldstatus == 1))
  916. X    {
  917. X      fprintf(stderr,
  918. X        "\nWarning ! I found a comment in line %d of the input file"
  919. X        "\n          but no separator line before it. This might"
  920. X        "\n          result in a line that interconnects different maps.\n",
  921. X        linecnt);
  922. X      if (unconnect)
  923. X        {
  924. X          fprintf(stderr,
  925. X              "As you gave the '-unconnect' option, I'll break the line here.\n");
  926. X          fprintf(ftmp,"\n%g %g M",x,y);
  927. X          isdrawn = 1;
  928. X          status = 0;
  929. X        }
  930. X      else
  931. X        fprintf(stderr,
  932. X            "You should check the file or specify the '-unconnect' option.\n");
  933. X    }
  934. X
  935. X      /* a blank line means break line connection */
  936. X      
  937. X      if (status)
  938. X    fprintf(ftmp,"\n%g %g L",lx,ly,x,y);
  939. X      else
  940. X    {
  941. X      if (!(isdrawn))
  942. X        {
  943. X          while (!(status))
  944. X        {
  945. X          status = rvalues(ftmp,&x,&y,mercat);    /* scan next starting point */
  946. X          if ((debug) && (!(status)))
  947. X            fprintf(stderr,"\nMultiple separators in line %d.\n",linecnt);
  948. X        }
  949. X          fprintf(ftmp,"\n%g %g M",x,y);
  950. X        }
  951. X    }
  952. X      lx = x; ly = y;
  953. X      oldstatus = status;
  954. X    }
  955. X
  956. X  fclose(ftmp);
  957. X
  958. X  /* -------------------------- computation --------------------------- */
  959. X
  960. X  bwidth = maxlong - minlong;    /* extents before scaling */
  961. X  bheight = maxy - miny;
  962. X  blat = maxlat - minlat;
  963. X
  964. X  /* if neither -w nor -h was given, use original size */
  965. X
  966. X  if ((height < 0.0) && (width < 0.0))
  967. X    {
  968. X      height = bheight;
  969. X      width = bwidth;
  970. X      unitfactor = 1.0;
  971. X    }
  972. X  else
  973. X    {
  974. X      if (height > 0.0)
  975. X    {
  976. X      /* compute width from desired height and object size */
  977. X      height*=unitfactor;
  978. X      if (width < 0.0)    /* preserve ratio */
  979. X        width = bwidth*height/bheight;
  980. X      else
  981. X        width*=unitfactor;    /* ok, that's what you wanted    */
  982. X    }
  983. X      else
  984. X    {
  985. X      /* compute height from desired width and object size */
  986. X      width*=unitfactor;
  987. X      height = bheight*width/bwidth;
  988. X    }
  989. X    }
  990. X
  991. X if (debug)
  992. X    fprintf(stderr,
  993. X        "\n\nNumber of data points        = %d"              
  994. X        "\nSelected unit                = %s"
  995. X        "\nBounding Box of given object = %6.1f %6.1f %6.1f %6.1f"
  996. X        "\nNatural size of object       = %6.1f x %6.1f points"
  997. X        "\nScaling factors              = %6.1f   %6.1f"
  998. X        "\nSize of object after scaling = %6.1f x %6.1f points"
  999. X        "\n                             = %6.1f x %6.1f inches"
  1000. X        "\n                             = %6.1f x %6.1f cm"
  1001. X        "\nDesired origin               = %6.1f , %6.1f points"
  1002. X        "\n                             = %6.1f , %6.1f inches"
  1003. X        "\n                             = %6.1f , %6.1f cm\n\n",
  1004. X        linecnt,
  1005. X        unitstr,
  1006. X        minlong,minlat,maxlong,maxlat,
  1007. X        bwidth,blat,
  1008. X        width/bwidth,height/blat,
  1009. X        width,height,
  1010. X        width/72.0,height/72.0,
  1011. X        width/28.34646,height/28.34646,
  1012. X        llx,lly,
  1013. X        llx/72.0,lly/72.0,
  1014. X        llx/28.34646,lly/28.34646);
  1015. X
  1016. X  /* write prologue */
  1017. X
  1018. X  fprintf(stdout,
  1019. X      "%%!PS-Adobe-2.0 EPSF-2.0"
  1020. X      "\n%%%%Title: (unknown)"
  1021. X      "\n%%%%Creator: wmap2ps by Patrick Dockhorn - WORLDMAP data (C) 1986 John B. Allison"
  1022. X      "\n%%%%BoundingBox: %g %g %g %g"
  1023. X      "\n%%%%Pages: 1"
  1024. X      "\n%%%%DocumentFonts:"
  1025. X      "\n%%%%EndComments"
  1026. X      "\n%%%%EndProlog\n"
  1027. X      "\n%% remember original state"
  1028. X      "\n/origstate save def\n"
  1029. X      "\n%% build a temporary dictionary"
  1030. X      "\n20 dict begin\n"
  1031. X      "\n%% scale to size desired by user"
  1032. X      "\n%% (%g x %g points ="
  1033. X      "\n%%  %g x %g inches ="
  1034. X      "\n%%  %g x %g centimeter)"
  1035. X      "\n%g %g scale\n"
  1036. X      "\n%% set color to black and select thinnest line\n"
  1037. X      "\n0 setlinewidth 0 setgray\n\n"
  1038. X      "\n%c newpath %g %g moveto %g 0 rlineto %% show bounding box"
  1039. X      "\n%c 0 %g rlineto %g 0 rlineto closepath stroke\n"
  1040. X      "\n%% lower left corner"
  1041. X      "\n%g %g translate\n"
  1042. X      "\n/M {%smoveto } def"
  1043. X      "\n/L { lineto%s} def\n",
  1044. X      llx,lly,llx+width,lly+height,
  1045. X      width,height,
  1046. X      width/72.0,height/72.0,
  1047. X      width/28.34646,height/28.34646,
  1048. X      width/bwidth,height/blat,
  1049. X      showbox ? ' ' : '%',
  1050. X      (llx*bwidth/width),
  1051. X      (lly*blat/height),bwidth,
  1052. X      showbox ? ' ' : '%',
  1053. X      blat,-1.0*bwidth,
  1054. X      (llx*bwidth/width)-minlong,
  1055. X      (lly*blat/height)-minlat,
  1056. X      drawsegs ? " newpath " : " ",
  1057. X      drawsegs ? " currentpoint stroke moveto " : " ");
  1058. X
  1059. X
  1060. X
  1061. Xif ((ftmp = fopen(TEMPFILE,"r")) == (FILE *) NULL)
  1062. X    {
  1063. X      fprintf(stderr,
  1064. X          "\nCouldn't open temporary file %s for reading - abort.\n",
  1065. X          TEMPFILE);
  1066. X      return(-1);
  1067. X    }
  1068. X  
  1069. X  /* copy from temporary file to stdout */
  1070. X
  1071. X  c = fgetc(ftmp);
  1072. X  while (!(feof(ftmp)))
  1073. X    {
  1074. X      fputc(c,stdout);
  1075. X      c = fgetc(ftmp);
  1076. X    }
  1077. X
  1078. X  /* write closing */
  1079. X
  1080. X  fprintf(stdout,
  1081. X      "%sshowpage"
  1082. X      "\n%% stop using temporary dictionary"
  1083. X      "\nend\n"
  1084. X      "\n%% restore original state"
  1085. X      "\norigstate restore"
  1086. X      "\n\n%%%%Trailer\n",
  1087. X      drawsegs ? "\n" : "\nstroke\n");
  1088. X
  1089. X  unlink(TEMPFILE);    /* remove temporary file */
  1090. X  return(0);
  1091. X}    /* end main */
  1092. END_OF_FILE
  1093.   if test 19844 -ne `wc -c <'wmap2ps.c'`; then
  1094.     echo shar: \"'wmap2ps.c'\" unpacked with wrong size!
  1095.   fi
  1096.   # end of 'wmap2ps.c'
  1097. fi
  1098. echo shar: End of archive 1 \(of 1\).
  1099. cp /dev/null ark1isdone
  1100. MISSING=""
  1101. for I in 1 ; do
  1102.     if test ! -f ark${I}isdone ; then
  1103.     MISSING="${MISSING} ${I}"
  1104.     fi
  1105. done
  1106. if test "${MISSING}" = "" ; then
  1107.     echo You have the archive.
  1108.     rm -f ark[1-9]isdone
  1109. else
  1110.     echo You still must unpack the following archives:
  1111.     echo "        " ${MISSING}
  1112. fi
  1113. exit 0
  1114. exit 0 # Just in case...
  1115.