[net.sources] Program for great circle navigation

llh@midacs.UUCP (Linn Hower) (09/14/85)

What follows is a shell archive of a program for aviation
navigation planning.  There  is no documentation.  This code runs
on (at least) bsd4.2 and 4.1 .  I suspect problems should
be very few for other systems.

For more information, refer to the recent discussions in
net.aviation.

--------------nav.sh----------------------------------
: This is a shar archive.  Extract with sh, not csh.
: The rest of this file will extract:
: Makefile file.c main.c main.corg nav.c nav.corg output.c output.corg scan.c nav.h nav.horg airports vors
echo extracting - Makefile
sed 's/^X//' > Makefile << '!E_O_F!'
X#
X#	Makefile for "nav" pre-flight great circle program
X#
X
Xall: nav
X
XCFLGS=-O
X
X#
X# "-lnm" refers to a "new math" library.  You might not have it, but "-lm".
X#
Xnav: main.o nav.o file.o scan.o output.o nav.h
X	cc ${CFLGS} main.o nav.o file.o scan.o output.o -o nav -lm
X
Xmain.o: main.c nav.h
X
Xnav.o: nav.c nav.h
X
Xfile.o: file.c nav.h
X
Xscan.o: scan.c nav.h
X
Xoutput.o: output.c
X
Xinstall: nav
X	install -c -s nav /whatever/bin/nav
X
Xclean:
X	-rm -f *.o core
X
Xcleanall:
X	-rm -f *.o core nav
!E_O_F!
echo extracting - file.c
sed 's/^X//' > file.c << '!E_O_F!'
X/*
X *	Routines for reading and parsing nav data files
X *
X *	All degrees stored as decimal degrees.
X */
X#include <stdio.h>
X#include "nav.h"
X
Xdouble Radians();
Xdouble Degrees();
Xchar *index();
Xchar *malloc();
Xdouble atof();
X
Xstruct vor *LineToVor(s)
Xchar *s;
X{
X	static struct vor buf;
X	register char *p, *q;
X	register double min;
X
X	p = s;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	strcpy(buf.id,p);		/* copy in the id */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	strcpy(buf.name,p);		/* copy in the name */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	buf.freq = (float)atof(p);	/* frequency */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	buf.var = atof(p);		/* variation in degrees */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	min = atof(p) / 60;		/* add variation minutes */
X	buf.var += buf.var<0 ? (0. - min) : min;
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	buf.loc.lat.deg = atof(p);	/* north degrees */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	min = atof(p) / 60;		/* add north minutes */
X	buf.loc.lat.deg += buf.loc.lat.deg<0 ? (0. - min) : min;
X	buf.loc.lat.rad = Radians(buf.loc.lat.deg);
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	buf.loc.lon.deg = atof(p);	/* west degrees */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	min = atof(p) / 60;		/* add west minutes */
X	buf.loc.lon.deg += buf.loc.lon.deg<0 ? (0. - min) : min;
X	buf.loc.lon.rad = Radians(buf.loc.lon.deg);
X	p = q+1;
X	if (! *p)
X		return NULL;
X	strncpy(buf.comments,p,sizeof buf.comments);
X	q = index(buf.comments,'\n');
X	q = 0;
X	return &buf;
X}
X
Xstruct apt *LineToApt(s)
Xchar *s;
X{
X	static struct apt buf;
X	register char *p, *q;
X	register double min;
X
X	p = s;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	strcpy(buf.id,p);		/* copy in the id */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	strcpy(buf.city,p);		/* city closest to airport */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	strcpy(buf.name,p);		/* name of airport */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	buf.alt = atoi(p);		/* airport altitude in feet */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	buf.var = atof(p);		/* variation in decimal degrees */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	min = atof(p) / 60;		/* add variation minutes */
X	buf.var += buf.var<0 ? (0. - min) : min;
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	buf.loc.lat.deg = atof(p);	/* north degrees */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	min = atof(p) / 60;		/* add north minutes */
X	buf.loc.lat.deg += buf.loc.lat.deg<0 ? (0. - min) : min;
X	buf.loc.lat.rad = Radians(buf.loc.lat.deg);
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	buf.loc.lon.deg = atof(p);	/* west degrees */
X	p = q+1;
X	q = index(p,':');
X	if (q == NULL)
X		return NULL;
X	*q = 0;
X	min = atof(p) / 60;		/* add west minutes */
X	buf.loc.lon.deg += buf.loc.lon.deg<0 ? (0. - min) : min;
X	buf.loc.lon.rad = Radians(buf.loc.lon.deg);
X	p = q+1;
X	if (! *p)
X		return NULL;
X	strncpy(buf.comments,p,sizeof buf.comments);
X	q = index(buf.comments,'\n');
X	q = 0;
X	return &buf;
X}
X
X/*
X *	Fill array of struct apt with data from file.
X *	Return number of elements in array, 0 on error.
X */
XParseApt(array,fp)
Xstruct apt array[];
XFILE fp;
X{
X	char line[BUFSIZ];
X	register char *s;
X	register struct apt *ptr;
X	register int cnt;
X
X	cnt = 0;
X	while ((cnt <= MAXAPTS) && (fgets(line, sizeof line, fp) != NULL)){
X		if ( line[0] == '#' ){	/* comment line */
X			continue;
X		}
X		ptr = LineToApt(line);
X		if (ptr == NULL){
X			fprintf(stderr,
X			"LineToApt from ParseApt returned NULL on line\n%s\n",
X			line);
X			return NULL;
X		}
X		array[cnt] = *ptr;
X		cnt++;
X	}
X	return cnt;
X}
X
X/*
X *	Fill array of struct vor with data from file.
X *	Return number of elements in array, 0 on error.
X */
XParseVor(array,fp)
Xstruct vor array[];
XFILE fp;
X{
X	char line[BUFSIZ];
X	register char *s;
X	register struct vor *ptr;
X	register int cnt;
X
X	cnt = 0;
X	while ((cnt <= MAXVORS) && (fgets(line, sizeof line, fp) != NULL)){
X		if ( line[0] == '#' ){	/* comment line */
X			continue;
X		}
X		ptr = LineToVor(line);
X		if (ptr == NULL){
X			fprintf(stderr,
X			"LineToVor from ParseVor returned NULL on line\n%s\n",
X			line);
X			return NULL;
X		}
X		array[cnt] = *ptr;
X		cnt++;
X	}
X	return cnt;
X}
!E_O_F!
echo extracting - main.c
sed 's/^X//' > main.c << '!E_O_F!'
X#include <stdio.h>
X#include <math.h>
X#include "nav.h"
X
Xdouble Distance();
Xdouble Bearing();
Xdouble Magnetic();
Xdouble Degrees();
Xdouble Radians();
Xdouble LatIntercept();
X
Xint comflg;
Xint rviaflg;
X
Xmain(ac,av)
Xint ac;
Xchar **av;
X{
X	struct apt AptArray[MAXAPTS];
X	struct vor VorArray[MAXVORS];
X	struct vor ViaArray[MAXVIA];
X	int AptC, VorC, ViaC;
X	FILE *fpa, *fpv;
X	struct apt From, To;
X	double Dist, TotalDist, Course, WpLat, WpDist, WpRad;
X	char sysbuf[BUFSIZ];
X
X	struct fix LastFix;
X	double LastVar;
X	char LastId[NAMLEN];
X
X	register int v;
X	register int i;
X	int fromflg, toflg, viaflg;
X
X	comflg = 0;
X	fromflg = 0;
X	toflg = 0;
X	viaflg = 0;
X	rviaflg = 0;
X
X	fpa = fopen(AIRPORTS,"r");
X	if (fpa == NULL){
X		perror(AIRPORTS);
X		exit(1);
X	}
X	fpv = fopen(VORS,"r");
X	if (fpv == NULL){
X		perror(VORS);
X		exit(1);
X	}
X	AptC = ParseApt(AptArray,fpa);
X	if (! AptC){
X		oops("Trouble parsing airports");
X	}
X	fclose(fpa);
X	VorC = ParseVor(VorArray,fpv);
X	if (! VorC){
X		oops("Trouble parsing VORs");
X	}
X	fclose(fpv);
X
X	ac--;av++;
X	while(ac){
X		if (strcmp(*av,"-from") == 0){
X			ac--;av++;
X			if(!ac || **av == '-')
X				usage("from: Missing departure ID");
X			if (fromflg)
X				usage("from: Two departure points?");
X			if (FindApt(&From,*av,AptArray,AptC) != 0)
X				oops("Couldn't find your departure airport");
X			fromflg++;
X			ac--;av++;
X		}else if (strcmp(*av,"-to") == 0){
X			ac--;av++;
X			if(!ac || **av == '-')
X				usage("to: Missing destination ID");
X			if (toflg)
X				usage("to: Two destinations?");
X			if (FindApt(&To,*av,AptArray,AptC) != 0)
X				oops("Couldn't find your destination airport");
X			toflg++;
X			ac--;av++;
X		}else if (strcmp(*av,"-via") == 0){
X			ac--;av++;
X			if(!ac || **av == '-')
X				usage("via: Missing VOR ID(s)");
X			if (viaflg)
X				usage("via: One set of 'via' VORs please");
X			for(ViaC=0;
X			ac && (**av != '-') && (ViaC < MAXVIA);
X			ViaC++){
X				if (FindVor(&ViaArray[ViaC],*av,VorArray,VorC)
X				!= 0){
X					fprintf(stderr,
X						"via: %s: VOR not found\n",*av);
X					exit(1);
X				}
X				ac--;av++;
X			}
X			viaflg++;
X		}else if (strcmp(*av,"-rvia") == 0){
X			ac--;av++;
X			if(!ac || **av == '-')
X				usage("rvia: Missing VOR ID(s)");
X			if (rviaflg)
X				usage("rvia: One set of 'rvia' VORs please");
X			for(ViaC=0;
X			ac && (**av != '-') && (ViaC < MAXVIA);
X			ViaC++){
X				if (FindVor(&ViaArray[ViaC],*av,VorArray,VorC)
X				!= 0){
X					fprintf(stderr,
X						"rvia: %s: VOR not found\n",*av);
X					exit(1);
X				}
X				ac--;av++;
X			}
X			rviaflg++;
X		}else if (strcmp(*av,"-com") == 0){
X			comflg++;
X			ac--;av++;
X		}else if (strcmp(*av,"-airports") == 0){
X			sprintf(sysbuf,"/usr/ucb/more %s",AIRPORTS);
X			system(sysbuf);
X			exit(0);
X		}else if (strcmp(*av,"-vors") == 0){
X			sprintf(sysbuf,"/usr/ucb/more %s",VORS);
X			system(sysbuf);
X			exit(0);
X		}else if (strcmp(*av,"-k") == 0){
X			ac--;av++;
X			if (!ac) usage("-k: missing keyword or pattern");
X			sprintf(sysbuf,"/bin/grep -i %s %s",
X				*av,AIRPORTS);
X			system(sysbuf);
X			sprintf(sysbuf,"/bin/grep -i %s %s",
X				*av,VORS);
X			system(sysbuf);
X			exit(0);
X		}
X		else
X/*
X *	Default action here
X */
X			usage("Plan a flight...");
X	}
X
X	if	( (fromflg && !(toflg || viaflg))	||
X		  ( toflg && !(fromflg || viaflg))	||
X		  (viaflg && rviaflg)			||
X		  (rviaflg && !(fromflg && toflg))	||
X		  ((!fromflg && !toflg) && !viaflg) )
X		usage("Plan a flight...");
X/*
X *	Now that we are done loading the data into the structs
X *	and parsing the command line, we can have some fun.
X */
X
X	TotalDist = Dist = 0.;
X	if(fromflg){
X		PrintApt(&From);
X		LastFix = From.loc;
X		LastVar = From.var;
X		strcpy(LastId,From.id);
X	}
X	if (rviaflg) {
X		viaflg = rviaflg;
X		for (v=0; v < ViaC; v++) {
X			WpLat =
X			   LatIntercept(LastFix.lat.rad, LastFix.lon.rad,
X					To.loc.lat.rad, To.loc.lon.rad,
X					ViaArray[v].loc.lon.rad);
X			WpDist = fabs(60. *
X			       	      Degrees(WpLat - ViaArray[v].loc.lat.rad));
X			/* WpDist = sqrt(pow(WpDist,2.) + pow(AVALT,2.)); */
X			if (WpLat < ViaArray[v].loc.lat.rad)
X				WpRad = 180.0 + ViaArray[v].var;
X			   else
X				WpRad = 360.0 + ViaArray[v].var;
X			ViaArray[v].loc.lat.rad = WpLat;
X			ViaArray[v].loc.lat.deg = Degrees(WpLat);
X			sprintf(ViaArray[v].waypoint,
X				"%s R-%05.1f / %.1f",
X				ViaArray[v].id, WpRad, WpDist);
X			sprintf(ViaArray[v].id,
X				"WP%d",
X				v+1);
X		}
X	}
X	if (viaflg){
X		v=0;
X		if (!fromflg){
X			PrintVor(&ViaArray[v]);
X			LastFix = ViaArray[v].loc;
X			LastVar = ViaArray[v].var;
X			strcpy(LastId,ViaArray[v].id);
X			v++;
X		}else{
X			Dist = Distance(LastFix.lat.rad,LastFix.lon.rad,
X			    ViaArray[v].loc.lat.rad,ViaArray[v].loc.lon.rad);
X			Course= Bearing(LastFix.lat.rad,LastFix.lon.rad,
X			    ViaArray[v].loc.lat.rad,ViaArray[v].loc.lon.rad);
X			TotalDist += Dist;
X			PrintVor(&ViaArray[v]);
X			if (rviaflg)
X				PrintWp(&ViaArray[v]);
X			PrintNav(LastId,ViaArray[v].id,Course,
X				Magnetic(Course,LastVar),
X				Dist,TotalDist);
X			LastFix = ViaArray[v].loc;
X			LastVar = ViaArray[v].var;
X			strcpy(LastId,ViaArray[v].id);
X			v++;
X		}
X		while(v < ViaC){
X			Dist = Distance(LastFix.lat.rad,LastFix.lon.rad,
X			    ViaArray[v].loc.lat.rad,ViaArray[v].loc.lon.rad);
X			Course= Bearing(LastFix.lat.rad,LastFix.lon.rad,
X			    ViaArray[v].loc.lat.rad,ViaArray[v].loc.lon.rad);
X			TotalDist += Dist;
X			PrintVor(&ViaArray[v]);
X			if (rviaflg)
X				PrintWp(&ViaArray[v]);
X			PrintNav(LastId,ViaArray[v].id,Course,
X				Magnetic(Course,LastVar),
X				Dist,TotalDist);
X			LastFix = ViaArray[v].loc;
X			LastVar = ViaArray[v].var;
X			strcpy(LastId,ViaArray[v].id);
X			v++;
X		}
X		printf("\n");
X	}
X	if (toflg){
X		Dist = Distance(LastFix.lat.rad,LastFix.lon.rad,
X		    To.loc.lat.rad,To.loc.lon.rad);
X		Course= Bearing(LastFix.lat.rad,LastFix.lon.rad,
X		    To.loc.lat.rad,To.loc.lon.rad);
X		TotalDist += Dist;
X		printf("\n");
X		PrintNav(LastId,To.id,Course,
X			Magnetic(Course,LastVar),
X			Dist,TotalDist);
X		PrintApt(&To);
X	}
X}
X
Xusage(s)
Xchar *s;
X{
X	fprintf(stderr,"nav: %s\n\n",s);
X	fprintf(stderr,
X	"Usage: nav [-from airport_id -to airport_id] [-[r]via vor [vor...]] [-com]\n");
X	fprintf(stderr,
X	"(The order of the 'from', 'to' and '[r]via' parts may be arbitrary)\n");
X	fprintf(stderr,
X	"Or:\nnav -k string: grep a string from the databases ignoring case\n");
X	fprintf(stderr,
X	"nav -airports : print out the airport database\n");
X	fprintf(stderr,
X	"nav -vors : print out the vor database\n");
X	fprintf(stderr,"\nUse the abbreviated IDs found in the databases.\n");
X	exit(1);
X}
X
Xoops(s)
Xchar *s;
X{
X	fprintf(stderr,"nav: %s\n",s);
X	exit(1);
X}
!E_O_F!
echo extracting - main.corg
sed 's/^X//' > main.corg << '!E_O_F!'
X#include <stdio.h>
X#include <math.h>
X#include "nav.h"
X
X#define AIRPORTS "/whatever/airports"
X#define VORS "/whatever/vors"
X
Xdouble Distance();
Xdouble Bearing();
Xdouble Magnetic();
Xdouble Radians();
X
Xint comflg;
X
Xmain(ac,av)
Xint ac;
Xchar **av;
X{
X	struct apt AptArray[MAXAPTS];
X	struct vor VorArray[MAXVORS];
X	struct vor ViaArray[MAXVIA];
X	int AptC, VorC, ViaC;
X	FILE *fpa, *fpv;
X	struct apt From, To;
X	double Dist, TotalDist, Course;
X	char sysbuf[BUFSIZ];
X
X	struct fix LastFix;
X	double LastVar;
X	char LastId[NAMLEN];
X
X	register int v;
X	register int i;
X	int fromflg, toflg, viaflg;
X
X	comflg = 0;
X	fromflg = 0;
X	toflg = 0;
X	viaflg = 0;
X
X	fpa = fopen(AIRPORTS,"r");
X	if (fpa == NULL){
X		perror(AIRPORTS);
X		exit(1);
X	}
X	fpv = fopen(VORS,"r");
X	if (fpv == NULL){
X		perror(VORS);
X		exit(1);
X	}
X	AptC = ParseApt(AptArray,fpa);
X	if (! AptC){
X		oops("Trouble parsing airports");
X	}
X	fclose(fpa);
X	VorC = ParseVor(VorArray,fpv);
X	if (! VorC){
X		oops("Trouble parsing VORs");
X	}
X	fclose(fpv);
X
X	ac--;av++;
X	while(ac){
X		if (strcmp(*av,"-from") == 0){
X			ac--;av++;
X			if(!ac || **av == '-')
X				usage("from: Missing departure ID");
X			if (fromflg)
X				usage("from: Two departure points?");
X			if (FindApt(&From,*av,AptArray,AptC) != 0)
X				oops("Couldn't find your departure airport");
X			fromflg++;
X			ac--;av++;
X		}else if (strcmp(*av,"-to") == 0){
X			ac--;av++;
X			if(!ac || **av == '-')
X				usage("to: Missing destination ID");
X			if (toflg)
X				usage("to: Two destinations?");
X			if (FindApt(&To,*av,AptArray,AptC) != 0)
X				oops("Couldn't find your destination airport");
X			toflg++;
X			ac--;av++;
X		}else if (strcmp(*av,"-via") == 0){
X			ac--;av++;
X			if(!ac)
X				usage("via: Missing VOR ID(s)");
X			if (viaflg)
X				usage("via: One set of 'via' VORs please");
X			for(ViaC=0;
X			ac && (**av != '-') && (ViaC <= MAXVIA);
X			ViaC++){
X				if (FindVor(&ViaArray[ViaC],*av,VorArray,VorC)
X				!= 0){
X					fprintf(stderr,
X						"via: %s: VOR not found\n",*av);
X					exit(1);
X				}
X				ac--;av++;
X			}
X			viaflg++;
X		}else if (strcmp(*av,"-com") == 0){
X			comflg++;
X			ac--;av++;
X		}else if (strcmp(*av,"-airports") == 0){
X			sprintf(sysbuf,"/usr/ucb/more %s",AIRPORTS);
X			system(sysbuf);
X			exit(0);
X		}else if (strcmp(*av,"-vors") == 0){
X			sprintf(sysbuf,"/usr/ucb/more %s",VORS);
X			system(sysbuf);
X			exit(0);
X		}else if (strcmp(*av,"-k") == 0){
X			ac--;av++;
X			if (!ac) usage("-k: missing keyword or pattern");
X			sprintf(sysbuf,"/bin/grep -i %s %s",
X				*av,AIRPORTS);
X			system(sysbuf);
X			sprintf(sysbuf,"/bin/grep -i %s %s",
X				*av,VORS);
X			system(sysbuf);
X			exit(0);
X		}
X		else
X/*
X *	Default action here
X */
X			usage("Plan a flight");
X	}
X
X	if	((fromflg && !(toflg || viaflg)) ||
X		( toflg && !(fromflg || viaflg)) ||
X		((!fromflg && !toflg) && !viaflg))
X		usage("If I were a real Unix program I'd say 'arg count'!");
X/*
X *	Now that we are done loading the data into the structs
X *	and parsing the command line, we can have some fun.
X */
X
X	TotalDist = Dist = 0.;
X	if(fromflg){
X		PrintApt(&From);
X		LastFix = From.loc;
X		LastVar = From.var;
X		strcpy(LastId,From.id);
X	}
X	if (viaflg){
X		v=0;
X		if (!fromflg){
X			PrintVor(&ViaArray[v]);
X			LastFix = ViaArray[v].loc;
X			LastVar = ViaArray[v].var;
X			strcpy(LastId,ViaArray[v].id);
X			v++;
X		}else{
X			Dist = Distance(LastFix.lat.rad,LastFix.lon.rad,
X			    ViaArray[v].loc.lat.rad,ViaArray[v].loc.lon.rad);
X			Course= Bearing(LastFix.lat.rad,LastFix.lon.rad,
X			    ViaArray[v].loc.lat.rad,ViaArray[v].loc.lon.rad);
X			TotalDist += Dist;
X			PrintVor(&ViaArray[v]);
X			PrintNav(LastId,ViaArray[v].id,Course,
X				Magnetic(Course,LastVar),
X				Dist,TotalDist);
X			LastFix = ViaArray[v].loc;
X			LastVar = ViaArray[v].var;
X			strcpy(LastId,ViaArray[v].id);
X			v++;
X		}
X		while(v < ViaC){
X			Dist = Distance(LastFix.lat.rad,LastFix.lon.rad,
X			    ViaArray[v].loc.lat.rad,ViaArray[v].loc.lon.rad);
X			Course= Bearing(LastFix.lat.rad,LastFix.lon.rad,
X			    ViaArray[v].loc.lat.rad,ViaArray[v].loc.lon.rad);
X			TotalDist += Dist;
X			PrintVor(&ViaArray[v]);
X			PrintNav(LastId,ViaArray[v].id,Course,
X				Magnetic(Course,LastVar),
X				Dist,TotalDist);
X			LastFix = ViaArray[v].loc;
X			LastVar = ViaArray[v].var;
X			strcpy(LastId,ViaArray[v].id);
X			v++;
X		}
X	}
X	if (toflg){
X		Dist = Distance(LastFix.lat.rad,LastFix.lon.rad,
X		    To.loc.lat.rad,To.loc.lon.rad);
X		Course= Bearing(LastFix.lat.rad,LastFix.lon.rad,
X		    To.loc.lat.rad,To.loc.lon.rad);
X		TotalDist += Dist;
X		PrintNav(LastId,To.id,Course,
X			Magnetic(Course,LastVar),
X			Dist,TotalDist);
X		PrintApt(&To);
X	}
X}
X
Xusage(s)
Xchar *s;
X{
X	fprintf(stderr,"nav: %s\n\n",s);
X	fprintf(stderr,
X	"Usage: nav [-from airport_id -to airport_id] [-via vor[vor...]]\n");
X	fprintf(stderr,
X	"(The order of the 'from', 'to' and 'via' parts may be arbitrary)\n");
X	fprintf(stderr,
X	"Or:\nnav -k string: grep a string from the databases ignoring case\n");
X	fprintf(stderr,
X	"nav -airports : print out the airport database\n");
X	fprintf(stderr,
X	"nav -vors : print out the vor database\n");
X	fprintf(stderr,"\nUse the abbreviated IDs found in the databases.\n");
X	exit(1);
X}
X
Xoops(s)
Xchar *s;
X{
X	fprintf(stderr,"nav: %s\n",s);
X	exit(1);
X}
!E_O_F!
echo extracting - nav.c
sed 's/^X//' > nav.c << '!E_O_F!'
X#include <math.h>
X#include "nav.h"
X
X/*
X *	Returns radians given decimal degrees
X */
Xdouble Radians(degrees)
Xdouble degrees;
X{
X	return degrees * (pi/180.);
X}
X
X/*
X *	Returns decimal degrees given radians
X */
Xdouble Degrees(radians)
Xdouble radians;
X{
X	return radians / (pi/180.);
X}
X
X/*
X *	Returns distance in Nautical Miles given two sets of latitude
X *	and longitude in radians.
X *	Latitudes are positive for North, negative for South (N1, N2)
X *	Longitudes are positive for West, negative for East  (W1, W2)
X *
X *	Algorithm from HP-25 Applications Programs, Rhumbline Navigation,
X *	page 65.
X */
Xdouble Distance(N1,W1,N2,W2)
Xdouble N1,W1,N2,W2;
X{
X	register double C;
X
X	C = atan2 (
X	    ( 2. * asin(sin(.5 * (W1 - W2))) )
X		,
X	    ( log(tan(pi*.25 + .5*N2)) - log(tan(pi*.25 + .5*N1)) )
X		 );
X
X	if (N1 == N2)
X	      return (60. * fabs(Degrees(2. * asin(sin(.5 * (W1 - W2)))))
X			  * cos(N1));
X	   else
X	      return (60. * Degrees(N2 - N1) / cos(fabs(C)));
X} 
X
X/*
X *	Returns true bearing from North in decimal degrees given two sets of
X *	latitude and longitude in radians.
X *	Latitudes are positive for North, negative for South (N1, N2)
X *	Longitudes are positive for West, negative for East  (W1, W2)
X *
X *	Algorithm from HP-25 Applications Programs, Rhumbline Navigation,
X *	page 65.
X */
Xdouble Bearing(N1,W1,N2,W2)
Xdouble N1,W1,N2,W2;
X{
X	register double C;
X
X	C = atan2 (
X	    ( 2. * asin(sin(.5 * (W1 - W2))) )
X		,
X	    ( log(tan(pi*.25 + .5*N2)) - log(tan(pi*.25 + .5*N1)) )
X		 );
X	return ( (asin(sin(W1-W2)) >= 0.)
X			? Degrees(fabs(C))
X			: 360. - Degrees(fabs(C)) );
X}
X
X/*
X *	Returns magnetic bearing in decimal degrees given true bearing and the
X *	magnetic variation in decimal degrees.  East variation is expressed
X *	by a negative value.	Pretty fancy, eh?
X */
Xdouble Magnetic(true,variation)
Xdouble true,variation;
X{
X	register double course;
X
X	course = true + variation;
X	if ( course < 0. ) course = 360. - course;
X	if ( course >= 360. ) course = course - 360.;
X	return course;
X}
X
X/*
X *	Returns latitude in radians (Ni) of the intercept at longitude
X *	Wi for the great circle course from (N1, W1) to (N2, W2).
X *	Latitude and longitude in radians.
X *	Latitudes are positive for North, negative for South (N1, N2)
X *	Longitudes are positive for West, negative for East  (W1, W2)
X *
X *	Algorithm from HP-25 Applications Programs, Great Circle Ploting,
X *	page 62.
X */
Xdouble LatIntercept(N1,W1,N2,W2,Wi)
Xdouble N1,W1,N2,W2,Wi;
X{
X	if (W1 == W2)
X		oops("Sorry, True N/S from/to's break nav");
X
X	return (
X		atan(
X		     (tan(N2)*sin(Wi-W1) - tan(N1)*sin(Wi-W2))
X				/
X		     (sin(W2-W1))
X		)
X	);
X}
!E_O_F!
echo extracting - nav.corg
sed 's/^X//' > nav.corg << '!E_O_F!'
X#include <math.h>
X#include "nav.h"
X
X/*
X *	Returns radians given decimal degrees
X */
Xdouble Radians(degrees)
Xdouble degrees;
X{
X	return degrees * (pi/180.);
X}
X
X/*
X *	Returns decimal degrees given radians
X */
Xdouble Degrees(radians)
Xdouble radians;
X{
X	return radians / (pi/180);
X}
X
X/*
X *	Returns distance in Nautical Miles given two sets of latitude
X *	and longitude in radians.
X *	Latitudes are positive for North, negative for South (N1, N2)
X *	Longitudes are positive for West, negative for East  (W1, W2)
X */
Xdouble Distance(N1,W1,N2,W2)
Xdouble N1,W1,N2,W2;
X{
X	return	60. * Degrees(acos((sin(N1) * sin(N2)) +
X		(cos(N1) * cos(N2) * (cos(W1 - W2)))));
X} 
X
X/*
X *	Returns true bearing from North in decimal degrees given two sets of
X *	latitude and longitude in radians.
X *	Latitudes are positive for North, negative for South (N1, N2)
X *	Longitudes are positive for West, negative for East  (W1, W2)
X */
Xdouble Bearing(N1,W1,N2,W2)
Xdouble N1,W1,N2,W2;
X{
X	register double D;
X	register double C;
X
X	D = acos(sin(N1) * sin(N2) + cos(N1) * cos(N2) * cos(W1 - W2));
X	C = acos((sin(N2) - sin(N1) * cos(D)) / (cos(N1) * sin(D)));
X	return (sin(W1-W2) >= 0.) ? Degrees(C) : 360. - Degrees(C);
X}
X
X/*
X *	Returns magnetic bearing in decimal degrees given true bearing and the
X *	magnetic variation in decimal degrees.  East variation is expressed
X *	by a negative value.	Pretty fancy, eh?
X */
Xdouble Magnetic(true,variation)
Xdouble true,variation;
X{
X	register double course;
X
X	course = true + variation;
X	if ( course < 0. ) course = 360. - course;
X	if ( course >= 360. ) course = course - 360.;
X	return course;
X}
!E_O_F!
echo extracting - output.c
sed 's/^X//' > output.c << '!E_O_F!'
X/*
X *	Output formatting and stuff
X */
X#include "nav.h"
X
Xextern int comflg;
Xextern int rviaflg;
X
Xcomment(s)
Xchar *s;
X{
X	register char *p;
X
X	for (p=s; *p != 0; p++)
X		if (*p == '\n')
X			*p = 0;
X	if (comflg && strlen(s))
X		printf("\t\t*** %s ***\n",s);
X}
X
XPrintWp(vortac)
Xstruct vor *vortac;
X{
X	printf("wp\t%s\n\n", vortac->waypoint);
X}
X
X
XPrintVor(vortac)
Xstruct vor *vortac;
X{
X	if (rviaflg)
X		printf("\nrvor\t%s\t\t\t\t\tfreq: %.1f\n", vortac->id,vortac->freq);
X	   else
X		printf("\nvor\t%s\t\t\t\t\tfreq: %.1f\n", vortac->id,vortac->freq);
X	comment(vortac->comments);
X	putchar('\n');
X}
X
XPrintApt(airport)
Xstruct apt *airport;
X{
X	printf("\%s\t(%s)\n", airport->name, airport->city);
X	printf("%s\taltitude:\t\t\t\t%d feet\n",
X		airport->id,airport->alt);
X	comment(airport->comments);
X	putchar('\n');
X}
X
XPrintNav(FromId,ToId,Course,Mag,Dist,TotalDist)
Xchar *FromId, *ToId;
Xdouble Course,Mag,Dist,TotalDist;
X{
X	if (Dist > 0.01){	/* there is some fudge factor here */
X		printf("\t\t%s to %s\nMagnetic:\t\t\t\t\t%03.0f\n",
X			FromId, ToId, Mag);
X		printf("Distance:\t\t\t\t\t%.1f NM\n",
X			Dist);
X		printf("(true course %03.0f, Total distance %.1f)\n",
X			Course,TotalDist);
X	}else{	/* special cased since flying 90 deg for 0 NM is silly */
X		printf("\n%s is at %s\n",
X			FromId, ToId);
X		printf("(Total distance %.1f)\n",
X			TotalDist);
X	}
X}
!E_O_F!
echo extracting - output.corg
sed 's/^X//' > output.corg << '!E_O_F!'
X/*
X *	Output formatting and stuff
X */
X#include "nav.h"
X
Xextern int comflg;
Xcomment(s)
Xchar *s;
X{
X	register char *p;
X
X	for (p=s; *p != 0; p++)
X		if (*p == '\n')
X			*p = 0;
X	if (comflg && strlen(s))
X		printf("\t\t*** %s ***\n",s);
X}
X
XPrintVor(vortac)
Xstruct vor *vortac;
X{
X	printf("\nvor\t%s\t\t\t\t\tfreq: %.1f\n", vortac->id,vortac->freq);
X	comment(vortac->comments);
X	putchar('\n');
X}
X
XPrintApt(airport)
Xstruct apt *airport;
X{
X	printf("\%s\t(%s)\n", airport->name, airport->city);
X	printf("%s\taltitude:\t\t\t\t%d feet\n",
X		airport->id,airport->alt);
X	comment(airport->comments);
X	putchar('\n');
X}
X
XPrintNav(FromId,ToId,Course,Mag,Dist,TotalDist)
Xchar *FromId, *ToId;
Xdouble Course,Mag,Dist,TotalDist;
X{
X	if (Dist > 0.01){	/* there is some fudge factor here */
X		printf("\t\t%s to %s\nMagnetic:\t\t\t\t\t%03.0f\n",
X			FromId, ToId, Mag);
X		printf("Distance:\t\t\t\t\t%.1f NM\n",
X			Dist);
X		printf("(true course %03.0f, Total distance %.1f)\n",
X			Course,TotalDist);
X	}else{	/* special cased since flying 90 deg for 0 NM is silly */
X		printf("\n%s is at %s\n",
X			FromId, ToId);
X		printf("(Total distance %.1f)\n",
X			TotalDist);
X	}
X}
!E_O_F!
echo extracting - scan.c
sed 's/^X//' > scan.c << '!E_O_F!'
X#include "nav.h"
X#include <ctype.h>
X
X/*
X *	Attempt to find airport in array by matching IDs, put result in airport.
X *	Return 1 on error, 0 on success.
X *	Ignore case by upping case in buf.
X */
XFindApt(airport,s,array,count)
Xstruct apt *airport;
Xchar *s;
Xstruct apt array[];
Xint count;
X{
X	char buf[IDLEN];
X	register int i;
X
X	strcpy(buf,s);
X	uppit(buf);
X	for (i=0; i < count; i++){
X		if (strcmp(array[i].id,buf) == 0){
X			*airport = array[i];
X			return 0;	/* we find only one at a time here */
X		}
X	}
X	return 1;
X}
X
X/*
X *	Attempt to find VOR in array by matching IDs, put result in vortac.
X *	Return 1 on error, 0 on success.
X *	Ignore case by upping case in buf.
X */
XFindVor(vortac,s,array,count)
Xstruct vor *vortac;
Xchar *s;
Xstruct vor array[];
Xint count;
X{
X	char buf[IDLEN];
X	register int i;
X
X	strcpy(buf,s);
X	uppit(buf);
X	for (i=0; i < count; i++){
X		if (strcmp(array[i].id,buf) == 0){
X			*vortac = array[i];
X			return 0;	/* we find only one at a time here */
X		}
X	}
X	return 1;
X}
X
X/*
X *	pretty self-explanatory
X */
Xuppit(s)
Xchar *s;
X{
X	while ((*s != '\0') && (*s != '\n')){
X		if ((isalpha(*s) && islower(*s))){
X			*s=toupper(*s);
X		}
X		if (isspace(*s)){
X			*s=' ';		/* Guarantee that it's a blank char */
X		}
X		s++;
X	}
X}
!E_O_F!
echo extracting - nav.h
sed 's/^X//' > nav.h << '!E_O_F!'
X/*
X *	Defines and structs for nav navigation program
X */
X
X#define AIRPORTS	"airports"
X#define VORS		"vors"
X
X#define AVALT		3.0	/* average nm agl for rnav slant range calc */
X
X#define pi (3.1415926535897932384626433)
X
X#define MAXAPTS 512	/* Maximum number of airports in APTarray */
X#define MAXVORS 512	/* Maximum number of VORs in VORarray */
X#define MAXVIA 64	/* Maximum number of VORs in ViaArray */
X#define NAMLEN 33	/* Size of name field + EOS */
X#define COMLEN 65	/* Size of comment field + EOS */
X#define IDLEN 6		/* Size of ID field + EOS */
X#define WPLEN 65	/* Size of WP field + EOS */
X
Xstruct lat_lon{
X	double rad;	/* radians */
X	double deg;	/* decimal degrees */
X};
Xstruct fix{
X	struct lat_lon lat;
X	struct lat_lon lon;
X};
Xstruct vor{
X	char id[IDLEN];		/* Three letter ID */
X	char name[NAMLEN];	/* Full name of VOR */
X	struct fix loc;		/* Location of the VOR */
X	double var;		/* Magnetic variation in decimal degrees */
X	float freq;		/* Radio frequency */
X	char comments[COMLEN];	/* Comments (optional) */
X	char waypoint[WPLEN];	/* Waypoint (not in VORS entry) */
X};
Xstruct apt{
X	char id[IDLEN];		/* Three letter ID */
X	char city[NAMLEN];	/* Name of nearest city */
X	char name[NAMLEN];	/* Name of airport */
X	int alt;		/* Altitude of airport in feet */
X	struct fix loc;		/* Location of the airport */
X	double var;		/* Magnetic variation in decimal degrees */
X	char comments[COMLEN];	/* Comments (optional) */
X};
!E_O_F!
echo extracting - nav.horg
sed 's/^X//' > nav.horg << '!E_O_F!'
X/*
X *	Defines and structs for nav navigation program
X */
X
X#define EARTH_RADIUS (6873.748728)		/* radius of earth in NM */
X#define EARTH_RADIUS_STAT (7915.6)		/* radius of earth in miles */
X
X#define pi (3.1415926535897932384626433)
X#define MAXAPTS 512	/* Maximum number of airports in APTarray */
X#define MAXVORS 512	/* Maximum number of VORs in VORarray */
X#define MAXVIA 64	/* Maximum number of VORs in ViaArray */
X#define NAMLEN 32	/* Size of name fields */
X#define COMLEN 64	/* Size of comment fields */
X#define IDLEN 4		/* Size of ID fields */
X
Xstruct lat_lon{
X	double rad;	/* radians */
X	double deg;	/* decimal degrees */
X};
Xstruct fix{
X	struct lat_lon lat;
X	struct lat_lon lon;
X};
Xstruct vor{
X	char id[IDLEN];		/* Three letter ID */
X	char name[NAMLEN];	/* Full name of VOR */
X	struct fix loc;		/* Location of the VOR */
X	double var;		/* Magnetic variation in decimal degrees */
X	float freq;		/* Radio frequency */
X	char comments[COMLEN];	/* Comments (optional) */
X};
Xstruct apt{
X	char id[IDLEN];		/* Three letter ID */
X	char city[NAMLEN];	/* Name of nearest city */
X	char name[NAMLEN];	/* Name of airport */
X	int alt;		/* Altitude of airport in feet */
X	struct fix loc;		/* Location of the airport */
X	double var;		/* Magnetic variation in decimal degrees */
X	char comments[COMLEN];	/* Comments (optional) */
X};
!E_O_F!
echo extracting - airports
sed 's/^X//' > airports << '!E_O_F!'
X#
X#	The fields in this file are in this order:
X#		ID	up to three letters, in caps
X#		City	name of nearest city, up to 32 chars
X#		Name	airport name, up to 32 chars
X#		Alt	airport altitude in feet
X#		Variation	west magnetic variation in degrees and minutes
X#		Latitude	north latitude, degrees and minutes
X#		Longitude	west longitude, degrees and minutes
X#		Comments	optional
X#
X#
X#	Each line in this and the vors file must either have a data entry or
X#	a comment line.
X#
X#	test stuff
X#
XP1:San Francisco:Harbor:0:0:0:37:49:122:25:
XP2:Tokyo:Harbor:0:0:0:35:40:-139:45:
X#
X#	Colorado
X#
XDRAKO:V-85:Intersection:0:-12:0:40:15.4:105:18.3:
XKDEN:Denver, CO:Stapleton Int'l:5333:-12:0:39:46.5:104:52.6:atis 125.6
X#
X#	Idaho
X#
XIDA:Idaho Falls, ID:Fanning:4741:-17:0:43:31.0:112:04.0:
X#
X#	Nebraska
X#
XIDA:Idaho Falls, ID:Fanning:4741:-17:0:43:31.0:112:04.0:
XOMA:Ohaha, NE:Eppley Field:983:-7:12:41:18.1:95:53.6:
X#
X#	Texas
X#
XHOU:Houston, TX:William P. Hobby:47:-6:30:29:38.7:95:16.7:
X#
X#	Utah
X#
XKSLC:Salt Lake City, UT:Salt Lake City Int'l:4227:-15:0:40:47.2:111:58.1:atis 124.75
X#
X################### original airports file ################################
X#
X#	California
X#
XACV:Arcata-Eureka:Arcata:218:-18:0:40:59:124:6:
XAPC:Napa:Napa County:33:-16:0:38:13:122:17:rght tffc ry 18
XAUN:Auburn:Auburn Municipal:1520:-16:45:38:57:121:5:
XBIH:Bishop:Bishop:4118:-15:25:37:22:118:22:
XBFL:Bakersfield:Meadows:490:-14:50:35:26:119:3:rght tffc ry 12R, 30R
XBUR:Burbank:Burbank:775:-14:15:34:12:118:21:rght tffc ry 15
XCCR:Concord:Buchannan:23:-16:23:37:59:122:3:
XCMA:Camarillo:Camarillo:79:-14:28:34:13:119:6:no strght in ry 26
XCOL:Columbia:Columbia:2112:-16:0:38:2:120:25:rght tffc ry 17, 11 11/29:turf
XEKA:Eureka:Murray:7:-18:0:40:48:124:7:rght tffc ry 29, 25
XGN:Novato:Gnoss:1:-16:30:38:9:122:33:Just plain suicidal. Ctn: Bonanzas.
XNC:Grass Valley:Nevada County Airpark:3150:-16:45:39:13:121:0:No tkffs ry 7
XHAF:Half Moon Bay:Half Moon Bay:67:-16:15:37:31:122:30:No strght in appch, rght tffc ry 30
XHR:Coalinga:Harris Ranch:465:-15:0:36:15:120:14:rght tffc ry 14
XLAX:Los Angeles:Los Angeles International:126:-15:30:33:57:118:24:lgt acft not recc
XLR:Little River:Mendocino:572:-16:0:39:16:123:45:Fog summers
XLVK:Livermore:Livermore Municipal:397:-16:15:37:42:121:49:
XMHV:Mojave:Mojave:2787:-14:30:35:4:118:9:rght tffc ry 25, 30
XMRY:Monterey:Monterey:244:-15:45:36:35:121:51:Rstrctd areas adj N & NE
XMYF:San Diego:Montgomery:423:-13:42:32:48.9:117:8.3:Noise Abate
XNT:Vacaville:Nut Tree:113:-16:0:38:23:121:58:rght tffc ry 19
XOAK:Oakland:Oakland Metro:6:-16:0:37:43:122:13:
XPRB:Paso Robles:Paso Robles Municipal:836:-15:15:35:40:120:38:
XPSR:Petaluma:Petaluma Sky Ranch:79:-16:35:38:16:122:37:P-lns ry 11
XRBL:Red Bluff:Red Bluff Municipal:349:-17:23:40:9:122:15:lgts & REIL on req aft 2200 thru FSS
XSAC:Sacramento:Sacramento Executive:21:-16:30:38:31:121:30:rght tffc ry 2,34,30
XSAN:San Diego:Lindbergh:15:-13:40:32:44:117:11.2:Noise Abate
XSCK:Stockton:Stockton Metro:30:-16:10:37:54:121:14:
XSDM:San Diego:Brown Municipal:524:-13:35:32:34.3:116:58.7:Ctn don't overfly Mex
XSEE:San Diego-El Cajon:Gillespie:385:-13:40:32:49.5:116:58.3:Noise Abate
XSFO:San Francisco:San Francisco International:11:-16:15:37:37:122:22:Fee
XSJC:San Jose:San Jose International:56:-16:5:37:22:121:56:
XSR:San Rafael:Smith Ranch:5:-16:25:38:1:122:31:night and IFR suicidal
XSRN:The Sea Ranch:Sea Ranch:360:-16:45:38:42:123:26:clsd to pub, hump in ctr of ry
XSTS:Santa Rosa:Sonoma County:125:-16:0:38:31:122:49:
XTRM:Thermal:Thermal:117:-13:45:33:38:116:10:
XTVL:South Lake Tahoe:Lake Tahoe:6264:-16:20:38:54:120:0:rght tffc ry 36
X#
X#	Nevada
X#
XLAS:Las Vegas:McCarran International:2174:-14:16:36:4.9:115:9.2:
XRNO:Reno:Cannon International:4412:-16:35:39:29.8:119:46:
X#	Oregon
X#
X#
XAS:Aurora State (Wilsonville):Aurora State:195:-19:50:45:15:122:46:
XHIO:Portland-Hillsboro:Hillsboro:204:-19:0:45:32:122:57:rght tffc ry 2, 30
XLMT:Klamath Falls:Kingsley:4092:-18:20:42:09:121:44:Birds, jets. Two-way com req'd. Ry 18/36 days only
XPDX:Portland:Portland International:26:-19:55:45:35:122:36:Ctn: balloon 600 AGL 4mi W.
XSP:Ashland:Sumner Parker:1894:-18:55:42:12:122:40:Pole ry 12. P-lns E.
X#
X#	Utah
X#
XSLC:Salt Lake City:Salt Lake City Int:4227:-14:0:40:47.2:111:58:
!E_O_F!
echo extracting - vors
sed 's/^X//' > vors << '!E_O_F!'
X#
X#	The fields in this file are in this order:
X#		ID	up to three letters, in caps
X#		Name	VOR name, up to 32 chars
X#		Freq	VOR frequency
X#		Variation	west magnetic variation in degrees and minutes
X#		Latitude	north latitude, degrees and minutes
X#		Longitude	west longitude, degrees and minutes
X#		Comments	optional
X#
X#	test stuff
X#
XW1:waypoint 1:0:0:0:47:46.1:155:0:
XW2:waypoint 2:0:0:0:47:36.17:-175:0:
X#
X#	Colorado VORs
X#
XCHE:Hayden:115.4:-14:0:40:31.2:107:18.2:D H 2.35 2.6
XDEN:Denver:117.0:-12:0:39:48.0:104:53.2:2.35 2.6
XPUB:Pueblo:116.7:-13:0:38:17.7:104:25.7:D H 2.35 2.6
XTBE:Tobe:115.8:-12:0:37:15.5:103:36.0:D L 2.2 2.65
X#
X#	Idaho VORs
X#
XIDA:Idaho Falls:109.0:-17:0:43:31.2:112:03.8:D L 2.2 2.55
X#
X#	Nebraska VORs
X#
XCDR:Chadron:113.4:-13:0:42:33.5:103:18.7:D L 2.2 3.6
XOBH:Wolbach:114.8:-10:0:41:22.6:98:21.2:D H 2.2 2.45
X#
X#	Texas VORs
X#
XACT:Waco:115.3:-9:0:31:39.7:97:16.1:D H 2.2 2.6
XAQN:Acton:110.6:-9:0:32:26.1:97:39.8:D L 2.2 2.6
XAMA:Amarillo:117.2:-11:0:35:17.3:101:38.3:D H 2.2 2.65
XCDS:Childress:117.6:-10:0:34:22.1:100:17.3:D L 2.2 2.45
XDHT:Dalhart:112.0:-12:0:36:05.5:102:32.7:D L 2.2 3.6
XIAH:Humble:116.6:-8:0:29:57.4:95:20.7:D H 2.35 2.4
XMQP:Millsap:117.7:-9:0:32:43.6:97:59.8:D H 2.2 2.6
XRLG:Kremmling:113.8:-14:0:40:00.2:106:26.5:D L 2.2 3.6
X#
X#	Utah VORs
X#
XSLC:Salt Lake City:116.8:-15:0:40:51.0:111:58.9:
X#
X#	Wyoming
X#
XBPI:Big Piney:116.5:-16:0:42:34.8:110:06.5:D L 2.2 2.6
XCKW:Cherokee:112.2:-15:0:41:45.4:107:34.9:D L 2.2 3.6
XCPR:Casper:116.2:-15:0:43:05.5:106:16.6:D L
XRIW:Riverton:108.8:-16:0:43:04.0:108:27.3:T 2.2 2.4
XRKS:Rock Springs:114.7:-16:0:41:35.4:109:00.9:D H 2.2 2.6
X#
X################## original vors file ################################
X#
X#	VORs from the Klamath Falls sectional chart
X#
XEUG:Eugene:112.9:-19:17:44:7:123:13:tweb
XFJS:Fort Jones:109.6:-18:0:41:27:122:48:tweb
XLMT:Klamath Falls:115.9:-18:10:42:9:121:44:tweb
XOED:Medford:113.6:-18:30:42:28:122:55:tweb
XRBG:Roseburg:108.2:-18:52:43:11:123:21:tweb
XRDD:Redding:108.4:-17:30:40:31:122:18:tweb
X#
X#	VORs from the San Francisco sectional chart
X#
XBIH:Bishop:109.6:-15:25:37:22:118:22:
XBSR:Big Sur:114.0:-15:35:36:10.5:121:38:
XCIC:Chico:109.8:-17:7:39:47:121:51:
XCCR:Concord:117.0:-16:23:38:2:122:3:
XENI:Mendocino:112.3:-16:55:39:3:123:16:
XFAT:Fresno:112.9:-15:31:36:53:119:48:
XFRA:Friant:115.6:-15:35:37:5:119:36:
XHNW:Hangtown:115.5:-16:25:38:43:120:16:
XHZN:Hazen:114.1:-16:25:39:31:119:0:
XILA:Williams:114.4:-16:45:39:4:122:2:
XLIN:Linden:114.8:-16:10:38:4:121:0.5:
XLOL:Lovelock:116.5:-16:35:40:4:118:33.5:
XLTA:Lake Tahoe:113.2:-16:35:39:10.5:120:16:
XMCE:Merced:114.2:-15:45:37:13:120:24:
XMXW:Maxwell:110.0:-16:55:39:19:122:23:
XMYV:Marysville:110.8:-16:45:39:6:121:34:
XOAK:Oakland:116.8:-16:16:37:43:122:13:
XOSI:Woodside:113.9:-16:9:37:23.5:122:17:
XPYE:Point Reyes:113.7:-16:30:38:5:122:52:
XPXN:Panoche:112.6:-15:40:36:43:120:47:
XRBL:Red Bluff:115.7:-17:22:40:5.5:122:14:
XRNO:Reno:117.9:-16:35:39:31.5:119:39.5:
XROM:Priest:110.0:-15:25:36:8:120:40:
XSAC:Sacramento:115.2:-16:30:38:26:121:33:
XSAU:Sausalito:116.2:-16:22:37:51:122:31:
XSCK:Stockton:116.0:-16:10:37:50:121:10:
XSFO:San Francisco:115.8:-16:15:37:37:122:22:
XSGD:Skaggs Island:112.1:-16:30:38:11:122:22:
XSJC:San Jose:114.1:-16:5:37:22:121:56:
XSNS:Salinas:117.3:-15:45:36:40:121:36:
XSTS:Santa Rosa:113.0:-16:40:38:31:122:49:
X#
X#	VORs from Los Angeles sectional chart
X#
XAVE:Avenal:117.1:-15:4:35:36:119:58.7:
XBFL:Bakersfield:115.4:-14:50:35:29:119:5.8:
XBLH:Blythe:117.4:-13:30:33:6:114:45:
XCMA:Camarillo:115.8:-14:27:34:12:119:2.5:
XDAG:Daggett:113.2:-14:15:34:57.5:116:35:
XFIM:Fillmore:112.5:-14:27:34:21:118:52.5:
XFLW:Fellows:117.5:-14:50:35:5.5:119:52:
XGFS:Goffs:114.4:-14:2:35:8:115:10.5:
XGMN:Gorman:116.1:-14:35:34:48:118:51.5:
XGVO:Gaviota:116.5:-14:40:34:32:120:5.5:IN PROHIBITED AREA P-66
XHEC:Hector:112.7:-14:10:34:48:116:27.5:
XIPL:Imperial:115.9:-13:22:32:45:115:30.5:
XJLI:Julian:114.0:-13:37:33:8:116:35:
XLAX:Los Angeles:113.6:-14:15:33:56:118:26:
XLHS:Lake Hughes:108.4:-14:29:34:41:118:34:
XMRX:March:113.4:-13:55:33:46.5:117:11:
XMZB:Mission Bay:117.8:-13:37:32:47:117:13.5:
XMXL:Mexicali:115.0:-13:20:32:38:115:13.5:VOR is in Mexico
XNZJ:Marine El Toro:117.2:-14:0:33:40.5:117:43.5:
XOCN:Oceanside:115.3:-13:45:33:14:117:25:
XPDZ:Paradise:112.2:-14:5:33:55:117:32:
XPGY:Poggi:109.8:-13:33:32:36:116:59:
XPKE:Parker:117.9:-13:40:34:6:114:41:
XPMD:Palmdale:114.5:-14:26:34:38:118:4:on Palmdale AFB
XPOM:Pomona:110.4:-14:10:34:4:117:47:
XPRB:Paso Robles:114.3:-15:15:35:40:120:38:
XPSP:Palm Springs:115.5:-13:50:33:52:116:26:
XPTV:Porterville:109.2:-15:0:35:55:119:1:
XSBA:Santa Barbara:114.9:-14:35:34:30.5:119:46:
XSBP:San Luis Obispo:112.4:-15:6:35:15:120:45.5:
XSLI:Seal Beach:115.7:-14:7:33:47:118:3:
XSXC:Santa Catalina:111.4:-14:57:33:22.5:118:25:
XTIJ:Tijuana:116.5:-13:32:32:32.5:116:58:Ctn IN MEXICO
XTNP:Twentynine Palms:114.2:-13:52:34:6.5:115:46:
XTRM:Thermal:116.2:-13:45:33:38:116:10:
X#
X#	VORs from Las Vegas sectional chart
X#
XBLD:Boulder City:116.7:-14:15:36:0:114:52:
XLAS:Las Vegas:116.9:-14:16:36:4.9:115:9.2:
!E_O_F!
----------end nav.sh----------------------------------
-- 
Linn Hower	Phone: 208-526-9353
   ...!ucbvax!ucdavis!midacs!isew02!linn