dna@dsd.UUCP (02/28/84)
Posted: Mon Feb 20, 1984 6:11 PM PST Msg: RGIE-1721-7533
From: TCLARK
To: docs
Subj: GRIDX program notes
The program GRIDX.BAS is intended to provide a simple way for AMSAT
members to calculate the "Maidenhead" grid square designators on their
home computers. This program allows input in either Longitude/Latitude
or Grid Square formats and will calculate the other format.
If a grid square is given to less than 6 character precision on input,
the center of the square defined by the characters is assumed. For
example, W3IWI at 76.936 degrees west and 39.185 degrees north yields
grid square FM19ME. If the grid location FM19 is specified, then the
center of FM19, which is at FM19LL is assumed. From my location, this
is about 30 km away.
Another feature of this program is that it gives you the range (along
the surface of the earth) and azimuth from the first station entered
(called 'home') to the target stations.
The GRIDX program was adapted from an earlier W3IWI program called
GRID (which was rather machine specific). It was written and tested in
North-Star (N*) disk basic (running under CP/M) and runs in N*, SoHo
or BAZIC as is. I wrote the program with transportability in mind. The
major N* "quirk" that you should have to adapt to other dialects is in
the area of string notation. N* explicitly calls out string members.
For example, if G$="ABCDEFGHI", then G$(3,5)="CDE". Microsoft uses the
MID$ function to accomplish this and would get the same sub-string
with MID$(G$,3,3). Similarly, G$(1,1) in N* is "A"; to get this in
Microsoft, you would use either LEFT$(G$,1) or MID$(G$,1,1). Another
minor change that is necessary (line 1830) is to change N*'s SQRT to
SQR in most other dialects.
When any of you get versions of this or other "grid" programs running,
please make them available thru the AMSAT Software Exchange.
73, Tom
Posted: Mon Feb 20, 1984 6:13 PM PST Msg: DGIE-1721-7539
From: TCLARK
To: DOCS
Subj: GRIDX Program in BASIC
10 DIM G$(10),T$(5),U$(5)
20 DIM X0$(60),X1$(60),X2$(60),X3$(60),X4$(60),X5$(60),X6$(60),X7$(60)
30 E9=1E-6 : T=50 : REM -- Small number & Tab location for responses
40 P1=3.1415926535 : P2=P1/180 : REM -- PI, Deg =>= Radians
50 I=0 : REM -- Pass counter ( for DO WHILE .not. Quit loop )
60 REM
70 REM -- Sign-on message and initialization
80 X0$="--------------------------------------------------------"
90 X1$="I I"
100 X2$="I Maidenhead Grid Square Utility Program = GRIDX I"
110 X3$="I (C) 1984 Dr. Thomas A. Clark, W3IWI I"
120 X4$="I 6388 Guilford Road I"
130 X5$="I Clarksville, MD 21029 I"
140 X6$="I Permission is granted for non-profit, amateur I"
150 X7$="I usage providing credit is given to the author. I"
160 REM ------------------------------------- TAC 20 Feb 84 ---
170 PRINT X0$ : PRINT X1$ : PRINT X2$ : PRINT X1$
180 PRINT X3$ : PRINT X4$ : PRINT X5$ : PRINT X1$
190 PRINT X6$ : PRINT X7$ : PRINT X1$ : PRINT X0$
200 PRINT
210 REM
220 REM -- Loop to get station info
230 PRINT "In the following, enter West Longitude and Latitude in"
240 PRINT "units of degrees and decimals" : PRINT
250 I=I+1 : PRINT : REM -- Start of loop
260 IF I > 1 THEN 300
270 PRINT "Coordinates of 'home' station:" : GOTO 500
280 REM
290 REM -- Get target station info
300 PRINT "Target: C=Coordinates, G=Grid, Q=Quit",TAB(T), : INPUT T$
310 T$=T$(1,1) : IF T$="C" THEN 490
320 IF T$="c" THEN 490
330 IF T$="G" THEN 400
340 IF T$="g" THEN 400
350 IF T$="Q" THEN STOP
360 IF T$="q" THEN STOP
370 PRINT "INVALID ENTRY -- TRY AGAIN" : GOTO 300
380 REM
390 REM--Grid Square entry for target station
400 PRINT "Enter Grid Square",TAB(T), : INPUT G$
410 GOSUB 1220 : IF L3=6 THEN 430
420 PRINT "Grid square was padded to middle of cell = ",TAB(T),G$
430 GOSUB 1450 : GOSUB 1500
440 PRINT "Coordinates: W.Longitude = ",TAB(T),W," Deg.W"
450 PRINT " Latitude = ",TAB(T),L," Deg."
460 GOTO 560
470 REM
480 REM -- Coordinate entry for either home or target station
490 PRINT "Coordinates of station # ",I," :"
500 PRINT "West Longitude =", TAB(T), : INPUT W
510 PRINT " Latitude =", TAB(T), : INPUT L
520 GOSUB 1090 : PRINT " Grid Square = ",TAB(T),G$
530 IF I = 1 THEN 620 : REM -- Exit to initialize "home" station
540 REM
550 REM -- Calculate Azimuth and bearing to target station
560 GOSUB 1770
570 PRINT "Azimuth to target station = ",TAB(T),A," Deg."
580 PRINT " Range = ",TAB(T),R,U$
590 GOTO 250
600 REM
610 REM--Initialization for "home" station
620 W5=W*P2 : L5=L*P2 : S5=SIN(L5) : C5=COS(L5) : REM -- Trigonometry
630 PRINT
640 PRINT "Do you want Ranges in Km, Miles or Nautical Miles ?"
650 PRINT " Enter K, M or N", TAB(T), : INPUT U$ : U$=U$(1,1)
660 REM
670 REM--Constants defined as U are the mean radius of the earth
680 IF U$="K" THEN 710
690 IF U$="k" THEN 710
700 GOTO 720
710 U$=" Km. " : U=6366.20 : GOTO 250
720 IF U$="M" THEN 750
730 IF U$="m" THEN 750
740 GOTO 760
750 U$=" Miles" : U=3956.09 : GOTO 250
760 IF U$="N" THEN 790
770 IF U$="n" THEN 790
780 PRINT "INVALID ENTRY -- TRY AGAIN" : GOTO 640
790 U$=" N.Mi." : U= 60/P2 : GOTO 250
1000 REM ---------------------
1010 REM -- Subroutine to convert Longitude and Latitude to Grid Square
1020 REM Call with W=West Longitude (e.g. Chicago = +88 degrees)
1030 REM and L=Latitude (+ for Northern Hemisphere).
1040 REM The units for both W and L are degrees.
1050 REM
1060 REM On Completion, the string G$ contains the "Maidenhead"
1070 REM Grid Square as a 6-character string.
1080 REM
1090 W3=180-W : IF W3<0 THEN W3=W3+360
1100 W1=INT(W3/20+E9)
1110 W2=INT((W3-20*W1)/2+E9)+48 : W1=W1+65
1120 W3=INT(24*(W3/2-INT(W3/2)+E9))+65
1130 L1=INT((L+90)/10+E9) : L2=INT(L+90+E9-10*L1)
1140 L3=INT((L+90-10*L1-L2)*24+E9) : L1=L1+65 : L2=L2+48 : L3=L3+65
1150 G$=CHR$(W1)+CHR$(L1)+CHR$(W2)+CHR$(L2)+CHR$(W3)+CHR$(L3)
1160 RETURN
1170 REM ---------------------
1180 REM -- Subroutine to Pad Grid Square to middle of a cell if
1190 REM all 6 characters are not given. This routine also checks
1200 REM the validity of the square and kills program if not correct.
1210 REM
1220 L3=LEN(G$) : IF L3>6 THEN 1400
1230 IF L3=6 THEN 1270
1240 IF L3 < 4 THEN 1260 ELSE G$=G$(1,4)+"LL"
1250 GOTO 1270
1260 IF L3 < 2 THEN 1400 ELSE G$=G$(1,2)+"55LL"
1270 IF G$(1,1) < "A" THEN 1400
1280 IF G$(1,1) > "R" THEN 1400
1290 IF G$(2,2) < "A" THEN 1400
1300 IF G$(2,2) > "S" THEN 1400
1310 IF G$(3,3) < "0" THEN 1400
1320 IF G$(3,3) > "9" THEN 1400
1330 IF G$(4,4) < "0" THEN 1400
1340 IF G$(4,4) > "9" THEN 1400
1350 IF G$(5,5) < "A" THEN 1400
1360 IF G$(5,5) > "X" THEN 1400
1370 IF G$(6,6) < "A" THEN 1400
1380 IF G$(6,6) > "X" THEN 1400
1390 RETURN
1400 PRINT " ***** INVALID GRID SQUARE = ",G$," ***** ABORTED *****"
1410 STOP
1420 REM ---------------------
1430 REM -- Subroutine to convert Grid Square=G$ to West Longitude=W
1440 REM with W returned in degrees and fractions
1450 W1=ASC(G$(1,1))-65 : W2=ASC(G$(3,3))-48 : W3=ASC(G$(5,5))-65
1460 W=180 -20*W1 -2*W2 -W3/12 -1/24 : IF W<0 THEN W=360+W
1470 RETURN
1480 REM ---------------------
1490 REM -- Subroutine to convert Grid Square=G$ to Latitude=L
1500 L1=ASC(G$(2,2))-65 : L2=ASC(G$(4,4))-48 : L3=ASC(G$(6,6))-65
1510 L=-90 +10*L1 +L2 +L3/24 +1/48
1520 RETURN
1530 REM ---------------------
1540 REM -- Subroutine to calculate distance and azimuth between stations
1550 REM
1560 REM On entry, W and L are the second stations west longitude
1570 REM and Latitude. The first ("home") station should already have
1580 REM its coordinates available as
1590 REM S5=Sin(Latitude), C5=Cos(Latitude), W5=W.Long (radians)
1600 REM
1610 REM In the following, P2 has the value PI/180 to convert degrees
1620 REM to radians. U is the units conversion constant of Km, miles,
1630 REM or N.Miles per mean earth radius (see note below).
1640 REM
1650 REM On exit, R is the range along a great circle from the "home"
1660 REM station to the remote station in the units defined by U.
1670 REM A is the azimuth (bearing) from the "home" station to the
1680 REM second station along the great circle connecting them.
1690 REM
1700 REM This routine makes a simplifying approximation that the earth
1710 REM is a sphere of radius U. Actually, the earth is an oblate
1720 REM Sphereoid with the polar radius 1 part in 300 less than the
1730 REM equatorial radius. This approximation leads to errors up to
1740 REM about 30 km and a fraction of a degree on ranges and azimuths
1750 REM to very distant stations.
1760 REM
1770 W6=W*P2 : L6=L*P2 : S6=SIN(L6) : C6=COS(L6)
1780 C=S5*S6 + C5*C6*COS(W6-W5) : IF ABS(C)>1 THEN C=SGN(C)
1790 S=SQRT(1-C*C) : X=ATN(S/C) : IF C<0 THEN X=X+P1
1800 R=U*X : IF S<>0 THEN 1820 ELSE A=0
1810 RETURN
1820 C1=(S6-S5*C)/(S*C5) : IF ABS(C1)>1 THEN C1=SGN(C1)
1830 S1=SQRT(1-C1*C1) : A=ATN(S1/ABS(C1))/P2 : S3 = SIN(W5-W6)
1840 IF S3<0 THEN A=-A
1850 IF C1<0 THEN A=180-A
1860 IF A<0 THEN A=A+360
1870 IF A>360 THEN A=A-360
1880 RETURN
1890 REM ---------------------
9999 END