/** * Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onebusaway.webapp.gwt.mobile_application.view; import java.util.List; import java.util.Map; import org.onebusaway.transit_data.model.RouteBean; import org.onebusaway.transit_data.model.StopBean; import org.onebusaway.transit_data.model.StopsForRouteBean; import org.onebusaway.webapp.gwt.common.control.Place; import org.onebusaway.webapp.gwt.common.widgets.DivPanel; import org.onebusaway.webapp.gwt.common.widgets.DivWidget; import org.onebusaway.webapp.gwt.common.widgets.SpanWidget; import org.onebusaway.webapp.gwt.geo_location_library.GeoLocationErrorEvent; import org.onebusaway.webapp.gwt.geo_location_library.GeoLocationEvent; import org.onebusaway.webapp.gwt.geo_location_library.GeoLocationHandler; import org.onebusaway.webapp.gwt.mobile_application.MobileApplicationContext; import org.onebusaway.webapp.gwt.mobile_application.control.Actions; import org.onebusaway.webapp.gwt.mobile_application.control.LocationManager; import org.onebusaway.webapp.gwt.mobile_application.resources.MobileApplicationCssResource; import org.onebusaway.webapp.gwt.mobile_application.resources.MobileApplicationResources; import org.onebusaway.webapp.gwt.viewkit.BarButtonItem; import org.onebusaway.webapp.gwt.viewkit.NavigationItem; import org.onebusaway.webapp.gwt.viewkit.ViewController; import org.onebusaway.webapp.gwt.viewkit.BarButtonItem.EBarButtonSystemItem; import org.onebusaway.webapp.gwt.where_library.view.events.StopClickedEvent; import org.onebusaway.webapp.gwt.where_library.view.events.StopClickedHandler; import org.onebusaway.webapp.gwt.where_library.view.stops.PlaceClickHandler; import org.onebusaway.webapp.gwt.where_library.view.stops.TransitMapManager; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.maps.client.InfoWindow; import com.google.gwt.maps.client.InfoWindowContent; import com.google.gwt.maps.client.MapWidget; import com.google.gwt.maps.client.control.MapTypeControl; import com.google.gwt.maps.client.control.ScaleControl; import com.google.gwt.maps.client.geom.LatLng; import com.google.gwt.maps.client.geom.LatLngBounds; import com.google.gwt.maps.client.overlay.Marker; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.FlowPanel; public class MapViewController extends ViewController { private MobileApplicationCssResource _css = MobileApplicationResources.INSTANCE.getCSS(); private LocationManager _locationManager = MobileApplicationContext.getLocationManager(); private static int _zoom = 11; private FlowPanel _panel = new FlowPanel(); private MapWidget _map; private TransitMapManager _transitMapManager; private Marker _currentLocationMarker = null; public void showStopsForRoute(RouteBean route, StopsForRouteBean stopsForRoute) { _transitMapManager.showStopsForRoute(route, stopsForRoute, true); LatLngBounds b = LatLngBounds.newInstance(); for (StopBean stop : stopsForRoute.getStops()) b.extend(LatLng.newInstance(stop.getLat(), stop.getLon())); if (!b.isEmpty()) { _map.setCenter(b.getCenter(), _map.getBoundsZoomLevel(b)); _locationManager.setLastSearchLocation(b.getCenter()); } } public void showPlace(Place place) { _transitMapManager.showPlace(place, true, null); _locationManager.setLastSearchLocation(place.getLocation()); } public void showPlaces(List<Place> places) { _transitMapManager.showPlaces(places, false, new PlaceClickHandlerImpl(true)); LatLngBounds b = LatLngBounds.newInstance(); for (Place place : places) b.extend(place.getLocation()); if (!b.isEmpty()) _locationManager.setLastSearchLocation(b.getCenter()); } /**** * {@link ViewController} Interface ****/ @Override protected void loadView() { super.loadView(); System.out.println("loading..."); NavigationItem navigationItem = getNavigationItem(); navigationItem.setTitle("Map"); navigationItem.setLeftBarButtonItem(new BarButtonItem( EBarButtonSystemItem.CROSS_HAIRS, new UseCurrentLocationClickHandler())); _locationManager.addGeoLocationHandler(new GeoLocationHandlerImpl()); LatLng currentLocation = _locationManager.getCurrentSearchLocation(); _map = new MapWidget(currentLocation, _zoom); _map.addControl(new LargeButtonMapControl()); _map.addControl(new MapTypeControl()); _map.addControl(new ScaleControl()); _map.setScrollWheelZoomEnabled(true); _map.setHeight("100%"); _map.setWidth("100%"); _transitMapManager = new TransitMapManager(_map); _transitMapManager.addStopClickedHandler(new StopClickedHandlerImpl()); _panel.addStyleName(_css.MapViewControllerContainer()); if (_locationManager.hasPhysicalLocation()) updateCurrentLocationMarker(currentLocation.getLatitude(), currentLocation.getLongitude()); _view = _panel; } @Override public void viewDidAppear() { super.viewDidAppear(); _panel.add(_map); System.out.println("check resize"); _map.checkResizeAndCenter(); } @Override public void viewWillDisappear() { super.viewWillDisappear(); _panel.remove(_map); } @Override public void handleContext(List<String> path, Map<String, String> context) { } @Override public void retrieveContext(List<String> path, Map<String, String> context) { } /**** * Private Methods ****/ private void showPlaceInfoWindow(Place place, boolean includeSelectionLink) { LatLng p = place.getLocation(); InfoWindow window = _map.getInfoWindow(); FlowPanel panel = new FlowPanel(); FlowPanel rowA = new FlowPanel(); panel.add(rowA); rowA.add(new SpanWidget(place.getName())); if (includeSelectionLink) { FlowPanel rowB = new FlowPanel(); panel.add(rowB); Anchor anchor = new Anchor("Show nearby stops"); anchor.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent arg0) { } }); rowB.add(anchor); } window.open(p, new InfoWindowContent(panel)); } private class StopClickedHandlerImpl implements StopClickedHandler { @Override public void handleStopClicked(StopClickedEvent event) { final StopBean stop = event.getStop(); FlowPanel panel = new FlowPanel(); panel.add(new DivWidget(stop.getName())); StringBuilder b = new StringBuilder(); if (stop.getDirection() != null) b.append(stop.getDirection()).append(" - "); b.append("Routes: "); boolean first = true; for (RouteBean route : stop.getRoutes()) { if (!first) b.append(","); b.append(" ").append(route.getShortName()); } panel.add(new DivWidget(b.toString())); Anchor anchor = new Anchor("Show Real-Time Arrivals"); anchor.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent arg0) { Actions.showArrivalsAndDeparturesForStop(getNavigationController(), stop.getId()); } }); DivPanel anchorRow = new DivPanel(); panel.add(anchorRow); anchorRow.add(anchor); InfoWindow window = _map.getInfoWindow(); LatLng point = LatLng.newInstance(stop.getLat(), stop.getLon()); window.open(point, new InfoWindowContent(panel)); } } private void updateCurrentLocationMarker(double lat, double lon) { if (_currentLocationMarker != null) { LatLng currentCenter = _currentLocationMarker.getLatLng(); if (currentCenter.getLatitude() == lat && currentCenter.getLongitude() == lon) return; _map.removeOverlay(_currentLocationMarker); _currentLocationMarker = null; } LatLng center = LatLng.newInstance(lat, lon); _currentLocationMarker = new Marker(center); _map.addOverlay(_currentLocationMarker); _map.panTo(center); } private class UseCurrentLocationClickHandler implements ClickHandler { @Override public void onClick(ClickEvent arg0) { if (_locationManager.hasPhysicalLocation()) { _map.setCenter(_locationManager.getPhysicalLocation()); _transitMapManager.showStopsInCurrentView(); } } } private class GeoLocationHandlerImpl implements GeoLocationHandler { @Override public void handleLocation(GeoLocationEvent event) { double lat = event.getLat(); double lon = event.getLon(); updateCurrentLocationMarker(lat, lon); } @Override public void handleError(GeoLocationErrorEvent event) { System.out.println("error: code=" + event.getCode() + " message=" + event.getMessage()); } } private class PlaceClickHandlerImpl implements PlaceClickHandler { private boolean _includeSelectionLink; public PlaceClickHandlerImpl(boolean includeSelectionLink) { _includeSelectionLink = includeSelectionLink; } @Override public void onPlaceClicked(Place place) { showPlaceInfoWindow(place, _includeSelectionLink); } } }