/******************************************************************************* * Gaggle is Copyright 2010 by Geeksville Industries LLC, a California limited liability corporation. * * Gaggle is distributed under a dual license. We've chosen this approach because within Gaggle we've used a number * of components that Geeksville Industries LLC might reuse for commercial products. Gaggle can be distributed under * either of the two licenses listed below. * * 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. * * Commercial Distribution License * If you would like to distribute Gaggle (or portions thereof) under a license other than * the "GNU General Public License, version 2", contact Geeksville Industries. Geeksville Industries reserves * the right to release Gaggle source code under a commercial license of its choice. * * GNU Public License, version 2 * All other distribution of Gaggle must conform to the terms of the GNU Public License, version 2. The full * text of this license is included in the Gaggle source, see assets/manual/gpl-2.0.txt. ******************************************************************************/ package com.geeksville.maps; import org.andnav.osm.ResourceProxy; import org.andnav.osm.util.GeoPoint; import org.andnav.osm.views.OpenStreetMapViewController; import org.andnav.osm.views.overlay.MyLocationOverlay; import org.andnav.osm.views.util.IOpenStreetMapRendererInfo; import org.andnav.osm.views.util.OpenStreetMapRendererFactory; import org.andnav.osm.views.util.XYRenderer; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.MenuItem.OnMenuItemClickListener; import android.view.SubMenu; import com.flurry.android.FlurryAgent; import com.geeksville.android.LifeCycleHandler; import com.geeksville.android.LifeCyclePublisher; import com.geeksville.android.LifeCyclePublisherImpl; import com.geeksville.gaggle.R; /** * * @author kevinh FIXME, add the following sources: http://toposm.com/usw/ Great * topos here: http://openpistemap.org/?lat=41&lon=-100&zoom=12 - we should check the author allow such a usage * FIXME : Most of the tiles here use openstreetmapdata, the licence needs that we attribute their work, but have no idea how to show that, * so, at least, I'm doing it here : Copyright : openstreetmap.org & contributors CC-BY-SA. - sly * * FIXME : This should better be changed into a config setting and generic way to add map providers instead of hardcoded here - sly */ public class GeeksvilleMapActivity extends Activity implements LifeCyclePublisher { // private LinearLayout linearLayout; protected GeeksvilleMapView mapView; private MyLocationOverlay myLocationOverlay; private LifeCyclePublisherImpl lifePublish = new LifeCyclePublisherImpl(); // There is also TopOSM features, but we don't bother to show that private static final IOpenStreetMapRendererInfo TopOSMRelief = new XYRenderer("Topo Relief (USA)", ResourceProxy.string.unknown, 4, 15, 8, ".jpg", "http://tile1.toposm.com/us/color-relief/", "http://tile2.toposm.com/us/color-relief/", "http://tile3.toposm.com/us/color-relief/"); private static final IOpenStreetMapRendererInfo TopOSMContours = new XYRenderer("Topo Contours (USA)", ResourceProxy.string.unknown, 12, 15, 8, ".png", "http://tile1.toposm.com/us/contours/", "http://tile2.toposm.com/us/contours/", "http://tile3.toposm.com/us/contours/"); private static final IOpenStreetMapRendererInfo OpenCycleMap = new XYRenderer("www.opencyclemap.org", ResourceProxy.string.unknown, 1, 18, 8, ".png", "http://a.tile.opencyclemap.org/cycle/", "http://b.tile.opencyclemap.org/cycle/", "http://c.tile.opencyclemap.org/cycle/" ); // I know the operator of this renderer allows us to use it, because it's me ;-) (sly) private static final IOpenStreetMapRendererInfo OpenHikingMap = new XYRenderer("maps.refuges.info", ResourceProxy.string.unknown, 1, 17, 8, ".png", "http://maps.refuges.info/hiking/"); // Tiles Courtesy of MapQuest : http://www.mapquest.com/" private static final IOpenStreetMapRendererInfo OpenMapQuest = new XYRenderer("www.mapquest.com", ResourceProxy.string.unknown, 1, 18, 8, ".png", "http://otile1.mqcdn.com/tiles/1.0.0/osm/"); // Tiles Courtesy of MapQuest : http://www.mapquest.com/" private static final IOpenStreetMapRendererInfo OpenMapQuestAerial = new XYRenderer("www.mapquest.com-aerial", ResourceProxy.string.unknown, 1, 18, 8, ".jpg", "http://oatile1.mqcdn.com/naip/"); private static IOpenStreetMapRendererInfo supportedRenderers[] = { OpenMapQuest, OpenMapQuestAerial, OpenCycleMap, OpenHikingMap, //OpenStreetMapRendererFactory.TOPO, This one is not working anymore, might need so update to osmdroid TopOSMContours, TopOSMRelief }; private String supportedRendererNames[]; public GeeksvilleMapActivity() { // FIXME - do this someplace better OpenStreetMapRendererFactory.addRenderer(TopOSMContours); OpenStreetMapRendererFactory.addRenderer(TopOSMRelief); OpenStreetMapRendererFactory.addRenderer(OpenCycleMap); OpenStreetMapRendererFactory.addRenderer(OpenHikingMap); OpenStreetMapRendererFactory.addRenderer(OpenMapQuest); OpenStreetMapRendererFactory.addRenderer(OpenMapQuestAerial); } /** Called when the activity is first created. */ public void onCreate(Bundle savedInstanceState, int layoutId, int mapViewId) { super.onCreate(savedInstanceState); supportedRendererNames = new String[] { getString(R.string.openmapquest), getString(R.string.openmapquestaerial), getString(R.string.opencyclemap), getString(R.string.openhikingmap), //getString(R.string.topo_europe), getString(R.string.topo_us_contour), getString(R.string.topo_us_relief) }; // Our license key is different for the emulator, otherwise these files // should be identical setContentView(layoutId); mapView = (GeeksvilleMapView) findViewById(mapViewId); mapView.setBuiltInZoomControls(true); // Set default map view mapView.setRenderer(OpenMapQuest); // Default to sat view // mapView.setSatellite(true); } /** * Collect app metrics on Flurry * * @see android.app.Activity#onStart() */ @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); lifePublish.onStart(); } /** * Collect app metrics on Flurry * * @see android.app.Activity#onStop() */ @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); lifePublish.onStop(); } /** * Create our options menu * * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu) */ @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.map_optionmenu, menu); // Set action for map prefetch // menu.findItem(R.id.prefetch_map).setIntent( // PrefetchMapActivity.createIntent(this, mapView.getMapCenter(), // mapView // .getZoomLevel(), mapView.getRenderer().name())); // Dynamically populate the list of renderers we support (FIXME - only // list known good renderers) MenuItem mapoptions = menu.findItem(R.id.mapmode_menu); SubMenu children = mapoptions.getSubMenu(); children.clear(); MenuItem toCheck = null; for (int i = 0; i < supportedRenderers.length; i++) { final IOpenStreetMapRendererInfo info = supportedRenderers[i]; String name = supportedRendererNames[i]; MenuItem item = children.add(1, i, Menu.NONE, name); if (mapView.getRenderer().name().equals(info.name())) toCheck = item; item.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { mapView.setRenderer(info); item.setChecked(true); return true; } }); } children.setGroupCheckable(1, true, true); toCheck.setChecked(true); return true; } /** * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem) */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.myloc_menu: zoomToLocation(); return true; } return super.onOptionsItemSelected(item); } /** * Override if you want a different my location view * * @return */ protected MyLocationOverlay createLocationOverlay() { return new CenteredMyLocationOverlay(this, mapView); } /** * If isLive is set, then add an overlay showing where user is */ protected void showCurrentPosition(boolean zoomToUser) { FlurryAgent.onEvent("View live position"); myLocationOverlay = createLocationOverlay(); if (zoomToUser) { // Once we find our position, center on it Runnable runnable = new Runnable() { @Override public void run() { zoomToLocation(); } }; myLocationOverlay.runOnFirstFix(runnable); } mapView.getOverlays().add(myLocationOverlay); } private void zoomToLocation() { // Center on where the user is OpenStreetMapViewController control = mapView.getController(); GeoPoint loc; if (myLocationOverlay != null && (loc = myLocationOverlay.getMyLocation()) != null) control.animateTo(loc); } @Override protected void onPause() { super.onPause(); if (myLocationOverlay != null) { myLocationOverlay.disableMyLocation(); // myLocationOverlay.disableCompass(); } lifePublish.onPause(); } @Override protected void onResume() { super.onResume(); // Show our cur location if (myLocationOverlay != null) { myLocationOverlay.enableMyLocation(); // myLocationOverlay.enableCompass(); } lifePublish.onResume(); } @Override public void addLifeCycleHandler(LifeCycleHandler h) { lifePublish.addLifeCycleHandler(h); } @Override public void removeLifeCycleHandler(LifeCycleHandler h) { lifePublish.removeLifeCycleHandler(h); } }