Avoid roads from file implementation. Parsing very slow.
This commit is contained in:
parent
06a17844f5
commit
bf7b067e8f
16 changed files with 453 additions and 4 deletions
|
@ -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.";
|
||||
|
|
|
@ -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/";
|
||||
}
|
||||
|
|
|
@ -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<Long, Location> multipleReverseGeocodingSearch(RoutingContext ctx, List<Location> points, boolean allowEmptyNames) throws IOException {
|
||||
RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd();
|
||||
Map<Long, Location> result = new HashMap<>();
|
||||
for (Location point : points) {
|
||||
List<GeocodingResult> lst = new ArrayList<>();
|
||||
List<RouteSegmentPoint> listR = new ArrayList<>();
|
||||
rp.findRouteSegment(point.getLatitude(), point.getLongitude(), ctx, listR);
|
||||
double distSquare = 0;
|
||||
TLongHashSet set = new TLongHashSet();
|
||||
Set<String> streetNames = new HashSet<String>();
|
||||
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<GeocodingResult> reverseGeocodingSearch(RoutingContext ctx, double lat, double lon, boolean allowEmptyNames) throws IOException {
|
||||
RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
<string name="test_avoid_roads_menu_item">Avoid roads [test]</string>
|
||||
<string name="add_new_profile_q">Add new profile \'%1$s\'?</string>
|
||||
<string name="save_heading">Include heading</string>
|
||||
<string name="save_heading_descr">Save heading to each trackpoint while recording.</string>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<Location> points,
|
||||
@Nullable ApplicationMode appMode,
|
||||
boolean cancelPreviousSearch,
|
||||
ResultMatcher<Map<Long, Location>> result) {
|
||||
return scheduleMultipleRouteSegmentFind(points, false, true, cancelPreviousSearch, null, result, appMode);
|
||||
|
||||
}
|
||||
|
||||
public boolean getGeocodingResult(Location loc, ResultMatcher<GeocodingResult> result) {
|
||||
return scheduleRouteSegmentFind(loc, false, false, true, result, null, null);
|
||||
}
|
||||
|
@ -116,6 +125,90 @@ public class CurrentPositionHelper {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private boolean scheduleMultipleRouteSegmentFind(final List<Location> points,
|
||||
final boolean storeFound,
|
||||
final boolean allowEmptyNames,
|
||||
final boolean cancelPreviousSearch,
|
||||
@Nullable final ResultMatcher<GeocodingResult> geoCoding,
|
||||
@Nullable final ResultMatcher<Map<Long, Location>> 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<Location> points,
|
||||
@Nullable ResultMatcher<GeocodingResult> geoCoding,
|
||||
boolean storeFound,
|
||||
boolean allowEmptyNames,
|
||||
@Nullable final ResultMatcher<Map<Long, Location>> result,
|
||||
@Nullable ApplicationMode appMode,
|
||||
int request,
|
||||
@NonNull AtomicInteger requestNumber,
|
||||
boolean cancelPreviousSearch) {
|
||||
|
||||
if (cancelPreviousSearch && request != requestNumber.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Map<Long, Location> 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<Long, Location> runUpdateInThreadBatch(List<Location> points,
|
||||
boolean geocoding,
|
||||
boolean allowEmptyNames,
|
||||
@Nullable ApplicationMode appMode) {
|
||||
|
||||
List<BinaryMapReaderResource> 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<BinaryMapReaderResource> checkReaders,
|
||||
@NonNull ApplicationMode appMode) {
|
||||
|
|
|
@ -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<RouteDataObject> result) {
|
||||
return currentPositionHelper.getRouteSegment(loc, appMode, cancelPreviousSearch, result);
|
||||
}
|
||||
|
||||
|
||||
public boolean getMultipleRouteSegmentsIds(List<net.osmand.Location> points,
|
||||
@Nullable ApplicationMode appMode,
|
||||
boolean cancelPreviousSearch,
|
||||
ResultMatcher<Map<Long, net.osmand.Location>> result) {
|
||||
return currentPositionHelper.getMultipleRouteSegmentsIds(points, appMode, cancelPreviousSearch, result);
|
||||
}
|
||||
|
||||
public boolean getGeocodingResult(net.osmand.Location loc, ResultMatcher<GeocodingResult> result) {
|
||||
return currentPositionHelper.getGeocodingResult(loc, result);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<ContextMenuItem> 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);
|
||||
|
||||
|
|
260
OsmAnd/src/net/osmand/plus/avoidroads/AvoidRoadsHelper.java
Normal file
260
OsmAnd/src/net/osmand/plus/avoidroads/AvoidRoadsHelper.java
Normal file
|
@ -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<Long, Location> roadsToAvoid;
|
||||
private final List<Location> 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<Location> 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<Long, Location> roadsToAvoid, final File out) {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@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<Location> parsedPoints) {
|
||||
|
||||
this.roadsToAvoid.clear();
|
||||
|
||||
app.getLocationProvider().getMultipleRouteSegmentsIds(parsedPoints, appMode, false, new ResultMatcher<Map<Long, Location>>() {
|
||||
@Override
|
||||
public boolean publish(Map<Long, Location> 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<String, Void, List<Location>>() {
|
||||
@Override
|
||||
protected List<Location> doInBackground(String... file) {
|
||||
FileReader fr = null;
|
||||
try {
|
||||
List<Location> 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<Location> result) {
|
||||
if (!Algorithms.isEmpty(result)) {
|
||||
rdoSearchCompleteCallback.onPointsParsed(result);
|
||||
}
|
||||
}
|
||||
}.executeOnExecutor(singleThreadExecutor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
interface RDOSearchCompleteCallback {
|
||||
void onRDOSearchComplete();
|
||||
void onPointsParsed(List<Location> result);
|
||||
}
|
||||
|
||||
class GeoJSON {
|
||||
|
||||
@SerializedName("type")
|
||||
@Expose
|
||||
String type;
|
||||
@SerializedName("features")
|
||||
@Expose
|
||||
List<Point> 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<Double> coordinates = null;
|
||||
|
||||
}
|
||||
|
||||
class RoadsToAvoid {
|
||||
@SerializedName("avoid_roads")
|
||||
@Expose
|
||||
List<RoadToAvoid> roadsToAvoid;
|
||||
|
||||
public RoadsToAvoid(Map<Long, Location> roads) {
|
||||
this.roadsToAvoid = new ArrayList<>();
|
||||
for (Map.Entry<Long, Location> 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package net.osmand.plus.avoidroads;
|
||||
|
||||
public class PointListJsonReader {
|
||||
|
||||
|
||||
}
|
|
@ -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<LatLon, RouteDataObject> impassableRoads = new LinkedHashMap<>();
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue