/** * Copyright 2012 Daniel Kreischer, Christopher Holm, Christopher Schwardt * * This file is part of TeamMeet. * * TeamMeet 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. * * TeamMeet 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 TeamMeet. If not, see <http://www.gnu.org/licenses/>. * */ package de.teammeet; import java.util.concurrent.locks.ReentrantLock; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Path; import android.graphics.Point; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; import de.teammeet.interfaces.ILocationUpdateRecipient; public class SelfOverlay extends Overlay implements ILocationUpdateRecipient { private double mArrowLength = 0; private GeoPoint mCurrentLocation = null; private Paint mPaintPlayer = null; private final ReentrantLock mLock = new ReentrantLock(); private boolean mHasPlayerDirection = false; private float mPlayerDirection = 0; private Resources mResources = null; private float mAccuracy = 0; public SelfOverlay(final Resources res) { super(); mResources = res; mPaintPlayer = new Paint(); mPaintPlayer.setStyle(Paint.Style.FILL); mPaintPlayer.setColor(mResources.getColor(R.color.paint_default)); mArrowLength = mResources.getInteger(R.integer.arrow_length); } @Override public boolean draw(final Canvas canvas, final MapView mapView, final boolean shadow, final long when) { super.draw(canvas, mapView, shadow); if (mCurrentLocation != null) { final Point coords = new Point(); acquireLock(); try { // paint player in noticeable fashion mapView.getProjection().toPixels(mCurrentLocation, coords); if (mHasPlayerDirection) { final Path path = new Path(); path.moveTo( (float) (coords.x + mArrowLength * Math.sin((-mPlayerDirection + 180) * Math.PI / 180)), (float) (coords.y + mArrowLength * Math.cos((-mPlayerDirection + 180) * Math.PI / 180))); path.lineTo( (float) (coords.x + (mArrowLength / 4) * Math.sin((-mPlayerDirection + 90) * Math.PI / 180)), (float) (coords.y + (mArrowLength / 4) * Math.cos((-mPlayerDirection + 90) * Math.PI / 180))); path.lineTo( (float) (coords.x + (mArrowLength / 4) * Math.sin((-mPlayerDirection - 90) * Math.PI / 180)), (float) (coords.y + (mArrowLength / 4) * Math.cos((-mPlayerDirection - 90) * Math.PI / 180))); path.close(); canvas.drawPath(path, mPaintPlayer); } else { canvas.drawCircle(coords.x, coords.y, 3, mPaintPlayer); mPaintPlayer.setStyle(Style.STROKE); canvas.drawCircle(coords.x, coords.y, 5, mPaintPlayer); } // TODO: represent accuracy somehow } finally { releaseLock(); } } return true; } @Override public void handleLocationUpdate(final GeoPoint geopoint, final float accuracy) { acquireLock(); try { mCurrentLocation = geopoint; mAccuracy = accuracy; } finally { releaseLock(); } } @Override public void onLocationAvailability() { // TODO Auto-generated method stub } @Override public void handleDirectionUpdate(final float direction) { acquireLock(); try { mPlayerDirection = direction; if (!mHasPlayerDirection) { mHasPlayerDirection = true; } } finally { releaseLock(); } } private void acquireLock() { mLock.lock(); } private void releaseLock() { mLock.unlock(); } }