Back to project page getback_gps.
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.
/** * 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); } }