basic implementation of functionality. Need to save results to avoid need for recalculation on startup
This commit is contained in:
parent
53268f462a
commit
a12812b564
8 changed files with 177 additions and 78 deletions
|
@ -143,9 +143,9 @@ public class GeocodingUtilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Long, Location> multipleReverseGeocodingSearch(RoutingContext ctx, List<Location> points, boolean allowEmptyNames) throws IOException {
|
public Map<RouteDataObject, Location> multipleReverseGeocodingSearch(RoutingContext ctx, List<Location> points, boolean allowEmptyNames) throws IOException {
|
||||||
RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd();
|
RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd();
|
||||||
Map<Long, Location> result = new HashMap<>();
|
Map<RouteDataObject, Location> result = new HashMap<>();
|
||||||
for (Location point : points) {
|
for (Location point : points) {
|
||||||
List<GeocodingResult> lst = new ArrayList<>();
|
List<GeocodingResult> lst = new ArrayList<>();
|
||||||
List<RouteSegmentPoint> listR = new ArrayList<>();
|
List<RouteSegmentPoint> listR = new ArrayList<>();
|
||||||
|
@ -184,12 +184,12 @@ public class GeocodingUtilities {
|
||||||
}
|
}
|
||||||
Collections.sort(lst, GeocodingUtilities.DISTANCE_COMPARATOR);
|
Collections.sort(lst, GeocodingUtilities.DISTANCE_COMPARATOR);
|
||||||
if (lst.size() > 0) {
|
if (lst.size() > 0) {
|
||||||
result.put(lst.get(0).point.getRoad().id, point);
|
result.put(lst.get(0).point.getRoad(), point);
|
||||||
// log.debug(String.format("Road %s", lst.get(0).point.getRoad()));
|
// log.debug(String.format("Road %s", lst.get(0).point.getRoad()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.debug(String.format("Time to load %d, time to findInitialSegment %d, timeToLoadHeaders %d, tiles loaded %d",
|
log.debug(String.format("Time to load %.3f s, time to findInitialSegment %.3f s, timeToLoadHeaders %.3f s, tiles loaded %d",
|
||||||
ctx.timeToLoad,ctx.timeToFindInitialSegments, ctx.timeToLoadHeaders, ctx.loadedTiles));
|
ctx.timeToLoad/1000000000.0f, ctx.timeToFindInitialSegments/1000000000.0f, ctx.timeToLoadHeaders/1000000000.0f, ctx.loadedTiles));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ public class RoutingConfiguration {
|
||||||
private Map<String, GeneralRouter> routers = new LinkedHashMap<>();
|
private Map<String, GeneralRouter> routers = new LinkedHashMap<>();
|
||||||
private Map<String, String> attributes = new LinkedHashMap<>();
|
private Map<String, String> attributes = new LinkedHashMap<>();
|
||||||
private HashMap<Long, Location> impassableRoadLocations = new HashMap<>();
|
private HashMap<Long, Location> impassableRoadLocations = new HashMap<>();
|
||||||
|
private HashMap<Long, Location> roadsToAvoid = new HashMap<>();
|
||||||
|
|
||||||
// Example
|
// Example
|
||||||
// {
|
// {
|
||||||
|
@ -88,6 +89,7 @@ public class RoutingConfiguration {
|
||||||
i.recalculateDistance = parseSilentFloat(getAttribute(i.router, "recalculateDistanceHelp"), i.recalculateDistance) ;
|
i.recalculateDistance = parseSilentFloat(getAttribute(i.router, "recalculateDistanceHelp"), i.recalculateDistance) ;
|
||||||
i.heuristicCoefficient = parseSilentFloat(getAttribute(i.router, "heuristicCoefficient"), i.heuristicCoefficient);
|
i.heuristicCoefficient = parseSilentFloat(getAttribute(i.router, "heuristicCoefficient"), i.heuristicCoefficient);
|
||||||
i.router.addImpassableRoads(impassableRoadLocations.keySet());
|
i.router.addImpassableRoads(impassableRoadLocations.keySet());
|
||||||
|
i.router.addImpassableRoads(roadsToAvoid.keySet());
|
||||||
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(i.router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(i.router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
||||||
int desirable = parseSilentInt(getAttribute(i.router, "memoryLimitInMB"), 0);
|
int desirable = parseSilentInt(getAttribute(i.router, "memoryLimitInMB"), 0);
|
||||||
if(desirable != 0) {
|
if(desirable != 0) {
|
||||||
|
@ -115,6 +117,13 @@ public class RoutingConfiguration {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addMultipleImpassableRoads(Map<RouteDataObject, Location> ir) {
|
||||||
|
for (Map.Entry<RouteDataObject, Location> r : ir.entrySet()) {
|
||||||
|
if (!impassableRoadLocations.containsKey(r.getKey().id)){
|
||||||
|
impassableRoadLocations.put(r.getKey().id, r.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String getAttribute(VehicleRouter router, String propertyName) {
|
private String getAttribute(VehicleRouter router, String propertyName) {
|
||||||
if (router.containsAttribute(propertyName)) {
|
if (router.containsAttribute(propertyName)) {
|
||||||
|
@ -140,6 +149,10 @@ public class RoutingConfiguration {
|
||||||
public void removeImpassableRoad(RouteDataObject obj) {
|
public void removeImpassableRoad(RouteDataObject obj) {
|
||||||
impassableRoadLocations.remove(obj.id);
|
impassableRoadLocations.remove(obj.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearImpassableRoads() {
|
||||||
|
impassableRoadLocations.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int parseSilentInt(String t, int v) {
|
public static int parseSilentInt(String t, int v) {
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class CurrentPositionHelper {
|
||||||
public boolean getMultipleRouteSegmentsIds(List<Location> points,
|
public boolean getMultipleRouteSegmentsIds(List<Location> points,
|
||||||
@Nullable ApplicationMode appMode,
|
@Nullable ApplicationMode appMode,
|
||||||
boolean cancelPreviousSearch,
|
boolean cancelPreviousSearch,
|
||||||
ResultMatcher<Map<Long, Location>> result) {
|
ResultMatcher<Map<RouteDataObject, Location>> result) {
|
||||||
return scheduleMultipleRouteSegmentFind(points, false, true, cancelPreviousSearch, null, result, appMode);
|
return scheduleMultipleRouteSegmentFind(points, false, true, cancelPreviousSearch, null, result, appMode);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ public class CurrentPositionHelper {
|
||||||
final boolean allowEmptyNames,
|
final boolean allowEmptyNames,
|
||||||
final boolean cancelPreviousSearch,
|
final boolean cancelPreviousSearch,
|
||||||
@Nullable final ResultMatcher<GeocodingResult> geoCoding,
|
@Nullable final ResultMatcher<GeocodingResult> geoCoding,
|
||||||
@Nullable final ResultMatcher<Map<Long, Location>> result,
|
@Nullable final ResultMatcher<Map<RouteDataObject, Location>> result,
|
||||||
@Nullable final ApplicationMode appMode) {
|
@Nullable final ApplicationMode appMode) {
|
||||||
boolean res = false;
|
boolean res = false;
|
||||||
if (points.get(0) != null) {
|
if (points.get(0) != null) {
|
||||||
|
@ -158,7 +158,7 @@ public class CurrentPositionHelper {
|
||||||
@Nullable ResultMatcher<GeocodingResult> geoCoding,
|
@Nullable ResultMatcher<GeocodingResult> geoCoding,
|
||||||
boolean storeFound,
|
boolean storeFound,
|
||||||
boolean allowEmptyNames,
|
boolean allowEmptyNames,
|
||||||
@Nullable final ResultMatcher<Map<Long, Location>> result,
|
@Nullable final ResultMatcher<Map<RouteDataObject, Location>> result,
|
||||||
@Nullable ApplicationMode appMode,
|
@Nullable ApplicationMode appMode,
|
||||||
int request,
|
int request,
|
||||||
@NonNull AtomicInteger requestNumber,
|
@NonNull AtomicInteger requestNumber,
|
||||||
|
@ -168,7 +168,7 @@ public class CurrentPositionHelper {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map<Long, Location> gr = runUpdateInThreadBatch(points,
|
final Map<RouteDataObject, Location> gr = runUpdateInThreadBatch(points,
|
||||||
geoCoding != null, allowEmptyNames, appMode);
|
geoCoding != null, allowEmptyNames, appMode);
|
||||||
|
|
||||||
if(result != null) {
|
if(result != null) {
|
||||||
|
@ -183,7 +183,7 @@ public class CurrentPositionHelper {
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Map<Long, Location> runUpdateInThreadBatch(List<Location> points,
|
private Map<RouteDataObject, Location> runUpdateInThreadBatch(List<Location> points,
|
||||||
boolean geocoding,
|
boolean geocoding,
|
||||||
boolean allowEmptyNames,
|
boolean allowEmptyNames,
|
||||||
@Nullable ApplicationMode appMode) {
|
@Nullable ApplicationMode appMode) {
|
||||||
|
|
|
@ -884,7 +884,7 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
public boolean getMultipleRouteSegmentsIds(List<net.osmand.Location> points,
|
public boolean getMultipleRouteSegmentsIds(List<net.osmand.Location> points,
|
||||||
@Nullable ApplicationMode appMode,
|
@Nullable ApplicationMode appMode,
|
||||||
boolean cancelPreviousSearch,
|
boolean cancelPreviousSearch,
|
||||||
ResultMatcher<Map<Long, net.osmand.Location>> result) {
|
ResultMatcher<Map<RouteDataObject, net.osmand.Location>> result) {
|
||||||
return currentPositionHelper.getMultipleRouteSegmentsIds(points, appMode, cancelPreviousSearch, result);
|
return currentPositionHelper.getMultipleRouteSegmentsIds(points, appMode, cancelPreviousSearch, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2615,6 +2615,7 @@ public class OsmandSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private abstract class MapPointsStorage {
|
private abstract class MapPointsStorage {
|
||||||
|
|
||||||
protected String pointsKey;
|
protected String pointsKey;
|
||||||
|
@ -2809,6 +2810,7 @@ public class OsmandSettings {
|
||||||
return mImpassableRoadsStorage.insertPoint(latitude, longitude, null, 0);
|
return mImpassableRoadsStorage.insertPoint(latitude, longitude, null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean removeImpassableRoad(int index) {
|
public boolean removeImpassableRoad(int index) {
|
||||||
return mImpassableRoadsStorage.deletePoint(index);
|
return mImpassableRoadsStorage.deletePoint(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -979,7 +979,7 @@ public class MapActivityActions implements DialogProvider {
|
||||||
@Override
|
@Override
|
||||||
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
|
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
|
||||||
app.logEvent("drawer_import_avoid_roads");
|
app.logEvent("drawer_import_avoid_roads");
|
||||||
app.getAvoidRoadsHelper().testRun();
|
app.getAvoidRoadsHelper().showUrlDialog(mapActivity);
|
||||||
// app.getAvoidRoadsHelper().testRunDownload();
|
// app.getAvoidRoadsHelper().testRunDownload();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
package net.osmand.plus.avoidroads;
|
package net.osmand.plus.avoidroads;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
@ -12,11 +17,14 @@ import net.osmand.Location;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.ResultMatcher;
|
import net.osmand.ResultMatcher;
|
||||||
import net.osmand.binary.RouteDataObject;
|
import net.osmand.binary.RouteDataObject;
|
||||||
|
import net.osmand.data.PointDescription;
|
||||||
import net.osmand.data.QuadRect;
|
import net.osmand.data.QuadRect;
|
||||||
import net.osmand.data.QuadTree;
|
import net.osmand.data.QuadTree;
|
||||||
import net.osmand.osm.io.NetworkUtils;
|
import net.osmand.osm.io.NetworkUtils;
|
||||||
import net.osmand.plus.ApplicationMode;
|
import net.osmand.plus.ApplicationMode;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.activities.MapActivity;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
@ -28,9 +36,11 @@ import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -41,12 +51,14 @@ public class AvoidRoadsHelper {
|
||||||
|
|
||||||
private static final Log LOG = PlatformUtil.getLog(AvoidRoadsHelper.class);
|
private static final Log LOG = PlatformUtil.getLog(AvoidRoadsHelper.class);
|
||||||
|
|
||||||
public static final int FROM_URL = 101;
|
private static final int FROM_URL = 101;
|
||||||
public static final int FROM_STORAGE = 100;
|
private static final int FROM_STORAGE = 100;
|
||||||
|
|
||||||
|
private static final int SOURCE = FROM_STORAGE;
|
||||||
|
|
||||||
private static boolean saveResultToFile = true;
|
private static boolean saveResultToFile = true;
|
||||||
|
|
||||||
private final Map<Long, Location> roadsToAvoid;
|
private final Map<RouteDataObject, Location> roadsToAvoid;
|
||||||
private final List<Location> parsedPoints;
|
private final List<Location> parsedPoints;
|
||||||
|
|
||||||
private final OsmandApplication app;
|
private final OsmandApplication app;
|
||||||
|
@ -55,9 +67,14 @@ public class AvoidRoadsHelper {
|
||||||
|
|
||||||
private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
|
private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
|
private WeakReference<MapActivity> mapActivityWeakReference = null;
|
||||||
|
|
||||||
// String inputFileName = "points_500.json";
|
// String inputFileName = "points_500.json";
|
||||||
// String inputFileName = "point_100.json";
|
// String inputFileName = "point_100.json";
|
||||||
String inputFileName = "points_10.json";
|
String inputFileName = "points_10.json";
|
||||||
|
String testurl = "https://gist.githubusercontent.com/MadWasp79/1238d8878792572e343eb2e296c3c7f5/raw/494f872425993797c3a3bc79a4ec82039db6ee46/point_100.json";
|
||||||
|
// String testurl = "https://gist.githubusercontent.com/MadWasp79/45f362ea48e9e8edd1593113593993c5/raw/6e817fb3bc7eaeaa3eda24847fde4855eb22485d/points_500.json";
|
||||||
|
|
||||||
|
|
||||||
public AvoidRoadsHelper(final OsmandApplication app) {
|
public AvoidRoadsHelper(final OsmandApplication app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
@ -68,84 +85,129 @@ public class AvoidRoadsHelper {
|
||||||
completionCallback = new CompletionCallback() {
|
completionCallback = new CompletionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onRDOSearchComplete() {
|
public void onRDOSearchComplete() {
|
||||||
|
|
||||||
if (saveResultToFile) {
|
if (saveResultToFile) {
|
||||||
File out = new File (app.getAppPath(IndexConstants.AVOID_ROADS_DIR).getAbsolutePath() + "/"
|
File out = new File (app.getAppPath(IndexConstants.AVOID_ROADS_DIR).getAbsolutePath() + "/"
|
||||||
+ "processed_ids.json");
|
+ "processed_ids.json");
|
||||||
saveRoadsToJson(roadsToAvoid, out);
|
saveRoadsToJson(roadsToAvoid, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
app.getAvoidRoadsHelper().addResultToImpassibleRoads(roadsToAvoid);
|
||||||
|
|
||||||
|
MapActivity mapActivity = mapActivityWeakReference.get();
|
||||||
|
if (mapActivity != null) {
|
||||||
|
app.getAvoidRoadsHelper().showParsingCompleteDialog(mapActivity);
|
||||||
|
} else {
|
||||||
|
app.showToastMessage("Successfully processed roads to avoid. Applying result to routing parameters");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPointsParsed(List<Location> result) {
|
public void onPointsParsed(List<Location> result) {
|
||||||
|
app.getRoutingConfig().clearImpassableRoads();
|
||||||
|
parsedPoints.clear();
|
||||||
parsedPoints.addAll(result);
|
parsedPoints.addAll(result);
|
||||||
convertPointsToRDO(parsedPoints);
|
convertPointsToRDO(parsedPoints);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRun() {
|
public Map<RouteDataObject, Location> getRoadsToAvoid() {
|
||||||
// File in = new File(app.getAppPath(IndexConstants.AVOID_ROADS_DIR).getAbsolutePath() + "/" + inputFileName);
|
return roadsToAvoid;
|
||||||
// LOG.debug(String.format("Input json: %s", in.getAbsolutePath()));
|
|
||||||
// if (in.exists()) {
|
|
||||||
// loadJson(in.getAbsolutePath(), FROM_STORAGE);
|
|
||||||
// }
|
|
||||||
//String url = "https://gist.githubusercontent.com/MadWasp79/1238d8878792572e343eb2e296c3c7f5/raw/494f872425993797c3a3bc79a4ec82039db6ee46/point_100.json";
|
|
||||||
String url = "https://gist.githubusercontent.com/MadWasp79/45f362ea48e9e8edd1593113593993c5/raw/6e817fb3bc7eaeaa3eda24847fde4855eb22485d/points_500.json";
|
|
||||||
LOG.debug(String.format("Loading json from url: %s", url));
|
|
||||||
loadJson(url, FROM_URL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRunDownload() {
|
public void addResultToImpassibleRoads(Map<RouteDataObject, Location> result) {
|
||||||
String url = "https://gist.githubusercontent.com/MadWasp79/1238d8878792572e343eb2e296c3c7f5/raw/494f872425993797c3a3bc79a4ec82039db6ee46/point_100.json";
|
app.getRoutingConfig().addMultipleImpassableRoads(result);
|
||||||
LOG.debug(String.format("Loading json from url: %s", url));
|
|
||||||
loadJson(url, FROM_URL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showUrlDialog(final MapActivity activity) {
|
||||||
public void convertPointsToRDO(final List<Location> parsedPoints) {
|
mapActivityWeakReference = new WeakReference<MapActivity>(activity);
|
||||||
final Map<Long, Location> avoidedRoads = new HashMap<>();
|
final AlertDialog.Builder db = new AlertDialog.Builder(activity);
|
||||||
final long timeStart = System.currentTimeMillis();
|
db.setTitle("Process Avoid Points");
|
||||||
final int[] count = {0};
|
db.setMessage("Enter url to JSON file. \"Parse\" to continue:");
|
||||||
this.roadsToAvoid.clear();
|
final EditText urlInputString = new EditText(activity);
|
||||||
// for (final Location point : parsedPoints) {
|
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
|
||||||
//
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
// app.getLocationProvider().getRouteSegment(point, appMode, false, new ResultMatcher<RouteDataObject>() {
|
LinearLayout.LayoutParams.MATCH_PARENT);
|
||||||
// @Override
|
urlInputString.setLayoutParams(lp);
|
||||||
// public boolean publish(RouteDataObject result) {
|
urlInputString.setText(testurl);
|
||||||
// count[0]++;
|
// urlInputString.selectAll();
|
||||||
// if (result == null) {
|
db.setView(urlInputString);
|
||||||
// LOG.error("Error! Find no result for point []");
|
db.setIcon(R.drawable.map_pin_avoid_road);
|
||||||
// } else {
|
db.setPositiveButton("Parse", new DialogInterface.OnClickListener() {
|
||||||
// avoidedRoads.put(result.id, point);
|
|
||||||
// }
|
|
||||||
// if (count[0] == parsedPoints.size()) {
|
|
||||||
// completionCallback.onRDOSearchComplete();
|
|
||||||
// }
|
|
||||||
// if (count[0]%10 == 0) {
|
|
||||||
// app.showShortToastMessage(String.format("Found %d roads", count[0]));
|
|
||||||
// }
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public boolean isCancelled() {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
app.getLocationProvider().getMultipleRouteSegmentsIds(parsedPoints, appMode, false,
|
|
||||||
new ResultMatcher<Map<Long, Location>>() {
|
|
||||||
@Override
|
@Override
|
||||||
public boolean publish(Map<Long, Location> result) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
String url = urlInputString.getText().toString();
|
||||||
|
boolean isValidJsonUrl = false;
|
||||||
|
try {
|
||||||
|
URL test = new URL(url);
|
||||||
|
if (url.endsWith(".json")) {
|
||||||
|
isValidJsonUrl = true;
|
||||||
|
}
|
||||||
|
} catch (MalformedURLException e){
|
||||||
|
isValidJsonUrl = false;
|
||||||
|
app.showShortToastMessage("Enter valid JSON url");
|
||||||
|
}
|
||||||
|
if (isValidJsonUrl) {
|
||||||
|
app.showShortToastMessage("Downloading JSON");
|
||||||
|
app.getAvoidRoadsHelper().loadJson(url, FROM_URL);
|
||||||
|
// dialog.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
db.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
db.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showParsingCompleteDialog(final MapActivity activity) {
|
||||||
|
final AlertDialog.Builder db = new AlertDialog.Builder(activity);
|
||||||
|
db.setTitle("Avoid Points");
|
||||||
|
db.setMessage("Parsing complete, applying result to routing config!");
|
||||||
|
db.setIcon(R.drawable.map_pin_avoid_road);
|
||||||
|
db.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
db.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRun() {
|
||||||
|
String in = "";
|
||||||
|
switch (SOURCE) {
|
||||||
|
case FROM_STORAGE:
|
||||||
|
in = app.getAppPath(IndexConstants.AVOID_ROADS_DIR).getAbsolutePath() + "/" + inputFileName;
|
||||||
|
LOG.debug(String.format("Input json from file: %s", in));
|
||||||
|
break;
|
||||||
|
case FROM_URL:
|
||||||
|
LOG.debug(String.format("Loading json from url: %s", in));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadJson(in, SOURCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convertPointsToRDO(final List<Location> parsedPoints) {
|
||||||
|
this.roadsToAvoid.clear();
|
||||||
|
app.getLocationProvider().getMultipleRouteSegmentsIds(parsedPoints, appMode, false,
|
||||||
|
new ResultMatcher<Map<RouteDataObject, Location>>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean publish(Map<RouteDataObject, Location> result) {
|
||||||
if (result == null || result.isEmpty()) {
|
if (result == null || result.isEmpty()) {
|
||||||
LOG.error("Error! No valid result");
|
LOG.error("Error! No valid result");
|
||||||
} else {
|
} else {
|
||||||
roadsToAvoid.putAll(result);
|
roadsToAvoid.putAll(result);
|
||||||
LOG.debug(String.format("Found %d road ids", result.size()));
|
LOG.debug(String.format("Found %d road ids", result.size()));
|
||||||
completionCallback.onRDOSearchComplete();
|
app.getAvoidRoadsHelper().completionCallback.onRDOSearchComplete();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -158,7 +220,7 @@ public class AvoidRoadsHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
private void loadJson(final String path, final int source) {
|
public void loadJson(final String path, final int source) {
|
||||||
new AsyncTask<Void, Void, List<Location>>() {
|
new AsyncTask<Void, Void, List<Location>>() {
|
||||||
@Override
|
@Override
|
||||||
protected List<Location> doInBackground(Void... voids) {
|
protected List<Location> doInBackground(Void... voids) {
|
||||||
|
@ -173,8 +235,12 @@ public class AvoidRoadsHelper {
|
||||||
is = connection.getInputStream();
|
is = connection.getInputStream();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Location> result = new ArrayList<>();
|
List<Location> result = new ArrayList<>();
|
||||||
parsePointsFromJson(is, result);
|
parseJson(is, result);
|
||||||
|
if (is != null) {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Error reading json !");
|
LOG.error("Error reading json !");
|
||||||
|
@ -193,14 +259,14 @@ public class AvoidRoadsHelper {
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(List<Location> result) {
|
protected void onPostExecute(List<Location> result) {
|
||||||
if (!Algorithms.isEmpty(result)) {
|
if (!Algorithms.isEmpty(result)) {
|
||||||
completionCallback.onPointsParsed(result);
|
app.getAvoidRoadsHelper().completionCallback.onPointsParsed(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.executeOnExecutor(singleThreadExecutor);
|
}.executeOnExecutor(singleThreadExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
private void saveRoadsToJson(final Map<Long, Location> roadsToAvoid, final File out) {
|
private void saveRoadsToJson(final Map<RouteDataObject, Location> roadsToAvoid, final File out) {
|
||||||
new AsyncTask<Void, Void, Void>() {
|
new AsyncTask<Void, Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... voids) {
|
protected Void doInBackground(Void... voids) {
|
||||||
|
@ -230,7 +296,7 @@ public class AvoidRoadsHelper {
|
||||||
}.executeOnExecutor(singleThreadExecutor);
|
}.executeOnExecutor(singleThreadExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parsePointsFromJson(InputStream is, List<Location> result) {
|
private void parseJson(InputStream is, List<Location> result) {
|
||||||
Gson gson = new Gson();
|
Gson gson = new Gson();
|
||||||
GeoJSON geoJSON = gson.fromJson(new BufferedReader(new InputStreamReader(is)), GeoJSON.class);
|
GeoJSON geoJSON = gson.fromJson(new BufferedReader(new InputStreamReader(is)), GeoJSON.class);
|
||||||
double minlat = 0 , maxlat = 0, minlon = 0, maxlon= 0;
|
double minlat = 0 , maxlat = 0, minlon = 0, maxlon= 0;
|
||||||
|
@ -260,7 +326,7 @@ public class AvoidRoadsHelper {
|
||||||
}
|
}
|
||||||
qt.queryInBox(qr, result);
|
qt.queryInBox(qr, result);
|
||||||
|
|
||||||
app.showShortToastMessage(String.format("Loaded and parsed %d avoid points from JSON. Starting segment search.", result.size()));
|
// app.showShortToastMessage(String.format("Loaded and parsed %d avoid points from JSON. Starting segment search.", result.size()));
|
||||||
LOG.debug(String.format("Points parsed: %d", result.size()));
|
LOG.debug(String.format("Points parsed: %d", result.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,10 +370,10 @@ public class AvoidRoadsHelper {
|
||||||
@Expose
|
@Expose
|
||||||
List<RoadToAvoid> roadsToAvoid;
|
List<RoadToAvoid> roadsToAvoid;
|
||||||
|
|
||||||
public RoadsToAvoid(Map<Long, Location> roads) {
|
public RoadsToAvoid(Map<RouteDataObject, Location> roads) {
|
||||||
this.roadsToAvoid = new ArrayList<>();
|
this.roadsToAvoid = new ArrayList<>();
|
||||||
for (Map.Entry<Long, Location> road : roads.entrySet()) {
|
for (Map.Entry<RouteDataObject, Location> road : roads.entrySet()) {
|
||||||
roadsToAvoid.add(new RoadToAvoid (road.getKey(), road.getValue().getLatitude(), road.getValue().getLongitude()));
|
roadsToAvoid.add(new RoadToAvoid (road.getKey().id >> 6, road.getValue().getLatitude(), road.getValue().getLongitude()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import android.graphics.PointF;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.osmand.Location;
|
||||||
import net.osmand.binary.RouteDataObject;
|
import net.osmand.binary.RouteDataObject;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.data.PointDescription;
|
import net.osmand.data.PointDescription;
|
||||||
|
@ -17,6 +18,7 @@ import net.osmand.data.RotatedTileBox;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.activities.MapActivity;
|
import net.osmand.plus.activities.MapActivity;
|
||||||
|
import net.osmand.plus.avoidroads.AvoidRoadsHelper;
|
||||||
import net.osmand.plus.helpers.AvoidSpecificRoads;
|
import net.osmand.plus.helpers.AvoidSpecificRoads;
|
||||||
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidSpecificRoadsCallback;
|
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidSpecificRoadsCallback;
|
||||||
import net.osmand.plus.views.ContextMenuLayer.ApplyMovedObjectCallback;
|
import net.osmand.plus.views.ContextMenuLayer.ApplyMovedObjectCallback;
|
||||||
|
@ -31,6 +33,7 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements
|
||||||
|
|
||||||
private final MapActivity activity;
|
private final MapActivity activity;
|
||||||
private AvoidSpecificRoads avoidSpecificRoads;
|
private AvoidSpecificRoads avoidSpecificRoads;
|
||||||
|
private AvoidRoadsHelper avoidRoadsHelper;
|
||||||
private ContextMenuLayer contextMenuLayer;
|
private ContextMenuLayer contextMenuLayer;
|
||||||
|
|
||||||
private Bitmap roadWorkIcon;
|
private Bitmap roadWorkIcon;
|
||||||
|
@ -44,6 +47,7 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements
|
||||||
@Override
|
@Override
|
||||||
public void initLayer(OsmandMapTileView view) {
|
public void initLayer(OsmandMapTileView view) {
|
||||||
avoidSpecificRoads = activity.getMyApplication().getAvoidSpecificRoads();
|
avoidSpecificRoads = activity.getMyApplication().getAvoidSpecificRoads();
|
||||||
|
avoidRoadsHelper = activity.getMyApplication().getAvoidRoadsHelper();
|
||||||
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
|
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
|
||||||
roadWorkIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_pin_avoid_road);
|
roadWorkIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_pin_avoid_road);
|
||||||
activePaint = new Paint();
|
activePaint = new Paint();
|
||||||
|
@ -79,6 +83,20 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements
|
||||||
drawPoint(canvas, tileBox, latitude, longitude, road != null);
|
drawPoint(canvas, tileBox, latitude, longitude, road != null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Map.Entry<RouteDataObject, Location> entry : avoidRoadsHelper.getRoadsToAvoid().entrySet()) {
|
||||||
|
RouteDataObject rdo = entry.getKey();
|
||||||
|
if (rdo != null && contextMenuLayer.getMoveableObject() instanceof RouteDataObject) {
|
||||||
|
RouteDataObject object = (RouteDataObject) contextMenuLayer.getMoveableObject();
|
||||||
|
if (object.id == rdo.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final double lat = entry.getValue().getLatitude();
|
||||||
|
final double lon = entry.getValue().getLongitude();
|
||||||
|
if (tileBox.containsLatLon(lat, lon)) {
|
||||||
|
drawPoint(canvas, tileBox, lat, lon, rdo != null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue