Avoid roads second part
This commit is contained in:
parent
bd0d4a9c9e
commit
1cb49fe402
4 changed files with 180 additions and 32 deletions
|
@ -116,9 +116,9 @@ public class RoutingConfiguration {
|
|||
return impassableRoadLocations;
|
||||
}
|
||||
|
||||
public boolean addImpassableRoad(RouteDataObject route) {
|
||||
if (!impassableRoadLocations.contains(route.id)) {
|
||||
impassableRoadLocations.add(route.id);
|
||||
public boolean addImpassableRoad(long routeId) {
|
||||
if (!impassableRoadLocations.contains(routeId)) {
|
||||
impassableRoadLocations.add(routeId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -629,6 +629,7 @@ public class AppInitializer implements IProgress {
|
|||
if (!customConfigs.isEmpty()) {
|
||||
app.getCustomRoutingConfigs().putAll(customConfigs);
|
||||
}
|
||||
app.avoidSpecificRoads.initRouteObjects(false);
|
||||
callback.onRoutingFilesLoaded();
|
||||
}
|
||||
|
||||
|
@ -739,8 +740,7 @@ public class AppInitializer implements IProgress {
|
|||
notifyEvent(InitEvents.RESTORE_BACKUPS);
|
||||
app.mapMarkersHelper.syncAllGroupsAsync();
|
||||
app.searchUICore.initSearchUICore();
|
||||
app.avoidSpecificRoads.initRouteObjects(false);
|
||||
|
||||
|
||||
checkLiveUpdatesAlerts();
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
|
|
|
@ -2798,9 +2798,136 @@ public class OsmandSettings {
|
|||
}
|
||||
|
||||
private class ImpassableRoadsStorage extends MapPointsStorage {
|
||||
|
||||
protected String roadsIdsKey;
|
||||
|
||||
public ImpassableRoadsStorage() {
|
||||
pointsKey = IMPASSABLE_ROAD_POINTS;
|
||||
descriptionsKey = IMPASSABLE_ROADS_DESCRIPTIONS;
|
||||
roadsIdsKey = IMPASSABLE_ROADS_IDS;
|
||||
}
|
||||
|
||||
public List<AvoidRoadInfo> getImpassableRoadsInfo() {
|
||||
List<LatLon> points = mImpassableRoadsStorage.getPoints();
|
||||
List<String> descriptions = mImpassableRoadsStorage.getPointDescriptions(points.size());
|
||||
List<Long> roadIds = getRoadIds(points.size());
|
||||
|
||||
List<AvoidRoadInfo> avoidRoadsInfo = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
LatLon latLon = points.get(i);
|
||||
PointDescription description = PointDescription.deserializeFromString(descriptions.get(i), null);
|
||||
|
||||
AvoidRoadInfo avoidRoadInfo = new AvoidRoadInfo();
|
||||
avoidRoadInfo.id = roadIds.get(i);
|
||||
avoidRoadInfo.lat = latLon.getLatitude();
|
||||
avoidRoadInfo.lon = latLon.getLongitude();
|
||||
avoidRoadInfo.name = description.getName();
|
||||
avoidRoadsInfo.add(avoidRoadInfo);
|
||||
}
|
||||
|
||||
return avoidRoadsInfo;
|
||||
}
|
||||
|
||||
public boolean addImpassableRoadInfo(AvoidRoadInfo avoidRoadInfo) {
|
||||
List<LatLon> points = getPoints();
|
||||
List<String> descriptions = getPointDescriptions(points.size());
|
||||
List<Long> roadIds = getRoadIds(points.size());
|
||||
|
||||
points.add(0, new LatLon(avoidRoadInfo.lat, avoidRoadInfo.lon));
|
||||
descriptions.add(0, PointDescription.serializeToString(new PointDescription("", avoidRoadInfo.name)));
|
||||
roadIds.add(0, avoidRoadInfo.id);
|
||||
|
||||
return savePoints(points, descriptions) && saveRoadIds(roadIds);
|
||||
}
|
||||
|
||||
public boolean updateImpassableRoadInfo(AvoidRoadInfo avoidRoadInfo) {
|
||||
List<LatLon> points = getPoints();
|
||||
List<Long> roadIds = getRoadIds(points.size());
|
||||
List<String> descriptions = getPointDescriptions(points.size());
|
||||
|
||||
int index = points.indexOf(new LatLon(avoidRoadInfo.lat, avoidRoadInfo.lon));
|
||||
if (index != -1) {
|
||||
roadIds.set(index, avoidRoadInfo.id);
|
||||
descriptions.set(index, PointDescription.serializeToString(new PointDescription("", avoidRoadInfo.name)));
|
||||
return savePoints(points, descriptions) && saveRoadIds(roadIds);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<Long> getRoadIds(int size) {
|
||||
List<Long> list = new ArrayList<>();
|
||||
String roadIds = settingsAPI.getString(globalPreferences, roadsIdsKey, "");
|
||||
if (roadIds.trim().length() > 0) {
|
||||
StringTokenizer tok = new StringTokenizer(roadIds, ",");
|
||||
while (tok.hasMoreTokens() && list.size() <= size) {
|
||||
String token = tok.nextToken();
|
||||
list.add(Long.parseLong(token));
|
||||
}
|
||||
}
|
||||
while (list.size() < size) {
|
||||
list.add(0L);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deletePoint(int index) {
|
||||
List<LatLon> points = getPoints();
|
||||
List<Long> roadIds = getRoadIds(points.size());
|
||||
List<String> descriptions = getPointDescriptions(points.size());
|
||||
|
||||
if (index < points.size()) {
|
||||
points.remove(index);
|
||||
roadIds.remove(index);
|
||||
descriptions.remove(index);
|
||||
return savePoints(points, descriptions) && saveRoadIds(roadIds);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deletePoint(LatLon latLon) {
|
||||
List<LatLon> points = getPoints();
|
||||
List<String> descriptions = getPointDescriptions(points.size());
|
||||
List<Long> roadIds = getRoadIds(points.size());
|
||||
int index = points.indexOf(latLon);
|
||||
if (index != -1) {
|
||||
points.remove(index);
|
||||
roadIds.remove(index);
|
||||
descriptions.remove(index);
|
||||
return savePoints(points, descriptions) && saveRoadIds(roadIds);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean movePoint(LatLon latLonEx, LatLon latLonNew) {
|
||||
List<LatLon> points = getPoints();
|
||||
List<String> descriptions = getPointDescriptions(points.size());
|
||||
List<Long> roadIds = getRoadIds(points.size());
|
||||
|
||||
int i = points.indexOf(latLonEx);
|
||||
if (i != -1) {
|
||||
points.set(i, latLonNew);
|
||||
return savePoints(points, descriptions) && saveRoadIds(roadIds);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean saveRoadIds(List<Long> roadIds) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
Iterator<Long> iterator = roadIds.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
stringBuilder.append(iterator.next());
|
||||
if (iterator.hasNext()) {
|
||||
stringBuilder.append(",");
|
||||
}
|
||||
}
|
||||
return settingsAPI.edit(globalPreferences)
|
||||
.putString(roadsIdsKey, stringBuilder.toString())
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2994,10 +3121,15 @@ public class OsmandSettings {
|
|||
public List<AvoidRoadInfo> getImpassableRoadPoints() {
|
||||
return mImpassableRoadsStorage.getImpassableRoadsInfo();
|
||||
}
|
||||
|
||||
public boolean addImpassableRoad(AvoidRoadInfo avoidRoadInfo) {
|
||||
return mImpassableRoadsStorage.addImpassableRoadInfo(avoidRoadInfo);
|
||||
}
|
||||
|
||||
public boolean updateImpassableRoadInfo(AvoidRoadInfo avoidRoadInfo) {
|
||||
return mImpassableRoadsStorage.updateImpassableRoadInfo(avoidRoadInfo);
|
||||
}
|
||||
|
||||
public boolean removeImpassableRoad(int index) {
|
||||
return mImpassableRoadsStorage.deletePoint(index);
|
||||
}
|
||||
|
|
|
@ -67,17 +67,21 @@ public class AvoidSpecificRoads {
|
|||
for (Map.Entry<LatLon, AvoidRoadInfo> entry : impassableRoads.entrySet()) {
|
||||
if (force || entry.getValue().id == 0) {
|
||||
addImpassableRoad(null, entry.getKey(), false, true);
|
||||
} else {
|
||||
for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) {
|
||||
builder.addImpassableRoad(entry.getValue().id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayAdapter<LatLon> createAdapter(MapActivity mapActivity, boolean nightMode) {
|
||||
final ArrayList<LatLon> points = new ArrayList<>(impassableRoads.keySet());
|
||||
private ArrayAdapter<AvoidRoadInfo> createAdapter(MapActivity mapActivity, boolean nightMode) {
|
||||
final ArrayList<AvoidRoadInfo> points = new ArrayList<>(impassableRoads.values());
|
||||
final LatLon mapLocation = mapActivity.getMapLocation();
|
||||
final LayoutInflater inflater = UiUtilities.getInflater(mapActivity, nightMode);
|
||||
Context themedContext = UiUtilities.getThemedContext(mapActivity, nightMode);
|
||||
|
||||
return new ArrayAdapter<LatLon>(themedContext, R.layout.waypoint_reached, R.id.title, points) {
|
||||
return new ArrayAdapter<AvoidRoadInfo>(themedContext, R.layout.waypoint_reached, R.id.title, points) {
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
|
||||
|
@ -85,12 +89,15 @@ public class AvoidSpecificRoads {
|
|||
if (v == null || v.findViewById(R.id.info_close) == null) {
|
||||
v = inflater.inflate(R.layout.waypoint_reached, parent, false);
|
||||
}
|
||||
final LatLon item = getItem(position);
|
||||
final AvoidRoadInfo item = getItem(position);
|
||||
v.findViewById(R.id.all_points).setVisibility(View.GONE);
|
||||
((ImageView) v.findViewById(R.id.waypoint_icon))
|
||||
.setImageDrawable(getIcon(R.drawable.ic_action_road_works_dark));
|
||||
((TextView) v.findViewById(R.id.waypoint_dist)).setText(getDist(mapLocation, item));
|
||||
((TextView) v.findViewById(R.id.waypoint_text)).setText(getText(item));
|
||||
|
||||
LatLon latLon = item != null ? new LatLon(item.lat, item.lon) : null;
|
||||
String name = item != null ? item.name : app.getString(R.string.shared_string_road);
|
||||
((TextView) v.findViewById(R.id.waypoint_dist)).setText(getDist(mapLocation, latLon));
|
||||
((TextView) v.findViewById(R.id.waypoint_text)).setText(name);
|
||||
ImageButton remove = (ImageButton) v.findViewById(R.id.info_close);
|
||||
remove.setVisibility(View.VISIBLE);
|
||||
remove.setImageDrawable(getIcon(R.drawable.ic_action_remove_dark));
|
||||
|
@ -153,15 +160,15 @@ public class AvoidSpecificRoads {
|
|||
|
||||
public void removeImpassableRoad(LatLon latLon) {
|
||||
app.getSettings().removeImpassableRoad(latLon);
|
||||
RouteDataObject obj = impassableRoads.remove(latLon);
|
||||
AvoidRoadInfo obj = impassableRoads.remove(latLon);
|
||||
if (obj != null) {
|
||||
for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) {
|
||||
builder.removeImpassableRoad(obj);
|
||||
builder.removeImpassableRoad(obj.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeImpassableRoad(RouteDataObject obj) {
|
||||
public void removeImpassableRoad(AvoidRoadInfo obj) {
|
||||
removeImpassableRoad(getLocation(obj));
|
||||
}
|
||||
|
||||
|
@ -174,13 +181,13 @@ public class AvoidSpecificRoads {
|
|||
if (impassableRoads.isEmpty()) {
|
||||
bld.setMessage(R.string.avoid_roads_msg);
|
||||
} else {
|
||||
final ArrayAdapter<LatLon> listAdapter = createAdapter(mapActivity, nightMode);
|
||||
final ArrayAdapter<AvoidRoadInfo> listAdapter = createAdapter(mapActivity, nightMode);
|
||||
bld.setAdapter(listAdapter, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
LatLon point = listAdapter.getItem(which);
|
||||
AvoidRoadInfo point = listAdapter.getItem(which);
|
||||
if (point != null) {
|
||||
showOnMap(mapActivity, point.getLatitude(), point.getLongitude(), getText(point));
|
||||
showOnMap(mapActivity, point.lat, point.lon, point.name);
|
||||
}
|
||||
dialog.dismiss();
|
||||
}
|
||||
|
@ -228,9 +235,12 @@ public class AvoidSpecificRoads {
|
|||
LatLon newLoc = new LatLon(MapUtils.get31LatitudeY((int) point.y), MapUtils.get31LongitudeX((int) point.x));
|
||||
ll.setLatitude(newLoc.getLatitude());
|
||||
ll.setLongitude(newLoc.getLongitude());
|
||||
addImpassableRoadInternal(roads.get(searchResult.getRoadIndex()).getObject(), ll, showDialog, mapActivity, newLoc);
|
||||
|
||||
RouteDataObject object = roads.get(searchResult.getRoadIndex()).getObject();
|
||||
AvoidRoadInfo avoidRoadInfo = getAvoidRoadInfoForDataObject(object, newLoc.getLatitude(), newLoc.getLongitude());
|
||||
addImpassableRoadInternal(avoidRoadInfo, showDialog, mapActivity, newLoc);
|
||||
if (!skipWritingSettings) {
|
||||
app.getSettings().addImpassableRoad(newLoc.getLatitude(), newLoc.getLongitude());
|
||||
app.getSettings().addImpassableRoad(avoidRoadInfo);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -244,7 +254,8 @@ public class AvoidSpecificRoads {
|
|||
Toast.makeText(mapActivity, R.string.error_avoid_specific_road, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
} else {
|
||||
addImpassableRoadInternal(object, ll, showDialog, mapActivity, loc);
|
||||
AvoidRoadInfo avoidRoadInfo = getAvoidRoadInfoForDataObject(object, ll.getLatitude(), ll.getLongitude());
|
||||
addImpassableRoadInternal(avoidRoadInfo, showDialog, mapActivity, loc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -256,12 +267,13 @@ public class AvoidSpecificRoads {
|
|||
|
||||
});
|
||||
if (!skipWritingSettings) {
|
||||
app.getSettings().addImpassableRoad(loc.getLatitude(), loc.getLongitude());
|
||||
AvoidRoadInfo avoidRoadInfo = getAvoidRoadInfoForDataObject(null, loc.getLatitude(), loc.getLongitude());
|
||||
app.getSettings().addImpassableRoad(avoidRoadInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public void replaceImpassableRoad(final MapActivity activity,
|
||||
final RouteDataObject currentObject,
|
||||
final AvoidRoadInfo currentObject,
|
||||
final LatLon newLoc,
|
||||
final boolean showDialog,
|
||||
final AvoidSpecificRoadsCallback callback) {
|
||||
|
@ -284,12 +296,13 @@ public class AvoidSpecificRoads {
|
|||
app.getSettings().moveImpassableRoad(oldLoc, newLoc);
|
||||
impassableRoads.remove(oldLoc);
|
||||
for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) {
|
||||
builder.removeImpassableRoad(currentObject);
|
||||
builder.removeImpassableRoad(currentObject.id);
|
||||
}
|
||||
addImpassableRoadInternal(object, ll, showDialog, activity, newLoc);
|
||||
AvoidRoadInfo avoidRoadInfo = getAvoidRoadInfoForDataObject(object, newLoc.getLatitude(), newLoc.getLongitude());
|
||||
|
||||
addImpassableRoadInternal(avoidRoadInfo, showDialog, activity, newLoc);
|
||||
if (callback != null) {
|
||||
callback.onAddImpassableRoad(true, object);
|
||||
callback.onAddImpassableRoad(true, avoidRoadInfo);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -302,19 +315,19 @@ public class AvoidSpecificRoads {
|
|||
});
|
||||
}
|
||||
|
||||
private void addImpassableRoadInternal(@NonNull RouteDataObject object,
|
||||
@NonNull Location ll,
|
||||
private void addImpassableRoadInternal(@NonNull AvoidRoadInfo avoidRoadInfo,
|
||||
boolean showDialog,
|
||||
@Nullable MapActivity activity,
|
||||
@NonNull LatLon loc) {
|
||||
boolean roadAdded = false;
|
||||
for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) {
|
||||
roadAdded |= builder.addImpassableRoad(object, ll);
|
||||
roadAdded |= builder.addImpassableRoad(avoidRoadInfo.id);
|
||||
}
|
||||
if (roadAdded) {
|
||||
impassableRoads.put(loc, object);
|
||||
app.getSettings().updateImpassableRoadInfo(avoidRoadInfo);
|
||||
impassableRoads.put(loc, avoidRoadInfo);
|
||||
} else {
|
||||
LatLon location = getLocation(object);
|
||||
LatLon location = getLocation(avoidRoadInfo);
|
||||
if (location != null) {
|
||||
app.getSettings().removeImpassableRoad(location);
|
||||
}
|
||||
|
@ -355,8 +368,11 @@ public class AvoidSpecificRoads {
|
|||
boolean isCancelled();
|
||||
}
|
||||
|
||||
private AvoidRoadInfo createAvoidRoadInfo(@Nullable RouteDataObject object, double lat, double lon) {
|
||||
AvoidRoadInfo avoidRoadInfo = new AvoidRoadInfo();
|
||||
private AvoidRoadInfo getAvoidRoadInfoForDataObject(@Nullable RouteDataObject object, double lat, double lon) {
|
||||
AvoidRoadInfo avoidRoadInfo = impassableRoads.get(new LatLon(lat, lon));
|
||||
if (avoidRoadInfo == null) {
|
||||
avoidRoadInfo = new AvoidRoadInfo();
|
||||
}
|
||||
avoidRoadInfo.id = object != null ? object.id : 0;
|
||||
avoidRoadInfo.lat = lat;
|
||||
avoidRoadInfo.lon = lon;
|
||||
|
|
Loading…
Reference in a new issue