Android Open Source - getback_gps Navigation View






From Project

Back to project page getback_gps.

License

The source code is released under:

GNU General Public License

If you think the Android project getback_gps listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Navigation View/*from  w ww.  j a v a  2s  .c om*/
 *
 * Copyright (C) 2012-2015 Dieter Adriaenssens
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @package com.github.ruleant.getback_gps
 * @author Dieter Adriaenssens <ruleant@users.sourceforge.net>
 */
package com.github.ruleant.getback_gps;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.github.ruleant.getback_gps.lib.Coordinate;
import com.github.ruleant.getback_gps.lib.CoordinateRotation;
import com.github.ruleant.getback_gps.lib.Coordinates;
import com.github.ruleant.getback_gps.lib.FormatUtils;

import de.keyboardsurfer.android.widget.crouton.Style;

/**
 * Navigation view is used to indicate the direction to the destination.
 *
 * @author Dieter Adriaenssens <ruleant@users.sourceforge.net>
 */
public class NavigationView extends ImageView {
    /**
     * Paint used for drawing compass rose lines.
     */
    private final Paint mPaintRoseLines = new Paint();

    /**
     * Paint used for drawing compass rose solids.
     */
    private final Paint mPaintRoseSolids = new Paint();

    /**
     * Paint used for drawing compass rose North solid.
     */
    private final Paint mPaintRoseSolidNorth = new Paint();

    /**
     * Paint used for drawing lines.
     */
    private final Paint mPaintLines = new Paint();

    /**
     * Paint used for drawing solids.
     */
    private final Paint mPaintSolids = new Paint();

    /**
     * Paint used for drawing white part of the arrow solid.
     */
    private final Paint mPaintArrowSolidWhite = new Paint();

    /**
     * Arrow indicating direction (lines).
     */
    private final Coordinates mArrowLines = new Coordinates();

    /**
     * Arrow indicating direction (solid right part).
     */
    private final Coordinates mArrowBodyRight = new Coordinates();

    /**
     * Arrow indicating direction (solid left part).
     */
    private final Coordinates mArrowBodyLeft = new Coordinates();

    /**
     * Compass rose.
     */
    private final Coordinates mCompassRose = new Coordinates();

    /**
     * Compass rose solid body.
     */
    private final Coordinates mCompassRoseBody = new Coordinates();

    /**
     * Compass rose rotation converter.
     */
    private CoordinateRotation mRoseRotationConverter;

    /**
     * Arrow indicating direction.
     */
    private CoordinateRotation mRotationConverter;

    /**
     * Rotation center.
     */
    private Coordinate mRotationCenter;

    /**
     * Direction to destination.
     */
    private double mDirection = 0;

    /**
     * Direction to azimuth.
     */
    private double mAzimuth = 0;

    /**
     * Navigation mode enum.
     */
    public enum Mode {
        /**
         * Mode disabled.
         */
        Disabled,
        /**
         * Mode inaccurate.
         */
        Inaccurate,
        /**
         * Mode accurate.
         */
        Accurate
    }

    /**
     * Navigation mode.
     */
    private Mode mNavigationMode = Mode.Disabled;

    /**
     * Orientation mode.
     */
    private Mode mOrientationMode = Mode.Disabled;

    /**
     * Attribute layout_height.
     */
    private int mAttributeLayoutHeight = ViewGroup.LayoutParams.WRAP_CONTENT;

    /**
     * Line thickness.
     */
    private static final float LINE_THICKNESS = 1;

    /**
     * 10 %.
     */
    private static final double D_10PCT = 0.1;

    /**
     * 40 %.
     */
    private static final double D_40PCT = 0.4;

    /**
     * 80 %.
     */
    private static final double D_80PCT = 0.8;

    /**
     * Compass rose arm length.
     */
    private static final double ROSE_LENGTH = 0.95;

    /**
     * Compass rose intersection length.
     */
    private static final double ROSE_INTER_LENGTH = 0.25;

    /**
     * arrow side angle.
     */
    private static final double ARROW_ANGLE = 35.0;

    /**
     * Compass rose intersection angle.
     */
    private static final double INTERSECTION_ANGLE = 45.0;

    /**
     * Constructor.
     *
     * @param context App context
     */
    public NavigationView(final Context context) {
        super(context);

        init();
    }

    /**
     * Constructor.
     *
     * @param context App context
     * @param attributes View Attributes
     */
    public NavigationView(final Context context,
                          final AttributeSet attributes) {
        super(context, attributes);

        // Retrieving the values of a few parameters as defined
        // in the xml configuration.
        int[] lookForAttributes = new int[] {android.R.attr.layout_height};

        TypedArray foundAttributes = context.getTheme().obtainStyledAttributes(
                attributes,
                lookForAttributes,
                0, 0);

        try {
            mAttributeLayoutHeight = foundAttributes.getInteger(
                    0, ViewGroup.LayoutParams.WRAP_CONTENT);
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        } finally {
            foundAttributes.recycle();
        }

        init();
    }

    /**
     * Sets Direction.
     *
     * @param direction Direction to destination (0-360).
     */
    public final void setDirection(final double direction) {
        this.mDirection = FormatUtils.normalizeAngle(direction);
    }

    /**
     * Get direction, return nothing if mode is DISABLED.
     *
     * @return Direction to destination (0-360)
     */
    public final double getDirection() {
        if (getNavigationMode() == Mode.Disabled) {
            return 0;
        } else {
            return mDirection;
        }
    }

    /**
     * Sets Azimuth.
     *
     * @param azimuth Angle to azimuth (0-360).
     */
    public final void setAzimuth(final double azimuth) {
        this.mAzimuth = FormatUtils.normalizeAngle(-1 * azimuth);
    }

    /**
     * Get azimuth, return nothing if mode is DISABLED.
     *
     * @return Angle to azimuth (0-360)
     */
    public final double getAzimuth() {
        if (getOrientationMode() == Mode.Disabled) {
            return 0;
        } else {
            return mAzimuth;
        }
    }

    /**
     * Sets navigation mode.
     *
     * @param mode Navigation mode : DISABLED, INACCURATE, ACCURATE
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public final void setNavigationMode(final Mode mode) {
        Resources res = getResources();

        switch (mode) {
            default:
            case Disabled:
                this.mNavigationMode = Mode.Disabled;
                mPaintLines.setColor(Color.GRAY);
                mPaintSolids.setColor(Color.LTGRAY);
                break;
            case Inaccurate:
                this.mNavigationMode = mode;
                if (Build.VERSION.SDK_INT
                        >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                    mPaintLines.setColor(
                            res.getColor(android.R.color.holo_blue_dark));
                    mPaintSolids.setColor(
                            res.getColor(android.R.color.holo_blue_light));
                } else {
                    mPaintLines.setColor(Style.holoBlueLight);
                    mPaintSolids.setColor(Style.holoBlueLight);
                }
                break;
            case Accurate:
                this.mNavigationMode = mode;
                if (Build.VERSION.SDK_INT
                        >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                    mPaintLines.setColor(
                            res.getColor(android.R.color.holo_green_dark));
                    mPaintSolids.setColor(
                            res.getColor(android.R.color.holo_green_light));
                } else {
                    mPaintLines.setColor(Style.holoGreenLight);
                    mPaintSolids.setColor(Style.holoGreenLight);
                }
                break;
        }
    }

    /**
     * Get navigation mode.
     *
     * @return Navigation mode : DISABLED, INACCURATE, ACCURATE
     */
    public final Mode getNavigationMode() {
        return mNavigationMode;
    }

    /**
     * Sets orientation mode.
     *
     * @param mode Orientation mode : DISABLED, INACCURATE, ACCURATE
     */
    public final void setOrientationMode(final Mode mode) {
        switch (mode) {
            default:
            case Disabled:
                this.mOrientationMode = Mode.Disabled;
                break;
            case Inaccurate:
                this.mOrientationMode = mode;
                break;
            case Accurate:
                this.mOrientationMode = mode;
                break;
        }
    }

    /**
     * Get orientation mode.
     *
     * @return Orientation mode : DISABLED, INACCURATE, ACCURATE
     */
    public final Mode getOrientationMode() {
        return mOrientationMode;
    }

    @Override
    public final void onDraw(final Canvas canvas) {
        // scale View if it is not square
        if (getWidth() != getHeight()) {
            ViewGroup.LayoutParams layoutParams = getLayoutParams();

            // adjust height/width according to attribute setting
            if (mAttributeLayoutHeight
                    == ViewGroup.LayoutParams.WRAP_CONTENT) {
                layoutParams.height = getWidth();
            } else {
                layoutParams.width = getHeight();
            }

            setLayoutParams(layoutParams);
        }

        // Set up rotation converter
        mRotationCenter.setCartesianCoordinate(getWidth() / 2, getHeight() / 2);
        double mRoseRotation = getAzimuth();
        mRoseRotationConverter.setScaleRadius((double) getHeight() / 2);
        mRotationConverter.setRotationAngle(getDirection());
        mRotationConverter.setScaleRadius((double) getHeight() / 2);
        // no need to reassign mRotationCenter to mRotationConverter,
        // and mRotationConverter to mArrowLines, mArrowBodyLeft/Right,
        // the instances were assigned in init().

        // draw circle with diameter scaled to length of compass rose arrow
        canvas.drawCircle(
                mRotationCenter.getCartesianX(),
                mRotationCenter.getCartesianY(),
                ((float) getHeight() / 2) * (float) ROSE_LENGTH,
                mPaintRoseLines);

        // draw compass rose
        if (getOrientationMode() == Mode.Accurate) {
            mRoseRotationConverter.setRotationAngle(mRoseRotation);
            canvas.drawPath(mCompassRoseBody.toPath(), mPaintRoseSolidNorth);
            canvas.drawLines(mCompassRose.toLinesArray(), mPaintRoseLines);

            mRoseRotationConverter.setRotationAngle(
                    FormatUtils.CIRCLE_1Q + mRoseRotation);
            canvas.drawPath(mCompassRoseBody.toPath(), mPaintRoseSolids);
            canvas.drawLines(mCompassRose.toLinesArray(), mPaintRoseLines);

            mRoseRotationConverter.setRotationAngle(
                    FormatUtils.CIRCLE_HALF + mRoseRotation);
            canvas.drawPath(mCompassRoseBody.toPath(), mPaintRoseSolids);
            canvas.drawLines(mCompassRose.toLinesArray(), mPaintRoseLines);

            mRoseRotationConverter.setRotationAngle(
                    FormatUtils.CIRCLE_3Q + mRoseRotation);
            canvas.drawPath(mCompassRoseBody.toPath(), mPaintRoseSolids);
            canvas.drawLines(mCompassRose.toLinesArray(), mPaintRoseLines);
        }

        // draw arrow to destination
        canvas.drawPath(mArrowBodyRight.toPath(), mPaintSolids);
        canvas.drawPath(mArrowBodyLeft.toPath(), mPaintArrowSolidWhite);
        canvas.drawLines(mArrowLines.toLinesArray(), mPaintLines);
    }

    /**
     * Initialise NavigationView.
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    private void init() {
        Resources res = getResources();

        // Get the screen's density scale
        final float scale = res.getDisplayMetrics().density;

        // Convert the line thickness to pixels, based on density scale
        mPaintRoseLines.setStrokeWidth(Math.round(LINE_THICKNESS * scale));
        mPaintRoseLines.setStyle(Paint.Style.STROKE);
        mPaintLines.setStrokeWidth(Math.round(LINE_THICKNESS * scale));

        // initialise paint color
        mPaintRoseLines.setColor(Color.DKGRAY);
        mPaintRoseSolids.setColor(Color.LTGRAY);
        mPaintRoseSolidNorth.setColor(Color.GRAY);
        mPaintArrowSolidWhite.setColor(Color.WHITE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            mPaintLines.setColor(
                    res.getColor(android.R.color.holo_red_dark));
            mPaintSolids.setColor(
                    res.getColor(android.R.color.holo_red_light));
        } else {
            mPaintLines.setColor(Color.RED);
            mPaintSolids.setColor(Color.RED);
        }

        // initialise rotationConverter
        mRotationCenter = new Coordinate(0, 0);
        mRotationConverter = new CoordinateRotation(mRotationCenter, 0.0, 1.0);
        mRoseRotationConverter
                = new CoordinateRotation(mRotationCenter, 0.0, 1.0);
        mCompassRose.setCoordinateConverter(mRoseRotationConverter);
        mCompassRoseBody.setCoordinateConverter(mRoseRotationConverter);
        mArrowLines.setCoordinateConverter(mRotationConverter);
        mArrowBodyRight.setCoordinateConverter(mRotationConverter);
        mArrowBodyLeft.setCoordinateConverter(mRotationConverter);

        // draw compass rose

        // left side/outline in lines
        mCompassRose.addCoordinate(ROSE_LENGTH, 0);
        mCompassRose.addCoordinate(0, 0);
        mCompassRose.addCoordinate(ROSE_INTER_LENGTH, INTERSECTION_ANGLE);
        mCompassRose.addCoordinate(ROSE_LENGTH, 0);
        mCompassRose.addCoordinate(ROSE_INTER_LENGTH, -1 * INTERSECTION_ANGLE);
        // don't close line
        mCompassRose.setCloseLine(false);

        // right side filled body
        mCompassRoseBody.addCoordinate(0, 0);
        mCompassRoseBody.addCoordinate(ROSE_LENGTH, 0);
        mCompassRoseBody.addCoordinate(ROSE_INTER_LENGTH,
                -1 * INTERSECTION_ANGLE);

        // draw arrow

        double arrowLength = D_80PCT;
        double arrowLengthDivide = -1 * D_10PCT;
        double arrowLengthTail = -1 * D_40PCT;

        // left side/outline in lines
        mArrowLines.addCoordinate(arrowLength, 0);
        mArrowLines.addCoordinate(arrowLengthTail, -1 * ARROW_ANGLE);
        mArrowLines.addCoordinate(arrowLengthDivide, 0);
        mArrowLines.addCoordinate(arrowLengthTail, ARROW_ANGLE);
        mArrowLines.addCoordinate(arrowLength, 0);
        mArrowLines.addCoordinate(arrowLengthDivide, 0);
        // don't close line
        mArrowLines.setCloseLine(false);

        // right side of the filled arrow body
        mArrowBodyRight.addCoordinate(arrowLength, 0);
        mArrowBodyRight.addCoordinate(arrowLengthTail, -1 * ARROW_ANGLE);
        mArrowBodyRight.addCoordinate(arrowLengthDivide, 0);

        // left side of the filled arrow body
        mArrowBodyLeft.addCoordinate(arrowLength, 0);
        mArrowBodyLeft.addCoordinate(arrowLengthTail, ARROW_ANGLE);
        mArrowBodyLeft.addCoordinate(arrowLengthDivide, 0);
    }
}




Java Source Code List

com.github.ruleant.getback_gps.AboutActivity.java
com.github.ruleant.getback_gps.AbstractGetBackGpsActivity.java
com.github.ruleant.getback_gps.DetailsActivity.java
com.github.ruleant.getback_gps.LocationService.java
com.github.ruleant.getback_gps.MainActivity.java
com.github.ruleant.getback_gps.NavigationView.java
com.github.ruleant.getback_gps.SettingsActivity.java
com.github.ruleant.getback_gps.lib.AbstractGeoCoordinate.java
com.github.ruleant.getback_gps.lib.AriadneLocation.java
com.github.ruleant.getback_gps.lib.CardinalDirection.java
com.github.ruleant.getback_gps.lib.CircularAverage.java
com.github.ruleant.getback_gps.lib.CoordinateConverterInterface.java
com.github.ruleant.getback_gps.lib.CoordinateRotation.java
com.github.ruleant.getback_gps.lib.Coordinate.java
com.github.ruleant.getback_gps.lib.Coordinates.java
com.github.ruleant.getback_gps.lib.DebugLevel.java
com.github.ruleant.getback_gps.lib.FormatUtils.java
com.github.ruleant.getback_gps.lib.Latitude.java
com.github.ruleant.getback_gps.lib.Longitude.java
com.github.ruleant.getback_gps.lib.LowPassFilter.java
com.github.ruleant.getback_gps.lib.Navigator.java
com.github.ruleant.getback_gps.lib.SensorOrientation.java
com.github.ruleant.getback_gps.lib.StoredDestination.java
com.github.ruleant.getback_gps.lib.StoredLocation.java
com.github.ruleant.getback_gps.lib.Tools.java
com.github.ruleant.getback_gps.lib.package-info.java
com.github.ruleant.getback_gps.package-info.java
com.github.ruleant.unitconversion.UnitConversionInterface.java
com.github.ruleant.unitconversion.package-info.java