package org.pyneo.tabulae.map; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import org.mapsforge.core.model.LatLong; import org.mapsforge.map.android.util.AndroidPreferences; import org.mapsforge.map.android.view.MapView; import org.mapsforge.map.model.DisplayModel; import org.mapsforge.map.model.MapViewPosition; import org.mapsforge.map.model.common.PreferencesFacade; import org.pyneo.tabulae.Base; import org.pyneo.tabulae.R; import org.pyneo.tabulae.Tabulae; import static org.pyneo.tabulae.map.Constants.*; public class Map extends Base { // get one from http://download.mapsforge.org/maps/ and adapt path to your needs: protected MapView mapView; protected int currentMap = -1; protected LayerBase layer; protected SharedPreferences preferences; protected PreferencesFacade preferencesFacade; protected boolean snapToLocationEnabled; protected LatLong lastLocation; void activateLayer(int id) { if (layer == null || id != currentMap) { if (layer != null) { layer.onPause(); layer.onDestroy(); layer = null; } currentMap = id; switch (id) { case 0: layer = new LayerMapsForge((Tabulae) getActivity(), mapView); break; case 1: layer = new LayerOpenAndroMaps((Tabulae) getActivity(), mapView); break; case 2: layer = new LayerBingSat((Tabulae) getActivity(), mapView); break; case 3: layer = new LayerGoogleSat((Tabulae) getActivity(), mapView); break; case 4: layer = new LayerMapQuest((Tabulae) getActivity(), mapView); break; case 5: layer = new LayerOutdoorActive((Tabulae) getActivity(), mapView); break; case 6: layer = new LayerWanderreitKarte((Tabulae) getActivity(), mapView); break; } announceMap(); if (id != -1) { Editor editor = preferences.edit(); editor.putInt("currentMap", currentMap); // TODO do not put a resource id into preferences editor.commit(); } } if (layer != null) { layer.setVisible(true); layer.onResume(); } } void informSnapToLocation(boolean newValue) { if (newValue != snapToLocationEnabled) { snapToLocationEnabled = newValue; Bundle extra = new Bundle(); extra.putBoolean("autofollow", snapToLocationEnabled); ((Tabulae) getActivity()).inform(R.id.event_notify_autofollow, extra); Editor editor = preferences.edit(); editor.putBoolean("autoFollow", snapToLocationEnabled); editor.commit(); if (snapToLocationEnabled) { centerIfFollow(); } } } @Override public void onCreate(Bundle bundle) { if (DEBUG) Log.d(TAG, "Map.onCreate bundle=" + bundle); super.onCreate(bundle); // AndroidGraphicFactory.createInstance(getActivity().getApplication()); mapView = new MapView(getActivity()) { @Override public boolean onTouchEvent(MotionEvent motionEvent) { if (snapToLocationEnabled) { informSnapToLocation(false); } return super.onTouchEvent(motionEvent); } }; preferences = getActivity().getSharedPreferences("map", Context.MODE_PRIVATE); mapView.setClickable(true); // TODO: consider mapView.setGestureDetector();? mapView.getMapScaleBar().setVisible(false); mapView.getModel().mapViewPosition.setZoomLevelMin((byte) 4); mapView.getModel().mapViewPosition.setZoomLevelMax((byte) 20); mapView.getModel(); mapView.setBuiltInZoomControls(false); mapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); DisplayModel displayModel = mapView.getModel().displayModel; displayModel.setBackgroundColor(0xffbbbbbb); displayModel.setUserScaleFactor(1.5f); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (DEBUG) Log.d(TAG, "Map.onCreateView"); return mapView; } @Override public void onResume() { super.onResume(); currentMap = preferences.getInt("currentMap", 0); preferencesFacade = new AndroidPreferences(preferences); mapView.getModel().init(preferencesFacade); announceZoom(); informSnapToLocation(preferences.getBoolean("autoFollow", false)); if (snapToLocationEnabled) { // if snapToLocationEnabled was on map-center is the last location lastLocation = mapView.getModel().mapViewPosition.getCenter(); } activateLayer(currentMap); } @Override public void onPause() { super.onPause(); mapView.getModel().save(preferencesFacade); preferencesFacade.save(); activateLayer(-1); mapView.getModel().mapViewPosition.destroy(); mapView.destroy(); } public MapView getMapView() { return mapView; } void announceMap() { if (layer != null) { Bundle b = new Bundle(); b.putString("current_map", layer.getId()); ((Tabulae) getActivity()).inform(R.id.event_notify_map, b); } } void announceZoom() { Bundle extra = new Bundle(); extra.putInt("zoom_level", mapView.getModel().mapViewPosition.getZoomLevel()); ((Tabulae) getActivity()).inform(R.id.event_notify_zoom, extra); } void centerIfFollow() { if (lastLocation != null && snapToLocationEnabled) { //if (DEBUG) Log.d(TAG, "Map.inform lastLocation=" + lastLocation); mapView.getModel().mapViewPosition.setCenter(lastLocation); } } public void inform(int event, Bundle extra) { //if (DEBUG) Log.d(TAG, "Map.inform event=" + event + ", extra=" + extra); switch (event) { case R.id.event_do_autofollow: { //if (DEBUG) Log.d(TAG, "Map.inform event=event_autofollow, extra=" + extra); informSnapToLocation(!snapToLocationEnabled); } break; case R.id.event_request_autofollow: { Bundle b = new Bundle(); b.putBoolean("autofollow", snapToLocationEnabled); ((Tabulae) getActivity()).inform(R.id.event_notify_autofollow, b); } break; case R.id.event_notify_location: { //if (DEBUG) Log.d(TAG, "Map.inform event=location, extra=" + extra); lastLocation = toLatLong(extra); //if (DEBUG) Log.d(TAG, "Map.inform lastLocation=" + lastLocation); centerIfFollow(); } break; case R.id.event_do_zoom_in: { MapViewPosition mvp = mapView.getModel().mapViewPosition; mvp.setZoomLevel((byte) (mvp.getZoomLevel() + 1)); announceZoom(); } break; case R.id.event_do_zoom_out: { MapViewPosition mvp = mapView.getModel().mapViewPosition; if (mvp.getZoomLevel() > 0) { mvp.setZoomLevel((byte) (mvp.getZoomLevel() - 1)); } announceZoom(); } break; case R.id.event_request_zoom: { announceZoom(); } break; case R.id.event_request_map: { announceMap(); } break; case R.id.event_do_send_location: { final MapViewPosition mvp = mapView.getModel().mapViewPosition; final String label = ""; final byte zoom = mvp.getZoomLevel(); final LatLong latLong = mvp.getCenter(); final Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, label + '\n' + "http://www.openstreetmap.org/?mlat=" + latLong.latitude + "&mlon=" + latLong.longitude + "#map=" + zoom + '/' + latLong.latitude + '/' + latLong.longitude + "&layers=T" ); startActivity(intent); } break; case R.id.event_do_view_location: { final MapViewPosition mvp = mapView.getModel().mapViewPosition; final String label = ""; //final byte zoom = mvp.getZoomLevel(); final LatLong latLong = mvp.getCenter(); final Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("geo:" + latLong.latitude + ',' + latLong.longitude + "?q=" + latLong.latitude + ',' + latLong.longitude + '(' + label + ')')); startActivity(intent); } break; case R.id.event_do_map_vector: activateLayer(0); break; case R.id.event_do_map_openandromaps: activateLayer(1); break; case R.id.event_do_map_bing_satellite: activateLayer(2); break; case R.id.event_do_map_google_satellite: activateLayer(3); break; case R.id.event_do_map_mapquest: activateLayer(4); break; case R.id.event_do_map_outdoor_active: activateLayer(5); break; case R.id.event_do_map_wanderreitkarte: activateLayer(6); break; } } private LatLong toLatLong(Bundle extra) { return new LatLong(extra.getDouble("latitude"), extra.getDouble("longitude")); } }