Avoid roads second part

This commit is contained in:
Vitaliy 2020-02-18 16:40:39 +02:00
parent bd0d4a9c9e
commit 1cb49fe402
4 changed files with 180 additions and 32 deletions

View file

@ -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;

View file

@ -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) {

View file

@ -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);
}

View file

@ -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;