'Program name: GPL2ASC.BAS 'Last revised: 08/29/97 ' Version: 1.10 ' Author: Tom Hammond ' E -mail: n0ss@sockets.net <= the '0' is a ZERO not an 'oh' ' Purpose: Convert the contents of a DeLorme GPS LOG (.GPL) ' file into straight ASCII format, for other uses 'Special thanks to John Werner for his assistance in correctly 'defining the record layout and data types. '-------------------------------------------------------------------- ' Copyright (C) 1997 Tom Hammond, All Rights Reserved. ' Copyright protection claimed includes all forms and matters of ' copyrightable material and information now allowed by statutory or ' judicial law or hereinafter granted, including without limitation, ' material generated from the software program which are displayed on ' the screen such as icons, screen display looks, etc. '-------------------------------------------------------------------- DECLARE FUNCTION Num2Dat$ (days&, baseyear%) 'Last touched: 08/28/97 DECLARE FUNCTION Secs2Time$ (seconds!) 'Last touched: 08/28/97 DECLARE SUB ScrnCtr (Ptab%, Stay%, Txt$) 'Last touched: 08/29/97 DEFINT A-Z TYPE GPLDataRec Status AS LONG Dummy1 AS LONG Lat AS DOUBLE Lon AS DOUBLE Alt AS DOUBLE Heading AS DOUBLE Speed AS DOUBLE TIME AS LONG DUMMY2 AS LONG END TYPE DIM DataRec AS GPLDataRec DIM LastLat AS DOUBLE, LastLon AS DOUBLE x = 0 y = 0 False = 0 True = NOT False baseyear% = 1970 'Reference year used by DeLorme for the TIME field DisplayHeader$ = "LinNo RecNo Latitude Longitude Heading Speed" DisplayHeader$ = DisplayHeader$ + " Date Time (Z)" FileHEader$ = "STATUS DUMMY1 LATITUDE LONGITUDE ALT HEADG SPEED" FileHEader$ = FileHEader$ + " DATE TIME (Z) DUMMY2" CLS LOCATE 10, 1 GetFileInName: PRINT TAB(13); "Enter the name of the DeLorme .GPL file to be converted." PRINT PRINT TAB(20); "Input filename: "; COLOR 15 INPUT "", FileIn$ COLOR 7 FileIn$ = UCASE$(FileIn$) IF FileIn$ = "" THEN CLS : END GetFileOutName: 'Create a proposed OUTPUT filename based upon the input filename DotFound = INSTR(FileIn$, ".") IF DotFound THEN FileOut$ = LEFT$(FileIn$, DotFound) + "CNV" ELSE FileOut$ = FileIn$ + ".CNV" END IF SaveToDiskCheck: PRINT PRINT ScrnCtr 0, 0, "Do you wish to output the results to a disk file? " ScrnCtr 0, 0, "If so, the output filename will be: {" + FileOut$ + "}" DO SaveToDisk$ = UCASE$(INKEY$) LOOP UNTIL SaveToDisk$ = "N" OR SaveToDisk$ = "Y" IF SaveToDisk$ = "Y" THEN PRINT PRINT ScrnCtr 0, 0, "Do you wish to add decriptive column labels to the file? " DO ColumnHeaders$ = UCASE$(INKEY$) LOOP UNTIL ColumnHeaders$ = "N" OR ColumnHeaders$ = "Y" END IF DisplayDupeCheck: CLS LOCATE 12, 1 ScrnCtr 0, 0, "Do you wish to include/display duplicate records (where" ScrnCtr 0, 0, "Latitude and Longitude have not changed? " DO KeepDupes$ = UCASE$(INKEY$) LOOP UNTIL KeepDupes$ = "N" OR KeepDupes$ = "Y" Main: CLS PRINT "Reading from: "; COLOR 15 PRINT FileIn$ COLOR 7 OPEN FileIn$ FOR RANDOM AS #1 LEN = LEN(DataRec) IF SaveToDisk$ = "Y" THEN OPEN FileOut$ FOR OUTPUT AS #2 IF ColumnHeaders$ = "Y" THEN PRINT #2, FileHEader$ END IF END IF PRINT DisplayHeader$ DO WHILE NOT EOF(1) x = x + 1 GET #1, x, DataRec IF KeepDupes$ = "Y" THEN DupeRec = False 'Force ALL records thru this filter ELSE 'If new record is same location as last, mark as duplicate IF LastLat = DataRec.Lat AND LastLon = DataRec.Lon THEN DupeRec = True ELSE DupeRec = False END IF END IF 'If the STATUS of the record is ZERO, mark it as a dupe and 'do not process it. IF DataRec.Status = 0 THEN DupeRec = True 'Keep track of last record read LastLat = DataRec.Lat LastLon = DataRec.Lon 'Do some work on the TIME field, to convert it to real ASCII 'date and time data. The contents of the TIME field is the 'number of SECONDS elapsed since the start of 01/01/1970. days# = DataRec.TIME / 86400 'Conv TIME rec to dec. days days& = INT(days#) 'Get integer days seconds! = (days# - days&) * 86400 'Get rest of day, in seconds RecDate$ = Num2Dat$(days&, baseyear%) 'Get date from TIME record RecTime$ = Secs2Time$(seconds!) 'Get time from record IF DupeRec = False THEN y = y + 1 'If Disply choice is NO PAUSES and OUTPUT TO DISK is selected 'then don't bother displaying any records to screen, just dump 'to disk. IF NOT (DisplayChoice$ = "N" AND SaveToDisk$ = "Y") THEN PRINT USING "##### "; x; 'Count of lines read from file PRINT USING "##### "; y; 'Count of lines output PRINT USING "##.##### "; DataRec.Lat; PRINT USING "###.##### "; DataRec.Lon; PRINT USING " ###.# "; DataRec.Heading; PRINT USING "###.# "; DataRec.Speed; PRINT USING "\ \ "; RecDate$; PRINT USING "\ \ "; RecTime$ END IF IF SaveToDisk$ = "Y" THEN PRINT #2, USING " # "; DataRec.Status; PRINT #2, USING "###### "; DataRec.Dummy1; PRINT #2, USING "##.##### "; DataRec.Lat; PRINT #2, USING "###.##### "; DataRec.Lon; PRINT #2, USING "##### "; DataRec.Alt; PRINT #2, USING "###.# "; DataRec.Heading; PRINT #2, USING "###.# "; DataRec.Speed; PRINT #2, USING "\ \ "; RecDate$; PRINT #2, USING "\ \ "; RecTime$; PRINT #2, USING "########"; DataRec.Dummy1 END IF 'Print 20 lines/screen then pause for user input IF DisplayChoice$ <> "N" AND y MOD (20) = 0 THEN PRINT ScrnCtr 2, -1, "uit, o pauses, or any other key to continue" DO DisplayChoice$ = UCASE$(INKEY$) LOOP UNTIL LEN(DisplayChoice$) SELECT CASE DisplayChoice$ CASE "Q" END CASE "N" 'If selected, program will no longer CLS 'pause every 20 display lines CASE ELSE CLS PRINT "Reading from: "; COLOR 15 PRINT FileIn$ COLOR 7 PRINT DisplayHeader$ END SELECT END IF END IF 'If Output To Disk and NonStop have been selected, display 'only a count of records read and records output IF DisplayChoice$ = "N" AND SaveToDisk$ = "Y" THEN LOCATE 12, 1 PRINT TAB(25); "GPS Log records read:"; x PRINT TAB(38); "written:"; y END IF LOOP CLOSE END DEFSNG A-Z FUNCTION Num2Dat$ (days&, baseyear%) 'inputs: a long integer (days&) which contains the number of days ' elapsed from a base year reference, and an integer ' (baseyear%) which represents the base reference year 'returns: a date string in the format MM-DD-YYYY 'provisions: automatically accounts for leap years, and those aberrant ' years that are evenly divisible by 4, but are not leap ' years (e.g. 1900, 2000) 'Year conversion to cumulative daily equivalent DO year% = year% + 1 yde& = INT(((year% - 1) / 4) * 1461) + 366 LOOP UNTIL yde& > days& yde& = INT(((year% - 2) / 4) * 1461) + 366 year% = baseyear% + year% - 1 'Subtract cumulative number of years evenly divisible by 4, 'but not leap years FOR I = baseyear% TO year% IF I MOD 100 = 0 THEN yde& = yde& - 1 END IF NEXT I 'Calculate days remaining daysleft% = days& - yde& + 1 'Convert days left to month SELECT CASE daysleft% CASE IS < 31: month% = 1 CASE IS < 59: month% = 2: daysleft% = daysleft% - 31 CASE IS < 90: month% = 3: daysleft% = daysleft% - 59 CASE IS < 120: month% = 4: daysleft% = daysleft% - 90 CASE IS < 151: month% = 5: daysleft% = daysleft% - 120 CASE IS < 181: month% = 6: daysleft% = daysleft% - 151 CASE IS < 212: month% = 7: daysleft% = daysleft% - 181 CASE IS < 243: month% = 8: daysleft% = daysleft% - 212 CASE IS < 273: month% = 9: daysleft% = daysleft% - 243 CASE IS < 304: month% = 10: daysleft% = daysleft% - 273 CASE IS < 334: month% = 11: daysleft% = daysleft% - 304 CASE IS < 365: month% = 12: daysleft% = daysleft% - 334 CASE ELSE: STOP END SELECT 'Check to see if leap year IF year% MOD 4 = 0 AND year% MOD 100 > 0 THEN IF month% >= 3 THEN daysleft% = daysleft% - 1 END IF Yr$ = LTRIM$(STR$(year%)) Mo$ = RIGHT$("0" + LTRIM$(STR$(month%)), 2) Da$ = RIGHT$("0" + LTRIM$(STR$(daysleft%)), 2) Num2Dat$ = Mo$ + "-" + Da$ + "-" + Yr$ END FUNCTION SUB ScrnCtr (Ptab%, Stay%, Txt$) 'By: Tom Hammond ' Text centering and hightlighting routine. ' Text enclosed by {}'s is highlighted WITHOUT the {}'s printed. ' Text enclosed by <>'s is highlighted WITH the <>'s printed, ' EXCEPT if text within the <>'s is enclosed by {}'s, in which ' case ONLY the text within {}'s is highlighted regardless of the ' <>'s (e.g. Txt$ = "", where only the 'N' is highlighted). ' PTab% is reset to zero after each pass through this routine. ' If PTab% = 0 then TXT$ will be centered. ' If PTab% > 0 then centering will be bypassed and the PTAB% value ' will be used as a TAB value. ' If PTab% < 0 then NO centering or TABbing is done, TXT$ is parsed ' and printed at the current cursor position. ' The Stay% variable determines whether the line focus stays on the ' last line printer, or moves to the next line. If Stay% = 0 then ' the focus moves to the next line, if Stay% = -1 then the focus ' remains on the currently printed-to line, so that further printing ' can be accomplished without having to re-position the focus back ' to the end of the line. DEFINT A-Z IF HighIntensity = 0 THEN 'No default settings elsewhere HighIntensity = 15 Normal = 7 END IF ' Check for matching Opening and Closing braces OBrace = 0 CBrace = 0 DO 'Count opening braces x = INSTR(x + 1, Txt$, "{") IF x THEN OBrace = OBrace + 1 LOOP WHILE x DO ' Count closing braces XBrace = INSTR(XBrace + 1, Txt$, "}") IF XBrace THEN CBrace = CBrace + 1 LOOP WHILE XBrace IF OBrace - CBrace = 0 THEN Braces = OBrace + CBrace IF Ptab% = 0 THEN LOCATE CSRLIN, INT((80 - LEN(Txt$) + Braces) / 2) + 1 ELSEIF Ptab% > 0 THEN LOCATE CSRLIN, Ptab% END IF IF OBrace - CBrace <> 0 THEN GOTO PrintAsIs Ptab% = 0 Pointer = 1 Parsed = 0 Parse1: ' Parse text to locate delimiters OBrace = INSTR(Pointer, Txt$, "{") LTSymb = INSTR(Pointer, Txt$, "<") IF OBrace = 0 AND LTSymb = 0 AND Parsed = 0 THEN GOTO PrintAsIs Parsed = -1 IF LTSymb AND OBrace = LTSymb + 1 THEN GOTO Parse3 ELSEIF (LTSymb AND LTSymb < OBrace) OR (OBrace = 0 AND LTSymb) THEN GOTO Parse2 ELSEIF (OBrace AND OBrace < LTSymb) OR (LTSymb = 0 AND OBrace) THEN GOTO Parse3 END IF COLOR Normal IF Stay% THEN PRINT MID$(Txt$, Pointer, LEN(Txt$)); ELSE PRINT MID$(Txt$, Pointer, LEN(Txt$)) END IF EXIT SUB Parse2: 'Highlight and print text, including the <> symbols COLOR Normal IF LTSymb > 1 THEN PRINT MID$(Txt$, Pointer, LTSymb - Pointer + 1); ELSE PRINT LEFT$(Txt$, 1); END IF GTSymb = INSTR(LTSymb, Txt$, ">") 'If there's an Open Brace WITHIN the <>'s, then don't highlight yet COLOR Normal IF OBrace > 0 AND GTSymb > OBrace THEN PRINT MID$(Txt$, LTSymb + 1, OBrace - LTSymb - 1); Pointer = OBrace GOTO Parse3 END IF COLOR HighIntensity PRINT MID$(Txt$, LTSymb + 1, GTSymb - LTSymb - 1); COLOR Normal PRINT MID$(Txt$, GTSymb, 1); Pointer = GTSymb + 1 GOTO Parse1 Parse3: 'Highlight and print text (only) within {} symbols COLOR Normal IF OBrace > 1 THEN PRINT MID$(Txt$, Pointer, OBrace - Pointer); END IF COLOR HighIntensity CBrace = INSTR(OBrace, Txt$, "}") PRINT MID$(Txt$, OBrace + 1, CBrace - OBrace - 1); COLOR Normal Pointer = CBrace + 1 GOTO Parse1 PrintAsIs: 'Print entire line (no <'s OR {'s found) COLOR Normal IF Stay% = 0 THEN PRINT Txt$ ELSE PRINT Txt$; END IF EXIT SUB END SUB DEFSNG A-Z FUNCTION Secs2Time$ (seconds!) hours! = INT(seconds! / 3600) 'Conv seconds to full hours seconds! = seconds! - (hours! * 3600)'Get seconds remaining minutes% = seconds! \ 60 'Conv seconds to full minutes seconds% = seconds! - (minutes% * 60) 'Get seconds remaining hours$ = RIGHT$("0" + LTRIM$(STR$(hours!)), 2) minutes$ = RIGHT$("0" + LTRIM$(STR$(minutes%)), 2) seconds$ = RIGHT$("0" + LTRIM$(STR$(seconds%)), 2) Secs2Time$ = hours$ + ":" + minutes$ + ":" + seconds$ END FUNCTION