home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / sources / misc / 3925 < prev    next >
Encoding:
Text File  |  1992-09-11  |  31.3 KB  |  1,122 lines

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