//Created by plusminus on 19:05:55 - 12.02.2008
package org.androad.ui.map;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.text.ClipboardManager;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.RelativeSizeSpan;
import android.text.style.StyleSpan;
import android.util.Log;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import junit.framework.Assert;
import org.androad.R;
import org.androad.adt.AndNavLocation;
import org.androad.adt.UnitSystem;
import org.androad.adt.DBPOI;
import org.androad.adt.Favorite;
import org.androad.adt.TrafficFeed;
import org.androad.app.APIIntentReceiver;
import org.androad.db.DBManager;
import org.androad.db.DataBaseException;
import org.androad.db.MapAnnotationsDBManager;
import org.androad.exc.Exceptor;
import org.androad.osm.util.CoordinatesExtractor;
import org.androad.osm.views.overlay.OSMMapViewCrosshairOverlay;
import org.androad.osm.views.overlay.OSMMapViewSimpleLineOverlay;
import org.androad.osm.views.tiles.util.OSMMapTilePreloader;
import org.androad.osm.views.util.Util;
import org.androad.osm.util.constants.OSMConstants;
import org.androad.nav.stats.StatisticsManager;
import org.androad.preferences.PreferenceConstants;
import org.androad.preferences.Preferences;
import org.androad.sys.ftpc.api.FTPCRequester;
import org.androad.sys.ors.adt.ds.POIGroup;
import org.androad.sys.ors.aas.AASRequester;
import org.androad.sys.ors.aas.AASResponse;
import org.androad.sys.ors.adt.GeocodedAddress;
import org.androad.sys.ors.adt.aoi.AreaOfInterest;
import org.androad.sys.ors.adt.aoi.Polygon;
import org.androad.sys.ors.adt.ds.POIType;
import org.androad.sys.ors.adt.lus.Country;
import org.androad.sys.ors.adt.lus.ReverseGeocodePreferenceType;
import org.androad.sys.ors.adt.ts.ISpatialDataOrganizer;
import org.androad.sys.ors.adt.ts.TrafficItem;
import org.androad.sys.ors.adt.ts.TrafficOverlayManager;
import org.androad.sys.ors.exceptions.ORSException;
import org.androad.sys.ors.ff.FoxyTagRequester;
import org.androad.sys.ors.lus.LUSRequester;
import org.androad.sys.ors.tuks.TUKSRequester;
import org.androad.sys.ors.util.RouteHandleIDExtractor;
import org.androad.sys.ors.views.overlay.AreaOfInterestOverlay;
import org.androad.sys.ors.views.overlay.OsmBugPoint;
import org.androad.sys.ors.views.overlay.FavoritePoint;
import org.androad.sys.ors.views.overlay.FoxyTagPoint;
import org.androad.sys.ors.views.overlay.BitmapItem;
import org.androad.sys.ors.views.overlay.BitmapOverlay;
import org.androad.sys.ors.views.overlay.CircleItem;
import org.androad.sys.ors.views.overlay.CircleOverlay;
import org.androad.sys.ors.views.overlay.TrafficOverlay;
import org.androad.sys.ors.views.overlay.TrafficOverlayItem;
import org.androad.sys.osb.adt.OpenStreetBug;
import org.androad.sys.osb.api.OSBRequester;
import org.androad.sys.postcode.uk_bs_7666.PostcodeUK_BS7776Matcher;
import org.androad.sys.vehicleregistrationplates.VRPRegistry;
import org.androad.sys.vehicleregistrationplates.tables.IVRPElement;
import org.androad.ui.camera.CameraFavorite;
import org.androad.ui.common.CommonCallback;
import org.androad.ui.common.CommonCallbackAdapter;
import org.androad.ui.common.CommonDialogFactory;
import org.androad.ui.common.CommonDialogFactory.OSBMapLongAddSelectorResult;
import org.androad.ui.common.InlineAutoCompleterConstant;
import org.androad.ui.common.views.CompassImageView;
import org.androad.ui.common.views.CompassRotateView;
import org.androad.ui.osm.api.nodes.POICategorySelector;
import org.androad.ui.sd.SDMainChoose;
import org.androad.ui.weather.WeatherForecast;
import org.androad.util.FileSizeFormatter;
import org.androad.util.TimeUtils;
import org.androad.util.UserTask;
import org.androad.util.constants.Constants;
import org.openstreetmap.api.exceptions.OSMAPIException;
import org.openstreetmap.api.node.NodeCreationRequester;
import org.osmdroid.events.MapListener;
import org.osmdroid.events.ScrollEvent;
import org.osmdroid.events.ZoomEvent;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.MapTileProviderBase;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.BoundingBoxE6;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.MapView.Projection;
import org.osmdroid.views.MapController.AnimationType;
import org.osmdroid.views.overlay.DirectedLocationOverlay;
import org.osmdroid.views.overlay.ItemizedOverlay;
import org.osmdroid.views.overlay.ItemizedOverlayWithFocus;
import org.osmdroid.views.overlay.ItemizedOverlayControlView;
import org.osmdroid.views.overlay.Overlay;
import org.osmdroid.views.overlay.OverlayItem;
import org.osmdroid.views.overlay.OverlayManager;
import org.osmdroid.views.overlay.ItemizedIconOverlay.OnItemGestureListener;
public class WhereAmIMap extends OpenStreetMapAndNavBaseActivity implements PreferenceConstants, Constants, OnItemGestureListener<OverlayItem>{
// ===========================================================
// Final Fields
// ===========================================================
/** Time in milliseconds the Autocentering is disabled, after the user panned the map. */
private static final int AUTOCENTER_BLOCKTIME = 5000;
private static final int REQUESTCODE_WEATHER = 0;
private static final int REQUESTCODE_STRUCTURED_SEARCH_SD_MAINCHOOSE = REQUESTCODE_WEATHER + 1;
private static final int REQUESTCODE_DDMAP = REQUESTCODE_STRUCTURED_SEARCH_SD_MAINCHOOSE + 1;
public static final int REQUESTCODE_PICTURE = REQUESTCODE_DDMAP + 1;
private static final int REQUESTCODE_POICATEGORYSELECTOR = REQUESTCODE_PICTURE + 1;
private final int LAT_INDEX = 0;
private final int LON_INDEX = 1;
private static final int MENU_QUIT_ID = Menu.FIRST;
private static final int MENU_SATELLITE_ID = MENU_QUIT_ID + 1;
private static final int MENU_SUBMENU_TRAFFIC_ID = MENU_SATELLITE_ID + 1;
private static final int MENU_WEATHER_ID = MENU_SUBMENU_TRAFFIC_ID + 1;
private static final int MENU_LAYER_ID = MENU_WEATHER_ID + 1;
private static final int MENU_SUBMENU_POI = MENU_LAYER_ID + 1;
private static final int MENU_SUBMENU_FOXYTAG = MENU_SUBMENU_POI + 1;
private static final int MENU_SUBMENU_FAVORITE = MENU_SUBMENU_FOXYTAG + 1;
private static final int MENU_SUBMENU_OSMBUG = MENU_SUBMENU_FAVORITE + 1;
private static final int MENU_SUBMENU_MAPANNOTATIONS = MENU_SUBMENU_OSMBUG + 1;
private static final int MENU_PRELOAD_ID = MENU_SUBMENU_MAPANNOTATIONS + 1;
private static final int MENU_ACCESSIBILITYANALYSIS_ID = MENU_PRELOAD_ID + 1;
private static final int MENU_LOAD_TRACE_ID = MENU_ACCESSIBILITYANALYSIS_ID + 1;
private static final int MENU_SHOWLATLON_ID = MENU_LOAD_TRACE_ID + 1;
private static final int MENU_INPUTLATLON_ID = MENU_SHOWLATLON_ID + 1;
private static final int MENU_VEHICLEREGISTRATIONPLATE_LOOKUP_ID = MENU_INPUTLATLON_ID + 1;
private static final int MENU_SUBMENU_TRAFFIC_CUSTOM = MENU_VEHICLEREGISTRATIONPLATE_LOOKUP_ID + 1;
private static final int MENU_SUBMENU_TRAFFIC_CLEAR = MENU_SUBMENU_TRAFFIC_CUSTOM + 1;
private static final int MENU_GPSSTATUS_ID = MENU_SUBMENU_TRAFFIC_CLEAR + 1;
private static final int MENU_SUBMENU_LAYERS_OFFSET = 1000;
private static final int DIALOG_SELECT_CUSTOM_TRAFFIC_FEED = 0;
private static final int DIALOG_ADD_CUSTOM_TRAFFIC_FEED = DIALOG_SELECT_CUSTOM_TRAFFIC_FEED + 1;
private static final int DIALOG_INPUT_LAT_LON = DIALOG_ADD_CUSTOM_TRAFFIC_FEED + 1;
private static final int DIALOG_SELECT_FREEFORM_OR_STRUCTURED_SEARCH = DIALOG_INPUT_LAT_LON + 1;
private static final int DIALOG_INPUT_FAVORITE_NAME = DIALOG_SELECT_FREEFORM_OR_STRUCTURED_SEARCH + 1;
private static final int DIALOG_SELECT_VEHICLEREGISTRATIONPLATE_LOOKUP_COUNTRIES = DIALOG_INPUT_FAVORITE_NAME + 1;
private static final int DIALOG_INPUT_VEHICLEREGISTRATIONPLATE_LOOKUP = DIALOG_SELECT_VEHICLEREGISTRATIONPLATE_LOOKUP_COUNTRIES + 1;
private static final int DIALOG_SELECT_POI_OR_OSB_OR_FTPC = DIALOG_INPUT_VEHICLEREGISTRATIONPLATE_LOOKUP + 1;
private static final int DIALOG_INPUT_OSB_BUG = DIALOG_SELECT_POI_OR_OSB_OR_FTPC + 1;
private static final int DIALOG_INPUT_OSM_POI = DIALOG_INPUT_OSB_BUG + 1;
private static final int CENTERMODE_NONE = 0;
private static final int CENTERMODE_ONCE = CENTERMODE_NONE + 1;
private static final int CENTERMODE_AUTO = CENTERMODE_ONCE + 1;
// ===========================================================
// Fields
// ===========================================================
/** Holds the timestamp until the AutoCentering is blocked, because the user has panned the map. */
private long mAutoCenterBlockedUntil = 0;
private SensorManager mSensorManager;
private ImageButton mIbtnCenter;
private ImageButton mIbtnWhereAmI;
private ImageButton mIbtnSearch;
private ImageButton mIbtnChooseRenderer;
private CompassRotateView mCompassRotateView;
private CompassImageView mIvCompass;
private TextView mIbtnSpeed;
private EditText mEtSearch;
private ImageButton mIbtnNavPointsDoStart;
private ImageButton mIbtnNavPointsDoCancel;
private ImageButton mIbtnNavPointsSetStart;
private ImageButton mIbtnNavPointsSetDestination;
private GeoPoint mGPLastMapClick;
private ItemizedOverlayControlView mMapItemControlView;
private ScaleBarOverlay mScaleIndicatorView;
private DirectedLocationOverlay mMyLocationOverlay;
private OSMMapViewCrosshairOverlay mCrosshairOverlay;
private TrafficFeed mCurrentTrafficFeed;
private int mDoCenter = WhereAmIMap.CENTERMODE_AUTO;
private ArrayList<OverlayItem> mSearchPinList;
/** Currently selected index in mSearchPinList. */
private int mSearchPinListIndex;
private ItemizedOverlayWithFocus<OverlayItem> mItemOverlay;
private AreaOfInterestOverlay mAASOverlay;
private CircleOverlay mPOIOverlay;
private CircleOverlay mFFOverlay;
private BitmapOverlay mFavoriteOverlay;
private CircleOverlay mOsmBugOverlay;
private CircleOverlay mMapAnnotationsOverlay;
private TrafficOverlay mTrafficOverlay;
private BitmapItem mStartFlagItem;
private BitmapItem mDestinationFlagItem;
private BitmapOverlay mFlagsOverlay;
private OSMMapViewSimpleLineOverlay mNavPointsConnectionLineOverlay;
/** Keeps the screen alive when it would lock otherwise. */
private PowerManager.WakeLock mWakeLock;
private Animation mFadeOutDelayedAnimation;
private Animation mFadeToLeftAnimation;
private Animation mFadeToRightAnimation;
private Animation mFadeOutQuickAnimation;
private AreaOfInterestOverlay mAreaOfAvoidingsOverlay;
private final ArrayList<AreaOfInterest> mAvoidAreas = new ArrayList<AreaOfInterest>();
private final UnitSystem us = Preferences.getUnitSystem(this);
private boolean mNavPointsCrosshairMode;
private MapAnnotationsDBManager mapAnnotationDB;
/**
* Indicates whether driving-statistics are generated.
* Loaded from Preferences in onResume().
*/
private boolean mStatisticsEnabled = false;
private StatisticsManager mStatisticsManager;
/* Show or not layers */
private boolean showOverlayPoi = false;
private boolean showOverlayFoxyTag = false;
private boolean showOverlayFavorite = false;
private boolean showOverlayOsmBug = false;
private boolean showOverlayMapAnnotations = false;
// POI Type of new added poi
private POIType mAddOSMPOIType;
// ===========================================================
// Constructors
// ===========================================================
@Override
protected void onSetupContentView() {
this.setContentView(R.layout.whereami_map);
this.mOSMapView = (MapView)findViewById(R.id.map_whereami);
this.mOSMapView.setTileSource(Preferences.getMapViewProviderInfoWhereAmI(this));
this.mOSMapView.setMapListener(new AndRoadMapListener(this));
final OverlayManager overlaymanager = this.mOSMapView.getOverlayManager();
/* Add a new instance of our fancy Overlay-Class to the MapView. */
this.mMyLocationOverlay = new DirectedLocationOverlay(this);
this.mMyLocationOverlay.setLocation(getLastKnownLocation(true));
this.mTrafficOverlay = new TrafficOverlay(this, new ArrayList<TrafficOverlayItem>(), new OnItemGestureListener<TrafficOverlayItem>(){
@Override
public boolean onItemSingleTapUp(final int index, final TrafficOverlayItem item) {
if(index >= WhereAmIMap.this.mTrafficOverlay.getOverlayItems().size()) {
throw new IllegalArgumentException();
}
final TrafficOverlayItem focusedItem = WhereAmIMap.this.mTrafficOverlay.getFocusedItem();
if(!item.equals(focusedItem)){
WhereAmIMap.this.mTrafficOverlay.setFocusedItem(item);
}else{
WhereAmIMap.this.mTrafficOverlay.unSetFocusedItem();
}
WhereAmIMap.this.mOSMapView.getController().animateTo(item.getPoint(), AnimationType.MIDDLEPEAKSPEED);
return true;
}
@Override
public boolean onItemLongPress(final int index, final TrafficOverlayItem item) {
return true;
}
});
this.mTrafficOverlay.setDrawnItemsLimit(50);
this.mTrafficOverlay.setFocusItemsOnTap(false);
this.mAASOverlay = new AreaOfInterestOverlay(this);
this.mAASOverlay.setDrawnAreasLimit(10);
this.mPOIOverlay = new CircleOverlay(this);
this.mFFOverlay = new CircleOverlay(this);
this.mFavoriteOverlay = new BitmapOverlay(this);
this.mOsmBugOverlay = new CircleOverlay(this);
this.mMapAnnotationsOverlay = new CircleOverlay(this);
this.mAreaOfAvoidingsOverlay = new AreaOfInterestOverlay(this, this.mAvoidAreas);
this.mFlagsOverlay = new BitmapOverlay(this);
/* SetNavPoints-Overlay. */
this.mCrosshairOverlay = new OSMMapViewCrosshairOverlay(this, Color.BLACK, 2, 17);
this.mCrosshairOverlay.setEnabled(false);
this.mStartFlagItem = new BitmapItem(null, this, R.drawable.flag_start, null, new Point(18,47));
this.mDestinationFlagItem = new BitmapItem(null, this, R.drawable.flag_destination, null, new Point(18,47));
this.mFlagsOverlay.getBitmapItems().add(this.mStartFlagItem);
this.mFlagsOverlay.getBitmapItems().add(this.mDestinationFlagItem);
this.mNavPointsConnectionLineOverlay = new OSMMapViewSimpleLineOverlay(this);
this.mNavPointsConnectionLineOverlay.setPaintNormal();
this.mNavPointsConnectionLineOverlay.setEnabled(false);
overlaymanager.add(this.mAASOverlay);
overlaymanager.add(this.mPOIOverlay);
overlaymanager.add(this.mFFOverlay);
overlaymanager.add(this.mFavoriteOverlay);
overlaymanager.add(this.mOsmBugOverlay);
overlaymanager.add(this.mMapAnnotationsOverlay);
overlaymanager.add(this.mAreaOfAvoidingsOverlay);
overlaymanager.add(this.mTrafficOverlay);
overlaymanager.add(this.mNavPointsConnectionLineOverlay);
overlaymanager.add(this.mFlagsOverlay);
overlaymanager.add(this.mMyLocationOverlay);
overlaymanager.add(this.mCrosshairOverlay);
mapAnnotationDB = new MapAnnotationsDBManager(this);
}
private void refreshPinOverlay(final GeoPoint pGeoPoint) {
final ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
items.add(new OverlayItem("", "", pGeoPoint));
refreshPinOverlay(items);
WhereAmIMap.this.updateUIForAutoCenterChange(WhereAmIMap.CENTERMODE_NONE);
WhereAmIMap.this.mOSMapView.getController().animateTo(pGeoPoint, AnimationType.MIDDLEPEAKSPEED);
}
private void refreshPinOverlay(final ArrayList<OverlayItem> items){
this.mSearchPinListIndex = 0;
clearPinOverlay();
this.mMapItemControlView.setVisibility(View.VISIBLE);
final boolean nextPreviousEnabled = items.size() > 1;
this.mMapItemControlView.setNextEnabled(nextPreviousEnabled);
this.mMapItemControlView.setPreviousEnabled(nextPreviousEnabled);
this.mSearchPinList = items;
this.mOSMapView.getOverlayManager().add(this.mItemOverlay = new ItemizedOverlayWithFocus<OverlayItem>(this, this.mSearchPinList, this));
this.mItemOverlay.setFocusItemsOnTap(false);
}
private void clearPinOverlay() {
this.mMapItemControlView.setVisibility(View.GONE);
if(this.mSearchPinList != null) {
this.mSearchPinList.clear();
}
final OverlayManager overlaymanager = this.mOSMapView.getOverlayManager();
if(this.mItemOverlay != null) {
overlaymanager.remove(this.mItemOverlay);
}
}
/** Called when the activity is first created. */
@Override
public void onCreate(final Bundle icicle) {
super.onCreate(icicle);
/* Load all the Views. */
this.mIbtnCenter = (ImageButton)this.findViewById(R.id.ibtn_whereami_center);
this.mIbtnWhereAmI = (ImageButton)this.findViewById(R.id.ibtn_whereami_whereami);
this.mIbtnSearch = (ImageButton)this.findViewById(R.id.ibtn_whereami_search);
this.mIbtnChooseRenderer = (ImageButton)this.findViewById(R.id.ibtn_whereami_choose_renderer);
this.mCompassRotateView = (CompassRotateView)this.findViewById(R.id.rotator_wheramimap);
this.mCompassRotateView.toggleActive();
this.mIvCompass = (CompassImageView)this.findViewById(R.id.iv_whereami_compass);
this.mIbtnSpeed = (TextView)this.findViewById(R.id.ibtn_whereami_speed);
this.mIbtnSpeed.setText("NaN");
this.mEtSearch = (EditText)this.findViewById(R.id.et_whereami_search);
this.mIbtnNavPointsSetStart = (ImageButton)this.findViewById(R.id.ibtn_whereami_setstartpoint);
this.mIbtnNavPointsSetDestination = (ImageButton)this.findViewById(R.id.ibtn_whereami_setendpoint);
this.mIbtnNavPointsDoStart = (ImageButton)this.findViewById(R.id.ibtn_whereami_setnavpoints_start);
this.mIbtnNavPointsDoCancel = (ImageButton)this.findViewById(R.id.ibtn_whereami_setnavpoints_cancel);
this.mMapItemControlView = (ItemizedOverlayControlView)this.findViewById(R.id.itemizedoverlaycontrol_whereami);
this.mScaleIndicatorView = new ScaleBarOverlay(this);
if (us == UnitSystem.IMPERIAL) {
this.mScaleIndicatorView.setImperial();
} else {
this.mScaleIndicatorView.setMetric();
}
this.mStatisticsEnabled = Preferences.getStatisticsEnabled(this);
if(this.mStatisticsEnabled) {
this.mStatisticsManager = new StatisticsManager(this, us, Preferences.getStatisticsSessionStart(this));
} else{
this.mStatisticsManager = null;
}
this.mScaleIndicatorView.setScaleBarOffset(getResources().getDisplayMetrics().widthPixels/2 - getResources().getDisplayMetrics().xdpi/2, 10);
final OverlayManager overlaymanager = this.mOSMapView.getOverlayManager();
overlaymanager.add(this.mScaleIndicatorView);
/* Load the animation from XML (XML file is res/anim/***.xml). */
this.mFadeOutDelayedAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_out_delayed);
this.mFadeOutDelayedAnimation.setFillAfter(true);
this.mFadeOutQuickAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_out);
this.mFadeOutQuickAnimation.setFillAfter(true);
this.mFadeToLeftAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_to_left);
this.mFadeToLeftAnimation.setFillAfter(true);
this.mFadeToRightAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_to_right);
this.mFadeToRightAnimation.setFillAfter(true);
/* Run the Hide-Icons animation on the start, because no touch is applied yet. */
this.startDelayedHideControlsAnimation();
this.mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
/* This code together with the one in onResume() will make the screen be always on during navigation. */
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
this.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "MyWakeLock");
this.mWakeLock.acquire();
this.applyQuickButtonListeners();
this.applyZoomButtonListeners();
this.applyMapViewLongPressListener();
this.applyAutoCompleteListeners();
final boolean doDefault = !handlePossibleAction();
if(doDefault){
final GeoPoint location = getLastKnownLocation(true);
if(location == null || Math.abs(location.getLatitudeE6()) <= 100 || Math.abs(location.getLongitudeE6()) <= 100) {
this.mOSMapView.getController().setZoom(3);
} else{
this.mOSMapView.getController().setZoom(13);
this.mOSMapView.getController().setCenter(location);
}
/* Show the user why the map is auto-centering on the user. */
Toast.makeText(WhereAmIMap.this, R.string.toast_autofollow_enabled, Toast.LENGTH_SHORT).show();
this.mDoCenter = WhereAmIMap.CENTERMODE_AUTO;
}
}
/**
*
* @return <code>true</code> whether an action was correctly recognized and handled.
*/
private boolean handlePossibleAction() {
final Intent iStartedWith = this.getIntent();
final String action = iStartedWith.getAction();
if(action != null){
if(action.equals(ANDROAD_VIEW_ACTION)){
final Bundle extras = iStartedWith.getExtras();
/* Extract geopoint-Strings from the Bundle. */
final ArrayList<String> geoPointStrings = extras.getStringArrayList(APIIntentReceiver.WHEREAMI_EXTRAS_LOCATIONS_ID);
if(geoPointStrings.size() > 0){
/* And convert them to actual GeoPoints */
final ArrayList<GeoPoint> geoPoints = new ArrayList<GeoPoint>(geoPointStrings.size());
for (final String locationString : geoPointStrings) {
geoPoints.add(GeoPoint.fromIntString(locationString));
}
/* Extract descriptions and titles from the Bundle. */
final ArrayList<String> descriptions = extras.getStringArrayList(APIIntentReceiver.WHEREAMI_EXTRAS_LOCATIONS_DESCRIPTIONS_ID);
final ArrayList<String> titles = extras.getStringArrayList(APIIntentReceiver.WHEREAMI_EXTRAS_LOCATIONS_TITLES_ID);
/* Create overlay-items from the data extracted. */
final ArrayList<OverlayItem> items = new ArrayList<OverlayItem>(geoPointStrings.size());
for(int i = 0; i < geoPointStrings.size(); i++) {
items.add(new OverlayItem(titles.get(i), descriptions.get(i), geoPoints.get(i)));
}
/* Calculate the BoundingBox around the items. */
final BoundingBoxE6 itemBoundingBoxE6 = BoundingBoxE6.fromGeoPoints(geoPoints);
refreshPinOverlay(items);
WhereAmIMap.this.updateUIForAutoCenterChange(WhereAmIMap.CENTERMODE_NONE);
new Handler().postDelayed(new Runnable(){
@Override
public void run() {
if(items.size() == 1) {
WhereAmIMap.this.mOSMapView.getController().setZoom(13);
} else {
WhereAmIMap.this.mOSMapView.getController().zoomToSpan(itemBoundingBoxE6);
}
WhereAmIMap.this.mOSMapView.getController().animateTo(itemBoundingBoxE6.getCenter(), AnimationType.MIDDLEPEAKSPEED);
}
}, 500);
return true;
}
}else if(action.equals(android.content.Intent.ACTION_VIEW)){
final Uri data = iStartedWith.getData();
if(data != null && data.getScheme().equals("geo")){
/* Extract lat/lon-String. */
final String coordsString = iStartedWith.getData().getSchemeSpecificPart();
if(coordsString.length() > 0){
final String[] coordinates = coordsString.split(",");
try{
final double lat = Double.parseDouble(coordinates[this.LAT_INDEX]);
final double lon = Double.parseDouble(coordinates[this.LON_INDEX]);
this.mOSMapView.getController().setZoom(15);
this.mOSMapView.getController().setCenter(new GeoPoint((int)(lat * 1E6), (int)(lon * 1E6)));
this.mDoCenter = WhereAmIMap.CENTERMODE_NONE;
return true;
}catch(final NumberFormatException nfe){
final int qParamIndex = coordsString.indexOf("q=");
if(qParamIndex != -1){
final String textualQuery = coordsString.substring(qParamIndex + "q=".length());
if(textualQuery.length() > 0){
searchORSLocations(textualQuery);
this.mEtSearch.setText(textualQuery);
this.mDoCenter = WhereAmIMap.CENTERMODE_NONE;
return true;
}
}else{
Log.d(Constants.DEBUGTAG, "Could not parse \"" + iStartedWith.getData().toString() + "\"-Uri");
}
}
}
}
}
}
return false;
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods from SuperClass/Interfaces
// ===========================================================
private void startDelayedHideControlsAnimation(){
/* Left icons */
if(this.mEtSearch.getVisibility() != View.VISIBLE) {
this.mIbtnSearch.startAnimation(this.mFadeToLeftAnimation);
}
if(this.mNavPointsCrosshairMode == false){
this.mIbtnNavPointsDoStart.startAnimation(this.mFadeToLeftAnimation);
this.mIbtnCenter.startAnimation(this.mFadeToRightAnimation);
}
/* Right icons */
this.mIbtnWhereAmI.startAnimation(this.mFadeToRightAnimation);
this.mIbtnChooseRenderer.startAnimation(this.mFadeToRightAnimation);
}
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch(requestCode){
case REQUESTCODE_STRUCTURED_SEARCH_SD_MAINCHOOSE:
if(resultCode == SUBACTIVITY_RESULTCODE_CHAINCLOSE_SUCCESS || resultCode == SUBACTIVITY_RESULTCODE_SUCCESS){
final Bundle b = data.getExtras();
final ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
final int latE6 = b.getInt(EXTRAS_DESTINATION_LATITUDE_ID);
final int lonE6 = b.getInt(EXTRAS_DESTINATION_LONGITUDE_ID);
final GeoPoint gp = new GeoPoint(latE6, lonE6);
items.add(new OverlayItem(b.getString(EXTRAS_DESTINATION_TITLE), "", gp));
refreshPinOverlay(items);
WhereAmIMap.this.updateUIForAutoCenterChange(WhereAmIMap.CENTERMODE_NONE);
WhereAmIMap.this.mOSMapView.getController().animateTo(gp, AnimationType.MIDDLEPEAKSPEED);
}
break;
case REQUESTCODE_PICTURE:
String result = data.getStringExtra(CommonDialogFactory.class.getName());
long favoriteid = -1;
if (WhereAmIMap.this.mGPLastMapClick == null)
break;
try {
favoriteid = DBManager.addFavorite(WhereAmIMap.this, result, WhereAmIMap.this.mGPLastMapClick.getLatitudeE6(), WhereAmIMap.this.mGPLastMapClick.getLongitudeE6());
} catch (final DataBaseException e) {
Toast.makeText(WhereAmIMap.this, R.string.toast_error_adding_favorite, Toast.LENGTH_LONG).show();
}
if (favoriteid == -1)
break;
Favorite f;
try {
f = DBManager.getFavoriteById(this, "" + favoriteid);
} catch (final DataBaseException e) {
break;
}
byte[] d = data.getByteArrayExtra(CameraFavorite.class.getName());
final String favoriteFolderPath = org.androad.osm.util.Util.getAndRoadExternalStoragePath() + OSMConstants.SDCARD_SAVEDFAVORITES_PATH;
new File(favoriteFolderPath).mkdirs();
final String filename = f.getPhotoFilename();
FileOutputStream outStream = null;
try {
// Write to sdcard
outStream = new FileOutputStream(filename);
outStream.write(d);
outStream.flush();
outStream.close();
} catch (final Exception e) {
Log.e(OSMConstants.DEBUGTAG, "File-Writing-Error", e);
}
break;
case REQUESTCODE_POICATEGORYSELECTOR:
this.mAddOSMPOIType = POIType.values()[resultCode];
if (CommonDialogFactory.inputOSMPOI != null) {
final TextView tvCategoryName = (TextView)CommonDialogFactory.inputOSMPOI.findViewById(R.id.tv_dlg_input_osmpoiname_name);
tvCategoryName.setText(this.mAddOSMPOIType.READABLENAMERESID);
}
showDialog(DIALOG_INPUT_OSM_POI);
break;
}
}
@Override
public void release(){
// Nothing...
}
@Override
public void onDestroy() {
Log.d(Constants.DEBUGTAG, "OnDESTROY");
this.mWakeLock.release();
if(this.mStatisticsManager != null) {
this.mStatisticsManager.finish();
}
super.onDestroy();
}
private final String STATE_AUTOCENTER_ID = "state_autocenter_id";
private final String STATE_ETSEARCHVISIBLE_ID = "state_etsearchvisible_id";
private final String STATE_ZOOM_ID = "state_zoom_id";
private final String STATE_MAPCENTER_ID = "state_mapcenter_id";
private final String STATE_VEHICLEREGISTRATIONPLATE_NATIONALITY_ID = "state_crp_nationality_id";
protected Country mVehicleRegistrationPlateLOokupNationality;
@Override
protected void onRestoreInstanceState(final Bundle savedInstanceState) {
if(savedInstanceState == null) {
return;
}
super.onRestoreInstanceState(savedInstanceState);
updateUIForAutoCenterChange(savedInstanceState.getInt(this.STATE_AUTOCENTER_ID, WhereAmIMap.CENTERMODE_AUTO));
if(savedInstanceState.getBoolean(this.STATE_ETSEARCHVISIBLE_ID)) {
handleSearchOpen();
}
this.mOSMapView.getController().setZoom(savedInstanceState.getInt(this.STATE_ZOOM_ID, 13));
final GeoPoint mapCenter = savedInstanceState.getParcelable(this.STATE_MAPCENTER_ID);
this.mOSMapView.getController().setCenter(mapCenter);
final String vrpLookupNationalityString = savedInstanceState.getString(this.STATE_VEHICLEREGISTRATIONPLATE_NATIONALITY_ID);
if(vrpLookupNationalityString != null){
this.mVehicleRegistrationPlateLOokupNationality = Country.fromAbbreviation(vrpLookupNationalityString);
}
}
@Override
protected void onSaveInstanceState(final Bundle outState) {
outState.putInt(this.STATE_AUTOCENTER_ID, this.mDoCenter);
outState.putBoolean(this.STATE_ETSEARCHVISIBLE_ID, this.mEtSearch.getVisibility() == View.VISIBLE);
outState.putInt(this.STATE_ZOOM_ID, this.mOSMapView.getZoomLevel());
outState.putParcelable(this.STATE_MAPCENTER_ID, this.mOSMapView.getMapCenter());
if(this.mVehicleRegistrationPlateLOokupNationality != null) {
outState.putString(this.STATE_VEHICLEREGISTRATIONPLATE_NATIONALITY_ID, this.mVehicleRegistrationPlateLOokupNationality.COUNTRYCODE);
}
if(this.mStatisticsEnabled && this.mStatisticsManager != null) {
this.mStatisticsManager.writeThrough();
}
super.onSaveInstanceState(outState);
}
/**
* Gets called when an item of the PinOverlay gets tapped.
*/
@Override
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
if(index >= this.mSearchPinList.size()) {
throw new IllegalArgumentException();
}
this.mSearchPinListIndex = index;
final TrafficOverlayItem focusedItem = WhereAmIMap.this.mTrafficOverlay.getFocusedItem();
if(!item.equals(focusedItem)){
this.mItemOverlay.setFocusedItem(item);
}else{
this.mItemOverlay.unSetFocusedItem();
}
this.mOSMapView.getController().animateTo(item.getPoint(), AnimationType.MIDDLEPEAKSPEED);
return true;
}
@Override
public boolean onItemLongPress(final int index, final OverlayItem item) {
return true;
}
@Override
protected void onResume() {
super.onResume();
if((this.mSensorManager.getSensors() & SensorManager.SENSOR_ORIENTATION) != 0){
this.mSensorManager.registerListener(this.mCompassRotateView, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_UI);
this.mSensorManager.registerListener(this.mIvCompass, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_UI);
}
}
@Override
protected void onPause() {
if((this.mSensorManager.getSensors() & SensorManager.SENSOR_ORIENTATION) != 0){
this.mSensorManager.unregisterListener(this.mCompassRotateView);
this.mSensorManager.unregisterListener(this.mIvCompass);
}
super.onPause();
}
@Override
public boolean onKeyDown(final int keyCode, final KeyEvent event) {
switch(keyCode){
case KeyEvent.KEYCODE_SEARCH:
if(this.mEtSearch.getVisibility() != View.VISIBLE) {
handleSearchOpen();
} else {
handleSearchSubmit(this.mEtSearch.getText().toString());
}
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
int menuPos = Menu.FIRST;
menu.setQwertyMode(true);
{ // Weather-Item
menu.add(menuPos, MENU_WEATHER_ID, menuPos, getString(R.string.maps_menu_weather))
.setIcon(R.drawable.weather_get)
.setAlphabeticShortcut('w');
menuPos++;
}
{ // Layer-Item
final SubMenu subMenu = menu.addSubMenu(menuPos, MENU_LAYER_ID, menuPos, getString(R.string.maps_menu_layer))
.setIcon(android.R.drawable.ic_menu_mapmode);
menuPos++;
{
subMenu.add(menuPos, MENU_SUBMENU_POI, menuPos, getString(R.string.maps_menu_submenu_layer_poi))
.setIcon(R.drawable.settingsmenu_poi);
subMenu.add(menuPos, MENU_SUBMENU_FOXYTAG, menuPos, getString(R.string.maps_menu_submenu_layer_foxytag))
.setIcon(R.drawable.foxytag);
subMenu.add(menuPos, MENU_SUBMENU_FAVORITE, menuPos, getString(R.string.maps_menu_submenu_layer_favorite))
.setIcon(R.drawable.settingsmenu_favorites);
subMenu.add(menuPos, MENU_SUBMENU_OSMBUG, menuPos, getString(R.string.maps_menu_submenu_layer_osmbug))
.setIcon(R.drawable.settingsmenu_osmbug);
subMenu.add(menuPos, MENU_SUBMENU_MAPANNOTATIONS, menuPos, getString(R.string.maps_menu_submenu_layer_mapannotations))
.setIcon(R.drawable.settingsmenu_mapannotations);
subMenu.setGroupCheckable(menuPos, true, false);
menuPos++;
}
}
{ // Traffic-SubMenuItem
final SubMenu subMenu = menu.addSubMenu(menuPos, MENU_SUBMENU_TRAFFIC_ID, menuPos, getString(R.string.maps_menu_submenu_traffic))
.setIcon(R.drawable.warning_severe);
menuPos++;
{
subMenu.add(0, MENU_SUBMENU_TRAFFIC_CLEAR, Menu.NONE, R.string.maps_menu_submenu_traffic_clear);
subMenu.add(1, MENU_SUBMENU_TRAFFIC_CUSTOM, Menu.NONE, R.string.maps_menu_submenu_traffic_custom_feeds);
}
}
{ // VRP-Lookup-Item
menu.add(menuPos, MENU_VEHICLEREGISTRATIONPLATE_LOOKUP_ID, menuPos, getString(R.string.maps_menu_vehicleregistrationplate_lookup))
.setIcon(R.drawable.vehicleregistrationplate)
.setAlphabeticShortcut('v');
menuPos++;
}
{ // AAS-Item
menu.add(menuPos, MENU_ACCESSIBILITYANALYSIS_ID, menuPos, getString(R.string.maps_menu_accessibility_analysis))
.setIcon(R.drawable.accessibility)
.setAlphabeticShortcut('a');
menuPos++;
}
{ // GPS-Status-Item
menu.add(menuPos, MENU_GPSSTATUS_ID, menuPos, getString(R.string.maps_menu_gpsstatus))
.setIcon(R.drawable.gps_status)
.setAlphabeticShortcut('g');
menuPos++;
}
{ // Preload-Item
menu.add(menuPos, MENU_PRELOAD_ID, menuPos, getString(R.string.maps_menu_preload))
.setIcon(R.drawable.preload)
.setAlphabeticShortcut('p');
menuPos++;
}
{ // Show Lat/Lng-Item
menu.add(menuPos, MENU_SHOWLATLON_ID, menuPos, getString(R.string.maps_menu_getcentetcoordinates))
.setIcon(R.drawable.world)
.setAlphabeticShortcut('l');
menuPos++;
}
{ // Input Lat/Lon-Item
menu.add(menuPos, MENU_INPUTLATLON_ID, menuPos, getString(R.string.maps_menu_focus_coordinates))
.setIcon(R.drawable.world)
.setAlphabeticShortcut('i');
menuPos++;
}
{ // Close-Item
if(menu.size() <= 5){ // If there will be no 'more'-item
menu.add(menuPos, MENU_QUIT_ID, menuPos, getString(R.string.maps_menu_quit))
.setIcon(R.drawable.exit)
.setAlphabeticShortcut('q');
}else{
// Place it as the fifth.
menu.add(4, MENU_QUIT_ID, 4, getString(R.string.maps_menu_quit))
.setIcon(R.drawable.exit)
.setAlphabeticShortcut('q');
}
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onPrepareOptionsMenu(final Menu menu) {
/* Refresh Accessibility item. */
final MenuItem item = menu.findItem(MENU_ACCESSIBILITYANALYSIS_ID);
item.setTitle((this.mAASOverlay.getAreasOfInterest().size() == 0) ? R.string.maps_menu_accessibility_analysis : R.string.hide);
menu.findItem(MENU_SUBMENU_TRAFFIC_CLEAR).setVisible(this.mTrafficOverlay.getOverlayItems() != null && this.mTrafficOverlay.getOverlayItems().size() > 0);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onMenuItemSelected(final int featureId, final MenuItem item) {
final int itemId = item.getItemId();
switch(itemId){
case MENU_ACCESSIBILITYANALYSIS_ID:
if(this.mAASOverlay.getAreasOfInterest().size() == 0) {
showAccessibilityAnalysisDialog(item);
} else {
this.mAASOverlay.getAreasOfInterest().clear();
}
return true;
case MENU_WEATHER_ID:
openWeatherDialog(this.mOSMapView.getMapCenter());
return true;
case MENU_SUBMENU_POI:
showPoi(item);
return true;
case MENU_SUBMENU_FOXYTAG:
showFoxyTag(item);
return true;
case MENU_SUBMENU_FAVORITE:
showFavorite(item);
return true;
case MENU_SUBMENU_OSMBUG:
showOsmBug(item);
return true;
case MENU_SUBMENU_MAPANNOTATIONS:
showMapAnnotations(item);
return true;
case MENU_GPSSTATUS_ID:
org.androad.ui.util.Util.startUnknownActivity(this, "com.eclipsim.gpsstatus.VIEW", "com.eclipsim.gpsstatus");
return true;
case MENU_QUIT_ID:
this.setResult(Constants.SUBACTIVITY_RESULTCODE_CHAINCLOSE_QUITTED);
this.finish();
return true;
case MENU_PRELOAD_ID:
showPreloadDialog();
return true;
case MENU_INPUTLATLON_ID:
showDialog(DIALOG_INPUT_LAT_LON);
return true;
case MENU_SHOWLATLON_ID:
showCenterLatLonDialog();
return true;
case MENU_VEHICLEREGISTRATIONPLATE_LOOKUP_ID:
showDialog(DIALOG_SELECT_VEHICLEREGISTRATIONPLATE_LOOKUP_COUNTRIES);
return true;
case MENU_SUBMENU_TRAFFIC_CLEAR:
this.mTrafficOverlay.setOverlayItems(null);
return true;
case MENU_SUBMENU_TRAFFIC_CUSTOM:
try {
final int feedCount = DBManager.getCustomTrafficFeedCount(this);
if(feedCount > 0) {
this.showDialog(DIALOG_SELECT_CUSTOM_TRAFFIC_FEED);
} else {
this.showDialog(DIALOG_ADD_CUSTOM_TRAFFIC_FEED);
}
} catch (final DataBaseException e) {
// TODO ERROR MESSAGE!
}
return true;
default:
if(itemId >= MENU_SUBMENU_LAYERS_OFFSET){
changeProviderInfo(TileSourceFactory.getTileSources().toArray(new ITileSource[0])[item.getItemId() - MENU_SUBMENU_LAYERS_OFFSET]);
return true;
}
}
return super.onMenuItemSelected(featureId, item);
}
@Override
protected void onPrepareDialog(final int id, final Dialog d) {
switch(id){
case DIALOG_SELECT_CUSTOM_TRAFFIC_FEED:
}
}
@Override
protected Dialog onCreateDialog(final int id) {
switch(id){
case DIALOG_SELECT_VEHICLEREGISTRATIONPLATE_LOOKUP_COUNTRIES:
return CommonDialogFactory.createNationalitySelectionDialog(this, Country.getAllWithVRPTable(), new CommonCallbackAdapter<Country>(){
@Override
public void onSuccess(final Country result) {
WhereAmIMap.this.mVehicleRegistrationPlateLOokupNationality = result;
showDialog(DIALOG_INPUT_VEHICLEREGISTRATIONPLATE_LOOKUP);
}
});
case DIALOG_INPUT_VEHICLEREGISTRATIONPLATE_LOOKUP:
/* TODO proper msg and title. */
return CommonDialogFactory.createInputDialog(this, R.string.dlg_input_vehicleregistrationplate_lookup_hint, R.string.dlg_input_vehicleregistrationplate_lookup_title, new CommonCallbackAdapter<String>(){
@Override
public void onSuccess(final String result) {
final IVRPElement vrp = VRPRegistry.resolve(WhereAmIMap.this.mVehicleRegistrationPlateLOokupNationality.getVRPTableID(), result);
if(vrp == null){
Toast.makeText(WhereAmIMap.this, "Sorry, not found", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(WhereAmIMap.this, "Found: " + vrp.getAbbreviation() + " = " + vrp.getRepresentation(), Toast.LENGTH_LONG).show();
}
}
});
case DIALOG_SELECT_CUSTOM_TRAFFIC_FEED:
List<TrafficFeed> customTrafficFeeds;
try {
customTrafficFeeds = DBManager.getCustomTrafficFeeds(this);
} catch (final DataBaseException e) {
customTrafficFeeds = new ArrayList<TrafficFeed>();
}
return CommonDialogFactory.createSelectCustomTrafficFeedDialog(this, customTrafficFeeds, new CommonCallbackAdapter<TrafficFeed>(){
@Override
public void onSuccess(final TrafficFeed result) {
if(result != null){
receiveTrafficFromFeed(result);
}else{
showDialog(DIALOG_ADD_CUSTOM_TRAFFIC_FEED);
}
}
});
case DIALOG_ADD_CUSTOM_TRAFFIC_FEED:
return CommonDialogFactory.createAddCustomTrafficFeedDialog(WhereAmIMap.this, new CommonCallbackAdapter<TrafficFeed>(){
@Override
public void onSuccess(final TrafficFeed result) {
if(result != null){
receiveTrafficFromFeed(result);
}
}
});
case DIALOG_INPUT_LAT_LON:
return CommonDialogFactory.createInputLatLonDialog(this, new CommonCallback<GeoPoint>(){
@Override
public void onFailure(final Throwable t) {
Toast.makeText(WhereAmIMap.this, R.string.dlg_input_direct_lat_lon_malformed, Toast.LENGTH_SHORT).show();
}
@Override
public void onSuccess(final GeoPoint result) {
refreshPinOverlay(result);
}
});
case DIALOG_SELECT_FREEFORM_OR_STRUCTURED_SEARCH:
return CommonDialogFactory.createFreeformOrStructuredAddressSelectorDialog(this, new CommonCallbackAdapter<Integer>(){
@Override
public void onSuccess(final Integer result) {
switch(result){
case 0:
handleSearchOpen();
break;
case 1:
/* Load SDMainChoose-Activity. */
final Intent sdIntent = new Intent(WhereAmIMap.this, SDMainChoose.class);
final Bundle b = new Bundle();
b.putInt(MODE_SD, MODE_SD_RESOLVE);
sdIntent.putExtras(b);
WhereAmIMap.this.startActivityForResult(sdIntent, REQUESTCODE_STRUCTURED_SEARCH_SD_MAINCHOOSE);
break;
}
}
});
case DIALOG_INPUT_FAVORITE_NAME:
return CommonDialogFactory.createInputFavoriteNameDialog(WhereAmIMap.this, new CommonCallback<String>(){
@Override
public void onFailure(final Throwable t) {
Toast.makeText(WhereAmIMap.this, R.string.toast_error_adding_favorite, Toast.LENGTH_LONG).show();
}
@Override
public void onSuccess(final String result) {
try {
DBManager.addFavorite(WhereAmIMap.this, result, WhereAmIMap.this.mGPLastMapClick.getLatitudeE6(), WhereAmIMap.this.mGPLastMapClick.getLongitudeE6());
} catch (final DataBaseException e) {
Toast.makeText(WhereAmIMap.this, R.string.toast_error_adding_favorite, Toast.LENGTH_LONG).show();
}
}
});
case DIALOG_SELECT_POI_OR_OSB_OR_FTPC:
return CommonDialogFactory.createAddOSBorFTPCDialog(WhereAmIMap.this, new CommonCallbackAdapter<OSBMapLongAddSelectorResult>(){
@Override
public void onSuccess(final OSBMapLongAddSelectorResult result) {
switch(result){
case OSB:
showDialog(DIALOG_INPUT_OSB_BUG);
break;
case FTPC:
showAddFTPCDialog();
break;
case OSMPOI:
showPOICategorySelectorActivity();
break;
}
}
});
case DIALOG_INPUT_OSB_BUG:
return CommonDialogFactory.createAddOSBBugDialog(this, new CommonCallbackAdapter<String>(){
@Override
public void onSuccess(final String result) {
mapAnnotationDB.addOsbBug(WhereAmIMap.this.mGPLastMapClick, result);
}
});
case DIALOG_INPUT_OSM_POI:
return CommonDialogFactory.createInputOSMPOIDialog(this, this.mAddOSMPOIType, new CommonCallback<String>(){
@Override
public void onSuccess(final String result) {
// TODO Ensure mapcenter did not change
if(result == null || result.length() == 0){
onFailure(new OSMAPIException("Invalid name."));
}else{
final GeoPoint mapCenter = WhereAmIMap.this.mGPLastMapClick;
final POIType poi = WhereAmIMap.this.mAddOSMPOIType;
Assert.assertNotNull(poi);
Assert.assertNotNull(mapCenter);
Assert.assertFalse(poi.POIGROUPS[0] == POIGroup.MAINGROUP);
mapAnnotationDB.addPoi(WhereAmIMap.this.mGPLastMapClick, WhereAmIMap.this.mAddOSMPOIType, result);
}
}
@Override
public void onFailure(final Throwable t) {
}
});
default:
return null;
}
}
private void receiveTrafficFromFeed(final TrafficFeed pTrafficFeed){
/* Check if we have the special case of the BBC TrafficFeed. */
if(pTrafficFeed.getURL().compareToIgnoreCase(TUKSRequester.BBC_TRAFFICFEED_URL) == 0){
this.mCurrentTrafficFeed = new TrafficFeed(TUKSRequester.BBC_TRAFFICFEED_URL, pTrafficFeed.getName(), Country.UNITEDKINGDOM);
}else{
this.mCurrentTrafficFeed = pTrafficFeed;
}
/* Check if there is a Nationality set. */
if(this.mCurrentTrafficFeed.getNationality() != null){
receiveTPEGMLTraffic(this.mCurrentTrafficFeed.getNationality().BOUNDINGBOXE6);
}else{
/* Get traffic for whole feed. (not BBox-filtering). */
receiveTPEGMLTraffic(null);
}
}
private void receiveTPEGMLTraffic(final BoundingBoxE6 bBox){
/* Check if we have the special case of the BBC TrafficFeed. */
if(this.mCurrentTrafficFeed.getURL().equals(TUKSRequester.BBC_TRAFFICFEED_URL)){
receiveTrafficUKBBC(bBox);
}else{
}
}
private void receiveTrafficUKBBC(final BoundingBoxE6 bBox){
new UserTask<Void, Void, ISpatialDataOrganizer<TrafficOverlayItem>>(){
@Override
public ISpatialDataOrganizer<TrafficOverlayItem> doInBackground(final Void... params) {
try {
Log.d(Constants.DEBUGTAG, "Before TUKS.");
final List<TrafficItem> trafficItems = TUKSRequester.request(bBox);
Log.d(Constants.DEBUGTAG, "Received TUKS.");
Log.d(Constants.DEBUGTAG, "Filtering items. (Before: " + trafficItems.size() + ")");
final List<TrafficOverlayItem> overlayItems = filterTrafficItemsToTrafficOverlayItems(trafficItems); // TODO vllt nur converten...
Log.d(Constants.DEBUGTAG, "Building index. (Count:" + trafficItems.size() + ")");
final ISpatialDataOrganizer<TrafficOverlayItem> trafficResult = new TrafficOverlayManager(overlayItems);
trafficResult.buildIndex();
Log.d(Constants.DEBUGTAG, "Built index.");
return trafficResult;
} catch (final Exception e) {
Log.d(Constants.DEBUGTAG, "Builign index failed.");
Exceptor.e("Error getting UK-Traffic.", e, WhereAmIMap.this);
return null;
}
}
@Override
public void onPostExecute(final ISpatialDataOrganizer<TrafficOverlayItem> result) {
if(result != null){
WhereAmIMap.this.mTrafficOverlay.setSpacialIndexManager(result);
}else{
Toast.makeText(WhereAmIMap.this, "Sorry there was a problem receiving the Traffic-Feed.", Toast.LENGTH_LONG).show();
}
}
}.execute();
}
/**
* Filters by Severity (Excludes: VERY_SLIGHT && SLIGHT)
* @return
*/
private List<TrafficOverlayItem> filterTrafficItemsToTrafficOverlayItems(final List<TrafficItem> trafficItems) {
final List<TrafficOverlayItem> overlayItems = new ArrayList<TrafficOverlayItem>(trafficItems.size());
for (final TrafficItem trafficItem : trafficItems){
switch(trafficItem.getSeverity()){
case VERY_SLIGHT:
case SLIGHT:
break;
case UNKNOWN:
case UNSPECIFIED:
case MEDIUM:
case SEVERE:
case VERY_SEVERE:
overlayItems.add(new TrafficOverlayItem(WhereAmIMap.this, trafficItem));
break;
}
}
return overlayItems;
}
@Override
public void onLocationLost(final AndNavLocation pLocation) {
// TODO anzeigen...
}
@Override
public void onLocationChanged(final AndNavLocation pLocation) {
if(this.mOSMapView == null || this.mMyLocationOverlay == null) {
return;
}
if(pLocation != null){
if(this.mMyLocationOverlay != null){
this.mMyLocationOverlay.setLocation(pLocation);
if(pLocation.hasBearing()) {
this.mMyLocationOverlay.setBearing(pLocation.getBearing());
}
if(pLocation.hasHorizontalPositioningError()) {
this.mMyLocationOverlay.setAccuracy(pLocation.getHorizontalPositioningError());
}
}
if(this.mDoCenter == WhereAmIMap.CENTERMODE_AUTO && System.currentTimeMillis() > this.mAutoCenterBlockedUntil){
this.mOSMapView.getController().setCenter(pLocation);
}
if(this.mStatisticsEnabled && this.mStatisticsManager != null) {
final DecimalFormat df = new DecimalFormat("#,###,##0.0");
this.mStatisticsManager.tick(pLocation);
int speed = (int) this.mStatisticsManager.getCurrentSpeed();
this.mIbtnSpeed.setText(""
+ df.format(us.mScaleToMetersPerSecond
* speed)
+ us.mAbbrKilometersPerHourScale);
}
}
this.mOSMapView.invalidate();
}
// ===========================================================
// Methods
// ===========================================================
private void showAddFTPCDialog() {
final LayoutInflater inflater = LayoutInflater.from(this);
final FrameLayout fl = (FrameLayout)inflater.inflate(R.layout.dlg_osb_add_ftpc, null);
final EditText etPostcode1 = (EditText)fl.findViewById(R.id.et_dlg_osb_add_ftpc_postcode1);
final EditText etPostcode2 = (EditText)fl.findViewById(R.id.et_dlg_osb_add_ftpc_postcode2);
etPostcode1.setSelectAllOnFocus(true);
etPostcode2.setSelectAllOnFocus(true);
new AlertDialog.Builder(this)
.setView(fl)
.setTitle(R.string.dlg_osb_add_ftpc_title)
.setPositiveButton(R.string.save, new DialogInterface.OnClickListener(){
@Override
public void onClick(final DialogInterface d, final int which) {
final String postcode1 = etPostcode1.getText().toString();
final String postcode2 = etPostcode2.getText().toString();
mapAnnotationDB.addFtpc(WhereAmIMap.this.mGPLastMapClick, postcode1, postcode2);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener(){
@Override
public void onClick(final DialogInterface d, final int which) {
d.dismiss();
}
}).create().show();
}
protected void showPOICategorySelectorActivity() {
final Intent i = new Intent(this, POICategorySelector.class);
startActivityForResult(i, REQUESTCODE_POICATEGORYSELECTOR);
}
private void showPoi(final MenuItem item) {
if (item.isChecked()) {
item.setChecked(false);
} else {
item.setChecked(true);
}
showOverlayPoi = item.isChecked();
updatePoi();
}
private void showFoxyTag(final MenuItem item) {
if (item.isChecked()) {
item.setChecked(false);
} else {
item.setChecked(true);
}
showOverlayFoxyTag = item.isChecked();
updateFoxyTag();
}
private void showFavorite(final MenuItem item) {
if (item.isChecked()) {
item.setChecked(false);
} else {
item.setChecked(true);
}
showOverlayFavorite = item.isChecked();
updateFavorite();
}
private void showOsmBug(final MenuItem item) {
if (item.isChecked()) {
item.setChecked(false);
} else {
item.setChecked(true);
}
showOverlayOsmBug = item.isChecked();
updateOsmBug();
}
private void showMapAnnotations(final MenuItem item) {
if (item.isChecked()) {
item.setChecked(false);
} else {
item.setChecked(true);
}
showOverlayMapAnnotations = item.isChecked();
updateMapAnnotations();
}
public void updateLayers() {
updatePoi();
updateFoxyTag();
updateFavorite();
updateOsmBug();
updateMapAnnotations();
}
private void updatePoi() {
final List<CircleItem> pois = WhereAmIMap.this.mPOIOverlay.getCircleItems();
if (pois.size() > 0) {
pois.clear();
}
if (showOverlayPoi &&
this.mOSMapView.getZoomLevel() > 11) {
new Thread(new Runnable(){
@Override
public void run() {
for (final DBPOI poi : DBManager.getPOIs(WhereAmIMap.this, WhereAmIMap.this.mOSMapView.getBoundingBox())) {
pois.add(new CircleItem(poi, WhereAmIMap.this, Color.BLUE, poi.getName()));
}
}
}, "POI-Runner").start();
}
}
private void updateFoxyTag() {
final List<CircleItem> ff = WhereAmIMap.this.mFFOverlay.getCircleItems();
if (ff.size() > 0) {
ff.clear();
}
if (showOverlayFoxyTag &&
this.mOSMapView.getZoomLevel() > 11) {
new Thread(new Runnable(){
@Override
public void run() {
try {
for (final FoxyTagPoint fpp : FoxyTagRequester.request(WhereAmIMap.this, WhereAmIMap.this.mOSMapView.getMapCenter())) {
if (WhereAmIMap.this.mOSMapView.getBoundingBox().contains(fpp.getCenter()))
ff.add(fpp);
}
} catch (final Exception e) {
Log.e(Constants.DEBUGTAG, "FoxyTagRequester-Error", e);
}
}
}, "FoxyTag-Runner").start();
}
}
private void updateFavorite() {
final List<BitmapItem> fs = WhereAmIMap.this.mFavoriteOverlay.getBitmapItems();
if (fs.size() > 0) {
fs.clear();
}
if (showOverlayFavorite &&
this.mOSMapView.getZoomLevel() > 11) {
new Thread(new Runnable(){
@Override
public void run() {
try {
for (final Favorite fp : DBManager.getFavorites(WhereAmIMap.this, WhereAmIMap.this.mOSMapView.getBoundingBox())) {
fs.add(new FavoritePoint(fp, WhereAmIMap.this));
}
} catch (final DataBaseException e) {
Log.e(Constants.DEBUGTAG, "Error on loading Favorites", e);
}
}
}, "Favorite-Runner").start();
}
}
private void updateOsmBug() {
final List<CircleItem> bugs = WhereAmIMap.this.mOsmBugOverlay.getCircleItems();
if (bugs.size() > 0) {
bugs.clear();
}
if (showOverlayOsmBug &&
this.mOSMapView.getZoomLevel() > 11) {
new Thread(new Runnable(){
@Override
public void run() {
try {
for (final OpenStreetBug bug : OSBRequester.getBugsFromBoundingBoxE6(WhereAmIMap.this.mOSMapView.getBoundingBox())) {
bugs.add(new OsmBugPoint(bug, WhereAmIMap.this));
}
} catch (final Exception e) {
Log.e(Constants.DEBUGTAG, "OSBRequester-Error", e);
}
}
}, "OsmBug-Runner").start();
}
}
private void updateMapAnnotations() {
final List<CircleItem> mapannotations = WhereAmIMap.this.mMapAnnotationsOverlay.getCircleItems();
if (mapannotations.size() > 0) {
mapannotations.clear();
}
if (showOverlayMapAnnotations &&
this.mOSMapView.getZoomLevel() > 11) {
new Thread(new Runnable(){
@Override
public void run() {
for (final DBPOI poi : mapAnnotationDB.getAll(WhereAmIMap.this.mOSMapView.getBoundingBox())) {
mapannotations.add(new CircleItem(poi, WhereAmIMap.this, Color.YELLOW, poi.getName()));
}
}
}, "MapAnnotations-Runner").start();
}
}
private void showCenterLatLonDialog() {
final GeoPoint mapCenter = WhereAmIMap.this.mOSMapView.getMapCenter();
new AlertDialog.Builder(this)
.setIcon(R.drawable.world)
.setTitle(R.string.coordinates)
.setMessage(getString(R.string.maps_menu_getcentetcoordinates_message, mapCenter.getLatitudeE6() / 1E6, mapCenter.getLongitudeE6() / 1E6))
.setNeutralButton(R.string.clipboard, new DialogInterface.OnClickListener(){
@Override
public void onClick(final DialogInterface d, final int which) {
final ClipboardManager cb = (ClipboardManager) WhereAmIMap.this.getSystemService(Context.CLIPBOARD_SERVICE);
final String clipboardText = String.format("%.6f %.6f",mapCenter.getLatitudeE6() / 1E6, mapCenter.getLongitudeE6() / 1E6);
cb.setText(clipboardText);
d.dismiss();
}
})
.setNegativeButton(R.string.ok, new DialogInterface.OnClickListener(){
@Override
public void onClick(final DialogInterface d, final int which) {
d.dismiss();
}
})
.create().show();
}
private void showPreloadDialog() {
final MapTileProviderBase providerInfo = this.mOSMapView.getTileProvider();
final String[] zoomLevelsRaw = getResources().getStringArray(R.array.preloader_rectangle_zoomlevels);
final String[] zoomLevelsForThisRenderer = new String[Math.min(providerInfo.getMaximumZoomLevel() + 1, zoomLevelsRaw.length)];
for(int i = 0; i < zoomLevelsForThisRenderer.length; i++) {
zoomLevelsForThisRenderer[i] = (zoomLevelsRaw[i] != null) ? zoomLevelsRaw[i] : "" + i;
}
new AlertDialog.Builder(this).setSingleChoiceItems(zoomLevelsForThisRenderer, 12, new DialogInterface.OnClickListener(){
@Override
public void onClick(final DialogInterface d, final int which) {
d.dismiss();
// which is the zoomLevel
preloadMapTilesUpToZoomLevel(which);
}
}).setTitle(R.string.dlg_preloader_rect_maxzoom_title)
.create().show();
}
private void preloadMapTilesUpToZoomLevel(final int pUptoZoomLevel) {
final MapTileProviderBase providerInfo = this.mOSMapView.getTileProvider();
/* For each zoomLevel, get the tiles, that hit the visible Rectangle. */
final BoundingBoxE6 bbE6Visible = this.mOSMapView.getBoundingBox();
final ArrayList<MapTile> tilesNeeded = new ArrayList<MapTile>();
for(int i = 0; i <= pUptoZoomLevel; i++) {
Util.calculateNeededTilesForZoomLevelInBoundingBox(tilesNeeded, i, bbE6Visible);
}
/* Calculate the number of tiles to download. */
final long tileCount = tilesNeeded.size();
/* Calculate the needed size. */
final long bytesEpectedNeeded = tileCount * providerInfo.getTileSource().getTileSizePixels() * 71;
final String formattedFileSize = FileSizeFormatter.formatFileSize(bytesEpectedNeeded);
final AlertDialog.Builder ab = new AlertDialog.Builder(this)
.setTitle(R.string.dlg_preloader_rect_title)
.setMessage(String.format(getString(R.string.dlg_preloader_rect_message), tileCount , formattedFileSize));
if(pUptoZoomLevel > 0){
ab.setNeutralButton(R.string.dlg_preloader_rect_reducezoom, new DialogInterface.OnClickListener(){
@Override
public void onClick(final DialogInterface d, final int which) {
d.dismiss();
preloadMapTilesUpToZoomLevel(pUptoZoomLevel - 1);
}
});
}
ab.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener(){
@Override
public void onClick(final DialogInterface d, final int which) {
d.dismiss();
final String progressMessage = getString(R.string.pdg_preloader_message);
final ProgressDialog pd = ProgressDialog.show(WhereAmIMap.this, getString(R.string.pdg_preloader_title), String.format(progressMessage, 0, tileCount), true, true);
final OSMMapTilePreloader preloader = new OSMMapTilePreloader(WhereAmIMap.this, providerInfo.getTileSource(), tilesNeeded);
preloader.setHandler(new Handler(){
@Override
public void handleMessage(Message msg) {
try {
int progress = preloader.getProgress();
int total = preloader.getTotal();
if(progress < total)
pd.setMessage(String.format(progressMessage, progress, total));
else
pd.dismiss();
} catch (final Exception e) {
Log.e(Constants.DEBUGTAG, "View error", e);
}
}
});
new Thread(preloader).start();
}
});
ab.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener(){
@Override
public void onClick(final DialogInterface d, final int which) {
d.dismiss();
}
}).show();
}
private void openWeatherDialog(final GeoPoint pGeoPoint) {
final Intent getWeatherIntent = new Intent(this, WeatherForecast.class);
getWeatherIntent.putExtra(WeatherForecast.WEATHERQUERY_GEOPOINTSTRING_ID, pGeoPoint.toString());
startActivityForResult(getWeatherIntent, REQUESTCODE_WEATHER);
}
private void showAccessibilityAnalysisDialog(final MenuItem item) {
final String minute = " " + getString(R.string.minute);
final String minutes = " " + getString(R.string.minutes);
final int[] minuteValues = getResources().getIntArray(R.array.accessibility_minutes);
final String[] minuteStrings = new String[minuteValues.length];
minuteStrings[0] = minuteValues[0] + " " + minute;
for (int i = 1; i < minuteValues.length; i++) {
minuteStrings[i] = minuteValues[i] + " " + minutes;
}
new AlertDialog.Builder(this).setSingleChoiceItems(minuteStrings, 4, new DialogInterface.OnClickListener(){
@Override
public void onClick(final DialogInterface d, final int which) {
d.dismiss();
item.setEnabled(false); // Disable AAS
final int minuteToResolve = minuteValues[which];
Toast.makeText(WhereAmIMap.this, R.string.please_wait_a_moment, Toast.LENGTH_LONG).show();
new Thread(new Runnable(){
@Override
public void run() {
try {
final AASResponse aasr = AASRequester.request(WhereAmIMap.this.mOSMapView.getMapCenter(), minuteToResolve);
final List<AreaOfInterest> areas = WhereAmIMap.this.mAASOverlay.getAreasOfInterest();
areas.clear();
for(final Polygon p : aasr.getPolygons()) {
areas.add(p);
}
runOnUiThread(new Runnable(){
@Override
public void run() {
Toast.makeText(WhereAmIMap.this, R.string.toast_map_accessibilityanalysis_finished, Toast.LENGTH_LONG).show();
}
});
} catch(final ORSException orse){
runOnUiThread(new Runnable(){
@Override
public void run() {
Toast.makeText(WhereAmIMap.this, orse.getErrors().get(0).toUserString(), Toast.LENGTH_LONG).show();
}
});
} catch (final Exception e) {
Log.e(Constants.DEBUGTAG, "AASRequester-Error", e);
} finally {
item.setEnabled(true); // Enable AAS
}
}
}, "Accessibility-Runner").start();
}
}).create().show();
}
private void applyAutoCompleteListeners() {
try{
final List<DBPOI> usedPOIs = DBManager.getPOIHistory(this);
final ArrayList<String> usedPOIStrings = new ArrayList<String>(usedPOIs.size());
for(final DBPOI poi : usedPOIs) {
usedPOIStrings.add(poi.getName());
}
new InlineAutoCompleterConstant(this.mEtSearch, usedPOIStrings, false){
@Override
public boolean onEnter() {
handleSearchSubmit(WhereAmIMap.this.mEtSearch.getText().toString());
return true;
}
};
} catch (final DataBaseException e) {
// Log.e(DEBUGTAG, "Error on loading POIs", e);
}
}
private void applyMapViewLongPressListener() {
final GestureDetector gd = new GestureDetector(new GestureDetector.SimpleOnGestureListener(){
@Override
public void onLongPress(final MotionEvent e) {
final Projection pj = WhereAmIMap.this.mOSMapView.getProjection();
WhereAmIMap.this.mGPLastMapClick = pj.fromPixels((int)e.getX(), (int)e.getY());
final String[] items = new String[]{
getString(R.string.tv_whereami_contextmenu_nav_here),
getString(R.string.tv_whereami_contextmenu_add_as_favorite),
getString(R.string.tv_whereami_contextmenu_show_radar),
getString(R.string.tv_whereami_contextmenu_weather_get),
getString(R.string.tv_whereami_contextmenu_osb),
getString(R.string.tv_whereami_contextmenu_close)};
new AlertDialog.Builder(WhereAmIMap.this)
.setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener(){
@Override
public void onClick(final DialogInterface d, final int which) {
d.dismiss();
switch(which){
case 0:
doNavToGeoPoint(WhereAmIMap.this.mGPLastMapClick);
break;
case 1:
showDialog(DIALOG_INPUT_FAVORITE_NAME);
break;
case 2:
final Intent i = new Intent("com.google.android.radar.SHOW_RADAR");
i.putExtra("latitude", (float)WhereAmIMap.this.mGPLastMapClick.getLatitudeE6() / 1E6);
i.putExtra("longitude", (float)WhereAmIMap.this.mGPLastMapClick.getLongitudeE6() / 1E6);
org.androad.ui.util.Util.startUnknownActivity(WhereAmIMap.this, i, "com.google.android.radar");
break;
case 3:
openWeatherDialog(WhereAmIMap.this.mGPLastMapClick);
break;
case 4:
showDialog(DIALOG_SELECT_POI_OR_OSB_OR_FTPC);
break;
case 5:
return;
}
}
})
.create().show();
}
});
this.mOSMapView.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(final View v, final MotionEvent ev) {
if(WhereAmIMap.this.mNavPointsCrosshairMode){
return false;
}else{
WhereAmIMap.this.mAutoCenterBlockedUntil = System.currentTimeMillis() + AUTOCENTER_BLOCKTIME;
if(ev.getAction() == MotionEvent.ACTION_DOWN) {
startDelayedHideControlsAnimation();
}
return gd.onTouchEvent(ev);
}
}
});
}
private void applyZoomButtonListeners(){
this.findViewById(R.id.iv_whereami_zoomin).setOnClickListener(new OnClickListener(){
@Override
public void onClick(final View v) {
WhereAmIMap.this.mOSMapView.getController().zoomIn();
WhereAmIMap.this.mOSMapView.invalidate();
}
});
this.findViewById(R.id.iv_whereami_zoomout).setOnClickListener(new OnClickListener(){
@Override
public void onClick(final View v) {
WhereAmIMap.this.mOSMapView.getController().zoomOut();
WhereAmIMap.this.mOSMapView.invalidate();
}
});
}
private void applyQuickButtonListeners() {
this.mMapItemControlView.setItemizedOverlayControlViewListener(new ItemizedOverlayControlView.ItemizedOverlayControlViewListener(){
@Override
public void onCenter() {
final OverlayItem oi = WhereAmIMap.this.mSearchPinList.get(WhereAmIMap.this.mSearchPinListIndex);
WhereAmIMap.this.mOSMapView.getController().animateTo(oi.getPoint(), AnimationType.MIDDLEPEAKSPEED);
}
@Override
public void onNavTo() {
final GeoPoint gp = WhereAmIMap.this.mSearchPinList.get(WhereAmIMap.this.mSearchPinListIndex).getPoint();
final String aPOIName = WhereAmIMap.this.mEtSearch.getText().toString();
try {
DBManager.addPOIToHistory(WhereAmIMap.this, aPOIName, gp.getLatitudeE6(), gp.getLongitudeE6());
} catch (final DataBaseException e) {
// Log.e(DEBUGTAG, "Error adding POI", e);
}
doNavToGeoPoint(gp);
}
@Override
public void onNext() {
WhereAmIMap.this.mSearchPinListIndex++;
WhereAmIMap.this.mSearchPinListIndex = WhereAmIMap.this.mSearchPinListIndex % WhereAmIMap.this.mSearchPinList.size();
final OverlayItem oi = WhereAmIMap.this.mSearchPinList.get(WhereAmIMap.this.mSearchPinListIndex);
WhereAmIMap.this.mOSMapView.getController().animateTo(oi.getPoint(), AnimationType.MIDDLEPEAKSPEED);
}
@Override
public void onPrevious() {
if(WhereAmIMap.this.mSearchPinListIndex == 0) {
WhereAmIMap.this.mSearchPinListIndex = WhereAmIMap.this.mSearchPinList.size() - 1;
} else {
WhereAmIMap.this.mSearchPinListIndex--;
}
final OverlayItem oi = WhereAmIMap.this.mSearchPinList.get(WhereAmIMap.this.mSearchPinListIndex);
WhereAmIMap.this.mOSMapView.getController().animateTo(oi.getPoint(), AnimationType.MIDDLEPEAKSPEED);
}
});
/* Left side. */
this.mIbtnNavPointsSetStart.setOnClickListener(new OnClickListener(){
@Override
public void onClick(final View v) {
/* Set destination-flag and start crosshair-mode. */
WhereAmIMap.this.mStartFlagItem.setCenter(WhereAmIMap.this.mOSMapView.getMapCenter());
updateUIForNavPointsCrosshairMode(true);
}
});
/* Left side. */
this.mIbtnNavPointsSetDestination.setOnClickListener(new OnClickListener(){
@Override
public void onClick(final View v) {
/* Set destination-flag and start crosshair-mode. */
WhereAmIMap.this.mDestinationFlagItem.setCenter(WhereAmIMap.this.mOSMapView.getMapCenter());
updateUIForNavPointsCrosshairMode(true);
}
});
/* Left side. */
this.mIbtnNavPointsDoCancel.setOnClickListener(new OnClickListener(){
@Override
public void onClick(final View v) {
/* End crosshair-mode. */
updateUIForNavPointsCrosshairMode(false);
}
});
this.mIbtnNavPointsDoStart.setOnClickListener(new OnClickListener(){
@Override
public void onClick(final View arg0) {
if(WhereAmIMap.this.mNavPointsCrosshairMode){
/* User chose a good start+destination. */
if (WhereAmIMap.this.mStartFlagItem.getCenter() != null) {
doNavBetweenGeoPoints(WhereAmIMap.this.mStartFlagItem.getCenter(), WhereAmIMap.this.mDestinationFlagItem.getCenter());
} else {
doNavToGeoPoint(WhereAmIMap.this.mDestinationFlagItem.getCenter());
}
/* End crosshair-mode. */
updateUIForNavPointsCrosshairMode(false);
}else{
/* Disable Auto-Follow. */
updateUIForAutoCenterChange(WhereAmIMap.CENTERMODE_NONE);
WhereAmIMap.this.mDestinationFlagItem.setCenter(null);
WhereAmIMap.this.mStartFlagItem.setCenter(null);
updateUIForNavPointsCrosshairMode(true);
}
}
});
this.mEtSearch.setOnKeyListener(new OnKeyListener(){
@Override
public boolean onKey(final View v, final int keyCode, final KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_UP){
switch(event.getKeyCode()){
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_CALL:
handleSearchSubmit(WhereAmIMap.this.mEtSearch.getText().toString());
return true;
}
}
return false;
}
});
this.mIbtnSearch.setOnClickListener(new OnClickListener(){
@Override
public void onClick(final View arg0) {
if(WhereAmIMap.this.mEtSearch.getVisibility() == View.GONE){
showDialog(DIALOG_SELECT_FREEFORM_OR_STRUCTURED_SEARCH);
// handleSearchOpen(); <-- Would directly open the edittext
}else{
handleSearchSubmit(WhereAmIMap.this.mEtSearch.getText().toString());
}
}
});
/* Right side. */
this.mIbtnChooseRenderer.setOnClickListener(new OnClickListener(){
@Override
public void onClick(final View arg0) {
startDelayedHideControlsAnimation();
final ITileSource[] providers = TileSourceFactory.getTileSources().toArray(new ITileSource[0]);
final SpannableString[] renderersNames = new SpannableString[providers.length];
for(int j = 0; j < providers.length; j ++){
final SpannableString itemTitle = new SpannableString(providers[j].name());
itemTitle.setSpan(new StyleSpan(Typeface.ITALIC), providers[j].name().length(), itemTitle.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
itemTitle.setSpan(new RelativeSizeSpan(0.5f), providers[j].name().length(), itemTitle.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
renderersNames[j] = itemTitle;
}
final int curRendererIndex = WhereAmIMap.this.mOSMapView.getTileProvider().getTileSource().ordinal();
new AlertDialog.Builder(WhereAmIMap.this)
.setTitle(R.string.maps_menu_submenu_renderers)
.setSingleChoiceItems(renderersNames, curRendererIndex , new DialogInterface.OnClickListener(){
@Override
public void onClick(final DialogInterface d, final int which) {
changeProviderInfo(providers[which]);
d.dismiss();
}
}).create().show();
}
});
this.mIbtnWhereAmI.setOnClickListener(new OnClickListener(){
@Override
public void onClick(final View arg0) {
startDelayedHideControlsAnimation();
Toast.makeText(WhereAmIMap.this, R.string.please_wait_a_moment, Toast.LENGTH_SHORT).show();
final GeoPoint mapCenter = WhereAmIMap.this.mOSMapView.getMapCenter();
final UnitSystem us = Preferences.getUnitSystem(WhereAmIMap.this);
new Thread(new Runnable(){
@Override
public void run() {
try {
final LUSRequester lus = Preferences.getORSServer(WhereAmIMap.this).LOCATIONUTILITYSERVICE;
final ArrayList<GeocodedAddress> addr = lus.requestReverseGeocode(WhereAmIMap.this, mapCenter, ReverseGeocodePreferenceType.STREETADDRESS);
runOnUiThread(new Runnable(){
@Override
public void run() {
if(addr == null || addr.size() == 0){
Toast.makeText(WhereAmIMap.this, R.string.whereami_location_not_resolvable, Toast.LENGTH_SHORT).show();
}else{
final GeocodedAddress closestGeocodedAddress = addr.get(0);
final String msg = closestGeocodedAddress.toString(WhereAmIMap.this, us, true);
Drawable icon;
try{
icon = getResources().getDrawable(closestGeocodedAddress.getNationality().FLAGRESID);
}catch(final Exception e){
icon = getResources().getDrawable(R.drawable.questionmark);
}
new AlertDialog.Builder(WhereAmIMap.this)
.setTitle(closestGeocodedAddress.getNationality().NAMERESID)
.setMessage(msg + '\n')
.setIcon(icon)
.setPositiveButton(R.string.ok, null)
.create().show();
}
}
});
} catch (final ORSException e) {
runOnUiThread(new Runnable(){
@Override
public void run() {
Toast.makeText(WhereAmIMap.this, e.getErrors().get(0).toUserString(), Toast.LENGTH_LONG).show();
}
});
} catch (final Exception e) {
Exceptor.e("LUSRequester", e);
}
}
}).start();
/* Invalidate map. */
WhereAmIMap.this.mOSMapView.invalidate();
}
});
this.mIbtnCenter.setOnClickListener(new OnClickListener(){
@Override
public void onClick(final View arg0) {
startDelayedHideControlsAnimation();
final int newMode = (WhereAmIMap.this.mDoCenter + 1) % 3;
final GeoPoint lastKnownLocationAsGeoPoint = WhereAmIMap.this.getLastKnownLocation(true);
if(lastKnownLocationAsGeoPoint != null){
switch(newMode){
case CENTERMODE_AUTO:
case CENTERMODE_ONCE:
WhereAmIMap.this.mOSMapView.getController().animateTo(lastKnownLocationAsGeoPoint, AnimationType.MIDDLEPEAKSPEED);
break;
}
}
updateUIForAutoCenterChange(newMode);
/* Invalidate map. */
WhereAmIMap.this.mOSMapView.invalidate();
}
});
}
private void updateUIForNavPointsCrosshairMode(final boolean pNewState) {
this.mCrosshairOverlay.setEnabled(pNewState);
this.mNavPointsCrosshairMode = pNewState;
if(pNewState){
this.mIbtnNavPointsDoCancel.setVisibility(View.VISIBLE);
this.mIbtnNavPointsSetDestination.setVisibility(View.VISIBLE);
this.mIbtnNavPointsSetStart.setVisibility(View.VISIBLE);
this.mIbtnNavPointsDoCancel.clearAnimation();
this.mIbtnNavPointsDoStart.clearAnimation();
this.mIbtnNavPointsSetStart.clearAnimation();
this.mIbtnNavPointsSetDestination.clearAnimation();
this.mIbtnCenter.clearAnimation();
final boolean destinationSet = this.mDestinationFlagItem.getCenter() != null;
this.mIbtnNavPointsDoStart.setEnabled(destinationSet);
final GeoPoint start;
if (WhereAmIMap.this.mStartFlagItem.getCenter() != null)
start = WhereAmIMap.this.mStartFlagItem.getCenter();
else
start = WhereAmIMap.this.mMyLocationOverlay.getLocation();
this.mNavPointsConnectionLineOverlay.setFrom(start);
this.mNavPointsConnectionLineOverlay.setTo(this.mDestinationFlagItem.getCenter());
this.mNavPointsConnectionLineOverlay.setEnabled(destinationSet);
}else{
startDelayedHideControlsAnimation();
this.mIbtnNavPointsDoCancel.setVisibility(View.GONE);
this.mIbtnNavPointsSetDestination.setVisibility(View.GONE);
this.mIbtnNavPointsSetStart.setVisibility(View.GONE);
this.mIbtnNavPointsDoStart.startAnimation(this.mFadeToLeftAnimation);
this.mIbtnCenter.startAnimation(this.mFadeToRightAnimation);
this.mIbtnNavPointsDoStart.setEnabled(true);
this.mStartFlagItem.setCenter(null);
this.mDestinationFlagItem.setCenter(null);
this.mNavPointsConnectionLineOverlay.setEnabled(false);
}
this.mOSMapView.invalidate();
}
private void doNavToGeoPoint(final GeoPoint gp) {
final Intent navTo = new Intent(Constants.ANDROAD_NAV_ACTION);
final Bundle b = new Bundle();
b.putString("to", gp.toDoubleString()); // i.e.: "to" --> "37.465259,-122.126456"
navTo.putExtras(b);
sendBroadcast(navTo);
}
private void doNavBetweenGeoPoints(final GeoPoint pGPStart, final GeoPoint pGPDestination) {
final Intent navTo = new Intent(Constants.ANDROAD_NAV_ACTION);
final Bundle b = new Bundle();
b.putString("from", pGPStart.toDoubleString()); // i.e.: "to" --> "37.465259,-122.126456"
b.putString("to", pGPDestination.toDoubleString()); // i.e.: "to" --> "37.465259,-122.126456"
navTo.putExtras(b);
sendBroadcast(navTo);
}
private void changeProviderInfo(final ITileSource aProviderInfo) {
/* Remember changes to the provider to start the next time with the same provider. */
Preferences.saveMapViewProviderInfoWhereAmI(this, aProviderInfo);
/* Check if Auto-Follow has to be disabled. */
this.mOSMapView.setTileSource(aProviderInfo);
}
private void updateUIForAutoCenterChange(final int pNewMode) {
if(WhereAmIMap.this.mDoCenter == pNewMode) {
return;
}
WhereAmIMap.this.mDoCenter = pNewMode;
if(WhereAmIMap.this.mDoCenter == WhereAmIMap.CENTERMODE_AUTO){
WhereAmIMap.this.mIbtnCenter.setImageResource(R.drawable.person_focused_small);
Toast.makeText(WhereAmIMap.this, R.string.toast_autofollow_enabled, Toast.LENGTH_SHORT).show();
}else if(WhereAmIMap.this.mDoCenter == WhereAmIMap.CENTERMODE_ONCE){
WhereAmIMap.this.mIbtnCenter.setImageResource(R.drawable.person_focused_once_small);
Toast.makeText(WhereAmIMap.this, R.string.toast_autofollow_once, Toast.LENGTH_SHORT).show();
}else if(WhereAmIMap.this.mDoCenter == WhereAmIMap.CENTERMODE_NONE){
WhereAmIMap.this.mIbtnCenter.setImageResource(R.drawable.person_small);
Toast.makeText(WhereAmIMap.this, R.string.toast_autofollow_disabled, Toast.LENGTH_SHORT).show();
}
}
private void handleSearchOpen() {
this.mIbtnSearch.setImageResource(R.drawable.search_submit);
this.mIbtnSearch.clearAnimation();
this.mEtSearch.setVisibility(View.VISIBLE);
/* And Focus on the */
this.mEtSearch.requestFocus();
this.mEtSearch.selectAll();
this.mOSMapView.invalidate();
WhereAmIMap.this.clearPinOverlay();
}
private void handleSearchSubmit(final String pQuery) {
final String query = pQuery.trim();
this.mIbtnSearch.setImageResource(R.drawable.search);
this.mEtSearch.setVisibility(View.GONE);
this.mIbtnSearch.startAnimation(this.mFadeOutQuickAnimation);
if(query.length() > 0){
/* Check if coordinates were entered. */
final GeoPoint coordsIfEntered = CoordinatesExtractor.match(query);
if(coordsIfEntered != null){
refreshPinOverlay(coordsIfEntered);
}else if(RouteHandleIDExtractor.match(query) != -1){
startDDMapWithRouteHandleID(RouteHandleIDExtractor.match(query));
}else{
/* No coords --> textual/freeform search. */
// final String[] choices = new String[]{getString(R.string.whereami_search_scope_global), getString(R.string.whereami_search_scope_local)};
// new AlertDialog.Builder(this)
// .setTitle(R.string.whereami_search_scope_title)
// .setCancelable(true)
// .setSingleChoiceItems(choices, 0, new DialogInterface.OnClickListener(){
// @Override
// public void onClick(final DialogInterface dialog, final int which) {
// dialog.dismiss();
Toast.makeText(WhereAmIMap.this, R.string.please_wait_a_moment, Toast.LENGTH_SHORT).show();
searchORSLocations(query);
// searchLocations(query, 0); // which
// }
// }).create().show();
}
}
}
private void startDDMapWithRouteHandleID(final long pRouteHandleID) {
final Intent directIntent = new Intent(this, OpenStreetDDMap.class);
final Bundle b = new Bundle();
b.putInt(EXTRAS_MODE, EXTRAS_MODE_LOAD_ROUTE_BY_ROUTEHANDLEID);
b.putLong(EXTRAS_ROUTEHANDLEID_ID, pRouteHandleID);
directIntent.putExtras(b);
this.startActivityForResult(directIntent, REQUESTCODE_DDMAP);
}
private void searchORSLocations(final String query) {
new Thread(new Runnable(){
@Override
public void run() {
try {
final LUSRequester lus = Preferences.getORSServer(WhereAmIMap.this).LOCATIONUTILITYSERVICE;
final ArrayList<GeocodedAddress> ret = lus.requestFreeformAddress(WhereAmIMap.this, null, query);
runOnUiThread(new Runnable(){
@Override
public void run() {
if(ret == null || ret.size() == 0){
Toast.makeText(WhereAmIMap.this, R.string.whereami_search_no_places_found, Toast.LENGTH_SHORT).show();
}else{
final BoundingBoxE6 bBox = BoundingBoxE6.fromGeoPoints(ret);
/* Disable Auto-Follow. */
if(WhereAmIMap.this.mDoCenter == WhereAmIMap.CENTERMODE_AUTO) {
updateUIForAutoCenterChange(WhereAmIMap.CENTERMODE_NONE);
}
final ArrayList<OverlayItem> itemsFound = new ArrayList<OverlayItem>();
for (final GeocodedAddress ga : ret) {
itemsFound.add(new OverlayItem(ga.getMunicipality(), ga.toString(WhereAmIMap.this), ga));
}
final int foundItemsSize = ret.size();
if(foundItemsSize == 1){
WhereAmIMap.this.mOSMapView.getController().setZoom(15);
WhereAmIMap.this.mOSMapView.getController().animateTo(bBox.getCenter(), AnimationType.MIDDLEPEAKSPEED);
}else{
WhereAmIMap.this.mOSMapView.getController().zoomToSpan(bBox);
WhereAmIMap.this.mOSMapView.getController().animateTo(bBox.getCenter(), AnimationType.MIDDLEPEAKSPEED);
}
WhereAmIMap.this.refreshPinOverlay(itemsFound);
Log.d(Constants.DEBUGTAG, "Items remained: " + foundItemsSize);
Toast.makeText(WhereAmIMap.this, getString(R.string.whereami_search_places_found) + " " + foundItemsSize, Toast.LENGTH_SHORT).show();
}
}
});
} catch (final ORSException e) {
runOnUiThread(new Runnable(){
@Override
public void run() {
WhereAmIMap.this.clearPinOverlay();
}
});
} catch (final Exception e) {
runOnUiThread(new Runnable(){
@Override
public void run() {
WhereAmIMap.this.clearPinOverlay();
}
});
Exceptor.e("GeocodeError", e, WhereAmIMap.this);
}
}
}).start();
}
@Override
public void onDataStateChanged(final int strength) {
// TODO
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
private class AndRoadMapListener implements MapListener {
private WhereAmIMap map;
AndRoadMapListener(WhereAmIMap map) {
this.map = map;
}
@Override
public boolean onScroll(ScrollEvent e) {
map.updateLayers();
return true;
}
@Override
public boolean onZoom(ZoomEvent e) {
map.updateLayers();
return true;
}
}
}