home *** CD-ROM | disk | FTP | other *** search
- '***********************************************
- '*
- '* Map digitizer program
- '*
- '* By W7KKE
- '*
- '-----------------------------------------------
- ' Modification History
- '------------------------------------------------
- ' date by comments
- '------------------------------------------------
- ' 090193 W7KKE Created program
- ' 112893 W7KKE 1. Fixed com port specification syntax.
- ' 2. Prohibited creation of a zero while building
- ' map, otherwise ARPS thinks its an end of segment marker.
- ' 3. Clarified map scale selection menu.
- '***********************************************
- CLS
- PRINT
- PRINT "This program converts digitizer coordinates to latitude and longitude"
- PRINT
- PRINT "A Mercator projection chart is expected. Other types, such as Lambert Conformal,"
- PRINT "Conical, etc., will induce distortions."
- PRINT
- PRINT "It has not been tested with East Longitude or South Latitude."
- PRINT
- PRINT "The expected digitzer is a GE Calma which uses a 4000 x 4000 grid"
- PRINT "with grid origin in the lower left corner. The max number of points"
- PRINT "the program will take for each map section, i.e. coastline, road, etc.,"
- PRINT "is set to 100."
- PRINT
-
- startit:
- 'Clear all arrays and variables
- CLEAR , , 4000' Increase stack size. Default stack size is 2048 bytes.
-
- 'Set comport parameters
- port$ = "COM2:"
- baud$ = "9600"
- parity$ = "E"
-
- ' Set number of data bits to be compatible with parity
- IF parity$ <> "N" THEN dtabits$ = "7" ELSE dtabits$ = "8"
-
- 'Zero variables
- segm = 0
- i = 0
-
- 'Dimension arrays for map
- DIM segcolor(75)
- DIM seglable$(75)
- DIM hiposit(75)
- DIM pixlat(75, 200)
- DIM pixlong(75, 200)
-
- 'Dimension labels
- DIM lablat(100)
- DIM lablong(100)
- DIM labrng(100)
- DIM N$(100)
-
-
- PRINT
- PRINT "The serial port is currently configured for ";
- PRINT port$; " at "; baud$; " baud "; parity$;
- PRINT " parity with "; dtabits$; "data bits."
- PRINT
- INPUT "Press <ENTER> to continue"; r$
- CLS
-
- REM First establish scale on digitizer and x/y conversion.
- PRINT
- PRINT "Establish scale on digitizer."
- PRINT
- PRINT "The scale is established by two points, the first near the"
- PRINT "upper left corner, the second near the lower right corner."
- PRINT
- PRINT "Establish the upper left reference point:"
- INPUT " Enter lat (deg,min)"; latdeg1, latmin1
- INPUT " Enter long (deg,min)"; longdeg1, longmin1
- PRINT
-
- digion:
- REM Open digitizer port
- portspec$ = port$ + baud$ + "," + parity$ + "," + dtabits$ + ",1,asc,cd0,cs0,ds0,op0"
- OPEN portspec$ FOR INPUT AS #2
-
- penget: PRINT "Place digitizer pen on upper left point."
- INPUT #2, in$
- SOUND 150, 5
- REM Following causes loop for debugging digitizer board
- REM PRINT MID$(in$, 2, 4); " "; RIGHT$(in$, 4)
- REM GOTO penget
- digix1 = 4000 - VAL(MID$(in$, 2, 4))
- digiy1 = VAL(RIGHT$(in$, 4))
- PRINT "Digitizer reads "; digix1, digiy1; " for this point."
- PRINT
-
- PRINT "Establish the lower right reference point:"
- INPUT " Enter lat (deg,min)"; latdeg2, latmin2
- INPUT " Enter long (deg,min)"; longdeg2, longmin2
- PRINT
- PRINT "Place digitizer pen on lower right point."
- INPUT #2, in$
- SOUND 150, 5
- digix2 = 4000 - VAL(MID$(in$, 2, 4))
- digiy2 = VAL(RIGHT$(in$, 4))
- PRINT "Digitizer reads "; digix2, digiy2; " for this point."
- PRINT
-
- REM Find delta lat/long between reference points
- REM Convert lat & long to decimal values from degrees and minutes
-
- dlat1# = latdeg1 + (latmin1 / 60)
- dlong1# = longdeg1 + (longmin1 / 60)
-
- dlat2# = latdeg2 + (latmin2 / 60)
- dlong2# = longdeg2 + (longmin2 / 60)
-
- REM Calculate the difference in lat long for conversion factor
- deltalat# = dlat1# - dlat2#
- deltalong# = dlong1# - dlong2#
-
- REM Calculate the X/Y difference between the two reference points.
- deltadigx = digix1 - digix2
- deltadigy = digiy1 - digiy2
-
- REM Calculate degrees per x/y unit
- degx# = deltalong# / deltadigx
- degy# = deltalat# / deltadigy
-
-
- REM Now set up APRS specific map data
- PRINT
- PRINT "Large areas (Continents) 6 pixels per degree"
- PRINT "Large States/Regions 60 pixels per degree"
- PRINT "States 120 pixels per degree"
- PRINT "Cities 1200 pixels per degree "
- PRINT "Neighborhoods 2400 pixels per degree"
- PRINT "Very fine detail 4800 pixels per degree"
- PRINT
- INPUT "Enter map scale in pixels"; pix
- PRINT
- PRINT "Using "; pix; " pixels per degree"
-
- ' Calculate minimum zoom range to keep display from crashing
-
- IF pix <= 60 THEN minrng = 4
- IF pix > 60 AND pix < 1200 THEN minrng = .5
- IF pix >= 1200 THEN minrng = .25
-
- PRINT "Minimum map range will be "; minrng; " nm."
-
-
-
- PRINT
- PRINT "Enter the origin lat/long for pixel 0/0 reference point"
- PRINT "(Use an even lat/long - no minutes, at upper left of map.)."
- INPUT "Enter latitude origin"; olat
- INPUT "Enter longitude origin"; olong
-
- PRINT
-
- centlatin:
- INPUT "Enter center latitude (deg,min)"; cenlatdeg, cenlatmin
- IF cenlatdeg > 90 THEN GOTO centlatin
- IF cenlatdeg < -90 THEN GOTO centlatin
- IF centlatmin >= 60 THEN GOTO centlatin
-
-
- centlongin:
- INPUT "Enter center longitude (deg,min)"; cenlongdeg, cenlongmin
- IF cenlogdeg > 180 THEN GOTO centlongin
- IF cenlogdeg < -180 THEN GOTO centlongin
- IF cenlongmin >= 60 THEN GOTO centlongin
-
- 'Convert degrees & minutes to decimal degrees
-
- dlat = cenlatdeg + (cenlatmin / 60)
- dlong = cenlongdeg + (cenlongmin / 60)
-
- 'Save in unique variable name for file print routine
- cendlat = dlat
- cendlong = dlong
-
- 'PRINT dlat, dlong ' For debugging
-
- PRINT
- INPUT "Enter map range (nm)"; maprng
- PRINT
-
-
- PRINT
- INPUT "Enter name for this map"; name$
- PRINT "Start entering points. Press 'F1' and tap digitizer pen on completion of data entry."
- ON KEY(1) GOSUB getout
-
- REM Start plotting points
- REM Continuous loop until F1 pressed
- enterseg:
- i = 0' zero individual point counter
- segm = segm + 1'Segment counter
- highseg = segm
- GOSUB getcolor
- segcolor(segm) = segcolor
- seglable$(segm) = r$
-
- PRINT "Point to first position on map"
- KEY(1) ON
- getposits:
- INPUT #2, in$
- SOUND 150, 5
- x = 4000 - VAL(MID$(in$, 2, 4))
- y = VAL(RIGHT$(in$, 4))
-
- dlat# = ((y - digiy2) * degy#) + dlat2#
- dlong# = ((x - digix2) * degx#) + dlong2#
-
- latmin = (dlat# - INT(dlat#)) * 60
- longmin = (dlong# - INT(dlong#)) * 60
-
- i = i + 1
- hiposit(segm) = i
- PRINT "Segment "; segm; " point "; i; " ";
- PRINT INT(dlat#); " deg "; latmin; "'"; " ";
- PRINT INT(dlong#); " deg "; longmin; "'"
-
- REM Convert lat/long to pixels
- GOSUB pixels:
- pixlat(segm, i) = pixlat
- pixlong(segm, i) = pixlong
-
- GOTO getposits
- END ' Should never get here
-
- REM***********
-
- labels: 'Routine to enter named labels on screen
- i = 0
- KEY(1) OFF
- CLS
- PRINT
- PRINT "Now starting entry of named geographic points for map."
-
- entlabels:
- i = i + 1
- maxlabel = i
- PRINT "Enter 'Q' for main menu"
- INPUT "Label name"; N$(i)
- IF N$(i) = "Q" OR N$ = "q" THEN GOTO getout
- PRINT "Place pen at point and press. "
- INPUT #2, in$
- SOUND 150, 5
- x = 4000 - VAL(MID$(in$, 2, 4))
- y = VAL(RIGHT$(in$, 4))
-
- dlat# = ((y - digiy2) * degy#) + dlat2#
- dlong# = ((x - digix2) * degx#) + dlong2#
-
- latmin = (dlat# - INT(dlat#)) * 60
- longmin = (dlong# - INT(dlong#)) * 60
-
- dlat = dlat#
- dlong = dlong#
-
- PRINT "Segment "; segm; " point "; i; " ";
- PRINT INT(dlat#); " deg "; latmin; "'"; " ";
- PRINT INT(dlong#); " deg "; longmin; "'"
-
- INPUT "Range scale you wish label to be displayed"; in
- lablat(i) = dlat
- lablong(i) = dlong
- labrng(i) = in
- PRINT
- GOTO entlabels
-
- savsegs: 'Routine to save data to map file
- CLS
- CLOSE #2
- INPUT "Enter name of map file (filename.map)"; r$
- filename$ = r$
- OPEN filename$ FOR OUTPUT AS #1
-
-
- CLS
- PRINT #1, olat; ", latitude of origin"
- PRINT #1, olong; ", long of origin "
- PRINT #1, pix; ", pixels per degree vert"
- PRINT #1, cendlat; ", Latitude of map center"
- PRINT #1, cendlong; ", Longitude of map center"
- PRINT #1, maprng; ", Map range in miles"
- PRINT #1, minrng; ", Min range for zoom function"
- PRINT #1, name$
-
- FOR k = 1 TO highseg
- PRINT #1, "0,0" 'End of line segment marker
- PRINT #1, segcolor(k); ","; seglable$(k)
- FOR l = 1 TO hiposit(k)
- x = pixlong(k, l)
- y = pixlat(k, l)
- PRINT #1, STR$(x); ","; STR$(y)
- NEXT l
- NEXT k
- PRINT #1, "0,-1"
- PRINT #1, "0, Start map label data"
-
- 'Print label data to file
- FOR i = 1 TO maxlabel - 1
- x = lablat(i)
- y = lablong(i)
- z = labrng(i)
- PRINT #1, N$(i); ","; STR$(x); ","; STR$(y); ","; STR$(z)
- PRINT
- NEXT i
- CLOSE #1
-
- PRINT "Data saved as "; filename$
- PRINT
- INPUT "Press enter to continue"; r$
- GOTO getout
-
- END
-
- 'SUBROUTINES
-
- getcolor: 'Subroutine to select line segment color code
-
- PRINT "Use following color codes:"
- PRINT " Red (4) = secondary roads"
- PRINT " Bright red (12) = important highways"
- PRINT " Green (10) = interstates"
- PRINT " Light blue (11) = rivers & coastlines"
- PRINT " Orange (6) = city/county lines"
- PRINT " Purple (13) = special event routes"
- PRINT
- INPUT "Select color for this line segment"; segcolor
- INPUT "Enter label for this segment"; r$
-
- RETURN
-
- pixels:
-
- ' Find delta lat/long from zero/zero reference point
-
- deltalat = olat - dlat#
- deltalong = olong - dlong#
-
- ' Convert the difference values into pixal values
-
- pixlat = INT(deltalat * pix)
- pixlong = INT(deltalong * pix)
- IF pixlat = 0 THEN
- pixlat = 1
- PRINT "Covernted pixal latitued from 0 to 1"
- END IF
- PRINT "Longitude/Latitude X/Y in pixels ="; pixlong; " / "; pixlat
- PRINT
-
- RETURN
-
- getout: 'Subroutine to getout of entry routines
-
- KEY(1) OFF
- CLS
- PRINT "Select:"
- PRINT " 1) Enter another segment"
- PRINT " 2) Enter named points for display on map (do after all segments)"
- PRINT " 3) Save data to file"
- PRINT " 4) Zero arrays and restart program"
- PRINT " 5) Return to DOS"
- INPUT in
- ON in GOTO enterseg, labels, savsegs, startit, leave
-
- leave: 'exit to DOS
- CLOSE #2
- SYSTEM
- END
-
-