diff options
author | Christopher Baines <cbaines8@gmail.com> | 2012-01-04 21:15:15 +0000 |
---|---|---|
committer | Christopher Baines <cbaines8@gmail.com> | 2012-01-04 21:15:15 +0000 |
commit | 9f0e1e1520070a2d73137f799538c44c42c47c0c (patch) | |
tree | 0be4f0a3484ac1cec6078b3c997d3db79820b6af /src/net/cbaines/suma/BusStopOverlay.java | |
download | southamptonuniversitymap-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.java | 309 |
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; + } + +} |