[net.ham-radio] GRIDX Program in Basic

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