From bf7b067e8fbe619aac31d4c4aafc66cf00a598eb Mon Sep 17 00:00:00 2001 From: MadWasp79 Date: Wed, 11 Dec 2019 17:54:06 +0200 Subject: [PATCH] Avoid roads from file implementation. Parsing very slow. --- .../aidlapi/OsmAndCustomizationConstants.java | 1 + .../main/java/net/osmand/IndexConstants.java | 1 + .../net/osmand/binary/GeocodingUtilities.java | 47 ++++ .../osmand/router/RoutePlannerFrontEnd.java | 1 + .../net/osmand/router/RoutingContext.java | 2 +- .../router/RouteResultPreparationTest.java | 2 +- OsmAnd/res/values/strings.xml | 1 + .../src/net/osmand/plus/AppInitializer.java | 2 + .../osmand/plus/CurrentPositionHelper.java | 93 +++++++ .../osmand/plus/OsmAndLocationProvider.java | 10 +- .../net/osmand/plus/OsmandApplication.java | 6 + .../plus/activities/MapActivityActions.java | 13 + .../plus/avoidroads/AvoidRoadsHelper.java | 260 ++++++++++++++++++ .../plus/avoidroads/PointListJsonReader.java | 6 + .../plus/helpers/AvoidSpecificRoads.java | 8 +- .../plus/resources/ResourceManager.java | 4 + 16 files changed, 453 insertions(+), 4 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/avoidroads/AvoidRoadsHelper.java create mode 100644 OsmAnd/src/net/osmand/plus/avoidroads/PointListJsonReader.java diff --git a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java index a8c0aebb1e..ddccdc44c1 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java @@ -20,6 +20,7 @@ public interface OsmAndCustomizationConstants { String DRAWER_HELP_ID = DRAWER_ITEM_ID_SCHEME + "help"; String DRAWER_BUILDS_ID = DRAWER_ITEM_ID_SCHEME + "builds"; String DRAWER_DIVIDER_ID = DRAWER_ITEM_ID_SCHEME + "divider"; + String DRAWER_AVOID_ID = DRAWER_ITEM_ID_SCHEME + "avoid_roads"; // Configure Map: String CONFIGURE_MAP_ITEM_ID_SCHEME = "map.configure."; diff --git a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java index 2c2802af69..c7f7c0a9bb 100644 --- a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java +++ b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java @@ -71,4 +71,5 @@ public class IndexConstants { public static final String SETTINGS_DIR = "settings/"; //$NON-NLS-1$ public static final String TEMP_DIR = "temp/"; public static final String ROUTING_PROFILES_DIR = "routing/"; + public static final String AVOID_ROADS_DIR = "avoidRoads/"; } diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java b/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java index ddcd137d92..6b696dc900 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java @@ -1,5 +1,6 @@ package net.osmand.binary; +import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; import net.osmand.CollatorStringMatcher.StringMatcherMode; @@ -25,9 +26,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -140,6 +143,50 @@ public class GeocodingUtilities { } } + public Map multipleReverseGeocodingSearch(RoutingContext ctx, List points, boolean allowEmptyNames) throws IOException { + RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd(); + Map result = new HashMap<>(); + for (Location point : points) { + List lst = new ArrayList<>(); + List listR = new ArrayList<>(); + rp.findRouteSegment(point.getLatitude(), point.getLongitude(), ctx, listR); + double distSquare = 0; + TLongHashSet set = new TLongHashSet(); + Set streetNames = new HashSet(); + for (RouteSegmentPoint p : listR) { + RouteDataObject road = p.getRoad(); + if (!set.add(road.getId())) { + continue; + } + String name = Algorithms.isEmpty(road.getName()) ? road.getRef("", false, true) : road.getName(); + if (allowEmptyNames || !Algorithms.isEmpty(name)) { + if (distSquare == 0 || distSquare > p.distSquare) { + distSquare = p.distSquare; + } + GeocodingResult sr = new GeocodingResult(); + sr.searchPoint = new LatLon(point.getLatitude(), point.getLongitude()); + sr.streetName = name == null ? "" : name; + sr.point = p; + sr.connectionPoint = new LatLon(MapUtils.get31LatitudeY(p.preciseY), MapUtils.get31LongitudeX(p.preciseX)); + sr.regionFP = road.region.getFilePointer(); + sr.regionLen = road.region.getLength(); + if (streetNames.add(sr.streetName)) { + lst.add(sr); + } + } + if (p.distSquare > STOP_SEARCHING_STREET_WITH_MULTIPLIER_RADIUS * STOP_SEARCHING_STREET_WITH_MULTIPLIER_RADIUS && + distSquare != 0 && p.distSquare > THRESHOLD_MULTIPLIER_SKIP_STREETS_AFTER * distSquare) { + break; + } + if (p.distSquare > STOP_SEARCHING_STREET_WITHOUT_MULTIPLIER_RADIUS * STOP_SEARCHING_STREET_WITHOUT_MULTIPLIER_RADIUS) { + break; + } + } + Collections.sort(lst, GeocodingUtilities.DISTANCE_COMPARATOR); + result.put(lst.get(0).point.getRoad().id, point); + } + return result; + } public List reverseGeocodingSearch(RoutingContext ctx, double lat, double lon, boolean allowEmptyNames) throws IOException { RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd(); diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java index 7e7901888f..75eec7c499 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java @@ -9,6 +9,7 @@ import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; +import net.osmand.Location; import net.osmand.NativeLibrary; import net.osmand.PlatformUtil; import net.osmand.binary.BinaryMapIndexReader; diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java b/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java index 5f548408e6..a078817543 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java @@ -438,7 +438,7 @@ public class RoutingContext { long now = System.nanoTime(); for(int i = -t; i <= t; i++) { for(int j = -t; j <= t; j++) { - ts.add(getRoutingTile(x31 +i*coordinatesShift, y31 + j*coordinatesShift, 0, OPTION_IN_MEMORY_LOAD)); + ts.add(getRoutingTile(x31 +i*coordinatesShift, y31 + j*coordinatesShift, 0, OPTION_IN_MEMORY_LOAD)); } } TLongIterator it = ts.iterator(); diff --git a/OsmAnd-java/src/test/java/net/osmand/router/RouteResultPreparationTest.java b/OsmAnd-java/src/test/java/net/osmand/router/RouteResultPreparationTest.java index 658bf28243..acbf88a083 100644 --- a/OsmAnd-java/src/test/java/net/osmand/router/RouteResultPreparationTest.java +++ b/OsmAnd-java/src/test/java/net/osmand/router/RouteResultPreparationTest.java @@ -109,7 +109,7 @@ public class RouteResultPreparationTest { String expectedResult = expectedResults.get(segmentId); if (expectedResult != null) { if(!Algorithms.objectEquals(expectedResult, turnLanes) && - !Algorithms.objectEquals(expectedResult, lanes) && + !Algorithms.objectEquals(expectedResult, lanes) && !Algorithms.objectEquals(expectedResult, turn)) { Assert.assertEquals("Segment " + segmentId, expectedResult, turnLanes); } diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index c6fb37ba2a..99f69e35c4 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,7 @@ Thx - Hardy --> + Avoid roads [test] Add new profile \'%1$s\'? Include heading Save heading to each trackpoint while recording. diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index da84471693..90f1fa1e63 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -28,6 +28,7 @@ import net.osmand.plus.activities.DayNightHelper; import net.osmand.plus.activities.LocalIndexHelper; import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.activities.SavingTrackHelper; +import net.osmand.plus.avoidroads.AvoidRoadsHelper; import net.osmand.plus.base.MapViewTrackingUtilities; import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask; @@ -485,6 +486,7 @@ public class AppInitializer implements IProgress { app.daynightHelper = startupInit(new DayNightHelper(app), DayNightHelper.class); app.locationProvider = startupInit(new OsmAndLocationProvider(app), OsmAndLocationProvider.class); app.avoidSpecificRoads = startupInit(new AvoidSpecificRoads(app), AvoidSpecificRoads.class); + app.avoidRoadsHelper = startupInit(new AvoidRoadsHelper(app), AvoidRoadsHelper.class); app.savingTrackHelper = startupInit(new SavingTrackHelper(app), SavingTrackHelper.class); app.analyticsHelper = startupInit(new AnalyticsHelper(app), AnalyticsHelper.class); app.notificationHelper = startupInit(new NotificationHelper(app), NotificationHelper.class); diff --git a/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java b/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java index 5787b62a44..0dd8fe4987 100644 --- a/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java +++ b/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; @@ -56,6 +57,14 @@ public class CurrentPositionHelper { return scheduleRouteSegmentFind(loc, false, true, cancelPreviousSearch, null, result, appMode); } + public boolean getMultipleRouteSegmentsIds(List points, + @Nullable ApplicationMode appMode, + boolean cancelPreviousSearch, + ResultMatcher> result) { + return scheduleMultipleRouteSegmentFind(points, false, true, cancelPreviousSearch, null, result, appMode); + + } + public boolean getGeocodingResult(Location loc, ResultMatcher result) { return scheduleRouteSegmentFind(loc, false, false, true, result, null, null); } @@ -116,6 +125,90 @@ public class CurrentPositionHelper { } return res; } + + private boolean scheduleMultipleRouteSegmentFind(final List points, + final boolean storeFound, + final boolean allowEmptyNames, + final boolean cancelPreviousSearch, + @Nullable final ResultMatcher geoCoding, + @Nullable final ResultMatcher> result, + @Nullable final ApplicationMode appMode) { + boolean res = false; + if (points.get(0) != null) { + long requestKey = getRequestNumberKey(storeFound, allowEmptyNames); + AtomicInteger requestNumber = requestNumbersMap.get(requestKey); + if (requestNumber == null) { + requestNumber = new AtomicInteger(); + requestNumbersMap.put(requestKey, requestNumber); + } + final int request = requestNumber.incrementAndGet(); + final AtomicInteger finalRequestNumber = requestNumber; + singleThreadExecutor.submit(new Runnable() { + @Override + public void run() { + processMultipleGeocoding(points, geoCoding, storeFound, allowEmptyNames, result, appMode, request, finalRequestNumber, cancelPreviousSearch); + } + }); + res = true; + } + return res; + } + + private synchronized void processMultipleGeocoding(@NonNull List points, + @Nullable ResultMatcher geoCoding, + boolean storeFound, + boolean allowEmptyNames, + @Nullable final ResultMatcher> result, + @Nullable ApplicationMode appMode, + int request, + @NonNull AtomicInteger requestNumber, + boolean cancelPreviousSearch) { + + if (cancelPreviousSearch && request != requestNumber.get()) { + return; + } + + final Map gr = runUpdateInThreadBatch(points, + geoCoding != null, allowEmptyNames, appMode); + + if(result != null) { + app.runInUIThread(new Runnable() { + @Override + public void run() { + result.publish(gr == null || gr.isEmpty() ? null : gr); + } + }); + } + } + + + @Nullable + private Map runUpdateInThreadBatch(List points, + boolean geocoding, + boolean allowEmptyNames, + @Nullable ApplicationMode appMode) { + + List checkReaders = new ArrayList<>(); + for (Location loc : points) { + checkReaders.addAll(checkReaders(loc.getLatitude(), loc.getLongitude(), usedReaders)); + } + + if (appMode == null) { + appMode = app.getSettings().getApplicationMode(); + } + if (ctx == null || am != appMode || checkReaders != usedReaders) { + initCtx(app, checkReaders, appMode); + if (ctx == null) { + return null; + } + } + try { + return new GeocodingUtilities().multipleReverseGeocodingSearch(geocoding ? defCtx : ctx, points, allowEmptyNames); + } catch (Exception e) { + log.error("Exception happened during runUpdateInThread", e); + return null; + } + } private void initCtx(OsmandApplication app, List checkReaders, @NonNull ApplicationMode appMode) { diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java index 0474ea19b7..faa9632e68 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java @@ -7,6 +7,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import net.osmand.GeoidAltitudeCorrection; @@ -879,7 +880,14 @@ public class OsmAndLocationProvider implements SensorEventListener { ResultMatcher result) { return currentPositionHelper.getRouteSegment(loc, appMode, cancelPreviousSearch, result); } - + + public boolean getMultipleRouteSegmentsIds(List points, + @Nullable ApplicationMode appMode, + boolean cancelPreviousSearch, + ResultMatcher> result) { + return currentPositionHelper.getMultipleRouteSegmentsIds(points, appMode, cancelPreviousSearch, result); + } + public boolean getGeocodingResult(net.osmand.Location loc, ResultMatcher result) { return currentPositionHelper.getGeocodingResult(loc, result); } diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 5fc477f84a..5541203325 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -46,6 +46,7 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.api.SQLiteAPI; import net.osmand.plus.api.SQLiteAPIImpl; +import net.osmand.plus.avoidroads.AvoidRoadsHelper; import net.osmand.plus.base.MapViewTrackingUtilities; import net.osmand.plus.dialogs.CrashBottomSheetDialogFragment; import net.osmand.plus.dialogs.RateUsBottomSheetDialog; @@ -137,6 +138,7 @@ public class OsmandApplication extends MultiDexApplication { LockHelper lockHelper; SettingsHelper settingsHelper; GpxDbHelper gpxDbHelper; + AvoidRoadsHelper avoidRoadsHelper; private RoutingConfiguration.Builder routingConfig; private Locale preferredLocale = null; @@ -340,6 +342,10 @@ public class OsmandApplication extends MultiDexApplication { return settingsHelper; } + public AvoidRoadsHelper getAvoidRoadsHelper() { + return avoidRoadsHelper; + } + public synchronized DownloadIndexesThread getDownloadThread() { if(downloadIndexesThread == null) { downloadIndexesThread = new DownloadIndexesThread(this); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 6430a68197..71736a577a 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -83,6 +83,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_AVOID_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_MAP_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_SCREEN_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DASHBOARD_ID; @@ -971,6 +972,18 @@ public class MapActivityActions implements DialogProvider { } }).createItem()); + optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.test_avoid_roads_menu_item, mapActivity) + .setId(DRAWER_AVOID_ID) + .setIcon(R.drawable.ic_action_road_works_dark) + .setListener(new ItemClickListener() { + @Override + public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { + app.logEvent("drawer_import_avoid_roads"); + app.getAvoidRoadsHelper().testRun(); + return true; + } + }).createItem()); + //////////// Others OsmandPlugin.registerOptionsMenu(mapActivity, optionsMenuHelper); diff --git a/OsmAnd/src/net/osmand/plus/avoidroads/AvoidRoadsHelper.java b/OsmAnd/src/net/osmand/plus/avoidroads/AvoidRoadsHelper.java new file mode 100644 index 0000000000..b8e8c6593d --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/avoidroads/AvoidRoadsHelper.java @@ -0,0 +1,260 @@ +package net.osmand.plus.avoidroads; + +import android.annotation.SuppressLint; +import android.os.AsyncTask; + +import com.google.gson.Gson; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import net.osmand.IndexConstants; +import net.osmand.Location; +import net.osmand.PlatformUtil; +import net.osmand.ResultMatcher; +import net.osmand.plus.ApplicationMode; +import net.osmand.plus.OsmandApplication; +import net.osmand.util.Algorithms; + +import org.apache.commons.logging.Log; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class AvoidRoadsHelper { + + private static final Log LOG = PlatformUtil.getLog(AvoidRoadsHelper.class); + + private static int[] foundObjCount; + private static boolean saveResultToFile = true; + + private final Map roadsToAvoid; + private final List parsedPoints; + + private final OsmandApplication app; + private final ApplicationMode appMode; + private final RDOSearchCompleteCallback rdoSearchCompleteCallback; + + private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); + +// String inputFileName = "points_500.json"; + String inputFileName = "point_100.json"; +// String inputFileName = "points_10.json"; + + public AvoidRoadsHelper(final OsmandApplication app) { + this.app = app; + this.appMode = app.getSettings().getApplicationMode(); + this.roadsToAvoid = new LinkedHashMap<>(); + this.parsedPoints = new ArrayList<>(); + foundObjCount = new int[] {0, 0}; + + rdoSearchCompleteCallback = new RDOSearchCompleteCallback() { + @Override + public void onRDOSearchComplete() { + if (saveResultToFile) { + File out = new File (app.getAppPath(IndexConstants.AVOID_ROADS_DIR).getAbsolutePath() + "/" + + inputFileName.substring(0, inputFileName.lastIndexOf(".")) + "_out.json"); + saveRoadsToJson(roadsToAvoid, out); + } + } + + @Override + public void onPointsParsed(List result) { + parsedPoints.addAll(result); + convertPointsToRDO(parsedPoints); + + } + }; + } + + public void testRun() { + File in = new File(app.getAppPath(IndexConstants.AVOID_ROADS_DIR).getAbsolutePath() + "/" + inputFileName); + LOG.debug(String.format("Input json: %s", in.getAbsolutePath())); + if (in.exists()) { + parsePointsFromJson(in.getAbsolutePath()); + } + } + + @SuppressLint("StaticFieldLeak") + private void saveRoadsToJson(final Map roadsToAvoid, final File out) { + new AsyncTask() { + @Override + protected Void doInBackground(Void... voids) { + FileWriter fileWriter = null; + if (out.exists()) { + out.delete(); + } + try { + Gson gson = new Gson(); + fileWriter = new FileWriter(out, true); + gson.toJson(new RoadsToAvoid (roadsToAvoid), fileWriter); + fileWriter.close(); + LOG.info(String.format("File saved: %s ", out.getAbsolutePath())); + } catch (Exception e) { + //inform user about error + LOG.error("Error writing file"); + } finally { + if (fileWriter != null) { + try { + fileWriter.close(); + } catch (IOException e) { + } + } + } + return null; + } + }.executeOnExecutor(singleThreadExecutor); + + } + + public void convertPointsToRDO(List parsedPoints) { + + this.roadsToAvoid.clear(); + + app.getLocationProvider().getMultipleRouteSegmentsIds(parsedPoints, appMode, false, new ResultMatcher>() { + @Override + public boolean publish(Map result) { + + if (result == null || result.isEmpty()) { + LOG.error("Error! No valid result"); + } else { + roadsToAvoid.putAll(result); + LOG.debug(String.format("Found %d road ids", result.size())); + + rdoSearchCompleteCallback.onRDOSearchComplete(); + + } + return true; + } + @Override + public boolean isCancelled() { + return false; + } + }); + + } + + @SuppressLint("StaticFieldLeak") + private void parsePointsFromJson(final String pointsJson) { + + new AsyncTask>() { + @Override + protected List doInBackground(String... file) { + FileReader fr = null; + try { + List result = new ArrayList<>(); + fr = new FileReader(pointsJson); + Gson gson = new Gson(); + GeoJSON geoJSON = gson.fromJson(fr, GeoJSON.class); + for (Point o : geoJSON.points) { + Location ll = new Location("geoJSON"); + ll.setLatitude(o.geo.coordinates.get(1)); + ll.setLongitude(o.geo.coordinates.get(0)); + result.add(ll); + } + LOG.debug(String.format("Points parsed: %d", result.size())); + return result; + } catch (Exception e) { + LOG.error("Error reading json file!"); + } finally { + if (fr != null) { + try { + fr.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return null; + } + + @Override + protected void onPostExecute(List result) { + if (!Algorithms.isEmpty(result)) { + rdoSearchCompleteCallback.onPointsParsed(result); + } + } + }.executeOnExecutor(singleThreadExecutor); + } + + + + + interface RDOSearchCompleteCallback { + void onRDOSearchComplete(); + void onPointsParsed(List result); + } + + class GeoJSON { + + @SerializedName("type") + @Expose + String type; + @SerializedName("features") + @Expose + List points = null; + + } + + class Point { + + @SerializedName("type") + @Expose + String type; + @SerializedName("geometry") + @Expose + Geometry geo; + } + + + class Geometry { + + @SerializedName("type") + @Expose + String type; + @SerializedName("coordinates") + @Expose + List coordinates = null; + + } + + class RoadsToAvoid { + @SerializedName("avoid_roads") + @Expose + List roadsToAvoid; + + public RoadsToAvoid(Map roads) { + this.roadsToAvoid = new ArrayList<>(); + for (Map.Entry road : roads.entrySet()) { + roadsToAvoid.add(new RoadToAvoid (road.getKey(), road.getValue().getLatitude(), road.getValue().getLongitude())); + } + } + } + + class RoadToAvoid { + + @SerializedName("road_id") + @Expose + long roadId; + @SerializedName("lat") + @Expose + double lat; + @SerializedName("lon") + @Expose + double lon; + + RoadToAvoid(long roadId, double lat, double lon) { + this.roadId = roadId; + this.lat = lat; + this.lon = lon; + } + } + +} diff --git a/OsmAnd/src/net/osmand/plus/avoidroads/PointListJsonReader.java b/OsmAnd/src/net/osmand/plus/avoidroads/PointListJsonReader.java new file mode 100644 index 0000000000..33d330f1cb --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/avoidroads/PointListJsonReader.java @@ -0,0 +1,6 @@ +package net.osmand.plus.avoidroads; + +public class PointListJsonReader { + + +} diff --git a/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java b/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java index bee1b4fdf4..7071dfba4c 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java +++ b/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java @@ -19,6 +19,7 @@ import android.widget.Toast; import net.osmand.CallbackWithObject; import net.osmand.Location; +import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; import net.osmand.binary.RouteDataObject; import net.osmand.data.LatLon; @@ -27,6 +28,7 @@ import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.plus.RndPointGenerator; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.mapcontextmenu.MapContextMenu; @@ -34,12 +36,16 @@ import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.views.ContextMenuLayer; import net.osmand.util.MapUtils; +import org.apache.commons.logging.Log; + import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import java.util.Set; public class AvoidSpecificRoads { - + private static final Log LOG = PlatformUtil.getLog(AvoidSpecificRoads.class); private OsmandApplication app; private Map impassableRoads = new LinkedHashMap<>(); diff --git a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java index e36bfd1368..21d4551502 100644 --- a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java @@ -253,6 +253,10 @@ public class ResourceManager { if (!path.exists()) { path.mkdir(); } + path = context.getAppPath(IndexConstants.AVOID_ROADS_DIR); + if (!path.exists()) { + path.mkdir(); + } } public BitmapTilesCache getBitmapTilesCache() {