Article View: comp.lang.postscript
Article #1877wmap2ps - WorldMap goes PostScript
From: Patrick Dockhorn
Date: Sun, 06 Sep 1992 14:29
Date: Sun, 06 Sep 1992 14:29
1318 lines
38937 bytes
38937 bytes
WHAT IS wmap2ps ?
=================
wmap2ps converts map files (MP1 format) from John B. Allisons
'The World Digitized' package to EPSF 2.0 conforming
PostScript files. The latitude is usually projected using the
mercator projection and the resulting figure may be scaled and
positioned to the needs of the user.
The MP1 format is described in the header of wmap2ps.c
THE WORLD DIGITIZED:
====================
The 'Digital World' data can be found on several
servers around the world; you might want to query
archie for 'worldmap' or get the data for example from
nz20.rz.uni-karlsruhe.de
in
/pub/msdos/worldmap
COPYLEFT
========
wmap2ps is in the Public Domain. You may use, copy and distribute
it freely, as long as the README file is kept intact.
On the contrary, the MP1 files you need to let it do something useful
are not. I suggest that you send a donation of $20 to the author of
'The World Digitized', John B. Allison. His address is
The World Digitized
Dept. PC SIG
166 Shady Lane
Apollo, PA 15613
have fun
Patsch
-----------------------------------------------------------------------------
Patrick Dockhorn Forschungszentrum Informatik, Karlsruhe/Germany.
INTERNET: dockhorn@fzi.de There are two rules for success in life:
BITNET : ukew@dkauni2.bitnet Rule 1: Don't tell people everything you know.
-----------------------------------------------------------------------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: WMAP2PS WMAP2PS/README WMAP2PS/Makefile WMAP2PS/wmap2ps.1
# WMAP2PS/wmap2ps.man WMAP2PS/wmap2ps.c
# Wrapped by dockhorn@prag on Sun Sep 6 16:13:58 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d 'WMAP2PS' ; then
echo shar: Creating directory \"'WMAP2PS'\"
mkdir 'WMAP2PS'
fi
if test -f 'WMAP2PS/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'WMAP2PS/README'\"
else
echo shar: Extracting \"'WMAP2PS/README'\" \(2480 characters\)
sed "s/^X//" >'WMAP2PS/README' <<'END_OF_FILE'
XFILES
X=====
X
XYou should have the following files:
X
XREADME - that's me
Xwmap2ps.c - C source
Xwmap2ps.1 - man page
Xwmap2ps.man - nroff'ed, i.e. human readable man page
XMakefile - genmake generated makefile to build wmap2ps
X
X
XWHAT IS wmap2ps ?
X=================
X
Xwmap2ps converts map files (MP1 format) from John B. Allisons
X'The World Digitized' package to EPSF 2.0 conforming
XPostScript files. The latitude is usually projected using the
Xmercator projection and the resulting figure may be scaled and
Xpositioned to the needs of the user.
XThe MP1 format is described in the header of wmap2ps.c
X
X
XHOW TO BUILD wmap2ps ?
X======================
X
XThe Makefile was created using Edwin R. Carp's 'genmake' - nice program !
XTo build wmap2ps simply do a 'make', provided that you have gcc installed.
XOtherwise you'll need to change the CC macro in the makefile.
X
XThe program was developed using gcc and SunOS 4.1,
Xbut there should be no problems in porting it to other platforms.
X
X
XPROBLEMS:
X=========
X
XI used old style function declarations and simple prototypes
Xso the worst thing will be the strings that exceed one line, i.e.
Xfprintf(stdout,"blablabla"
X "blubbblubbblubb"
X "yupyupyup");
XI know that there are compilers that do not support this feature,
Xbut it should be no problem to work around it.
X
X
X
XTHE WORLD DIGITIZED:
X====================
X
XThe 'Digital World' data can be found on several
Xservers around the world; you might want to query
Xarchie for 'worldmap' or get the data for example from
X
Xnz20.rz.uni-karlsruhe.de
Xin
X/pub/msdos/worldmap
X
XIf you decide to go there, you'll need the arc utility to extract the maps.
X
Xwmap2ps is in the Public Domain. You may use, copy and distribute it freely,
Xas long as this README file is kept intact.
XOn the contrary, the MP1 files you need to let it do something useful are not.
XI suggest that you send a donation of $20 to the author of
X'The World Digitized', John B. Allison. His address is
X
XThe World Digitized
XDept. PC SIG
X166 Shady Lane
XApollo, PA 15613
X
X
XSTILL READING ?
X===============
X
XThe reason for writing this program was the need of a map of Tassie -
Xwell, I can promise that it is AT LEAST able to solve this problem.
X
XAny suggestions, bug reports etc. should be directed to dockhorn@fzi.de
XAs this address is subject to change, do a
Xfinger dockhorn@keemun.fzi.de
Xor
Xfinger dockhorn@141.21.4.77
Xif your mail is not answered within a week.
XI'll leave my new mail address in the finger info.
X
X have fun
X
X Patsch
END_OF_FILE
if test 2480 -ne `wc -c <'WMAP2PS/README'`; then
echo shar: \"'WMAP2PS/README'\" unpacked with wrong size!
fi
# end of 'WMAP2PS/README'
fi
if test -f 'WMAP2PS/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'WMAP2PS/Makefile'\"
else
echo shar: Extracting \"'WMAP2PS/Makefile'\" \(1299 characters\)
sed "s/^X//" >'WMAP2PS/Makefile' <<'END_OF_FILE'
X#
X# Makefile generated with genmake - version 1.1 08/22/92
X#
X# genmake is Copyright 1991 by Edwin R. Carp
X#
X# GENMAKE [files]
X#
X
XCC = gcc -O
XCFLAGS = $(INCLUDE)
XSOURCES = wmap2ps
XOBJECTS = wmap2ps.o
XPROGRAMS = wmap2ps
X
Xall: $(PROGRAMS)
X
Xwmap2ps: wmap2ps.o
X $(CC) $(CFLAGS) -o wmap2ps wmap2ps.o $(LDFLAGS) -lm -O
X
Xclean:
X /bin/rm -f $(OBJECTS) MAKELOG eddep makedep
X
Xclobber:
X /bin/rm -f $(OBJECTS) $(PROGRAMS) MAKELOG eddep makedep *~ *.bak *.BAK
Xhidden:
X echo "make all > MAKELOG 2>&1 &"|/bin/sh
X
Xmakefile:
X genmake $(SOURCES) &
X
Xmakeall:
X genmake *.c &
X
X
Xdepend:
X $(CC) -M ${INCLUDES} ${SOURCES} | \
X awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
X else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
X else rec = rec " " $$2 } } \
X END { print rec } ' > makedep
X echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
X echo '$$r makedep' >>eddep
X echo 'w' >>eddep
X cp Makefile Makefile.bak
X cat eddep | ed - Makefile
X rm eddep makedep
X echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
X echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
X echo '# see make depend above' >> Makefile
X
X# DO NOT DELETE THIS LINE -- make depend uses it
X
X
X# DEPENDENCIES MUST END AT END OF FILE
X# IF YOU PUT STUFF HERE IT WILL GO AWAY
X# see make depend above
END_OF_FILE
if test 1299 -ne `wc -c <'WMAP2PS/Makefile'`; then
echo shar: \"'WMAP2PS/Makefile'\" unpacked with wrong size!
fi
# end of 'WMAP2PS/Makefile'
fi
if test -f 'WMAP2PS/wmap2ps.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'WMAP2PS/wmap2ps.1'\"
else
echo shar: Extracting \"'WMAP2PS/wmap2ps.1'\" \(3535 characters\)
sed "s/^X//" >'WMAP2PS/wmap2ps.1' <<'END_OF_FILE'
X.TH WMAP2PS 1
X.SH NAME
Xwmap2ps \- convert a worldmap file to PostScript
X.SH SYNOPSIS
X.B wmap2ps [ -u unit ]
X.nf
X [ -o x y ]
X.nf
X [ -w width ]
X.nf
X [ -h height ]
X.nf
X [ -nomercat ]
X.nf
X [ -unconnect ]
X.nf
X [ -drawsegs ]
X.nf
X [ -showbox ]
X.nf
X [ -debug ]
X.sp
X.SH DESCRIPTION
X.I wmap2ps
Xconverts map files (MP1 format) from the
X.I Digitized World
Xpackage by John B. Allison to an EPSF 2.0 conforming
X.B PostScript
Xfile. This is done by reading map data from stdin and piping
Xthe resulting PostScript code to stdout, taking user desired
Xscaling and change of origin into account. The problem of
Xmapping a three-dimensional surface to a two-dimensional plane
Xis handled using the mercator projection, if this is desired.
XUsing this transformation, distortions at extreme latitudes are
Xavoided.
X.SH OPTIONS
X.TP
X.B \-u unit
Xdefines the unit in which the other scalar values will be given.
XThe default is
X.I cm
X, other possible values are
X.I pt
Xor
X.I in
X.TP
X.B \-o x y
XSets the origin of the figure. The values are given in the current unit,
Xdefault is the lower left corner of the page.
X.TP
X.B \-w width
XSpecify the desired width of the figure using the current unit.
X.TP
X.B \-h height
XSpecify the desired height of the figure using the current unit. Only one
Xof -h and -w may be used so that the original image ratio is preserved.
XIf neither -w nor -h is given, the image is left in its original size.
X.TP
X.B \-nomercat
XDon't use mercator projection. You may still achieve nice pictures if
Xyour favourite country is close to the equator.
X.TP
X.B \-unconnect
XThe MP1 files include comments, usually to give some information about the
Xarea that is described by the following data. If one concatenates several
Xmaps to form a bigger one, this may result in lines that interconnect the
Xpreviously separate maps. If the maps are described by comments, wmap2ps
Xis able to detect such interconnection points and, if you specify this
Xoption, unconnects them.
X.TP
X.B \-drawsegs
XUsually the lines drawn are stroked when the map is completed.
XBut if your PostScript device is not able to handle all the
Xline segments at once, i.e. you get an error message like
X.nf
X%%[ Error: limitcheck; OffendingCommand: lineto ]%%
X.nf
X%%[ Flushing: rest of job (to end-of-file) will be ignored ]%%
X.nf
Xyou can force the program to stroke every single segment
Ximmediately after it is drawn by giving it this option.
X.TP
X.B \-showbox
XThe bounding box of the figure is drawn too.
X.TP
X.B \-debug
XWrite some additional information to stderr.
X.SH EXAMPLES
Xcat AU?.MP1 | wmap2ps -unconnect -o 1 1 -w 6 > au.ps
X
XThis would create a PostScript file that draws
Xthe map of Australia, its seas and its islands
Xwith an origin that lies 1 cm to the right and 1 cm
Xabove the lower left corner of the page. The mercator
Xprojection will be used and the resulting picture is
Xscaled so that it's exactly 6 cm wide.
X
X.SH BUGS
XIf, like in the above example, several map files are
Xconcatenated, the
Xresulting
X.B PostScript
Xfile may include visible lines that connect the partial maps.
XTo fix this bug, simply add a separator line (blank line)
Xat the end of the map files. If possible, wmap2ps detects
Xsuch problems and offers help through the '-unconnect' option.
X.SH FILES
Xwmap2ps.tmp - temporary, needed as wmap2ps acts as a pipe
X.SH AUTHOR
XPatrick Dockhorn (dockhorn@fzi.de).
X.nf
XForschungszentrum Informatik, Karlsruhe, Germany.
X.nf
X(Address is subject to change, do a 'finger dockhorn@keemun.fzi.de'
X.nf
Xto find out about the author's present address)
X
END_OF_FILE
if test 3535 -ne `wc -c <'WMAP2PS/wmap2ps.1'`; then
echo shar: \"'WMAP2PS/wmap2ps.1'\" unpacked with wrong size!
fi
# end of 'WMAP2PS/wmap2ps.1'
fi
if test -f 'WMAP2PS/wmap2ps.man' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'WMAP2PS/wmap2ps.man'\"
else
echo shar: Extracting \"'WMAP2PS/wmap2ps.man'\" \(4531 characters\)
sed "s/^X//" >'WMAP2PS/wmap2ps.man' <<'END_OF_FILE'
X
X
X
XWMAP2PS(1) USER COMMANDS WMAP2PS(1)
X
X
X
XNAME
X wmap2ps - convert a worldmap file to PostScript
X
XSYNOPSIS
X wmap2ps [ -u unit ]
X [ -o x y ]
X [ -w width ]
X [ -h height ]
X [ -nomercat ]
X [ -unconnect ]
X [ -drawsegs ]
X [ -showbox ]
X [ -debug ]
X
X
XDESCRIPTION
X wmap2ps converts map files (MP1 format) from the Digitized
X World package by John B. Allison to an EPSF 2.0 conforming
X PostScript file. This is done by reading map data from stdin
X and piping the resulting PostScript code to stdout, taking
X user desired scaling and change of origin into account. The
X problem of mapping a three-dimensional surface to a two-
X dimensional plane is handled using the mercator projection,
X if this is desired. Using this transformation, distortions
X at extreme latitudes are avoided.
X
XOPTIONS
X -u unit
X defines the unit in which the other scalar values will
X be given. The default is cm , other possible values
X are pt or in
X
X -o x y
X Sets the origin of the figure. The values are given in
X the current unit, default is the lower left corner of
X the page.
X
X -w width
X Specify the desired width of the figure using the
X current unit.
X
X -h height
X Specify the desired height of the figure using the
X current unit. Only one of -h and -w may be used so that
X the original image ratio is preserved. If neither -w
X nor -h is given, the image is left in its original
X size.
X
X -nomercat
X Don't use mercator projection. You may still achieve
X nice pictures if your favourite country is close to the
X equator.
X
X
X
XSun Release 4.1 Last change: 1
X
X
X
X
X
X
XWMAP2PS(1) USER COMMANDS WMAP2PS(1)
X
X
X
X -unconnect
X The MP1 files include comments, usually to give some
X information about the area that is described by the
X following data. If one concatenates several maps to
X form a bigger one, this may result in lines that inter-
X connect the previously separate maps. If the maps are
X described by comments, wmap2ps is able to detect such
X interconnection points and, if you specify this option,
X unconnects them.
X
X -drawsegs
X Usually the lines drawn are stroked when the map is
X completed. But if your PostScript device is not able
X to handle all the line segments at once, i.e. you get
X an error message like
X %%[ Error: limitcheck; OffendingCommand: lineto ]%%
X %%[ Flushing: rest of job (to end-of-file) will be ignored ]%%
X you can force the program to stroke every single segment
X immediately after it is drawn by giving it this option.
X
X -showbox
X The bounding box of the figure is drawn too.
X
X -debug
X Write some additional information to stderr.
X
XEXAMPLES
X cat AU?.MP1 | wmap2ps -unconnect -o 1 1 -w 6 > au.ps
X
X This would create a PostScript file that draws the map of
X Australia, its seas and its islands with an origin that lies
X 1 cm to the right and 1 cm above the lower left corner of
X the page. The mercator projection will be used and the
X resulting picture is scaled so that it's exactly 6 cm wide.
X
X
XBUGS
X If, like in the above example, several map files are con-
X catenated, the resulting PostScript file may include visible
X lines that connect the partial maps. To fix this bug, simply
X add a separator line (blank line) at the end of the map
X files. If possible, wmap2ps detects such problems and offers
X help through the '-unconnect' option.
X
XFILES
X wmap2ps.tmp - temporary, needed as wmap2ps acts as a pipe
X
XAUTHOR
X Patrick Dockhorn (dockhorn@fzi.de).
X Forschungszentrum Informatik, Karlsruhe, Germany.
X (Address is subject to change, do a 'finger dockhorn@keemun.fzi.de'
X to find out about the author's present address)
X
X
X
XSun Release 4.1 Last change: 2
X
X
X
X
X
X
XWMAP2PS(1) USER COMMANDS WMAP2PS(1)
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
XSun Release 4.1 Last change: 3
X
X
X
X
X
X
END_OF_FILE
if test 4531 -ne `wc -c <'WMAP2PS/wmap2ps.man'`; then
echo shar: \"'WMAP2PS/wmap2ps.man'\" unpacked with wrong size!
fi
# end of 'WMAP2PS/wmap2ps.man'
fi
if test -f 'WMAP2PS/wmap2ps.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'WMAP2PS/wmap2ps.c'\"
else
echo shar: Extracting \"'WMAP2PS/wmap2ps.c'\" \(19844 characters\)
sed "s/^X//" >'WMAP2PS/wmap2ps.c' <<'END_OF_FILE'
X/*
X wmap2ps
X
X Description: converts files from the WORLDMAP package
X (MP1 format) by John B. Allison to PostScript
X
X The program expects input from stdin in WORLDMAP format
X as described below and writes a corresponding PostScript
X file to stdout.
X
X Written by Patsch in September 1992 (I needed the map of Tassie...)
X
X This program is in the Public Domain, as
X long as the README file is kept intact.
X
X =====================================================================
X
X Usage :
X
X wmap2ps [ -u unit ] %% one from { cm, in, pt }
X [ -o x y ] %% lower left corner of image
X [ -w width ] %% desired target width/height
X [ -h height ] %% using the current unit
X [ -nomercat ] %% don't use mercator projection
X [ -unconnect ] %% if multiple maps are concatenated
X %% this may be detected by the presence of
X %% a comment. if you activate this option,
X %% every block of comments that appears implies
X %% that the first pair of data points in the block
X %% should be treaten as the beginning of a new line.
X [ -showbox ] %% draw the bounding box
X [ -drawsegs ] %% do a 'stroke' after every line segment
X [ -debug ] %% print additional information
X
X NOTES: - If you specify both width and height this will result
X in a change of the image ratio, i.e. a distortion.
X - default unit is cm"
X - default origin is 0 0"
X - default width is original width\n"
X
X =====================================================================
X
X Compiled successfully on a SPARCstation running SunOS 4.1.1 with:
X gcc -O -o wmap2ps wmap2ps.c
X
X If you have problems compiling the program, you might need to change
X the lines where strings are concatenated over more than one line.
X I know that many compilers are not able to do that.
X
X =====================================================================
X
X .MP1 File Format: variable length ASCII records
X
X Data Records
X field
X 1 latitude floating point number
X
X 2 blank field separator
X
X 3 longitude floating point number
X
X [4] optional begining with a blank
X comment
X
X 5 line feed end of record (LF - 10)
X
X Separator Records
X field
X [1] optional blanks[s]
X
X 2 line feed end of record (LF - 10)
X
X
X All you have to do is
X - to draw a line from (x0,y0) to (x1,y1); the from (x1,y1) to (x2,y2) etc.
X - if a separator line (blank line) is read, break the connection,
X
X You may have noticed distortion in the maps displayed in the
X previous programs, epecially at extreme latitudes. This
X distortion is caused by an attempt to map the curved surface
X of a three dimensional globe onto a two dimensional plane. As
X you travel toward the poles, the 360 degrees of longitude are
X squeezed into less and less space on the globe, but not on the
X plane.
X
X There are many ways to compensate for the distortion problem.
X Probably the solution most widely recognized is the Mercator
X projection, named for a famous early map maker. Mercator's
X projection has the characteristics that both lines of latitude
X and longitude are straight and at right angles to each other
X (orthogonal). In addition, if a small area is viewed, there
X is no distortion of form: areas have the right shape although
X the vertical scale and total area is distorted as you move from
X the equator.
X
X The formula for the Mercator projection is
X
X y = ln{tan[45 deg + latitude/2)/deg_per_radian]}
X
X Check out the Encyclopedia Britannica under Map for all this
X good stuff and more.
X
X ========================================================================
X
X The data you may use with this tool can be found for example on host
X
X nz20.rz.uni-karlsruhe.de
X
X in the directory
X
X /pub/msdos/worldmap
X
X Just use archie and look for 'worldmap' in EXACT mode.
X
X
X =======================================================================
X
X As wmap2ps acts as a pipe, you may do the following
X
X cat AU0.MP1 AU1.MP1 AU2.MP1 | wmap2ps -unconnect -o 1 1 -w 6 > au.ps
X
X This would create a PostScript file that draws
X the map of Australia, its seas and its islands.
X
X If you glue together different maps in such a way, this may result in
X a map where the parts are connected by visible lines - to fix this
X problem you may want to add an extra separator line (blank line)
X at the end of the map files.
X
X =====================================================================
X cookies to RCS
X =====================================================================
X
X $Author: dockhorn $
X $Revision: 1.0 $
X $Log: wmap2ps.c,v $
X * Revision 1.0 92/09/05 18:06:07 dockhorn
X * Initial revision
X *
X*/
X
X#include <stdio.h>
X#include <math.h>
X
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 $";
X
X#define TEMPFILE "wmap2ps.tmp"
X
X#define Key(x) if (!(strcmp(argv[i],x)))
X
X
X/* primitive prototyping */
Xvoid hints();
Xint main();
Xshort rvalues();
Xint check_arguments();
X
X/* print out the command line format */
X
Xvoid hints(void)
X{
X fprintf(stderr,
X "\n\nwmap2ps [ -u unit ] /* one from { cm, in, pt } */"
X "\n [ -o x y ] /* lower left corner of image */"
X "\n [ -w width ] /* desired target width/height */"
X "\n [ -h height ] /* using the current unit */"
X "\n [ -nomercat ] /* don't use mercator projection */"
X "\n [ -unconnect ] /* don't draw illegal connections*/"
X "\n [ -showbbox ] /* draw the bounding box */"
X "\n [ -debug ] /* print additional information */\n"
X "\nNOTES: - If you specify both width and height this will result"
X "\n in a change of the image ratio, i.e. a distortion."
X "\n - default unit is cm"
X "\n - default origin is 0 0"
X "\n - default width is original width\n"
X "\nSee the manpage for more information.\n");
X
X
X}
X
X/* ok, ok, too many global variables,
X but here speed is more important than style
X and I lose enough speed by letting the
X program act as a pipe */
X
X#define BUFSIZE 80
Xstatic int linecnt = 0; /* number of lines read */
Xstatic short debug = 0; /* several flags */
X
Xstatic float minlong = 1e10,minlat = 1e10, /* to compute bounding box */
X maxlong = -1e10, maxlat = -1e10,
X miny = 1e10, maxy = -1e10;
X
Xstatic float llx = 0.0,lly = 0.0; /* user desired object origin */
X
Xstatic char *unitnames[] = { "cm" , "in" , "pt" };
Xstatic float unitfacts[] = { 28.34646, 72.0, 1.0 };
X
X
X
X
X/*
X read in two values from stdin.
X I use a procedure rather than fscanf to be able to cope with
X additional comments after the values, i.e. lines like
X -40.723 144.912 The World Digitized
X -40.781 144.891 Islands of Australia
X -40.801 144.896 Copyright 1986 John B. Allison
X
X the returned value tells me whether I should break the line
X connection or not.
X*/
X
X
Xshort rvalues(ftmp,x,y,mercat)
XFILE *ftmp;
Xfloat *x; /* longitude */
Xfloat *y; /* latitude */
Xshort mercat; /* do conversion?*/
X{
X static unsigned char buf[BUFSIZE]; /* buffer for line read from file*/
X unsigned char c = (unsigned char) 0; /* current char read */
X unsigned char *tmp;
X float latitude,longitude;
X short idx = 0;
X
X c = fgetc(stdin);
X while ((!(feof(stdin))) && (c != '\n') && (idx < BUFSIZE))
X {
X buf[idx++] = c;
X c = (unsigned char) fgetc(stdin);
X }
X
X /* separator line ? */
X while ((idx > 0) &&
X ((buf[idx-1] == ' ') ||
X (buf[idx-1] == '\011') ||
X (buf[idx-1] == '\015')))
X buf[--idx] = (unsigned char) 0;
X
X if (!(feof(stdin)))
X {
X linecnt++;
X if (!(idx < BUFSIZE))
X fprintf(stderr,"\nSorry, line %d is too long.",linecnt);
X else
X {
X if (idx == 0) return(0); /* break line connection */
X buf[idx] = (unsigned char) 0;
X tmp = &buf[0];
X /* discard any control characters at the beginning of the buffer */
X while ((*tmp) && (*tmp < ' ')) tmp++;
X sscanf(tmp,"%g %g",&latitude,&longitude);
X
X if (latitude < miny) miny = latitude;
X if (latitude > maxy) maxy = latitude;
X
X if (mercat)
X {
X /* too close to pole -> don't project */
X if (!((fabs(latitude-90.0) < 1) ||
X (fabs(latitude-270.0) < 1)))
X latitude = (float) log(tan((45.0 +
X 0.5*(double)latitude)*M_PI/180.0));
X }
X
X /* bounding box changed ? */
X if (longitude < minlong) minlong = longitude;
X if (longitude > maxlong) maxlong = longitude;
X if (latitude < minlat) minlat = latitude;
X if (latitude > maxlat) maxlat = latitude;
X
X /* control output */
X if ((debug) && ((linecnt % 200) == 0))
X {
X fputc('.',stderr);
X fflush(stderr);
X }
X
X /* if there is a comment, print it to the output file */
X tmp = &buf[0];
X while ((*tmp) && (!(((*tmp >= 'a') && (*tmp <= 'z')) ||
X ((*tmp >= 'A') && (*tmp <= 'Z'))))) tmp++;
X
X *y = latitude;
X *x = longitude;
X
X
X if (*tmp)
X {
X fprintf(ftmp,"\n%% %s",tmp);
X return(2); /* comment encountered */
X }
X }
X }
X return(1);
X}
X
X/*
X parse command line arguments
X*/
X
Xint check_arguments(argc,argv,
X p_unitstr,p_unitfactor,
X p_width,p_height,
X p_mercat,p_unconnect,
X p_showbox,p_drawsegs)
Xint argc;
Xchar *argv[];
Xchar **p_unitstr;
Xfloat *p_unitfactor;
Xfloat *p_width;
Xfloat *p_height;
Xshort *p_mercat;
Xshort *p_unconnect;
Xshort *p_showbox;
Xshort *p_drawsegs;
X{
X int i,j;
X short hit;
X
X /* check for command line params */
X for (i = 1 ; i < argc ; i++)
X {
X if (*argv[i] != '-')
X {
X fprintf(stderr,
X "\nUnknown command line argument '%s' - abort.",
X argv[i]);
X hints();
X return(-1);
X }
X else
X switch(*(argv[i]+1))
X {
X case 'u':
X if (!(strcmp(argv[i]+1,"unconnect"))) *p_unconnect = 1;
X else
X {
X if (*(argv[i]+2) != (char) 0)
X {
X fprintf(stderr,
X "\nUnknown option '%s' - maybe '-u' was intended.",
X argv[i]);
X hints();
X return(-1);
X }
X
X i++;
X for (j = 0 , hit = 0; j < 3 ; j++)
X {
X Key(unitnames[j])
X {
X hit = 1;
X *p_unitstr = &unitnames[j][0];
X *p_unitfactor = unitfacts[j];
X }
X }
X
X if (!(hit))
X {
X fprintf(stderr,"\nUnknown unit '%s' requested.",argv[i]);
X hints();
X return(-1);
X }
X }
X break;
X
X case 'w' :
X case 'W':
X if (*(argv[i]+2) != (char) 0)
X {
X fprintf(stderr,
X "\nUnknown option '%s' - maybe '-w' was intended.",
X argv[i]);
X hints();
X return(-1);
X }
X
X if ((i+1) < argc)
X sscanf(argv[++i],"%g",p_width);
X else
X {
X fprintf(stderr,"\nMissing value after -w option - abort.");
X hints();
X return(-1);
X }
X break;
X
X case 'h' :
X case 'H':
X if (*(argv[i]+2) != (char) 0)
X {
X fprintf(stderr,
X "\nUnknown option '%s' - maybe '-w' was intended.",
X argv[i]);
X hints();
X return(-1);
X };
X
X if ((i+1) < argc)
X sscanf(argv[++i],"%g",p_height);
X else
X {
X fprintf(stderr,"\nMissing value after -h option - abort.");
X hints();
X return(-1);
X }
X break;
X
X case 'n':
X if (!(strcmp(argv[i]+1,"nomercat"))) *p_mercat = 0;
X else
X {
X fprintf(stderr,
X "\nUnknown option '%s' - maybe '-nomercat' was intended.",
X argv[i]);
X hints();
X return(-1);
X };
X break;
X
X case 's':
X if (!(strcmp(argv[i]+1,"showbox"))) *p_showbox = 1;
X else
X {
X fprintf(stderr,
X "\nUnknown option '%s' - maybe '-showbox' was intended.",
X argv[i]);
X hints();
X return(-1);
X };
X break;
X
X case 'd':
X if (!(strcmp(argv[i]+1,"debug"))) debug = 1;
X else
X {
X if (!(strcmp(argv[i]+1,"drawsegs")))
X *p_drawsegs = 1;
X else
X {
X fprintf(stderr,
X "\nUnknown option '%s'"
X "\n - maybe '-debug' or '-drawsegs' have been intended.",
X argv[i]);
X hints();
X return(-1);
X }
X }
X
X break;
X
X case 'o':
X if (*(argv[i]+2) != (char) 0)
X {
X fprintf(stderr,
X "\nUnknown option '%s' - maybe '-o' was intended.",
X argv[i]);
X hints();
X return(-1);
X }
X else
X {
X if ((i+2) < argc) /* arguments given ? */
X {
X sscanf(argv[++i],"%g",&llx);
X sscanf(argv[++i],"%g",&lly);
X }
X else
X {
X fprintf(stderr,
X "\nMissing values after '-o' - abort.");
X hints();
X return(-1);
X }
X }
X break;
X
X default :
X fprintf(stderr,
X "\nUnknown command line argument '%s' - abort.",
X argv[i]);
X hints();
X return(-1);
X
X } /* end switch */
X } /* end loop over command line options */
X
X return(0);
X /* ------------------ end of command line parsing------------------- */
X} /* end check_arguments() */
X
X
X/***********************************************************************/
X/***********************************************************************/
X/* M A I N */
X/***********************************************************************/
X/***********************************************************************/
X
Xint main(argc, argv)
Xint argc;
Xchar *argv[];
X{
X /* ============================= VARIABLES ========================== */
X
X float y,x,lx,ly; /* temporary location variables */
X float bwidth,bheight,blat; /* natural object size */
X float width = -1.0, height = -1.0; /* user desired object size */
X
X char *unitstr = unitnames[0];
X float unitfactor = unitfacts[0];
X
X short mercat = 1, showbox = 0, status,
X oldstatus = 0, drawsegs = 0, unconnect = 0;
X short isdrawn;
X
X FILE *ftmp = fopen(TEMPFILE,"w"); /* handle for temporary file */
X
X char c;
X
X /* possible units and their conversion values */
X
X /* =============================== CODE ============================= */
X
X if (check_arguments(argc,argv,
X &unitstr,&unitfactor,
X &width,&height,
X &mercat,&unconnect,
X &showbox,&drawsegs)) return(-1);
X
X llx*=unitfactor; /* convert origin to current unit */
X lly*=unitfactor;
X
X /* read stdin and write the data to a temporary
X file while looking for the bounding box */
X
X if (ftmp == (FILE *) NULL)
X {
X fprintf(stderr,
X "\nCouldn't open temporary file %s for writing - abort.\n",
X TEMPFILE);
X return(-1);
X }
X
X
X if (debug)
X {
X fprintf(stderr,
X mercat ? "\nUsing mercator projection." : "\nNo projection.");
X fprintf(stderr,"\nscanning");
X }
X
X /* -------------------------- conversion --------------------------- */
X
X rvalues(ftmp,&lx,&ly,mercat);
X fprintf(ftmp,"\n%g %g M",lx,ly);
X
X while (!(feof(stdin)))
X {
X status = rvalues(ftmp,&x,&y,mercat);
X isdrawn = 0;
X
X if ((status == 2) && (oldstatus == 1))
X {
X fprintf(stderr,
X "\nWarning ! I found a comment in line %d of the input file"
X "\n but no separator line before it. This might"
X "\n result in a line that interconnects different maps.\n",
X linecnt);
X if (unconnect)
X {
X fprintf(stderr,
X "As you gave the '-unconnect' option, I'll break the line here.\n");
X fprintf(ftmp,"\n%g %g M",x,y);
X isdrawn = 1;
X status = 0;
X }
X else
X fprintf(stderr,
X "You should check the file or specify the '-unconnect' option.\n");
X }
X
X /* a blank line means break line connection */
X
X if (status)
X fprintf(ftmp,"\n%g %g L",lx,ly,x,y);
X else
X {
X if (!(isdrawn))
X {
X while (!(status))
X {
X status = rvalues(ftmp,&x,&y,mercat); /* scan next starting point */
X if ((debug) && (!(status)))
X fprintf(stderr,"\nMultiple separators in line %d.\n",linecnt);
X }
X fprintf(ftmp,"\n%g %g M",x,y);
X }
X }
X lx = x; ly = y;
X oldstatus = status;
X }
X
X fclose(ftmp);
X
X /* -------------------------- computation --------------------------- */
X
X bwidth = maxlong - minlong; /* extents before scaling */
X bheight = maxy - miny;
X blat = maxlat - minlat;
X
X /* if neither -w nor -h was given, use original size */
X
X if ((height < 0.0) && (width < 0.0))
X {
X height = bheight;
X width = bwidth;
X unitfactor = 1.0;
X }
X else
X {
X if (height > 0.0)
X {
X /* compute width from desired height and object size */
X height*=unitfactor;
X if (width < 0.0) /* preserve ratio */
X width = bwidth*height/bheight;
X else
X width*=unitfactor; /* ok, that's what you wanted */
X }
X else
X {
X /* compute height from desired width and object size */
X width*=unitfactor;
X height = bheight*width/bwidth;
X }
X }
X
X if (debug)
X fprintf(stderr,
X "\n\nNumber of data points = %d"
X "\nSelected unit = %s"
X "\nBounding Box of given object = %6.1f %6.1f %6.1f %6.1f"
X "\nNatural size of object = %6.1f x %6.1f points"
X "\nScaling factors = %6.1f %6.1f"
X "\nSize of object after scaling = %6.1f x %6.1f points"
X "\n = %6.1f x %6.1f inches"
X "\n = %6.1f x %6.1f cm"
X "\nDesired origin = %6.1f , %6.1f points"
X "\n = %6.1f , %6.1f inches"
X "\n = %6.1f , %6.1f cm\n\n",
X linecnt,
X unitstr,
X minlong,minlat,maxlong,maxlat,
X bwidth,blat,
X width/bwidth,height/blat,
X width,height,
X width/72.0,height/72.0,
X width/28.34646,height/28.34646,
X llx,lly,
X llx/72.0,lly/72.0,
X llx/28.34646,lly/28.34646);
X
X /* write prologue */
X
X fprintf(stdout,
X "%%!PS-Adobe-2.0 EPSF-2.0"
X "\n%%%%Title: (unknown)"
X "\n%%%%Creator: wmap2ps by Patrick Dockhorn - WORLDMAP data (C) 1986 John B. Allison"
X "\n%%%%BoundingBox: %g %g %g %g"
X "\n%%%%Pages: 1"
X "\n%%%%DocumentFonts:"
X "\n%%%%EndComments"
X "\n%%%%EndProlog\n"
X "\n%% remember original state"
X "\n/origstate save def\n"
X "\n%% build a temporary dictionary"
X "\n20 dict begin\n"
X "\n%% scale to size desired by user"
X "\n%% (%g x %g points ="
X "\n%% %g x %g inches ="
X "\n%% %g x %g centimeter)"
X "\n%g %g scale\n"
X "\n%% set color to black and select thinnest line\n"
X "\n0 setlinewidth 0 setgray\n\n"
X "\n%c newpath %g %g moveto %g 0 rlineto %% show bounding box"
X "\n%c 0 %g rlineto %g 0 rlineto closepath stroke\n"
X "\n%% lower left corner"
X "\n%g %g translate\n"
X "\n/M {%smoveto } def"
X "\n/L { lineto%s} def\n",
X llx,lly,llx+width,lly+height,
X width,height,
X width/72.0,height/72.0,
X width/28.34646,height/28.34646,
X width/bwidth,height/blat,
X showbox ? ' ' : '%',
X (llx*bwidth/width),
X (lly*blat/height),bwidth,
X showbox ? ' ' : '%',
X blat,-1.0*bwidth,
X (llx*bwidth/width)-minlong,
X (lly*blat/height)-minlat,
X drawsegs ? " newpath " : " ",
X drawsegs ? " currentpoint stroke moveto " : " ");
X
X
X
Xif ((ftmp = fopen(TEMPFILE,"r")) == (FILE *) NULL)
X {
X fprintf(stderr,
X "\nCouldn't open temporary file %s for reading - abort.\n",
X TEMPFILE);
X return(-1);
X }
X
X /* copy from temporary file to stdout */
X
X c = fgetc(ftmp);
X while (!(feof(ftmp)))
X {
X fputc(c,stdout);
X c = fgetc(ftmp);
X }
X
X /* write closing */
X
X fprintf(stdout,
X "%sshowpage"
X "\n%% stop using temporary dictionary"
X "\nend\n"
X "\n%% restore original state"
X "\norigstate restore"
X "\n\n%%%%Trailer\n",
X drawsegs ? "\n" : "\nstroke\n");
X
X unlink(TEMPFILE); /* remove temporary file */
X return(0);
X} /* end main */
END_OF_FILE
if test 19844 -ne `wc -c <'WMAP2PS/wmap2ps.c'`; then
echo shar: \"'WMAP2PS/wmap2ps.c'\" unpacked with wrong size!
fi
# end of 'WMAP2PS/wmap2ps.c'
fi
echo shar: End of shell archive.
exit 0
Technical Details
Message-ID:
<1992Sep6.142939.13963@fzi.de>Path:
arc1-ca.pugleaf.net!sparky!uunet!ogicse!uwm.edu!spool.mu.edu!yale.edu!ira.uka.de!gate.fzi.de!dockhornShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!ogicse!uwm.edu!spool.mu.edu!yale.edu!ira.uka.de!gate.fzi.de!dockhorn From: dockhorn@fzi.de (Patrick Dockhorn) Newsgroups: comp.lang.postscript Subject: wmap2ps - WorldMap goes PostScript Keywords: map world PostScript converter mercator Message-ID: <1992Sep6.142939.13963@fzi.de> Date: 6 Sep 92 14:29:39 GMT Article-I.D.: fzi.1992Sep6.142939.13963 Sender: news@fzi.de (FZI-news) Reply-To: dockhorn@fzi.de Followup-To: poster Organization: Forschungszentrum Informatik (FZI), Karlsruhe, Germany Lines: 1318