diff --git a/OsmAnd/res/drawable-hdpi/poi_parking_pos_info.png b/OsmAnd/res/drawable-hdpi/poi_parking_pos_info.png
new file mode 100644
index 0000000000..3b2ffb13bf
Binary files /dev/null and b/OsmAnd/res/drawable-hdpi/poi_parking_pos_info.png differ
diff --git a/OsmAnd/res/drawable-hdpi/poi_parking_pos_limit_menu.png b/OsmAnd/res/drawable-hdpi/poi_parking_pos_limit_menu.png
index ae9b234874..cad52bba3a 100644
Binary files a/OsmAnd/res/drawable-hdpi/poi_parking_pos_limit_menu.png and b/OsmAnd/res/drawable-hdpi/poi_parking_pos_limit_menu.png differ
diff --git a/OsmAnd/res/drawable-hdpi/poi_parking_pos_no_limit_menu.png b/OsmAnd/res/drawable-hdpi/poi_parking_pos_no_limit_menu.png
index 6719431465..1348f994d1 100644
Binary files a/OsmAnd/res/drawable-hdpi/poi_parking_pos_no_limit_menu.png and b/OsmAnd/res/drawable-hdpi/poi_parking_pos_no_limit_menu.png differ
diff --git a/OsmAnd/res/drawable/parking_limit_button.xml b/OsmAnd/res/drawable/parking_limit_button.xml
new file mode 100644
index 0000000000..d5d2a6adf5
--- /dev/null
+++ b/OsmAnd/res/drawable/parking_limit_button.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/drawable/parking_no_limit_button.xml b/OsmAnd/res/drawable/parking_no_limit_button.xml
new file mode 100644
index 0000000000..1cb787b27f
--- /dev/null
+++ b/OsmAnd/res/drawable/parking_no_limit_button.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/parking_set_time_limit.xml b/OsmAnd/res/layout/parking_set_time_limit.xml
new file mode 100644
index 0000000000..3088730631
--- /dev/null
+++ b/OsmAnd/res/layout/parking_set_time_limit.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/parking_set_type.xml b/OsmAnd/res/layout/parking_set_type.xml
new file mode 100644
index 0000000000..32f253d492
--- /dev/null
+++ b/OsmAnd/res/layout/parking_set_type.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index df1bb69cf0..da23969330 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -1,4 +1,4 @@
-
+
+ Pick up the car from parking
+ Warning
+ Notification to pick up your car was previously added to your Calendar. It will remain there until you will delete it manually.
+ Set the time limit of parking
+ Do you want to remove the location of the parked car?
+ Delete a parking marker
+ Choose the type of parking
+ Time-limited
+ Time-unlimited
+ Add a notification to Calendar application
+ Time-limited parking
+ Time-unlimited parking
+ The position of your parked car. %1$s
+ To pick up the car at:
+ PM
+ AM
+ Parking point
+ This plugin allows to store the location of your parked car.
+ Parking Position Plugin
+ Mark as a parking position
+ Delete a parking marker
+
Public
Identifiable
Trackable
diff --git a/OsmAnd/src/net/osmand/plus/OptionsMenuHelper.java b/OsmAnd/src/net/osmand/plus/OptionsMenuHelper.java
new file mode 100644
index 0000000000..e6276657e8
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/OptionsMenuHelper.java
@@ -0,0 +1,32 @@
+package net.osmand.plus;
+
+import android.view.Menu;
+
+public class OptionsMenuHelper {
+
+ private final Menu menu;
+
+ public OptionsMenuHelper(Menu menu) {
+ this.menu = menu;
+ }
+
+ public void registerOptionsMenuItem(int resItemId, int resName, int resIcon, boolean visibility) {
+ if (resIcon != -1) {
+ menu.add(Menu.CATEGORY_CONTAINER, resItemId, Menu.NONE, resName).setVisible(visibility).setIcon(resIcon);
+ } else {
+ menu.add(Menu.CATEGORY_CONTAINER, resItemId, Menu.NONE, resName).setVisible(visibility);
+ }
+ }
+
+ public void registerOptionsMenuItem(int resItemId, int resName, int resIcon) {
+ registerOptionsMenuItem(resItemId, resName, resIcon, true);
+ }
+
+ public void registerOptionsMenuItem(int resItemId, int resName, boolean visibility) {
+ registerOptionsMenuItem(resItemId, resName, -1, visibility);
+ }
+
+ public void registerOptionsMenuItem(int resItemId, int resName) {
+ registerOptionsMenuItem(resItemId, resName, -1, true);
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java
index 8c1c504cd2..4aca31e008 100644
--- a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java
+++ b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java
@@ -5,10 +5,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
-import org.apache.commons.logging.Log;
-
-import android.preference.PreferenceScreen;
-
import net.osmand.LogUtil;
import net.osmand.access.AccessibilityPlugin;
import net.osmand.plus.activities.MapActivity;
@@ -18,9 +14,15 @@ import net.osmand.plus.development.OsmandDevelopmentPlugin;
import net.osmand.plus.extrasettings.OsmandExtraSettings;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.osmedit.OsmEditingPlugin;
+import net.osmand.plus.parkingpoint.ParkingPositionPlugin;
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
import net.osmand.plus.views.OsmandMapTileView;
+import org.apache.commons.logging.Log;
+
+import android.preference.PreferenceScreen;
+import android.view.Menu;
+
public abstract class OsmandPlugin {
private static List installedPlugins = new ArrayList();
@@ -56,6 +58,7 @@ public abstract class OsmandPlugin {
installedPlugins.add(new AccessibilityPlugin(app));
installedPlugins.add(new OsmEditingPlugin(app));
installedPlugins.add(new OsmandDevelopmentPlugin(app));
+ installedPlugins.add(new ParkingPositionPlugin(app));
Set enabledPlugins = settings.getEnabledPlugins();
for (OsmandPlugin plugin : installedPlugins) {
@@ -107,6 +110,12 @@ public abstract class OsmandPlugin {
public void registerMapContextMenuActions(MapActivity mapActivity, double latitude, double longitude, ContextMenuAdapter adapter, Object selectedObj) {}
+ public void registerOptionsMenuItems(MapActivity mapActivity, OptionsMenuHelper helper) {}
+
+ public void prepareOptionsMenuItems(MapActivity mapActivity, Menu menu) {}
+
+ public boolean onOptionsItemSelected(MapActivity mapActivity, int itemId) { return false; }
+
public static void refreshLayers(OsmandMapTileView mapView, MapActivity activity) {
for (OsmandPlugin plugin : activePlugins) {
plugin.updateLayers(mapView, activity);
@@ -192,5 +201,26 @@ public abstract class OsmandPlugin {
plugin.registerLayerContextMenuActions(mapView, adapter, mapActivity);
}
}
+
+ public static void registerOptionsMenu(MapActivity map, OptionsMenuHelper helper) {
+ for (OsmandPlugin plugin : activePlugins) {
+ plugin.registerOptionsMenuItems(map, helper);
+ }
+ }
+
+ public static void registerOnPrepareOptionsMenu(MapActivity mapActivity, Menu menu) {
+ for (OsmandPlugin plugin : activePlugins) {
+ plugin.prepareOptionsMenuItems(mapActivity, menu);
+ }
+ }
+
+ public static boolean registerOnOptionsMenuItemSelected(MapActivity mapActivity, int itemId) {
+ for (OsmandPlugin plugin : activePlugins) {
+ if (plugin.onOptionsItemSelected(mapActivity, itemId)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java
index 083964a46f..aa9bea02c5 100644
--- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java
+++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java
@@ -950,6 +950,60 @@ public class OsmandSettings {
return add;
}
+
+ /**
+ * the location of a parked car
+ */
+ public final static String PARKING_POINT_LAT = "parking_point_lat"; //$NON-NLS-1$
+ public final static String PARKING_POINT_LON = "parking_point_lon"; //$NON-NLS-1$
+ public final static String PARKING_TYPE = "parking_type"; //$NON-NLS-1$
+ public final static String PARKING_TIME = "parking_limit_time"; //$//$NON-NLS-1$
+ public final static String PARKING_EVENT_ADDED = "parking_event_added"; //$//$NON-NLS-1$
+
+ public LatLon getParkingPosition() {
+ float lat = globalPreferences.getFloat(PARKING_POINT_LAT, 0);
+ float lon = globalPreferences.getFloat(PARKING_POINT_LON, 0);
+ if (lat == 0 && lon == 0) {
+ return null;
+ }
+ return new LatLon(lat, lon);
+ }
+
+ public boolean getParkingType() {
+ return globalPreferences.getBoolean(PARKING_TYPE, false);
+ }
+
+ public boolean isParkingEventAdded() {
+ return globalPreferences.getBoolean(PARKING_EVENT_ADDED, false);
+ }
+
+ public boolean addOrRemoveParkingEvent(boolean added) {
+ return globalPreferences.edit().putBoolean(PARKING_EVENT_ADDED, added).commit();
+ }
+
+ public long getParkingTime() {
+ return globalPreferences.getLong(PARKING_TIME, -1);
+ }
+
+ public boolean clearParkingPosition() {
+ return globalPreferences.edit().remove(PARKING_POINT_LAT).remove(PARKING_POINT_LON).remove(PARKING_TYPE)
+ .remove(PARKING_TIME).remove(PARKING_EVENT_ADDED).commit();
+ }
+
+ public boolean setParkingPosition(double latitude, double longitude) {
+ return globalPreferences.edit().putFloat(PARKING_POINT_LAT, (float) latitude).putFloat(PARKING_POINT_LON, (float) longitude).commit();
+ }
+
+ public boolean setParkingType(boolean limited) {
+ if (!limited)
+ globalPreferences.edit().remove(PARKING_TIME).commit();
+ return globalPreferences.edit().putBoolean(PARKING_TYPE, limited).commit();
+ }
+
+ public boolean setParkingTime(long timeInMillis) {
+ return globalPreferences.edit().putLong(PARKING_TIME, timeInMillis).commit();
+ }
+
public static final String LAST_SEARCHED_REGION = "last_searched_region"; //$NON-NLS-1$
public static final String LAST_SEARCHED_CITY = "last_searched_city"; //$NON-NLS-1$
public static final String LAST_SEARCHED_CITY_NAME = "last_searched_city_name"; //$NON-NLS-1$
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
index cad9c302d3..61b1d7afb3 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
@@ -20,7 +20,6 @@ import net.osmand.map.IMapLocationListener;
import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
import net.osmand.plus.BusyIndicator;
-import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
@@ -35,20 +34,15 @@ import net.osmand.plus.views.AnimateDraggingMapThread;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.PointLocationLayer;
import android.app.Activity;
-import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
-import android.content.ActivityNotFoundException;
-import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.hardware.Sensor;
@@ -67,12 +61,10 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
-import android.provider.Settings.Secure;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
@@ -84,9 +76,6 @@ import android.view.animation.Transformation;
import android.widget.Toast;
public class MapActivity extends AccessibleActivity implements IMapLocationListener, SensorEventListener {
-
- private static final String GPS_STATUS_ACTIVITY = "com.eclipsim.gpsstatus2.GPSStatus"; //$NON-NLS-1$
- private static final String GPS_STATUS_COMPONENT = "com.eclipsim.gpsstatus2"; //$NON-NLS-1$
// stupid error but anyway hero 2.1 : always lost gps signal (temporarily unavailable) for timeout = 2000
private static final int GPS_TIMEOUT_REQUEST = 0;
@@ -591,31 +580,6 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
}
}
- private void whereAmIDialog() {
- final List items = new ArrayList();
- items.add(getString(R.string.show_location));
- items.add(getString(R.string.show_details));
- AlertDialog.Builder menu = new AlertDialog.Builder(this);
- menu.setItems(items.toArray(new String[items.size()]),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int item) {
- dialog.dismiss();
- switch (item) {
- case 0:
- backToLocationImpl();
- break;
- case 1:
- navigationInfo.show(settings.getPointToNavigate(), mapLayers.getLocationLayer().getHeading());
- break;
- default:
- break;
- }
- }
- });
- menu.show();
- }
-
public void setMapLocation(double lat, double lon){
mapView.setLatLon(lat, lon);
locationChanged(lat, lon, this);
@@ -1061,10 +1025,10 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
//return true;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
if (!getMyApplication().accessibilityEnabled()) {
- contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
+ mapActions.contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
} else if (uiHandler.hasMessages(LONG_KEYPRESS_MSG_ID)) {
uiHandler.removeMessages(LONG_KEYPRESS_MSG_ID);
- contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
+ mapActions.contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
}
return true;
} else if (settings.ZOOM_BY_TRACKBALL.get()) {
@@ -1151,162 +1115,22 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
}
}
-
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.map_menu, menu);
- return true;
+ return mapActions.onCreateOptionsMenu(menu);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
boolean val = super.onPrepareOptionsMenu(menu);
- MenuItem navigateToPointMenu = menu.findItem(R.id.map_navigate_to_point);
- if (navigateToPointMenu != null) {
- if (settings.getPointToNavigate() != null) {
- navigateToPointMenu.setTitle((routingHelper.isRouteCalculated() || routingHelper.isFollowingMode() || routingHelper.isRouteBeingCalculated()) ? R.string.stop_routing : R.string.stop_navigation);
- navigateToPointMenu.setVisible(true);
- } else {
- navigateToPointMenu.setVisible(false);
- }
- }
- MenuItem muteMenu = menu.findItem(R.id.map_mute);
- if(muteMenu != null){
- if (routingHelper.getFinalLocation() != null && routingHelper.isFollowingMode()) {
- muteMenu.setTitle(routingHelper.getVoiceRouter().isMute() ? R.string.menu_mute_on : R.string.menu_mute_off);
- muteMenu.setVisible(true);
- } else {
- muteMenu.setVisible(false);
- }
- }
- MenuItem directions = menu.findItem(R.id.map_get_directions);
- if(routingHelper.isRouteCalculated()){
- directions.setTitle(R.string.show_route);
- } else {
- directions.setTitle(R.string.get_directions);
- }
-
- MenuItem animateMenu = menu.findItem(R.id.map_animate_route);
-
- if (animateMenu != null) {
- if(settings.TEST_ANIMATE_ROUTING.get()){
- animateMenu.setTitle(routeAnimation.isRouteAnimating() ? R.string.animate_route_off
- : R.string.animate_route);
- animateMenu.setVisible("1".equals(Secure.getString(
- getContentResolver(), Secure.ALLOW_MOCK_LOCATION))
- && settings.getPointToNavigate() != null
- && routingHelper.isRouteCalculated());
- animateMenu.setVisible(true);
- } else {
- animateMenu.setVisible(false);
- }
- }
+ mapActions.onPrepareOptionsMenu(menu);
return val;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- final int itemId = item.getItemId();
- if (itemId == R.id.map_show_settings) {
- final Intent intentSettings = new Intent(MapActivity.this, OsmandIntents.getSettingsActivity());
- startActivity(intentSettings);
- return true;
- } else if (itemId == R.id.map_where_am_i) {
- if (getMyApplication().accessibilityEnabled()) {
- whereAmIDialog();
- } else {
- backToLocationImpl();
- }
- return true;
- } else if (itemId == R.id.map_show_gps_status) {
- startGpsStatusIntent();
- return true;
- } else if (itemId == R.id.map_specify_point) {
- Intent newIntent = new Intent(this, OsmandIntents.getSearchActivity());
- // causes wrong position caching: newIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
- LatLon loc = getMapLocation();
- newIntent.putExtra(SearchActivity.SEARCH_LAT, loc.getLatitude());
- newIntent.putExtra(SearchActivity.SEARCH_LON, loc.getLongitude());
- newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(newIntent);
- return true;
- } else if (itemId == R.id.map_get_directions) {
- if (routingHelper.isRouteCalculated()) {
- mapActions.aboutRoute();
- } else {
- Location loc = getLastKnownLocation();
- if (loc != null) {
- mapActions.getDirections(loc.getLatitude(), loc.getLongitude(), true);
- } else {
- mapActions.getDirections(mapView.getLatitude(), mapView.getLongitude(), true);
- }
- }
- return true;
- } else if (itemId == R.id.map_layers) {
- mapLayers.openLayerSelectionDialog(mapView);
- return true;
- } else if (itemId == R.id.map_mute) {
- routingHelper.getVoiceRouter().setMute(!routingHelper.getVoiceRouter().isMute());
- return true;
- } else if (itemId == R.id.map_navigate_to_point) {
- if (mapLayers.getNavigationLayer().getPointToNavigate() != null) {
- if (routingHelper.isRouteCalculated() || routingHelper.isFollowingMode() || routingHelper.isRouteBeingCalculated()) {
- routingHelper.setFinalAndCurrentLocation(null, routingHelper.getCurrentLocation(), routingHelper.getCurrentGPXRoute());
- // restore default mode
- boolean changed = settings.APPLICATION_MODE.set(settings.PREV_APPLICATION_MODE.get());
- updateApplicationModeSettings();
- mapView.refreshMap(changed);
- } else {
- navigateToPoint(null);
- }
- } else {
- navigateToPoint(new LatLon(mapView.getLatitude(), mapView.getLongitude()));
- }
- mapView.refreshMap();
- return true;
- } else if (itemId == R.id.map_show_point_options) {
- contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
- return true;
- } else if (itemId == R.id.map_animate_route) {
- // animate moving on route
- routeAnimation.startStopRouteAnimation(routingHelper, this);
- return true;
- } else {
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void startGpsStatusIntent() {
- Intent intent = new Intent();
- intent.setComponent(new ComponentName(GPS_STATUS_COMPONENT,
- GPS_STATUS_ACTIVITY));
- ResolveInfo resolved = getPackageManager().resolveActivity(intent,
- PackageManager.MATCH_DEFAULT_ONLY);
- if (resolved != null) {
- startActivity(intent);
- } else {
- AlertDialog.Builder builder = new AccessibleAlertBuilder(this);
- builder.setMessage(getString(R.string.gps_status_app_not_found));
- builder.setPositiveButton(
- getString(R.string.default_buttons_yes),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog,
- int which) {
- Intent intent = new Intent(Intent.ACTION_VIEW,
- Uri.parse("market://search?q=pname:"
- + GPS_STATUS_COMPONENT));
- try {
- startActivity(intent);
- } catch (ActivityNotFoundException e) {
- }
- }
- });
- builder.setNegativeButton(
- getString(R.string.default_buttons_no), null);
- builder.show();
- }
+ return mapActions.onOptionsItemSelected(item) == true ? true : super.onOptionsItemSelected(item);
}
@@ -1338,15 +1162,6 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
return getMyApplication().getFavorites();
}
-
- public void contextMenuPoint(final double latitude, final double longitude){
- mapActions.contextMenuPoint(latitude, longitude, null, null);
- }
-
- public void contextMenuPoint(final double latitude, final double longitude, ContextMenuAdapter adapter, Object selectedObj) {
- mapActions.contextMenuPoint(latitude, longitude, adapter, selectedObj);
- }
-
public MapActivityActions getMapActions() {
return mapActions;
}
@@ -1400,4 +1215,8 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
uiHandler.sendMessageDelayed(msg, delay * 1000);
}
+ public NavigationInfo getNavigationInfo() {
+ return navigationInfo;
+ }
+
}
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index e3c5d4d091..afc8396e7b 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -25,12 +25,14 @@ import net.osmand.plus.AmenityIndexRepositoryOdb;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.FavouritesDbHelper;
+import net.osmand.plus.OptionsMenuHelper;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.ResourceManager;
import net.osmand.plus.activities.search.SearchActivity;
+import net.osmand.plus.routing.RouteAnimation;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.views.BaseMapLayer;
@@ -41,19 +43,27 @@ import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.RectF;
import android.location.Location;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.provider.Settings.Secure;
import android.text.ClipboardManager;
import android.text.Html;
import android.util.FloatMath;
import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
@@ -70,6 +80,9 @@ import android.widget.ToggleButton;
public class MapActivityActions implements DialogProvider {
+ private static final String GPS_STATUS_COMPONENT = "com.eclipsim.gpsstatus2"; //$NON-NLS-1$
+ private static final String GPS_STATUS_ACTIVITY = "com.eclipsim.gpsstatus2.GPSStatus"; //$NON-NLS-1$
+
private static final String KEY_LONGITUDE = "longitude";
private static final String KEY_LATITUDE = "latitude";
private static final String KEY_NAME = "name";
@@ -86,10 +99,13 @@ public class MapActivityActions implements DialogProvider {
private final MapActivity mapActivity;
private OsmandSettings settings;
+ private RoutingHelper routingHelper;
+ private RouteAnimation routeAnimation = new RouteAnimation();
public MapActivityActions(MapActivity mapActivity){
this.mapActivity = mapActivity;
settings = mapActivity.getMyApplication().getSettings();
+ routingHelper = mapActivity.getMyApplication().getRoutingHelper();
}
protected void addFavouritePoint(final double latitude, final double longitude){
@@ -738,6 +754,10 @@ public class MapActivityActions implements DialogProvider {
builder.create().show();
}
+ public void contextMenuPoint(final double latitude, final double longitude){
+ contextMenuPoint(latitude, longitude, null, null);
+ }
+
private Dialog createReloadTitleDialog(final Bundle args) {
Builder builder = new AccessibleAlertBuilder(mapActivity);
builder.setMessage(R.string.context_menu_item_update_map_confirm);
@@ -825,5 +845,199 @@ public class MapActivityActions implements DialogProvider {
break;
}
}
+
+ public boolean onCreateOptionsMenu(Menu menu) {
+// NOTE: delete not a "menu.xml" because all id-resources are generated to R-class from there
+ OptionsMenuHelper helper = new OptionsMenuHelper(menu);
+ helper.registerOptionsMenuItem(R.id.map_where_am_i, R.string.where_am_i, android.R.drawable.ic_menu_mylocation);
+ helper.registerOptionsMenuItem(R.id.map_layers, R.string.menu_layers, android.R.drawable.ic_menu_mapmode);
+ helper.registerOptionsMenuItem(R.id.map_show_settings, R.string.settings_Button, android.R.drawable.ic_menu_preferences);
+ helper.registerOptionsMenuItem(R.id.map_navigate_to_point, R.string.stop_navigation, android.R.drawable.ic_menu_close_clear_cancel, false);
+ helper.registerOptionsMenuItem(R.id.map_mute, R.string.menu_mute_off, false);
+ helper.registerOptionsMenuItem(R.id.map_animate_route, R.string.animate_route, false);
+ helper.registerOptionsMenuItem(R.id.map_get_directions, R.string.get_directions, android.R.drawable.ic_menu_directions);
+ helper.registerOptionsMenuItem(R.id.map_specify_point, R.string.search_button, android.R.drawable.ic_menu_search);
+ helper.registerOptionsMenuItem(R.id.map_show_gps_status, R.string.show_gps_status, android.R.drawable.ic_menu_compass);
+ helper.registerOptionsMenuItem(R.id.map_show_point_options, R.string.show_point_options);
+ OsmandPlugin.registerOptionsMenu(mapActivity, helper);
+ return true;
+ }
+
+ public void onPrepareOptionsMenu(Menu menu) {
+ MenuItem navigateToPointMenu = menu.findItem(R.id.map_navigate_to_point);
+ if (navigateToPointMenu != null) {
+ if (settings.getPointToNavigate() != null) {
+ navigateToPointMenu.setTitle((routingHelper.isRouteCalculated() || routingHelper.isFollowingMode() ||
+ routingHelper.isRouteBeingCalculated()) ? R.string.stop_routing : R.string.stop_navigation);
+ navigateToPointMenu.setVisible(true);
+ } else {
+ navigateToPointMenu.setVisible(false);
+ }
+ }
+ MenuItem muteMenu = menu.findItem(R.id.map_mute);
+ if(muteMenu != null){
+ if (routingHelper.getFinalLocation() != null && routingHelper.isFollowingMode()) {
+ muteMenu.setTitle(routingHelper.getVoiceRouter().isMute() ? R.string.menu_mute_on : R.string.menu_mute_off);
+ muteMenu.setVisible(true);
+ } else {
+ muteMenu.setVisible(false);
+ }
+ }
+ MenuItem directions = menu.findItem(R.id.map_get_directions);
+ if(routingHelper.isRouteCalculated()){
+ directions.setTitle(R.string.show_route);
+ } else {
+ directions.setTitle(R.string.get_directions);
+ }
+
+ MenuItem animateMenu = menu.findItem(R.id.map_animate_route);
+
+ if (animateMenu != null) {
+ if(settings.TEST_ANIMATE_ROUTING.get()){
+ animateMenu.setTitle(routeAnimation.isRouteAnimating() ? R.string.animate_route_off
+ : R.string.animate_route);
+ animateMenu.setVisible("1".equals(Secure.getString(
+ mapActivity.getContentResolver(), Secure.ALLOW_MOCK_LOCATION))
+ && settings.getPointToNavigate() != null
+ && routingHelper.isRouteCalculated());
+ animateMenu.setVisible(true);
+ } else {
+ animateMenu.setVisible(false);
+ }
+ }
+
+ OsmandPlugin.registerOnPrepareOptionsMenu(mapActivity, menu);
+ }
+
+ public boolean onOptionsItemSelected(MenuItem item) {
+ final int itemId = item.getItemId();
+ OsmandMapTileView mapView = mapActivity.getMapView();
+ if (itemId == R.id.map_show_settings) {
+ final Intent intentSettings = new Intent(mapActivity, OsmandIntents.getSettingsActivity());
+ mapActivity.startActivity(intentSettings);
+ return true;
+ } else if (itemId == R.id.map_where_am_i) {
+ if (getMyApplication().accessibilityEnabled()) {
+ whereAmIDialog();
+ } else {
+ mapActivity.backToLocationImpl();
+ }
+ return true;
+ } else if (itemId == R.id.map_show_gps_status) {
+ startGpsStatusIntent();
+ return true;
+ } else if (itemId == R.id.map_specify_point) {
+ Intent newIntent = new Intent(mapActivity, OsmandIntents.getSearchActivity());
+ // causes wrong position caching: newIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+ LatLon loc = mapActivity.getMapLocation();
+ newIntent.putExtra(SearchActivity.SEARCH_LAT, loc.getLatitude());
+ newIntent.putExtra(SearchActivity.SEARCH_LON, loc.getLongitude());
+ newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mapActivity.startActivity(newIntent);
+ return true;
+ } else {
+ if (itemId == R.id.map_get_directions) {
+ if (routingHelper.isRouteCalculated()) {
+ aboutRoute();
+ } else {
+ Location loc = mapActivity.getLastKnownLocation();
+ if (loc != null) {
+ getDirections(loc.getLatitude(), loc.getLongitude(), true);
+ } else {
+ getDirections(mapView.getLatitude(), mapView.getLongitude(), true);
+ }
+ }
+ return true;
+ } else if (itemId == R.id.map_layers) {
+ mapActivity.getMapLayers().openLayerSelectionDialog(mapView);
+ return true;
+ } else if (itemId == R.id.map_mute) {
+ routingHelper.getVoiceRouter().setMute(!routingHelper.getVoiceRouter().isMute());
+ return true;
+ } else if (itemId == R.id.map_navigate_to_point) {
+ if (mapActivity.getMapLayers().getNavigationLayer().getPointToNavigate() != null) {
+ if (routingHelper.isRouteCalculated() || routingHelper.isFollowingMode() || routingHelper.isRouteBeingCalculated()) {
+ routingHelper.setFinalAndCurrentLocation(null, routingHelper.getCurrentLocation(), routingHelper.getCurrentGPXRoute());
+ // restore default mode
+ boolean changed = settings.APPLICATION_MODE.set(settings.PREV_APPLICATION_MODE.get());
+ mapActivity.updateApplicationModeSettings();
+ mapView.refreshMap(changed);
+ } else {
+ mapActivity.navigateToPoint(null);
+ }
+ } else {
+ mapActivity.navigateToPoint(new LatLon(mapView.getLatitude(), mapView.getLongitude()));
+ }
+ mapView.refreshMap();
+ return true;
+ } else if (itemId == R.id.map_show_point_options) {
+ contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
+ return true;
+ } else if (itemId == R.id.map_animate_route) {
+ // animate moving on route
+ routeAnimation.startStopRouteAnimation(routingHelper, mapActivity);
+ return true;
+ } else {
+ return OsmandPlugin.registerOnOptionsMenuItemSelected(mapActivity, itemId);
+ }
+ }
+ }
+ private void startGpsStatusIntent() {
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(GPS_STATUS_COMPONENT,
+ GPS_STATUS_ACTIVITY));
+ ResolveInfo resolved = mapActivity.getPackageManager().resolveActivity(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+ if (resolved != null) {
+ mapActivity.startActivity(intent);
+ } else {
+ AlertDialog.Builder builder = new AccessibleAlertBuilder(mapActivity);
+ builder.setMessage(getString(R.string.gps_status_app_not_found));
+ builder.setPositiveButton(
+ getString(R.string.default_buttons_yes),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog,
+ int which) {
+ Intent intent = new Intent(Intent.ACTION_VIEW,
+ Uri.parse("market://search?q=pname:"
+ + GPS_STATUS_COMPONENT));
+ try {
+ mapActivity.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ }
+ }
+ });
+ builder.setNegativeButton(
+ getString(R.string.default_buttons_no), null);
+ builder.show();
+ }
+ }
+
+ private void whereAmIDialog() {
+ final List items = new ArrayList();
+ items.add(getString(R.string.show_location));
+ items.add(getString(R.string.show_details));
+ AlertDialog.Builder menu = new AlertDialog.Builder(mapActivity);
+ menu.setItems(items.toArray(new String[items.size()]),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int item) {
+ dialog.dismiss();
+ switch (item) {
+ case 0:
+ mapActivity.backToLocationImpl();
+ break;
+ case 1:
+ mapActivity.getNavigationInfo().show(settings.getPointToNavigate(), mapActivity.getMapLayers().
+ getLocationLayer().getHeading());
+ break;
+ default:
+ break;
+ }
+ }
+ });
+ menu.show();
+ }
}
diff --git a/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionLayer.java b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionLayer.java
new file mode 100644
index 0000000000..3b6bf6c9c5
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionLayer.java
@@ -0,0 +1,301 @@
+package net.osmand.plus.parkingpoint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.osmand.OsmAndFormatter;
+import net.osmand.access.AccessibleToast;
+import net.osmand.osm.LatLon;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.OsmandSettings;
+import net.osmand.plus.R;
+import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.views.AnimateDraggingMapThread;
+import net.osmand.plus.views.ContextMenuLayer;
+import net.osmand.plus.views.MapInfoLayer;
+import net.osmand.plus.views.OsmandMapLayer;
+import net.osmand.plus.views.OsmandMapTileView;
+import net.osmand.plus.views.TextInfoControl;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.Style;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.location.Location;
+import android.text.format.DateFormat;
+import android.text.format.Time;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Toast;
+
+/**
+ * Class represents a layer which depicts the position of the parked car
+ * @author Alena Fedasenka
+ * @see ParkingPositionPlugin
+ *
+ */
+public class ParkingPositionLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider {
+ /**
+ * magic number so far
+ */
+ private static final int radius = 20;
+
+ private LatLon parkingPoint = null;
+
+ private DisplayMetrics dm;
+
+ private final MapActivity map;
+ private OsmandMapTileView view;
+ private OsmandSettings settings;
+
+ private Paint bitmapPaint;
+ private Paint paintText;
+ private Paint paintSubText;
+
+ private Bitmap parkingNoLimitIcon;
+ private Bitmap parkingLimitIcon;
+
+ private TextInfoControl parkingPlaceControl;
+
+ private boolean timeLimit;
+
+ public ParkingPositionLayer(MapActivity map) {
+ this.map = map;
+ }
+
+ @Override
+ public void initLayer(OsmandMapTileView view) {
+ this.view = view;
+ this.settings = ((OsmandApplication) map.getApplication()).getSettings();
+ parkingPoint = settings.getParkingPosition();
+ dm = new DisplayMetrics();
+ WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
+ wmgr.getDefaultDisplay().getMetrics(dm);
+
+ paintText = new Paint();
+ paintText.setStyle(Style.FILL_AND_STROKE);
+ paintText.setColor(Color.BLACK);
+ paintText.setTextSize(23 * MapInfoLayer.scaleCoefficient);
+ paintText.setAntiAlias(true);
+ paintText.setStrokeWidth(4);
+
+ paintSubText = new Paint();
+ paintSubText.setStyle(Style.FILL_AND_STROKE);
+ paintSubText.setColor(Color.BLACK);
+ paintSubText.setTextSize(15 * MapInfoLayer.scaleCoefficient);
+ paintSubText.setAntiAlias(true);
+
+ bitmapPaint = new Paint();
+ bitmapPaint.setDither(true);
+ bitmapPaint.setAntiAlias(true);
+ bitmapPaint.setFilterBitmap(true);
+ parkingNoLimitIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.poi_parking_pos_no_limit);
+ parkingLimitIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.poi_parking_pos_limit);
+
+
+ MapInfoLayer mapInfoLayer = map.getMapLayers().getMapInfoLayer();
+ if ((mapInfoLayer != null) && (parkingPlaceControl == null))
+ mapInfoLayer.addRightStack(createParkingPlaceInfoControl());
+ }
+
+ @Override
+ public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
+// settings.clearParkingPosition();
+ parkingPoint = settings.getParkingPosition();
+ if (parkingPoint == null)
+ return;
+ timeLimit = settings.getParkingType();
+ Bitmap parkingIcon;
+ if (!timeLimit) {
+ parkingIcon = parkingNoLimitIcon;
+ } else {
+ parkingIcon = parkingLimitIcon;
+ }
+ double latitude = parkingPoint.getLatitude();
+ double longitude = parkingPoint.getLongitude();
+ if (isLocationVisible(latitude, longitude)) {
+ int marginX = parkingNoLimitIcon.getWidth() / 2;
+// TODO tune y
+ int marginY = 72;//magic number!
+ int locationX = view.getMapXForPoint(longitude);
+ int locationY = view.getMapYForPoint(latitude);
+ canvas.rotate(-view.getRotate(), locationX, locationY);
+ canvas.drawBitmap(parkingIcon, locationX - marginX, locationY - marginY, bitmapPaint);
+ }
+ }
+
+ @Override
+ public boolean onSingleTap(PointF point) {
+ List parkPos = new ArrayList();
+ getParkingFromPoint(point, parkPos);
+ if(!parkPos.isEmpty()){
+ StringBuilder res = new StringBuilder();
+ res.append(view.getContext().getString(R.string.osmand_parking_position_description));
+ AccessibleToast.makeText(view.getContext(), getObjectDescription(null), Toast.LENGTH_LONG).show();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void destroyLayer() {
+ }
+
+ @Override
+ public boolean drawInScreenPixels() {
+ return false;
+ }
+
+ @Override
+ public void collectObjectsFromPoint(PointF point, List