package co.createch.MetroRappid.ui; import android.location.Location; import android.os.Bundle; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.LatLngBounds; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import java.util.HashMap; import java.util.Map; import co.createch.MetroRappid.model.CapStop; import co.createch.MetroRappid.model.CapStopCollection; import co.createch.MetroRappid.model.RoutePath; import co.createch.MetroRappid.model.TripInfo; import co.createch.MetroRappid.model.TripInfoCollection; /** * Created by sean on 5/31/14. */ public class RouteMapFragment extends SupportMapFragment implements GoogleMap.OnMapLoadedCallback, GoogleMap.OnMarkerClickListener { private Location mCurrentLocation; private RoutePath mCurrentPath; private CapStopCollection mCurrentStops; private CapStop mSelectedStop; private Map<Marker, String> mStopMarkerCache; private OnStopClickListener mStopClickListener; private HashMap<String, Marker> mTripMarkers; public void selectStop(String stopId) { mSelectedStop = null; for (CapStop m : mCurrentStops) { if (stopId == m.stopId) { mSelectedStop = m; break; } } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getMap().setOnMapLoadedCallback(this); getMap().setOnMarkerClickListener(this); } public void loadRouteData(RoutePath path, CapStopCollection stops) { clear(); setRoutePath(path); setStops(stops); mapZoomToShowNearestStop(); } private void setRoutePath(RoutePath path) { if (path == null) { return; } mCurrentPath = path; getMap().addPolyline(path.getPolyLineOptions()); } private void setStops(CapStopCollection stops) { if (stops == null) { return; } mCurrentStops = stops; final GoogleMap map = getMap(); mStopMarkerCache = new HashMap<Marker, String>(); Map<MarkerOptions, String> markerOptions = stops.getMarkerHashMap(); for (MarkerOptions mo : markerOptions.keySet()) { Marker m = map.addMarker(mo); mStopMarkerCache.put(m, markerOptions.get(mo)); } } public void setLocation(Location location) { if (location != null) { mCurrentLocation = location; getMap().setMyLocationEnabled(true); double[] lats = new double[2]; double[] lons = new double[2]; mCurrentStops.setLocation(location); lats[0] = mCurrentLocation.getLatitude(); lats[1] = mCurrentStops.get(0).latitude; lons[0] = mCurrentLocation.getLongitude(); lons[1] = mCurrentStops.get(0).longitude; mapZoomToShowCoordinates(lats, lons, false); selectNearestStop(); } } public void selectNearestStop() { Marker nearestMarker = null; CapStop nearestStop = mCurrentStops.get(0); for(Marker m : mStopMarkerCache.keySet()) { if(nearestStop.stopId.equals(mStopMarkerCache.get(m))) { nearestMarker = m; } } if(nearestMarker != null) { nearestMarker.showInfoWindow(); if (mStopClickListener != null) { mStopClickListener.onStopClicked(nearestStop.stopId); } } } public void clear() { getMap().clear(); } @Override public void onMapLoaded() { } public void loadTrips(TripInfoCollection trips) { if(trips == null || trips.size() == 0) { return; } //Remove existing vehicles if we have any. if(mTripMarkers != null) { for(Marker m : mTripMarkers.values()) { m.remove(); } } mTripMarkers = new HashMap<String, Marker>(); for(TripInfo t : trips) { Marker m = getMap().addMarker(t.getBusMarker()); //Cache the markers so we can remove them later. mTripMarkers.put(t.tripId,m); } // The rest of this depends on us having a location defined if (mCurrentLocation == null) { mCurrentStops.setLocation(mCurrentLocation); trips.setLocation(mCurrentLocation); CapStop nearStop = mSelectedStop == null ? mCurrentStops.get(0) : mSelectedStop; TripInfo nearTrip = trips.get(0); double[] lats = new double[3]; double[] lons = new double[3]; lats[0] = mCurrentLocation.getLatitude(); lats[1] = nearStop.latitude; lats[2] = nearTrip.realtimeInfo.latitude; lons[0] = mCurrentLocation.getLongitude(); lons[1] = nearStop.longitude; lons[2] = nearTrip.realtimeInfo.longitude; mapZoomToShowCoordinates(lats, lons, true); } } public void mapZoomToShowNearestStop() { setLocation(mCurrentLocation); } private void mapZoomToShowCoordinates(double[] latitudes, double[] longitudes, boolean animate) { double lat0 = 1e28; double lon0 = 1e28; double lat1 = -1e28; double lon1 = -1e28; for (int i = 0; i < latitudes.length; i++) { lat0 = latitudes[i] < lat0 ? latitudes[i] : lat0; lat1 = latitudes[i] > lat1 ? latitudes[i] : lat1; } for (int i = 0; i < longitudes.length; i++) { lon0 = longitudes[i] < lon0 ? longitudes[i] : lon0; lon1 = longitudes[i] > lon1 ? longitudes[i] : lon1; } LatLng southWest = new LatLng(lat0, lon0); LatLng northEast = new LatLng(lat1, lon1); LatLngBounds latLngBox = new LatLngBounds(southWest, northEast); if (animate) { getMap().animateCamera(CameraUpdateFactory.newLatLngBounds( latLngBox, 100)); } else { getMap().moveCamera(CameraUpdateFactory.newLatLngBounds( latLngBox, 100)); } } @Override public boolean onMarkerClick(Marker marker) { if (mStopClickListener == null) { return false; } String stopId = mStopMarkerCache.get(marker); if (stopId != null) { mStopClickListener.onStopClicked(stopId); } return false; } public void setOnStopClickListener(OnStopClickListener listener) { mStopClickListener = listener; } public interface OnStopClickListener { public void onStopClicked(String stopId); } }