Add impassable road implementation
This commit is contained in:
parent
8210315c7b
commit
ee2eff593f
9 changed files with 224 additions and 5 deletions
|
@ -135,6 +135,12 @@ public class RoutingConfiguration {
|
||||||
return routers.get(applicationMode);
|
return routers.get(applicationMode);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeImpassableRoad(RouteDataObject obj) {
|
||||||
|
impassableRoadIds.remove(obj.id);
|
||||||
|
impassableRoads.remove(obj);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int parseSilentInt(String t, int v) {
|
private static int parseSilentInt(String t, int v) {
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
|
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
|
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
|
||||||
-->
|
-->
|
||||||
|
<string name="select_impassable_raod">Select on map</string>
|
||||||
|
<string name="impassable_road">Avoid roads…</string>
|
||||||
<string name="rendering_attr_tramTrainRoutes_name">Tram and train</string>
|
<string name="rendering_attr_tramTrainRoutes_name">Tram and train</string>
|
||||||
<string name="tip_recent_changes_1_9_t">Changes in 1.9:
|
<string name="tip_recent_changes_1_9_t">Changes in 1.9:
|
||||||
* Updated maps styles with road surface rendering, transport layers and hiking symbols
|
* Updated maps styles with road surface rendering, transport layers and hiking symbols
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class CurrentPositionHelper {
|
||||||
ctx = new RoutePlannerFrontEnd(false).buildRoutingContext(cfg, null, app.getResourceManager().getRoutingMapFiles());
|
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);
|
RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd(false);
|
||||||
try {
|
try {
|
||||||
if(ctx == null || am != app.getSettings().getApplicationMode()) {
|
if(ctx == null || am != app.getSettings().getApplicationMode()) {
|
||||||
|
@ -51,7 +51,7 @@ public class CurrentPositionHelper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RouteSegment sg = rp.findRouteSegment(loc.getLatitude(), loc.getLongitude(), ctx);
|
RouteSegment sg = rp.findRouteSegment(lat, lon, ctx);
|
||||||
if(sg == null) {
|
if(sg == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -64,13 +64,13 @@ public class CurrentPositionHelper {
|
||||||
|
|
||||||
private void scheduleRouteSegmentFind(final Location loc){
|
private void scheduleRouteSegmentFind(final Location loc){
|
||||||
if(calculatingThread == Thread.currentThread()) {
|
if(calculatingThread == Thread.currentThread()) {
|
||||||
lastFound = runUpdateInThread(loc);
|
lastFound = runUpdateInThread(loc.getLatitude(), loc.getLongitude());
|
||||||
} else if(calculatingThread == null && loc != null) {
|
} else if(calculatingThread == null && loc != null) {
|
||||||
Runnable run = new Runnable() {
|
Runnable run = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
lastFound = runUpdateInThread(loc);
|
lastFound = runUpdateInThread(loc.getLatitude(), loc.getLongitude());
|
||||||
if (lastAskedLocation != loc) {
|
if (lastAskedLocation != loc) {
|
||||||
// refresh and run new task if needed
|
// refresh and run new task if needed
|
||||||
getLastKnownRouteSegment(lastAskedLocation);
|
getLastKnownRouteSegment(lastAskedLocation);
|
||||||
|
|
|
@ -215,6 +215,10 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
locationSimulation = new OsmAndLocationSimulation(app, this);
|
locationSimulation = new OsmAndLocationSimulation(app, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RouteDataObject findRoute(double lat , double lon) {
|
||||||
|
return currentPositionHelper.runUpdateInThread(lat, lon);
|
||||||
|
}
|
||||||
|
|
||||||
public void resumeAllUpdates() {
|
public void resumeAllUpdates() {
|
||||||
final LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
|
final LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
|
||||||
service.addGpsStatusListener(getGpsStatusListener(service));
|
service.addGpsStatusListener(getGpsStatusListener(service));
|
||||||
|
|
|
@ -25,6 +25,7 @@ import net.osmand.plus.activities.SettingsActivity;
|
||||||
import net.osmand.plus.api.SQLiteAPI;
|
import net.osmand.plus.api.SQLiteAPI;
|
||||||
import net.osmand.plus.api.SQLiteAPIImpl;
|
import net.osmand.plus.api.SQLiteAPIImpl;
|
||||||
import net.osmand.plus.download.DownloadActivity;
|
import net.osmand.plus.download.DownloadActivity;
|
||||||
|
import net.osmand.plus.helpers.AvoidSpecificRoads;
|
||||||
import net.osmand.plus.helpers.WaypointHelper;
|
import net.osmand.plus.helpers.WaypointHelper;
|
||||||
import net.osmand.plus.monitoring.LiveMonitoringHelper;
|
import net.osmand.plus.monitoring.LiveMonitoringHelper;
|
||||||
import net.osmand.plus.render.NativeOsmandLibrary;
|
import net.osmand.plus.render.NativeOsmandLibrary;
|
||||||
|
@ -109,6 +110,7 @@ public class OsmandApplication extends Application {
|
||||||
private TargetPointsHelper targetPointsHelper;
|
private TargetPointsHelper targetPointsHelper;
|
||||||
private RoutingConfiguration.Builder defaultRoutingConfig;
|
private RoutingConfiguration.Builder defaultRoutingConfig;
|
||||||
private WaypointHelper waypointHelper;
|
private WaypointHelper waypointHelper;
|
||||||
|
private AvoidSpecificRoads avoidSpecificRoads;
|
||||||
|
|
||||||
private boolean applicationInitializing = false;
|
private boolean applicationInitializing = false;
|
||||||
private Locale preferredLocale = null;
|
private Locale preferredLocale = null;
|
||||||
|
@ -161,6 +163,7 @@ public class OsmandApplication extends Application {
|
||||||
taskManager = new OsmAndTaskManager(this);
|
taskManager = new OsmAndTaskManager(this);
|
||||||
resourceManager = new ResourceManager(this);
|
resourceManager = new ResourceManager(this);
|
||||||
daynightHelper = new DayNightHelper(this);
|
daynightHelper = new DayNightHelper(this);
|
||||||
|
avoidSpecificRoads = new AvoidSpecificRoads(this);
|
||||||
locationProvider = new OsmAndLocationProvider(this);
|
locationProvider = new OsmAndLocationProvider(this);
|
||||||
savingTrackHelper = new SavingTrackHelper(this);
|
savingTrackHelper = new SavingTrackHelper(this);
|
||||||
liveMonitoringHelper = new LiveMonitoringHelper(this);
|
liveMonitoringHelper = new LiveMonitoringHelper(this);
|
||||||
|
@ -218,6 +221,10 @@ public class OsmandApplication extends Application {
|
||||||
return taskManager;
|
return taskManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AvoidSpecificRoads getAvoidSpecificRoads() {
|
||||||
|
return avoidSpecificRoads;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public OsmAndLocationProvider getLocationProvider() {
|
public OsmAndLocationProvider getLocationProvider() {
|
||||||
return locationProvider;
|
return locationProvider;
|
||||||
|
@ -227,6 +234,7 @@ public class OsmandApplication extends Application {
|
||||||
return appCustomization;
|
return appCustomization;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setAppCustomization(OsmAndAppCustomization appCustomization) {
|
public void setAppCustomization(OsmAndAppCustomization appCustomization) {
|
||||||
this.appCustomization = appCustomization;
|
this.appCustomization = appCustomization;
|
||||||
this.appCustomization.setup(this);
|
this.appCustomization.setup(this);
|
||||||
|
|
|
@ -758,6 +758,17 @@ public class MapActivityActions implements DialogProvider {
|
||||||
}
|
}
|
||||||
}).reg();
|
}).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)
|
// 5-9. Default actions (Layers, Configure Map screen, Settings, Search, Favorites)
|
||||||
optionsMenuHelper.item(R.string.search_button)
|
optionsMenuHelper.item(R.string.search_button)
|
||||||
|
|
|
@ -24,7 +24,6 @@ import net.osmand.render.RenderingRulesStorage;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
|
172
OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java
Normal file
172
OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java
Normal file
|
@ -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<RouteDataObject> 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<RouteDataObject> createAdapter(final MapActivity ctx) {
|
||||||
|
final ArrayList<RouteDataObject> points = new ArrayList<RouteDataObject>();
|
||||||
|
points.add(new RouteDataObject((RouteRegion) null));
|
||||||
|
points.addAll(missingRoads);
|
||||||
|
final LatLon mapLocation = ctx.getMapLocation();
|
||||||
|
return new ArrayAdapter<RouteDataObject>(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<LatLon>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean processResult(LatLon result) {
|
||||||
|
findRoad(mapActivity, result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void findRoad(final MapActivity activity, final LatLon loc) {
|
||||||
|
new AsyncTask<LatLon, Void, RouteDataObject>() {
|
||||||
|
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,11 +7,13 @@ import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import net.osmand.CallbackWithObject;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.data.RotatedTileBox;
|
import net.osmand.data.RotatedTileBox;
|
||||||
import net.osmand.plus.ContextMenuAdapter;
|
import net.osmand.plus.ContextMenuAdapter;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.activities.MapActivity;
|
import net.osmand.plus.activities.MapActivity;
|
||||||
|
import alice.util.Sleep;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.AlertDialog.Builder;
|
import android.app.AlertDialog.Builder;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
@ -70,6 +72,7 @@ public class ContextMenuLayer extends OsmandMapLayer {
|
||||||
private Drawable boxLeg;
|
private Drawable boxLeg;
|
||||||
private float scaleCoefficient = 1;
|
private float scaleCoefficient = 1;
|
||||||
private Rect textPadding;
|
private Rect textPadding;
|
||||||
|
private CallbackWithObject<LatLon> selectOnMap = null;
|
||||||
|
|
||||||
public ContextMenuLayer(MapActivity activity){
|
public ContextMenuLayer(MapActivity activity){
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
|
@ -170,6 +173,12 @@ public class ContextMenuLayer extends OsmandMapLayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setSelectOnMap(CallbackWithObject<LatLon> selectOnMap) {
|
||||||
|
this.selectOnMap = selectOnMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void layoutText() {
|
private void layoutText() {
|
||||||
Rect padding = new Rect();
|
Rect padding = new Rect();
|
||||||
if (textView.getLineCount() > 0) {
|
if (textView.getLineCount() > 0) {
|
||||||
|
@ -333,6 +342,14 @@ public class ContextMenuLayer extends OsmandMapLayer {
|
||||||
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
|
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
|
||||||
boolean nativeMode = (Build.VERSION.SDK_INT >= 14) || view.getSettings().SCROLL_MAP_BY_GESTURES.get();
|
boolean nativeMode = (Build.VERSION.SDK_INT >= 14) || view.getSettings().SCROLL_MAP_BY_GESTURES.get();
|
||||||
int val = pressedInTextView(tileBox, point.x, point.y);
|
int val = pressedInTextView(tileBox, point.x, point.y);
|
||||||
|
if(selectOnMap != null) {
|
||||||
|
LatLon latlon = tileBox.getLatLonFromPixel(point.x, point.y);
|
||||||
|
CallbackWithObject<LatLon> cb = selectOnMap;
|
||||||
|
selectOnMap = null;
|
||||||
|
cb.processResult(latlon);
|
||||||
|
setLocation(latlon, null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (val == 2) {
|
if (val == 2) {
|
||||||
setLocation(null, ""); //$NON-NLS-1$
|
setLocation(null, ""); //$NON-NLS-1$
|
||||||
view.refreshMap();
|
view.refreshMap();
|
||||||
|
|
Loading…
Reference in a new issue