/* This file is part of OpenSatNav. OpenSatNav 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 (at your option) any later version. OpenSatNav 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 OpenSatNav. If not, see <http://www.gnu.org/licenses/>. */ // Created by plusminus on 22:01:11 - 29.09.2008 package org.andnav.osm.views.overlay; import org.andnav.osm.util.GeoPoint; import org.andnav.osm.views.OpenStreetMapView; import org.andnav.osm.views.OpenStreetMapView.OpenStreetMapViewProjection; import org.opensatnav.R; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Point; import android.graphics.Paint.Style; /** * * @author Nicolas Gramlich * */ public class OpenStreetMapViewDirectedLocationOverlay extends OpenStreetMapViewOverlay { // =========================================================== // Constants // =========================================================== // =========================================================== // Fields // =========================================================== protected final Paint mPaint = new Paint(); protected final Bitmap LOCATION_MOVING; protected final Bitmap LOCATION_STOPPED; protected GeoPoint mLocation; protected float mBearing; protected float speed = 0.0f; private final Matrix directionRotater = new Matrix(); private final float DIRECTION_ARROW_CENTER_X; private final float DIRECTION_ARROW_CENTER_Y; private final int DIRECTION_ARROW_WIDTH; private final int DIRECTION_ARROW_HEIGHT; protected float accuracy = 0; // =========================================================== // Constructors // =========================================================== public OpenStreetMapViewDirectedLocationOverlay(final Context ctx) { this.LOCATION_MOVING = BitmapFactory.decodeResource(ctx.getResources(), R.drawable.direction_arrow); this.LOCATION_STOPPED = BitmapFactory.decodeResource(ctx.getResources(), R.drawable.location_marker); this.DIRECTION_ARROW_CENTER_X = this.LOCATION_MOVING.getWidth() / 2 - 0.5f; this.DIRECTION_ARROW_CENTER_Y = this.LOCATION_MOVING.getHeight() / 2 - 0.5f; this.DIRECTION_ARROW_HEIGHT = this.LOCATION_MOVING.getHeight(); this.DIRECTION_ARROW_WIDTH = this.LOCATION_MOVING.getWidth(); } // =========================================================== // Getter & Setter // =========================================================== public void setLocation(final GeoPoint mp) { this.mLocation = mp; } public void setBearing(final float aHeading) { this.mBearing = aHeading; } public void setSpeed(final float speed) { this.speed = speed; } public void setAccuracy(float accuracy) { this.accuracy = accuracy; } // =========================================================== // Methods from SuperClass/Interfaces // =========================================================== @Override protected void onDrawFinished(Canvas c, OpenStreetMapView osmv) { return; } @Override public void onDraw(final Canvas c, final OpenStreetMapView osmv) { if (this.mLocation != null) { final OpenStreetMapViewProjection pj = osmv.getProjection(); final Point screenCoords = new Point(); pj.toPixels(this.mLocation, screenCoords); // draw innacuracy circle // accuracy means the number of metres that we are accurate to float diameter = pj.metersToEquatorPixels(accuracy) * 100; //if it won't be hidden under the icon anyway if (diameter > DIRECTION_ARROW_WIDTH) { this.mPaint.setColor(Color.BLUE); this.mPaint.setAlpha(80); this.mPaint.setStrokeWidth(2); this.mPaint.setStyle(Style.STROKE); this.mPaint.setAntiAlias(true); c.drawCircle(screenCoords.x, screenCoords.y, diameter, this.mPaint); this.mPaint.setAlpha(20); this.mPaint.setStyle(Style.FILL); c.drawCircle(screenCoords.x, screenCoords.y, diameter, this.mPaint); //reset alpha this.mPaint.setAlpha(255); } // 0.5 m/s is a slow person walking if (speed > 0.5f) { /* * Rotate the direction-Arrow according to the bearing we are * moving. And draw it to the canvas. */ this.directionRotater.setRotate(this.mBearing, DIRECTION_ARROW_CENTER_X, DIRECTION_ARROW_CENTER_Y); Bitmap rotatedDirection = Bitmap.createBitmap(LOCATION_MOVING, 0, 0, DIRECTION_ARROW_WIDTH, DIRECTION_ARROW_HEIGHT, this.directionRotater, false); c.drawBitmap(rotatedDirection, screenCoords.x - rotatedDirection.getWidth() / 2, screenCoords.y - rotatedDirection.getHeight() / 2, this.mPaint); } else { // we're not moving, or we're moving too slowly for the bearing // to be accurate Bitmap locationStopped = Bitmap.createBitmap(LOCATION_STOPPED, 0, 0, DIRECTION_ARROW_WIDTH, DIRECTION_ARROW_HEIGHT); c.drawBitmap(locationStopped, screenCoords.x - locationStopped.getWidth() / 2, screenCoords.y - locationStopped.getHeight() / 2, this.mPaint); } } } // =========================================================== // Methods // =========================================================== // =========================================================== // Inner and Anonymous Classes // =========================================================== }