aboutsummaryrefslogtreecommitdiff
path: root/src/net/cbaines/suma/BusStopOverlay.java
diff options
context:
space:
mode:
authorChristopher Baines <cbaines8@gmail.com>2012-01-04 21:15:15 +0000
committerChristopher Baines <cbaines8@gmail.com>2012-01-04 21:15:15 +0000
commit9f0e1e1520070a2d73137f799538c44c42c47c0c (patch)
tree0be4f0a3484ac1cec6078b3c997d3db79820b6af /src/net/cbaines/suma/BusStopOverlay.java
downloadsouthamptonuniversitymap-9f0e1e1520070a2d73137f799538c44c42c47c0c.tar
southamptonuniversitymap-9f0e1e1520070a2d73137f799538c44c42c47c0c.tar.gz
Initial commit.
Diffstat (limited to 'src/net/cbaines/suma/BusStopOverlay.java')
-rw-r--r--src/net/cbaines/suma/BusStopOverlay.java309
1 files changed, 309 insertions, 0 deletions
diff --git a/src/net/cbaines/suma/BusStopOverlay.java b/src/net/cbaines/suma/BusStopOverlay.java
new file mode 100644
index 0000000..69687b6
--- /dev/null
+++ b/src/net/cbaines/suma/BusStopOverlay.java
@@ -0,0 +1,309 @@
+/*
+ * Southampton University Map App
+ * Copyright (C) 2011 Christopher Baines
+ *
+ * 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 2
+ * of the License, or (at your option) 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package net.cbaines.suma;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.osmdroid.views.MapView;
+import org.osmdroid.views.MapView.Projection;
+import org.osmdroid.views.overlay.Overlay;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.Style;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.widget.Toast;
+
+import com.j256.ormlite.android.apptools.OpenHelperManager;
+import com.j256.ormlite.dao.Dao;
+
+public class BusStopOverlay extends Overlay implements RouteColorConstants {
+
+ private ArrayList<BusStop> busStops;
+
+ private final Point mCurScreenCoords = new Point();
+ private final Point mTouchScreenPoint = new Point();
+ private final Point mItemPoint = new Point();
+
+ private final Rect mRect = new Rect();
+
+ private final Drawable marker;
+ private final Drawable favMarker;
+
+ private final Paint paint;
+
+ private static final String TAG = "BusStopOverlay";
+
+ private final Context context;
+
+ private Dao<BusStop, String> busStopDao;
+
+ private float userScale = 1f;
+
+ private boolean[] routes = new boolean[5];
+
+ public BusStopOverlay(Context context) throws SQLException {
+ super(context);
+
+ this.context = context;
+
+ marker = context.getResources().getDrawable(R.drawable.busstop);
+ favMarker = context.getResources().getDrawable(R.drawable.busstop_fav);
+
+ DatabaseHelper helper = OpenHelperManager.getHelper(context, DatabaseHelper.class);
+ busStopDao = helper.getBusStopDao();
+
+ paint = new Paint();
+ paint.setStyle(Style.FILL);
+ paint.setStrokeWidth(6);
+
+ busStops = new ArrayList<BusStop>((int) busStopDao.countOf());
+ busStops.addAll(busStopDao.queryForAll());
+ }
+
+ void setRoutes(int route, boolean visible) {
+ routes[route] = visible;
+ }
+
+ @Override
+ public void draw(final Canvas canvas, final MapView mapView, final boolean shadow) {
+
+ if (shadow) {
+ return;
+ }
+
+ float scale = mScale * userScale;
+
+ final Projection pj = mapView.getProjection();
+
+ final int markerWidth = (int) (marker.getIntrinsicWidth() * userScale);
+ final int markerHeight = (int) (marker.getIntrinsicHeight() * userScale);
+
+ mRect.set(0, 0, 0 + markerWidth, 0 + markerHeight);
+ mRect.offset(-markerWidth / 2, -markerHeight);
+ marker.setBounds(mRect);
+ favMarker.setBounds(mRect);
+
+ /* Draw in backward cycle, so the items with the least index are on the front. */
+
+ for (int stopNum = 0; stopNum < busStops.size(); stopNum++) {
+ BusStop stop = busStops.get(stopNum);
+
+ final byte stopRoutes = stop.routes;
+ byte routeNum = 0;
+ boolean drawing = false;
+
+ for (int i = 0; i < 5; i++) {
+ if ((stopRoutes & (1 << i)) != 0) {
+ routeNum++;
+ if (routes[i]) {
+ drawing = true;
+ }
+ }
+ }
+
+ if (!drawing)
+ continue;
+
+ int yOfsetPerMarker = (int) (10 * scale);
+ int markerYSize = (int) (8 * scale);
+
+ pj.toMapPixels(stop.point, mCurScreenCoords);
+
+ if (stop.favourite) {
+ Overlay.drawAt(canvas, favMarker, mCurScreenCoords.x, mCurScreenCoords.y, false);
+ } else {
+ Overlay.drawAt(canvas, marker, mCurScreenCoords.x, mCurScreenCoords.y, false);
+ }
+ // Log.i(TAG, "Got " + routes.size() + " routes " + routes);
+
+ int makersPlaced = 0;
+
+ float rectLeft = mCurScreenCoords.x + (8.8f * scale);
+ float rectRight = rectLeft + markerYSize;
+
+ if (routeNum == 5) {
+ markerYSize = (int) (5 * scale);
+ yOfsetPerMarker = (int) (7 * scale);
+ } else if (routeNum == 4) {
+ markerYSize = (int) (6.5f * scale);
+ yOfsetPerMarker = (int) (8 * scale);
+ }
+
+ for (int i = 0; i < 5; i++) {
+ if ((stopRoutes & (1 << i)) != 0) {
+
+ // Log.i(TAG, "Route " + route + " is " + routes.get(route));
+
+ // Log.i(TAG, "Index is " + busRoutes.indexOf(route) + " busRoutes " + busRoutes);
+
+ if (i == 0) {
+ paint.setColor(U1);
+ } else if (i == 1) {
+ paint.setColor(U1N);
+ } else if (i == 2) {
+ paint.setColor(U2);
+ } else if (i == 3) {
+ paint.setColor(U6);
+ } else if (i == 4) {
+ paint.setColor(U9);
+ } else {
+ Log.e(TAG, "Unknown route code");
+ }
+
+ canvas.drawRect(rectLeft, mCurScreenCoords.y + ((yOfsetPerMarker * makersPlaced) - (45 * scale)), rectRight, mCurScreenCoords.y
+ + (yOfsetPerMarker * makersPlaced) - ((45 * scale) - markerYSize), paint);
+
+ makersPlaced++;
+ }
+ }
+
+ }
+ }
+
+ @Override
+ public boolean onSingleTapUp(final MotionEvent event, final MapView mapView) {
+
+ BusStop busStop = getSelectedItem(event, mapView);
+
+ if (busStop == null) {
+ Log.i(TAG, "No busStop pressed");
+
+ return false;
+ } else {
+ Log.i(TAG, "Pressed " + busStop.id);
+
+ Intent i = new Intent(context, BusTimeActivity.class);
+ i.putExtra("busStopID", busStop.id);
+ i.putExtra("busStopName", busStop.description);
+ ((Activity) context).startActivityForResult(i, 0);
+
+ return true;
+ }
+
+ }
+
+ @Override
+ public boolean onLongPress(final MotionEvent event, final MapView mapView) {
+ BusStop busStop = getSelectedItem(event, mapView);
+
+ if (busStop == null) {
+ Log.i(TAG, "No busStop pressed");
+ return false;
+ } else {
+ Log.i(TAG, "Pressed " + busStop.id);
+
+ if (busStop.favourite) {
+ busStop.favourite = false;
+
+ Toast.makeText(context, busStop.id + " removed from favourites", Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(context, busStop.id + " made a favourite", Toast.LENGTH_SHORT).show();
+
+ busStop.favourite = true;
+ }
+
+ try {
+ busStopDao.update(busStop);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ Collections.sort(busStops, new POIFavouriteComparator());
+
+ mapView.invalidate();
+
+ return true;
+ }
+
+ }
+
+ public void refresh() {
+ try {
+ for (int i = 0; i < busStops.size(); i++) {
+ BusStop busStop = busStops.get(i);
+ busStopDao.refresh(busStop);
+ if (busStop.favourite) {
+ busStops.remove(i);
+ busStops.add(busStop);
+ } else {
+ busStops.set(i, busStop);
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Replaces any bus stops that equal the argument in the overlay with the argument
+ *
+ * @param busStop
+ */
+ public void refresh(BusStop busStop) {
+ for (int i = 0; i < busStops.size(); i++) {
+ if (busStop.equals(busStops.get(i))) {
+ busStops.set(i, busStop);
+ }
+ }
+ }
+
+ private BusStop getSelectedItem(final MotionEvent event, final MapView mapView) {
+ final Projection pj = mapView.getProjection();
+ final int eventX = (int) event.getX();
+ final int eventY = (int) event.getY();
+
+ /* These objects are created to avoid construct new ones every cycle. */
+ pj.fromMapPixels(eventX, eventY, mTouchScreenPoint);
+
+ for (int i = busStops.size() - 1; i > 0; i--) {
+ BusStop busStop = busStops.get(i);
+
+ pj.toPixels(busStop.point, mItemPoint);
+
+ if (marker.getBounds().contains(mTouchScreenPoint.x - mItemPoint.x, mTouchScreenPoint.y - mItemPoint.y)) {
+ boolean drawing = false;
+ for (int route = 0; route < 5; route++) {
+ if ((busStop.routes & (1 << route)) != 0) {
+ if (routes[route]) {
+ drawing = true;
+ break;
+ }
+ }
+ }
+ if (!drawing)
+ continue;
+
+ return busStop;
+ }
+ }
+ return null;
+ }
+
+}