// Created by plusminus on 00:23:14 - 03.10.2008
package org.osmdroid;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.util.DisplayMetrics;
import android.view.InputDevice;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.constants.OpenStreetMapConstants;
import org.osmdroid.samplefragments.BaseSampleFragment;
import org.osmdroid.samplefragments.SampleFactory;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.CopyrightOverlay;
import org.osmdroid.views.overlay.MinimapOverlay;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.overlay.compass.CompassOverlay;
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
import org.osmdroid.views.overlay.gestures.RotationGestureOverlay;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
/**
* Default map view activity.
*
* @author Marc Kurtz
* @author Manuel Stahl
*
*/
public class StarterMapFragment extends Fragment implements OpenStreetMapConstants {
// ===========================================================
// Constants
// ===========================================================
private static final int DIALOG_ABOUT_ID = 1;
private static final int MENU_SAMPLES = Menu.FIRST + 1;
private static final int MENU_ABOUT = MENU_SAMPLES + 1;
private static final int MENU_LAST_ID = MENU_ABOUT + 1; // Always set to last unused id
// ===========================================================
// Fields
// ===========================================================
private SharedPreferences mPrefs;
private MapView mMapView;
private MyLocationNewOverlay mLocationOverlay;
private CompassOverlay mCompassOverlay=null;
private MinimapOverlay mMinimapOverlay;
private ScaleBarOverlay mScaleBarOverlay;
private RotationGestureOverlay mRotationGestureOverlay;
private CopyrightOverlay mCopyrightOverlay;
public static StarterMapFragment newInstance() {
return new StarterMapFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Note! we are programmatically construction the map view
//be sure to handle application lifecycle correct (see note in on pause)
mMapView = new MapView(inflater.getContext());
// Call this method to turn off hardware acceleration at the View level but only if you run into problems ( please report them too!)
// setHardwareAccelerationOff();
//update, no longer needed, the mapView is hardware acceleration off by defaul tnow
if (Build.VERSION.SDK_INT >= 12) {
mMapView.setOnGenericMotionListener(new View.OnGenericMotionListener() {
/**
* mouse wheel zooming ftw
* http://stackoverflow.com/questions/11024809/how-can-my-view-respond-to-a-mousewheel
* @param v
* @param event
* @return
*/
@Override
public boolean onGenericMotion(View v, MotionEvent event) {
if (0 != (event.getSource() & InputDevice.SOURCE_CLASS_POINTER)) {
switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL:
if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f)
mMapView.getController().zoomOut();
else {
//this part just centers the map on the current mouse location before the zoom action occurs
IGeoPoint iGeoPoint = mMapView.getProjection().fromPixels((int) event.getX(), (int) event.getY());
mMapView.getController().animateTo(iGeoPoint);
mMapView.getController().zoomIn();
}
return true;
}
}
return false;
}
});
}
return mMapView;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setHardwareAccelerationOff() {
// Turn off hardware acceleration here, or in manifest
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mMapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Context context = this.getActivity();
final DisplayMetrics dm = context.getResources().getDisplayMetrics();
// mResourceProxy = new ResourceProxyImpl(getActivity().getApplicationContext());
mPrefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(context),
mMapView);
mMinimapOverlay = new MinimapOverlay(context, mMapView.getTileRequestCompleteHandler());
mMinimapOverlay.setWidth(dm.widthPixels / 5);
mMinimapOverlay.setHeight(dm.heightPixels / 5);
mCopyrightOverlay = new CopyrightOverlay(context);
//i hate this very much, but it seems as if certain versions of android and/or
//device types handle screen offsets differently
if (Build.VERSION.SDK_INT <= 10)
mCopyrightOverlay.setOffset(0,(int)(55*dm.density));
mScaleBarOverlay = new ScaleBarOverlay(mMapView);
mScaleBarOverlay.setCentred(true);
mScaleBarOverlay.setScaleBarOffset(dm.widthPixels / 2, 10);
mRotationGestureOverlay = new RotationGestureOverlay(mMapView);
mRotationGestureOverlay.setEnabled(true);
mMapView.setBuiltInZoomControls(true);
mMapView.setMultiTouchControls(true);
mMapView.setTilesScaledToDpi(true);
mMapView.getOverlays().add(this.mLocationOverlay);
mMapView.getOverlays().add(this.mCopyrightOverlay);
mMapView.getOverlays().add(this.mMinimapOverlay);
mMapView.getOverlays().add(this.mScaleBarOverlay);
mMapView.getOverlays().add(this.mRotationGestureOverlay);
mMapView.getController().setZoom(mPrefs.getInt(PREFS_ZOOM_LEVEL, 1));
mMapView.scrollTo(mPrefs.getInt(PREFS_SCROLL_X, 0), mPrefs.getInt(PREFS_SCROLL_Y, 0));
mLocationOverlay.enableMyLocation();
//sorry for the spaghetti code this is to filter out the compass on api 8
//Note: the compass overlay causes issues on API 8 devices. See https://github.com/osmdroid/osmdroid/issues/218
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) {
mCompassOverlay = new CompassOverlay(context, new InternalCompassOrientationProvider(context),
mMapView);
mCompassOverlay.enableCompass();
mMapView.getOverlays().add(this.mCompassOverlay);
}
setHasOptionsMenu(true);
}
@Override
public void onPause() {
final SharedPreferences.Editor edit = mPrefs.edit();
edit.putString(PREFS_TILE_SOURCE, mMapView.getTileProvider().getTileSource().name());
edit.putInt(PREFS_SCROLL_X, mMapView.getScrollX());
edit.putInt(PREFS_SCROLL_Y, mMapView.getScrollY());
edit.putInt(PREFS_ZOOM_LEVEL, mMapView.getZoomLevel());
edit.putBoolean(PREFS_SHOW_LOCATION, mLocationOverlay.isMyLocationEnabled());
//sorry for the spaghetti code this is to filter out the compass on api 8
//Note: the compass overlay causes issues on API 8 devices. See https://github.com/osmdroid/osmdroid/issues/218
if (mCompassOverlay!=null) {
edit.putBoolean(PREFS_SHOW_COMPASS, mCompassOverlay.isCompassEnabled());
this.mCompassOverlay.disableCompass();
}
edit.commit();
this.mLocationOverlay.disableMyLocation();
super.onPause();
}
@Override
public void onDestroyView(){
super.onDestroyView();
//this part terminates all of the overlays and background threads for osmdroid
//only needed when you programmatically create the map
mMapView.onDetach();
}
@Override
public void onResume() {
super.onResume();
final String tileSourceName = mPrefs.getString(PREFS_TILE_SOURCE,
TileSourceFactory.DEFAULT_TILE_SOURCE.name());
try {
final ITileSource tileSource = TileSourceFactory.getTileSource(tileSourceName);
mMapView.setTileSource(tileSource);
} catch (final IllegalArgumentException e) {
mMapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
}
if (mPrefs.getBoolean(PREFS_SHOW_LOCATION, false)) {
this.mLocationOverlay.enableMyLocation();
}
//sorry for the spaghetti code this is to filter out the compass on api 8
//Note: the compass overlay causes issues on API 8 devices. See https://github.com/osmdroid/osmdroid/issues/218
if (mPrefs.getBoolean(PREFS_SHOW_COMPASS, false)) {
if (mCompassOverlay!=null)
//this call is needed because onPause, the orientation provider is destroyed to prevent context leaks
this.mCompassOverlay.setOrientationProvider(new InternalCompassOrientationProvider(getActivity()));
this.mCompassOverlay.enableCompass();
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Put overlay items first
mMapView.getOverlayManager().onCreateOptionsMenu(menu, MENU_LAST_ID, mMapView);
// Put samples next
SubMenu samplesSubMenu = menu.addSubMenu(0, MENU_SAMPLES, Menu.NONE, org.osmdroid.R.string.samples)
.setIcon(android.R.drawable.ic_menu_gallery);
ISampleFactory sampleFactory = SampleFactory.getInstance();
for (int a = 0; a < sampleFactory.count(); a++) {
final BaseSampleFragment f = sampleFactory.getSample(a);
samplesSubMenu.add(f.getSampleTitle()).setOnMenuItemClickListener(
new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
startSampleFragment(f);
return true;
}
});
}
// Put "About" menu item last
menu.add(0, MENU_ABOUT, Menu.CATEGORY_SECONDARY, org.osmdroid.R.string.about).setIcon(
android.R.drawable.ic_menu_info_details);
super.onCreateOptionsMenu(menu, inflater);
}
protected void startSampleFragment(Fragment fragment) {
FragmentManager fm = getFragmentManager();
fm.beginTransaction().hide(this).add(android.R.id.content, fragment, "SampleFragment")
.addToBackStack(null).commit();
}
@Override
public void onPrepareOptionsMenu(final Menu pMenu) {
mMapView.getOverlayManager().onPrepareOptionsMenu(pMenu, MENU_LAST_ID, mMapView);
super.onPrepareOptionsMenu(pMenu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mMapView.getOverlayManager().onOptionsItemSelected(item, MENU_LAST_ID, mMapView)) {
return true;
}
switch (item.getItemId()) {
case MENU_ABOUT:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle(org.osmdroid.R.string.app_name).setMessage(org.osmdroid.R.string.about_message)
.setIcon(org.osmdroid.R.drawable.icon)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//
}
}
);
builder.create().show();
return true;
}
return super.onOptionsItemSelected(item);
}
public MapView getMapView() {
return mMapView;
}
// @Override
// public boolean onTrackballEvent(final MotionEvent event) {
// return this.mMapView.onTrackballEvent(event);
// }
}