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