diff --git a/OsmAnd-java/src/net/osmand/router/RoutingConfiguration.java b/OsmAnd-java/src/net/osmand/router/RoutingConfiguration.java
index 037cd619cd..7b7d4ca14d 100644
--- a/OsmAnd-java/src/net/osmand/router/RoutingConfiguration.java
+++ b/OsmAnd-java/src/net/osmand/router/RoutingConfiguration.java
@@ -135,6 +135,12 @@ public class RoutingConfiguration {
return routers.get(applicationMode);
}
+
+ public void removeImpassableRoad(RouteDataObject obj) {
+ impassableRoadIds.remove(obj.id);
+ impassableRoads.remove(obj);
+
+ }
}
private static int parseSilentInt(String t, int v) {
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 3e7adf30cc..ddc776da96 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -9,6 +9,8 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
-->
+ Select on map
+ Avoid roads…
Tram and train
Changes in 1.9:
* Updated maps styles with road surface rendering, transport layers and hiking symbols
diff --git a/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java b/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java
index 5057cc3d47..beff07b766 100644
--- a/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java
+++ b/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java
@@ -42,7 +42,7 @@ public class CurrentPositionHelper {
ctx = new RoutePlannerFrontEnd(false).buildRoutingContext(cfg, null, app.getResourceManager().getRoutingMapFiles());
}
- private RouteDataObject runUpdateInThread(Location loc) {
+ public synchronized RouteDataObject runUpdateInThread(double lat , double lon) {
RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd(false);
try {
if(ctx == null || am != app.getSettings().getApplicationMode()) {
@@ -51,7 +51,7 @@ public class CurrentPositionHelper {
return null;
}
}
- RouteSegment sg = rp.findRouteSegment(loc.getLatitude(), loc.getLongitude(), ctx);
+ RouteSegment sg = rp.findRouteSegment(lat, lon, ctx);
if(sg == null) {
return null;
}
@@ -64,13 +64,13 @@ public class CurrentPositionHelper {
private void scheduleRouteSegmentFind(final Location loc){
if(calculatingThread == Thread.currentThread()) {
- lastFound = runUpdateInThread(loc);
+ lastFound = runUpdateInThread(loc.getLatitude(), loc.getLongitude());
} else if(calculatingThread == null && loc != null) {
Runnable run = new Runnable() {
@Override
public void run() {
try {
- lastFound = runUpdateInThread(loc);
+ lastFound = runUpdateInThread(loc.getLatitude(), loc.getLongitude());
if (lastAskedLocation != loc) {
// refresh and run new task if needed
getLastKnownRouteSegment(lastAskedLocation);
diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java
index 85ccc9cf21..d4f4afbfd7 100644
--- a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java
+++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java
@@ -214,6 +214,10 @@ public class OsmAndLocationProvider implements SensorEventListener {
currentPositionHelper = new CurrentPositionHelper(app);
locationSimulation = new OsmAndLocationSimulation(app, this);
}
+
+ public RouteDataObject findRoute(double lat , double lon) {
+ return currentPositionHelper.runUpdateInThread(lat, lon);
+ }
public void resumeAllUpdates() {
final LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java
index f00eeb7db9..a7e63613f8 100644
--- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java
+++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java
@@ -25,6 +25,7 @@ import net.osmand.plus.activities.SettingsActivity;
import net.osmand.plus.api.SQLiteAPI;
import net.osmand.plus.api.SQLiteAPIImpl;
import net.osmand.plus.download.DownloadActivity;
+import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.monitoring.LiveMonitoringHelper;
import net.osmand.plus.render.NativeOsmandLibrary;
@@ -109,6 +110,7 @@ public class OsmandApplication extends Application {
private TargetPointsHelper targetPointsHelper;
private RoutingConfiguration.Builder defaultRoutingConfig;
private WaypointHelper waypointHelper;
+ private AvoidSpecificRoads avoidSpecificRoads;
private boolean applicationInitializing = false;
private Locale preferredLocale = null;
@@ -161,6 +163,7 @@ public class OsmandApplication extends Application {
taskManager = new OsmAndTaskManager(this);
resourceManager = new ResourceManager(this);
daynightHelper = new DayNightHelper(this);
+ avoidSpecificRoads = new AvoidSpecificRoads(this);
locationProvider = new OsmAndLocationProvider(this);
savingTrackHelper = new SavingTrackHelper(this);
liveMonitoringHelper = new LiveMonitoringHelper(this);
@@ -217,6 +220,10 @@ public class OsmandApplication extends Application {
public OsmAndTaskManager getTaskManager() {
return taskManager;
}
+
+ public AvoidSpecificRoads getAvoidSpecificRoads() {
+ return avoidSpecificRoads;
+ }
public OsmAndLocationProvider getLocationProvider() {
@@ -227,6 +234,7 @@ public class OsmandApplication extends Application {
return appCustomization;
}
+
public void setAppCustomization(OsmAndAppCustomization appCustomization) {
this.appCustomization = appCustomization;
this.appCustomization.setup(this);
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index 6c49b9fc60..d9a87f8ee5 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -758,6 +758,17 @@ public class MapActivityActions implements DialogProvider {
}
}).reg();
}
+ if(routingHelper.isRouteCalculated()) {
+ optionsMenuHelper.item(R.string.impassable_road)
+ .icons(R.drawable.ic_action_road_works_dark, R.drawable.ic_action_road_works_light)
+ .listen(new OnContextMenuClick() {
+ @Override
+ public boolean onContextMenuClick(ArrayAdapter> adapter, int itemId, int pos, boolean isChecked) {
+ app.getAvoidSpecificRoads().showDialog(mapActivity);
+ return true;
+ }
+ }).reg();
+ }
// 5-9. Default actions (Layers, Configure Map screen, Settings, Search, Favorites)
optionsMenuHelper.item(R.string.search_button)
diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java
index accaf3e288..a6293ccb71 100644
--- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java
+++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java
@@ -24,7 +24,6 @@ import net.osmand.render.RenderingRulesStorage;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.View;
-import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Toast;
diff --git a/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java b/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java
new file mode 100644
index 0000000000..56a5072d82
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java
@@ -0,0 +1,172 @@
+package net.osmand.plus.helpers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.osmand.CallbackWithObject;
+import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
+import net.osmand.binary.RouteDataObject;
+import net.osmand.data.LatLon;
+import net.osmand.plus.OsmAndFormatter;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.R;
+import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.routing.RoutingHelper;
+import net.osmand.plus.views.AnimateDraggingMapThread;
+import net.osmand.plus.views.ContextMenuLayer;
+import net.osmand.router.RoutingConfiguration;
+import net.osmand.util.MapUtils;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.content.DialogInterface;
+import android.os.AsyncTask;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class AvoidSpecificRoads {
+ private List missingRoads;
+ private OsmandApplication app;
+
+ public AvoidSpecificRoads(OsmandApplication app) {
+ this.app = app;
+ missingRoads = getBuilder().getImpassableRoads();
+ }
+
+
+
+ protected net.osmand.router.RoutingConfiguration.Builder getBuilder() {
+ return RoutingConfiguration.getDefault();
+ }
+
+
+
+ public ArrayAdapter createAdapter(final MapActivity ctx) {
+ final ArrayList points = new ArrayList();
+ points.add(new RouteDataObject((RouteRegion) null));
+ points.addAll(missingRoads);
+ final LatLon mapLocation = ctx.getMapLocation();
+ return new ArrayAdapter(ctx,
+ R.layout.waypoint_reached, R.id.title, points) {
+
+ @Override
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ // User super class to create the View
+ View v = convertView;
+ if (position == 0) {
+ TextView tv = new TextView(ctx);
+ tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
+ v = tv;
+ } else {
+ if (v == null || v.findViewById(R.id.info_close) == null) {
+ v = ctx.getLayoutInflater().inflate(R.layout.waypoint_reached, null);
+ }
+ final RouteDataObject obj = getItem(position);
+ v.findViewById(R.id.all_points).setVisibility(View.GONE);
+ ((ImageView) v.findViewById(R.id.waypoint_icon)).setImageResource(app.getSettings().isLightContentMenu()?
+ R.drawable.ic_action_road_works_light : R.drawable.ic_action_road_works_dark);
+ double dist = MapUtils.getDistance(mapLocation, MapUtils.get31LatitudeY(obj.getPoint31YTile(0)) ,
+ MapUtils.get31LongitudeX(obj.getPoint31XTile(0)));
+ ((TextView)v.findViewById(R.id.waypoint_dist)).setText(OsmAndFormatter.getFormattedDistance((float) dist, app));
+
+ ((TextView)v.findViewById(R.id.waypoint_text)).setText(getText(obj));
+ View remove = v.findViewById(R.id.info_close);
+ remove.setVisibility(View.VISIBLE);
+ remove.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ remove(obj);
+ getBuilder().removeImpassableRoad(obj);
+ notifyDataSetChanged();
+ }
+ });
+
+ }
+ return v;
+ }
+
+
+ };
+ }
+
+
+ protected String getText(RouteDataObject obj) {
+ return RoutingHelper.formatStreetName(obj.getName(), obj.getRef(), obj.getDestinationName());
+ }
+
+ public void showDialog(final MapActivity mapActivity) {
+ Builder bld = new AlertDialog.Builder(mapActivity);
+ bld.setTitle(R.string.impassable_road);
+ final ArrayAdapter> listAdapter = createAdapter(mapActivity);
+ bld.setAdapter(listAdapter, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if(which == 0) {
+ selectFromMap(mapActivity);
+ } else {
+ RouteDataObject obj = missingRoads.get(which - 1);
+ double lat = MapUtils.get31LatitudeY(obj.getPoint31YTile(0));
+ double lon = MapUtils.get31LongitudeX(obj.getPoint31XTile(0));
+ showOnMap(app, mapActivity, lat, lon, getText(obj), dialog);
+ }
+ }
+
+ });
+ bld.show();
+ }
+
+
+ protected void selectFromMap(final MapActivity mapActivity) {
+ ContextMenuLayer cm = mapActivity.getMapLayers().getContextMenuLayer();
+ cm.setSelectOnMap(new CallbackWithObject() {
+
+ @Override
+ public boolean processResult(LatLon result) {
+ findRoad(mapActivity, result);
+ return true;
+ }
+
+ });
+ }
+ private void findRoad(final MapActivity activity, final LatLon loc) {
+ new AsyncTask() {
+
+ @Override
+ protected RouteDataObject doInBackground(LatLon... params) {
+ return app.getLocationProvider().findRoute(loc.getLatitude(), loc.getLongitude());
+ }
+
+ protected void onPostExecute(RouteDataObject result) {
+ if(result != null) {
+ getBuilder().addImpassableRoad(result);
+ showDialog(activity);
+ }
+ };
+ }.execute(loc);
+ }
+
+ public static void showOnMap(OsmandApplication app, Activity a, double lat, double lon, String name,
+ DialogInterface dialog) {
+ if (!(a instanceof MapActivity)) {
+ return;
+ }
+ MapActivity ctx = (MapActivity) a;
+ AnimateDraggingMapThread thread = ctx.getMapView().getAnimatedDraggingThread();
+ int fZoom = ctx.getMapView().getZoom() < 15 ? 15 : ctx.getMapView().getZoom();
+ if (thread.isAnimating()) {
+ ctx.getMapView().setIntZoom(fZoom);
+ ctx.getMapView().setLatLon(lat, lon);
+ } else {
+ thread.startMoving(lat, lon, fZoom, true);
+ }
+ ctx.getMapLayers().getContextMenuLayer().setLocation(new LatLon(lat, lon), name);
+ dialog.dismiss();
+ }
+
+}
diff --git a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java
index f5781ac746..29e81d39c7 100644
--- a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java
+++ b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java
@@ -7,11 +7,13 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
+import net.osmand.CallbackWithObject;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
+import alice.util.Sleep;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
@@ -70,6 +72,7 @@ public class ContextMenuLayer extends OsmandMapLayer {
private Drawable boxLeg;
private float scaleCoefficient = 1;
private Rect textPadding;
+ private CallbackWithObject selectOnMap = null;
public ContextMenuLayer(MapActivity activity){
this.activity = activity;
@@ -170,6 +173,12 @@ public class ContextMenuLayer extends OsmandMapLayer {
}
}
+
+ public void setSelectOnMap(CallbackWithObject selectOnMap) {
+ this.selectOnMap = selectOnMap;
+ }
+
+
private void layoutText() {
Rect padding = new Rect();
if (textView.getLineCount() > 0) {
@@ -333,6 +342,14 @@ public class ContextMenuLayer extends OsmandMapLayer {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
boolean nativeMode = (Build.VERSION.SDK_INT >= 14) || view.getSettings().SCROLL_MAP_BY_GESTURES.get();
int val = pressedInTextView(tileBox, point.x, point.y);
+ if(selectOnMap != null) {
+ LatLon latlon = tileBox.getLatLonFromPixel(point.x, point.y);
+ CallbackWithObject cb = selectOnMap;
+ selectOnMap = null;
+ cb.processResult(latlon);
+ setLocation(latlon, null);
+ return true;
+ }
if (val == 2) {
setLocation(null, ""); //$NON-NLS-1$
view.refreshMap();