public void calcCommand() {
        float lowerBadWayAngle = -181;
        float higherBadWayAngle = 181;
        if (badWays != null) {
            for (MessageData badWay : badWays) {
                if (badWay.isBadOneway()) {
                    continue;
                }
                if (lowerBadWayAngle < badWay.turnangle && badWay.turnangle < goodWay.turnangle) {
                    lowerBadWayAngle = badWay.turnangle;
                }
                if (higherBadWayAngle > badWay.turnangle && badWay.turnangle > goodWay.turnangle) {
                    higherBadWayAngle = badWay.turnangle;
                }
            }
        }

        float cmdAngle = angle;

        // fall back to local angle if otherwise inconsistent
        //if ( lowerBadWayAngle > angle || higherBadWayAngle < angle )
        //{
        //cmdAngle = goodWay.turnangle;
        //}
        if (angle == Float.MAX_VALUE) {
            cmdAngle = goodWay.turnangle;
        }
        if (cmd == BL) {
            return;
        }

        if (roundaboutExit > 0) {
            cmd = RNDB;
        } else if (roundaboutExit < 0) {
            cmd = RNLB;
        } else if (is180DegAngle(cmdAngle) && cmdAngle <= -179.f && higherBadWayAngle == 181.f && lowerBadWayAngle == -181.f) {
            cmd = TU;
        } else if (cmdAngle < -159.f) {
            cmd = TLU;
        } else if (cmdAngle < -135.f) {
            cmd = TSHL;
        } else if (cmdAngle < -45.f) {
            // a TL can be pushed in either direction by a close-by alternative
            if (cmdAngle < -95.f && higherBadWayAngle < -30.f && lowerBadWayAngle < -180.f) {
                cmd = TSHL;
            } else if (cmdAngle > -85.f && lowerBadWayAngle > -180.f && higherBadWayAngle > -10.f) {
                cmd = TSLL;
            } else {
                if (cmdAngle < -110.f) {
                    cmd = TSHL;
                } else if (cmdAngle > -60.f) {
                    cmd = TSLL;
                } else {
                    cmd = TL;
                }
            }
        } else if (cmdAngle < -21.f) {
            if (cmd != KR) { // don't overwrite KR with TSLL
                cmd = TSLL;
            }
        } else if (cmdAngle < -5.f) {
            if (lowerBadWayAngle < -100.f && higherBadWayAngle < 45.f) {
                cmd = TSLL;
            } else if (lowerBadWayAngle >= -100.f && higherBadWayAngle < 45.f) {
                cmd = KL;
            } else {
                cmd = C;
            }
        } else if (cmdAngle < 5.f) {
            if (lowerBadWayAngle > -30.f) {
                cmd = KR;
            } else if (higherBadWayAngle < 30.f) {
                cmd = KL;
            } else {
                cmd = C;
            }
        } else if (cmdAngle < 21.f) {
            // a TR can be pushed in either direction by a close-by alternative
            if (lowerBadWayAngle > -45.f && higherBadWayAngle > 100.f) {
                cmd = TSLR;
            } else if (lowerBadWayAngle > -45.f && higherBadWayAngle <= 100.f) {
                cmd = KR;
            } else {
                cmd = C;
            }
        } else if (cmdAngle < 45.f) {
            cmd = TSLR;
        } else if (cmdAngle < 135.f) {
            if (cmdAngle < 85.f && higherBadWayAngle < 180.f && lowerBadWayAngle < 10.f) {
                cmd = TSLR;
            } else if (cmdAngle > 95.f && lowerBadWayAngle > 30.f && higherBadWayAngle > 180.f) {
                cmd = TSHR;
            } else {
                if (cmdAngle > 110.) {
                    cmd = TSHR;
                } else if (cmdAngle < 60.) {
                    cmd = TSLR;
                } else {
                    cmd = TR;
                }
            }
        } else if (cmdAngle < 159.f) {
            cmd = TSHR;
        } else if (is180DegAngle(cmdAngle) && cmdAngle >= 179.f && higherBadWayAngle == 181.f && lowerBadWayAngle == -181.f) {
            cmd = TU;
        } else {
            cmd = TRU;
        }
    }
Container for a voice hint
(both input- and result data for voice hint processing)

@author ab
main/src/main/java/cgeo/geocaching/brouter/core/VoiceHint.java