javAPRS
Home Page

Compressed Preprocessor


Note that the following is done at object creation to ensure proper formatting:

    private final DecimalFormatSymbols dfs = new DecimalFormatSymbols();
    TNCparser()
    {
        dfs.setDecimalSeparator('.');
        dfs.setZeroDigit('0');
    }

This code converts compressed format to standard format.

    protected void convertCompressed(String theString, Report theReport)
    {
        // theString is the compressed part of the packet
        if (!theReport.toField.startsWith("AP")) return; // Will cause lat parse to bomb
        
        // Parse Icon for later adjustment
        char symID = theString.charAt(0);
        
        // Adjust the icon for plain text
        if ((symID >= 'a') && (symID <= 'j')) symID = (char)(symID - 49);
        char symCode = theString.charAt(9);
        if (!isValidSymbol(symCode) || !isValidOverlay(symID)) return;
        theReport.icon = symCode - ' ';
        if (isLetterOrDigit(symID))
        {
            theReport.altIcons = true;
            theReport.overlay = symID - ' ';
        }
        else if (symID == '\\')
            theReport.altIcons = true;
        
        // Compute lat/long
        theReport.position.lat = 90.0-((((((((theString.charAt(1)-33)*91.0)+(theString.charAt(2)-33))*91.0)+(theString.charAt(3)-33))*91.0)+(theString.charAt(4)-33))/380926.0);
        theReport.position.lon = -180.0+((((((((theString.charAt(5)-33)*91.0)+(theString.charAt(6)-33))*91.0)+(theString.charAt(7)-33))*91.0)+(theString.charAt(8)-33))/190463.0);
        
        // Compute course/speed bytes
        if (theString.charAt(10) != ' ')
        {
            // c/s represents something
            if (((theString.charAt(12) - 33) & 0x18) == 0x10)
            {
                theReport.reportType = "GGA";
                theReport.altitude = (int)Math.round(Math.pow(1.002,(theString.charAt(10)-33)*91+(theString.charAt(11)-33)));
            }
            else if (theString.charAt(10) == '{')
            {
                // Radio Range
                theReport.range = (int)(Math.round(2.0*Math.pow(1.08,theString.charAt(11)-33)));
            }
            else
            {
                // Course/Speed
                DecimalFormat df = new DecimalFormat("000", dfs);
                // Compressed speed is in Knots
                theReport.course = (theString.charAt(10)-33)*4;
                if (theReport.course == 0) theReport.course = 360;
                theReport.speed = (int)(Math.round(Math.pow(1.08,theString.charAt(11)-33)-1.0));
            }
            if (((theString.charAt(12)-33) & 0x18) == 0x18)
                theReport.reportType = "RMC";
            else if (((theString.charAt(12)-33) & 0x18) == 0x08)
                theReport.reportType = "GLL";
        }
        if ((symID == '_' || symID == 'W&') && theString.length() >= 21)
            computeWX(theReport, 13, theString);
        if (theString.length() >= 20 && !theReport.reportType.equals("GGA"))
            computeAlt(theReport, theString.substring(13));
    }