Merge remote-tracking branch 'origin/RoutePreparationMenu' into RoutePreparationMenu
This commit is contained in:
commit
1a440d73b5
16 changed files with 671 additions and 72 deletions
|
@ -10,6 +10,7 @@
|
||||||
- For wording and consistency, please note https://osmand.net/help-online?id=technical-articles#Creating_a_Consistent_User_Experience
|
- For wording and consistency, please note https://osmand.net/help-online?id=technical-articles#Creating_a_Consistent_User_Experience
|
||||||
Thx - Hardy
|
Thx - Hardy
|
||||||
-->
|
-->
|
||||||
|
<string name="app_mode_public_transport">Public transport</string>
|
||||||
<string name="avoid_roads_descr">Select road on the map or from the list below that you want to avoid during navigation:</string>
|
<string name="avoid_roads_descr">Select road on the map or from the list below that you want to avoid during navigation:</string>
|
||||||
<string name="show_along_the_route">Show along the route</string>
|
<string name="show_along_the_route">Show along the route</string>
|
||||||
<string name="simulate_navigation">Simulate navigation</string>
|
<string name="simulate_navigation">Simulate navigation</string>
|
||||||
|
|
|
@ -44,6 +44,7 @@ import net.osmand.plus.render.RendererRegistry;
|
||||||
import net.osmand.plus.resources.ResourceManager;
|
import net.osmand.plus.resources.ResourceManager;
|
||||||
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper;
|
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper;
|
||||||
import net.osmand.plus.routing.RoutingHelper;
|
import net.osmand.plus.routing.RoutingHelper;
|
||||||
|
import net.osmand.plus.routing.TransportRoutingHelper;
|
||||||
import net.osmand.plus.search.QuickSearchHelper;
|
import net.osmand.plus.search.QuickSearchHelper;
|
||||||
import net.osmand.plus.views.corenative.NativeCoreContext;
|
import net.osmand.plus.views.corenative.NativeCoreContext;
|
||||||
import net.osmand.plus.voice.CommandPlayer;
|
import net.osmand.plus.voice.CommandPlayer;
|
||||||
|
@ -458,6 +459,7 @@ public class AppInitializer implements IProgress {
|
||||||
app.applyTheme(app);
|
app.applyTheme(app);
|
||||||
app.inAppPurchaseHelper = startupInit(new InAppPurchaseHelper(app), InAppPurchaseHelper.class);
|
app.inAppPurchaseHelper = startupInit(new InAppPurchaseHelper(app), InAppPurchaseHelper.class);
|
||||||
app.poiTypes = startupInit(MapPoiTypes.getDefaultNoInit(), MapPoiTypes.class);
|
app.poiTypes = startupInit(MapPoiTypes.getDefaultNoInit(), MapPoiTypes.class);
|
||||||
|
app.transportRoutingHelper = startupInit(new TransportRoutingHelper(app), TransportRoutingHelper.class);
|
||||||
app.routingHelper = startupInit(new RoutingHelper(app), RoutingHelper.class);
|
app.routingHelper = startupInit(new RoutingHelper(app), RoutingHelper.class);
|
||||||
app.resourceManager = startupInit(new ResourceManager(app), ResourceManager.class);
|
app.resourceManager = startupInit(new ResourceManager(app), ResourceManager.class);
|
||||||
app.daynightHelper = startupInit(new DayNightHelper(app), DayNightHelper.class);
|
app.daynightHelper = startupInit(new DayNightHelper(app), DayNightHelper.class);
|
||||||
|
|
|
@ -57,6 +57,9 @@ public class ApplicationMode {
|
||||||
public static final ApplicationMode TRAIN = create(R.string.app_mode_train, "train").speed(25f, 40).
|
public static final ApplicationMode TRAIN = create(R.string.app_mode_train, "train").speed(25f, 40).
|
||||||
carLocation().icon(R.drawable.map_action_train, R.drawable.ic_action_train).reg();
|
carLocation().icon(R.drawable.map_action_train, R.drawable.ic_action_train).reg();
|
||||||
|
|
||||||
|
public static final ApplicationMode PUBLIC_TRANSPORT = create(R.string.app_mode_public_transport, "public_transport").
|
||||||
|
icon(R.drawable.map_action_bus_dark, R.drawable.ic_action_bus_dark).reg();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ApplicationMode[] exceptDefault = new ApplicationMode[]{CAR, PEDESTRIAN, BICYCLE, BOAT, AIRCRAFT, BUS, TRAIN};
|
ApplicationMode[] exceptDefault = new ApplicationMode[]{CAR, PEDESTRIAN, BICYCLE, BOAT, AIRCRAFT, BUS, TRAIN};
|
||||||
ApplicationMode[] exceptPedestrianAndDefault = new ApplicationMode[]{CAR, BICYCLE, BOAT, AIRCRAFT, BUS, TRAIN};
|
ApplicationMode[] exceptPedestrianAndDefault = new ApplicationMode[]{CAR, BICYCLE, BOAT, AIRCRAFT, BUS, TRAIN};
|
||||||
|
|
|
@ -57,6 +57,7 @@ import net.osmand.plus.render.RendererRegistry;
|
||||||
import net.osmand.plus.resources.ResourceManager;
|
import net.osmand.plus.resources.ResourceManager;
|
||||||
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper;
|
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper;
|
||||||
import net.osmand.plus.routing.RoutingHelper;
|
import net.osmand.plus.routing.RoutingHelper;
|
||||||
|
import net.osmand.plus.routing.TransportRoutingHelper;
|
||||||
import net.osmand.plus.search.QuickSearchHelper;
|
import net.osmand.plus.search.QuickSearchHelper;
|
||||||
import net.osmand.plus.voice.CommandPlayer;
|
import net.osmand.plus.voice.CommandPlayer;
|
||||||
import net.osmand.plus.wikivoyage.data.TravelDbHelper;
|
import net.osmand.plus.wikivoyage.data.TravelDbHelper;
|
||||||
|
@ -106,6 +107,7 @@ public class OsmandApplication extends MultiDexApplication {
|
||||||
PoiFiltersHelper poiFilters;
|
PoiFiltersHelper poiFilters;
|
||||||
MapPoiTypes poiTypes;
|
MapPoiTypes poiTypes;
|
||||||
RoutingHelper routingHelper;
|
RoutingHelper routingHelper;
|
||||||
|
TransportRoutingHelper transportRoutingHelper;
|
||||||
FavouritesDbHelper favorites;
|
FavouritesDbHelper favorites;
|
||||||
CommandPlayer player;
|
CommandPlayer player;
|
||||||
GpxSelectionHelper selectedGpxHelper;
|
GpxSelectionHelper selectedGpxHelper;
|
||||||
|
@ -402,6 +404,10 @@ public class OsmandApplication extends MultiDexApplication {
|
||||||
return routingHelper;
|
return routingHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TransportRoutingHelper getTransportRoutingHelper() {
|
||||||
|
return transportRoutingHelper;
|
||||||
|
}
|
||||||
|
|
||||||
public RoutingOptionsHelper getRoutingOptionsHelper() {
|
public RoutingOptionsHelper getRoutingOptionsHelper() {
|
||||||
return routingOptionsHelper;
|
return routingOptionsHelper;
|
||||||
}
|
}
|
||||||
|
|
|
@ -379,8 +379,8 @@ public class TargetPointsHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateRouteAndRefresh(boolean updateRoute) {
|
public void updateRouteAndRefresh(boolean updateRoute) {
|
||||||
if(updateRoute && ( routingHelper.isRouteBeingCalculated() || routingHelper.isRouteCalculated() ||
|
if(updateRoute && (routingHelper.isPublicTransportMode() || routingHelper.isRouteBeingCalculated() ||
|
||||||
routingHelper.isFollowingMode() || routingHelper.isRoutePlanningMode())) {
|
routingHelper.isRouteCalculated() || routingHelper.isFollowingMode() || routingHelper.isRoutePlanningMode())) {
|
||||||
updateRoutingHelper();
|
updateRoutingHelper();
|
||||||
}
|
}
|
||||||
updateListeners();
|
updateListeners();
|
||||||
|
@ -388,15 +388,14 @@ public class TargetPointsHelper {
|
||||||
|
|
||||||
private void updateRoutingHelper() {
|
private void updateRoutingHelper() {
|
||||||
LatLon start = settings.getPointToStart();
|
LatLon start = settings.getPointToStart();
|
||||||
Location lastKnownLocation = ctx.getLocationProvider().getLastKnownLocation();
|
LatLon finish = settings.getPointToNavigate();
|
||||||
List<LatLon> is = getIntermediatePointsLatLonNavigation();
|
List<LatLon> is = getIntermediatePointsLatLonNavigation();
|
||||||
|
Location lastKnownLocation = ctx.getLocationProvider().getLastKnownLocation();
|
||||||
if((routingHelper.isFollowingMode() && lastKnownLocation != null) || start == null) {
|
if((routingHelper.isFollowingMode() && lastKnownLocation != null) || start == null) {
|
||||||
routingHelper.setFinalAndCurrentLocation(settings.getPointToNavigate(),
|
routingHelper.setFinalAndCurrentLocation(finish, is, lastKnownLocation);
|
||||||
is, lastKnownLocation);
|
|
||||||
} else {
|
} else {
|
||||||
Location loc = wrap(start);
|
Location loc = wrap(start);
|
||||||
routingHelper.setFinalAndCurrentLocation(settings.getPointToNavigate(),
|
routingHelper.setFinalAndCurrentLocation(finish, is, loc);
|
||||||
is, loc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,9 +110,11 @@ import net.osmand.plus.measurementtool.MeasurementToolFragment;
|
||||||
import net.osmand.plus.measurementtool.NewGpxData;
|
import net.osmand.plus.measurementtool.NewGpxData;
|
||||||
import net.osmand.plus.render.RendererRegistry;
|
import net.osmand.plus.render.RendererRegistry;
|
||||||
import net.osmand.plus.resources.ResourceManager;
|
import net.osmand.plus.resources.ResourceManager;
|
||||||
|
import net.osmand.plus.routing.IRouteInformationListener;
|
||||||
import net.osmand.plus.routing.RoutingHelper;
|
import net.osmand.plus.routing.RoutingHelper;
|
||||||
import net.osmand.plus.routing.RoutingHelper.IRouteInformationListener;
|
|
||||||
import net.osmand.plus.routing.RoutingHelper.RouteCalculationProgressCallback;
|
import net.osmand.plus.routing.RoutingHelper.RouteCalculationProgressCallback;
|
||||||
|
import net.osmand.plus.routing.TransportRoutingHelper;
|
||||||
|
import net.osmand.plus.routing.TransportRoutingHelper.TransportRouteCalculationProgressCallback;
|
||||||
import net.osmand.plus.search.QuickSearchDialogFragment;
|
import net.osmand.plus.search.QuickSearchDialogFragment;
|
||||||
import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchTab;
|
import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchTab;
|
||||||
import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchType;
|
import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchType;
|
||||||
|
@ -439,7 +441,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
|
||||||
private void createProgressBarForRouting() {
|
private void createProgressBarForRouting() {
|
||||||
final ProgressBar pb = (ProgressBar) findViewById(R.id.map_horizontal_progress);
|
final ProgressBar pb = (ProgressBar) findViewById(R.id.map_horizontal_progress);
|
||||||
|
|
||||||
app.getRoutingHelper().setProgressBar(new RouteCalculationProgressCallback() {
|
final RouteCalculationProgressCallback progressCallback = new RouteCalculationProgressCallback() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
|
@ -501,6 +503,25 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
|
||||||
dashboardOnMap.routeCalculationFinished();
|
dashboardOnMap.routeCalculationFinished();
|
||||||
pb.setVisibility(View.GONE);
|
pb.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
app.getRoutingHelper().setProgressBar(progressCallback);
|
||||||
|
|
||||||
|
app.getTransportRoutingHelper().setProgressBar(new TransportRouteCalculationProgressCallback() {
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
progressCallback.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateProgress(int progress) {
|
||||||
|
progressCallback.updateProgress(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finish() {
|
||||||
|
progressCallback.finish();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import net.osmand.plus.R;
|
||||||
import net.osmand.plus.dashboard.DashboardOnMap;
|
import net.osmand.plus.dashboard.DashboardOnMap;
|
||||||
import net.osmand.plus.mapcontextmenu.MapContextMenu;
|
import net.osmand.plus.mapcontextmenu.MapContextMenu;
|
||||||
import net.osmand.plus.routing.RoutingHelper;
|
import net.osmand.plus.routing.RoutingHelper;
|
||||||
import net.osmand.plus.routing.RoutingHelper.IRouteInformationListener;
|
import net.osmand.plus.routing.IRouteInformationListener;
|
||||||
import net.osmand.plus.views.AnimateDraggingMapThread;
|
import net.osmand.plus.views.AnimateDraggingMapThread;
|
||||||
import net.osmand.plus.views.OsmandMapTileView;
|
import net.osmand.plus.views.OsmandMapTileView;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
|
@ -80,7 +80,7 @@ import net.osmand.plus.mapillary.MapillaryPlugin.MapillaryFirstDialogFragment;
|
||||||
import net.osmand.plus.osmedit.OsmNotesMenu;
|
import net.osmand.plus.osmedit.OsmNotesMenu;
|
||||||
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
||||||
import net.osmand.plus.routing.RoutingHelper;
|
import net.osmand.plus.routing.RoutingHelper;
|
||||||
import net.osmand.plus.routing.RoutingHelper.IRouteInformationListener;
|
import net.osmand.plus.routing.IRouteInformationListener;
|
||||||
import net.osmand.plus.srtmplugin.ContourLinesMenu;
|
import net.osmand.plus.srtmplugin.ContourLinesMenu;
|
||||||
import net.osmand.plus.srtmplugin.HillshadeMenu;
|
import net.osmand.plus.srtmplugin.HillshadeMenu;
|
||||||
import net.osmand.plus.srtmplugin.SRTMPlugin;
|
import net.osmand.plus.srtmplugin.SRTMPlugin;
|
||||||
|
|
|
@ -108,7 +108,8 @@ public class ResourceManager {
|
||||||
TRANSPORT,
|
TRANSPORT,
|
||||||
ADDRESS,
|
ADDRESS,
|
||||||
QUICK_SEARCH,
|
QUICK_SEARCH,
|
||||||
ROUTING
|
ROUTING,
|
||||||
|
TRANSPORT_ROUTING
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BinaryMapReaderResource {
|
public static class BinaryMapReaderResource {
|
||||||
|
@ -998,7 +999,20 @@ public class ResourceManager {
|
||||||
}
|
}
|
||||||
return readers.toArray(new BinaryMapIndexReader[readers.size()]);
|
return readers.toArray(new BinaryMapIndexReader[readers.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BinaryMapIndexReader[] getTransportRoutingMapFiles() {
|
||||||
|
List<BinaryMapIndexReader> readers = new ArrayList<>(fileReaders.size());
|
||||||
|
for(BinaryMapReaderResource r : fileReaders.values()) {
|
||||||
|
if(r.isUseForRouting()) {
|
||||||
|
BinaryMapIndexReader reader = r.getReader(BinaryMapReaderResourceType.TRANSPORT_ROUTING);
|
||||||
|
if (reader != null) {
|
||||||
|
readers.add(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return readers.toArray(new BinaryMapIndexReader[readers.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
public BinaryMapIndexReader[] getQuickSearchFiles() {
|
public BinaryMapIndexReader[] getQuickSearchFiles() {
|
||||||
List<BinaryMapIndexReader> readers = new ArrayList<>(fileReaders.size());
|
List<BinaryMapIndexReader> readers = new ArrayList<>(fileReaders.size());
|
||||||
for(BinaryMapReaderResource r : fileReaders.values()) {
|
for(BinaryMapReaderResource r : fileReaders.values()) {
|
||||||
|
|
|
@ -70,7 +70,7 @@ import net.osmand.plus.mapmarkers.MapMarkerSelectionFragment;
|
||||||
import net.osmand.plus.poi.PoiUIFilter;
|
import net.osmand.plus.poi.PoiUIFilter;
|
||||||
import net.osmand.plus.routing.RouteDirectionInfo;
|
import net.osmand.plus.routing.RouteDirectionInfo;
|
||||||
import net.osmand.plus.routing.RoutingHelper;
|
import net.osmand.plus.routing.RoutingHelper;
|
||||||
import net.osmand.plus.routing.RoutingHelper.IRouteInformationListener;
|
import net.osmand.plus.routing.IRouteInformationListener;
|
||||||
import net.osmand.plus.views.MapControlsLayer;
|
import net.osmand.plus.views.MapControlsLayer;
|
||||||
import net.osmand.router.GeneralRouter;
|
import net.osmand.router.GeneralRouter;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package net.osmand.plus.routing;
|
||||||
|
|
||||||
|
import net.osmand.ValueHolder;
|
||||||
|
|
||||||
|
public interface IRouteInformationListener {
|
||||||
|
|
||||||
|
void newRouteIsCalculated(boolean newRoute, ValueHolder<Boolean> showToast);
|
||||||
|
|
||||||
|
void routeWasCancelled();
|
||||||
|
|
||||||
|
void routeWasFinished();
|
||||||
|
}
|
|
@ -36,21 +36,12 @@ public class RoutingHelper {
|
||||||
|
|
||||||
private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(RoutingHelper.class);
|
private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(RoutingHelper.class);
|
||||||
|
|
||||||
public interface IRouteInformationListener {
|
|
||||||
|
|
||||||
void newRouteIsCalculated(boolean newRoute, ValueHolder<Boolean> showToast);
|
|
||||||
|
|
||||||
void routeWasCancelled();
|
|
||||||
|
|
||||||
void routeWasFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final float POSITION_TOLERANCE = 60;
|
private static final float POSITION_TOLERANCE = 60;
|
||||||
|
|
||||||
|
private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<>();
|
||||||
private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<WeakReference<IRouteInformationListener>>();
|
|
||||||
|
|
||||||
private OsmandApplication app;
|
private OsmandApplication app;
|
||||||
|
private TransportRoutingHelper transportRoutingHelper;
|
||||||
|
|
||||||
private boolean isFollowingMode = false;
|
private boolean isFollowingMode = false;
|
||||||
private boolean isRoutePlanningMode = false;
|
private boolean isRoutePlanningMode = false;
|
||||||
|
@ -99,9 +90,13 @@ public class RoutingHelper {
|
||||||
settings = context.getSettings();
|
settings = context.getSettings();
|
||||||
voiceRouter = new VoiceRouter(this, settings);
|
voiceRouter = new VoiceRouter(this, settings);
|
||||||
provider = new RouteProvider();
|
provider = new RouteProvider();
|
||||||
|
transportRoutingHelper = context.getTransportRoutingHelper();
|
||||||
setAppMode(settings.APPLICATION_MODE.get());
|
setAppMode(settings.APPLICATION_MODE.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TransportRoutingHelper getTransportRoutingHelper() {
|
||||||
|
return transportRoutingHelper;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isFollowingMode() {
|
public boolean isFollowingMode() {
|
||||||
return isFollowingMode;
|
return isFollowingMode;
|
||||||
|
@ -160,8 +155,6 @@ public class RoutingHelper {
|
||||||
this.isRoutePlanningMode = isRoutePlanningMode;
|
this.isRoutePlanningMode = isRoutePlanningMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public synchronized void setFinalAndCurrentLocation(LatLon finalLocation, List<LatLon> intermediatePoints, Location currentLocation){
|
public synchronized void setFinalAndCurrentLocation(LatLon finalLocation, List<LatLon> intermediatePoints, Location currentLocation){
|
||||||
RouteCalculationResult previousRoute = route;
|
RouteCalculationResult previousRoute = route;
|
||||||
clearCurrentRoute(finalLocation, intermediatePoints);
|
clearCurrentRoute(finalLocation, intermediatePoints);
|
||||||
|
@ -201,6 +194,7 @@ public class RoutingHelper {
|
||||||
this.lastProjection = null;
|
this.lastProjection = null;
|
||||||
setFollowingMode(false);
|
setFollowingMode(false);
|
||||||
}
|
}
|
||||||
|
transportRoutingHelper.clearCurrentRoute(newFinalLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void finishCurrentRoute() {
|
private synchronized void finishCurrentRoute() {
|
||||||
|
@ -265,7 +259,8 @@ public class RoutingHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addListener(IRouteInformationListener l){
|
public void addListener(IRouteInformationListener l){
|
||||||
listeners.add(new WeakReference<RoutingHelper.IRouteInformationListener>(l));
|
listeners.add(new WeakReference<>(l));
|
||||||
|
transportRoutingHelper.addListener(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeListener(IRouteInformationListener lt){
|
public boolean removeListener(IRouteInformationListener lt){
|
||||||
|
@ -278,6 +273,7 @@ public class RoutingHelper {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
transportRoutingHelper.removeListener(lt);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +301,11 @@ public class RoutingHelper {
|
||||||
private Location setCurrentLocation(Location currentLocation, boolean returnUpdatedLocation,
|
private Location setCurrentLocation(Location currentLocation, boolean returnUpdatedLocation,
|
||||||
RouteCalculationResult previousRoute, boolean targetPointsChanged) {
|
RouteCalculationResult previousRoute, boolean targetPointsChanged) {
|
||||||
Location locationProjection = currentLocation;
|
Location locationProjection = currentLocation;
|
||||||
if (finalLocation == null || currentLocation == null) {
|
if (isPublicTransportMode() && currentLocation != null) {
|
||||||
|
transportRoutingHelper.setFinalAndCurrentLocation(finalLocation,
|
||||||
|
new LatLon(currentLocation.getLatitude(), currentLocation.getLongitude()));
|
||||||
|
}
|
||||||
|
if (finalLocation == null || currentLocation == null || isPublicTransportMode()) {
|
||||||
isDeviatedFromRoute = false;
|
isDeviatedFromRoute = false;
|
||||||
return locationProjection;
|
return locationProjection;
|
||||||
}
|
}
|
||||||
|
@ -567,7 +567,7 @@ public class RoutingHelper {
|
||||||
|
|
||||||
|
|
||||||
private boolean identifyUTurnIsNeeded(Location currentLocation, float posTolerance) {
|
private boolean identifyUTurnIsNeeded(Location currentLocation, float posTolerance) {
|
||||||
if (finalLocation == null || currentLocation == null || !route.isCalculated()) {
|
if (finalLocation == null || currentLocation == null || !route.isCalculated() || isPublicTransportMode()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
boolean isOffRoute = false;
|
boolean isOffRoute = false;
|
||||||
|
@ -664,7 +664,7 @@ public class RoutingHelper {
|
||||||
app.runInUIThread(new Runnable() {
|
app.runInUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ValueHolder<Boolean> showToast = new ValueHolder<Boolean>();
|
ValueHolder<Boolean> showToast = new ValueHolder<>();
|
||||||
showToast.value = true;
|
showToast.value = true;
|
||||||
Iterator<WeakReference<IRouteInformationListener>> it = listeners.iterator();
|
Iterator<WeakReference<IRouteInformationListener>> it = listeners.iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
|
@ -937,7 +937,18 @@ public class RoutingHelper {
|
||||||
|
|
||||||
public void recalculateRouteDueToSettingsChange() {
|
public void recalculateRouteDueToSettingsChange() {
|
||||||
clearCurrentRoute(finalLocation, intermediatePoints);
|
clearCurrentRoute(finalLocation, intermediatePoints);
|
||||||
recalculateRouteInBackground(lastFixedLocation, finalLocation, intermediatePoints, currentGPXRoute, route, true, false);
|
if (isPublicTransportMode()) {
|
||||||
|
Location start = lastFixedLocation;
|
||||||
|
LatLon finish = finalLocation;
|
||||||
|
if (start != null && finish != null) {
|
||||||
|
transportRoutingHelper.setFinalAndCurrentLocation(finish,
|
||||||
|
new LatLon(start.getLatitude(), start.getLongitude()));
|
||||||
|
} else {
|
||||||
|
transportRoutingHelper.recalculateRouteDueToSettingsChange();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
recalculateRouteInBackground(lastFixedLocation, finalLocation, intermediatePoints, currentGPXRoute, route, true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recalculateRouteInBackground(final Location start, final LatLon end, final List<LatLon> intermediates,
|
private void recalculateRouteInBackground(final Location start, final LatLon end, final List<LatLon> intermediates,
|
||||||
|
@ -1060,6 +1071,9 @@ public class RoutingHelper {
|
||||||
void finish();
|
void finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPublicTransportMode() {
|
||||||
|
return mode == ApplicationMode.PUBLIC_TRANSPORT;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isRouteBeingCalculated(){
|
public boolean isRouteBeingCalculated(){
|
||||||
return currentRunningJob instanceof RouteRecalculationThread;
|
return currentRunningJob instanceof RouteRecalculationThread;
|
||||||
|
|
358
OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java
Normal file
358
OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java
Normal file
|
@ -0,0 +1,358 @@
|
||||||
|
package net.osmand.plus.routing;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import net.osmand.PlatformUtil;
|
||||||
|
import net.osmand.ValueHolder;
|
||||||
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
|
import net.osmand.data.LatLon;
|
||||||
|
import net.osmand.plus.OsmandApplication;
|
||||||
|
import net.osmand.plus.OsmandPlugin;
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.routing.RouteProvider.RouteService;
|
||||||
|
import net.osmand.router.RouteCalculationProgress;
|
||||||
|
import net.osmand.router.RoutingConfiguration;
|
||||||
|
import net.osmand.router.TransportRoutePlanner;
|
||||||
|
import net.osmand.router.TransportRoutePlanner.TransportRouteResult;
|
||||||
|
import net.osmand.router.TransportRoutePlanner.TransportRoutingContext;
|
||||||
|
import net.osmand.router.TransportRoutingConfiguration;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static net.osmand.plus.notifications.OsmandNotification.NotificationType.NAVIGATION;
|
||||||
|
|
||||||
|
public class TransportRoutingHelper {
|
||||||
|
|
||||||
|
private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(TransportRoutingHelper.class);
|
||||||
|
|
||||||
|
private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<>();
|
||||||
|
|
||||||
|
private OsmandApplication app;
|
||||||
|
|
||||||
|
private List<TransportRouteResult> routes;
|
||||||
|
private int currentRoute;
|
||||||
|
|
||||||
|
private LatLon startLocation;
|
||||||
|
private LatLon endLocation;
|
||||||
|
private boolean useSchedule;
|
||||||
|
|
||||||
|
private Thread currentRunningJob;
|
||||||
|
private String lastRouteCalcError;
|
||||||
|
private String lastRouteCalcErrorShort;
|
||||||
|
private long lastTimeEvaluatedRoute = 0;
|
||||||
|
|
||||||
|
private TransportRouteCalculationProgressCallback progressRoute;
|
||||||
|
|
||||||
|
public TransportRoutingHelper(@NonNull OsmandApplication app) {
|
||||||
|
this.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LatLon getStartLocation() {
|
||||||
|
return startLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LatLon getEndLocation() {
|
||||||
|
return endLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUseSchedule() {
|
||||||
|
return useSchedule;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUseSchedule(boolean useSchedule) {
|
||||||
|
this.useSchedule = useSchedule;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurrentRoute() {
|
||||||
|
return currentRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TransportRouteResult> getRoutes() {
|
||||||
|
return routes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentRoute(int currentRoute) {
|
||||||
|
this.currentRoute = currentRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addListener(IRouteInformationListener l){
|
||||||
|
listeners.add(new WeakReference<>(l));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeListener(IRouteInformationListener lt){
|
||||||
|
Iterator<WeakReference<IRouteInformationListener>> it = listeners.iterator();
|
||||||
|
while(it.hasNext()) {
|
||||||
|
WeakReference<IRouteInformationListener> ref = it.next();
|
||||||
|
IRouteInformationListener l = ref.get();
|
||||||
|
if(l == null || lt == l) {
|
||||||
|
it.remove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recalculateRouteDueToSettingsChange() {
|
||||||
|
clearCurrentRoute(endLocation);
|
||||||
|
recalculateRouteInBackground(startLocation, endLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recalculateRouteInBackground(LatLon start, LatLon end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TransportRouteCalculationParams params = new TransportRouteCalculationParams();
|
||||||
|
params.start = start;
|
||||||
|
params.end = end;
|
||||||
|
params.useSchedule = useSchedule;
|
||||||
|
params.type = RouteService.OSMAND;
|
||||||
|
params.ctx = app;
|
||||||
|
params.calculationProgress = new RouteCalculationProgress();
|
||||||
|
|
||||||
|
startRouteCalculationThread(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startRouteCalculationThread(TransportRouteCalculationParams params) {
|
||||||
|
synchronized (this) {
|
||||||
|
final Thread prevRunningJob = currentRunningJob;
|
||||||
|
RouteRecalculationThread newThread =
|
||||||
|
new RouteRecalculationThread("Calculating public transport route", params);
|
||||||
|
currentRunningJob = newThread;
|
||||||
|
startProgress(params);
|
||||||
|
updateProgress(params);
|
||||||
|
if (prevRunningJob != null) {
|
||||||
|
newThread.setWaitPrevJob(prevRunningJob);
|
||||||
|
}
|
||||||
|
currentRunningJob.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgressBar(TransportRouteCalculationProgressCallback progressRoute) {
|
||||||
|
this.progressRoute = progressRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startProgress(final TransportRouteCalculationParams params) {
|
||||||
|
final TransportRouteCalculationProgressCallback progressRoute = this.progressRoute;
|
||||||
|
if (progressRoute != null) {
|
||||||
|
progressRoute.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateProgress(final TransportRouteCalculationParams params) {
|
||||||
|
final TransportRouteCalculationProgressCallback progressRoute = this.progressRoute;
|
||||||
|
if (progressRoute != null) {
|
||||||
|
app.runInUIThread(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
RouteCalculationProgress calculationProgress = params.calculationProgress;
|
||||||
|
if (isRouteBeingCalculated()) {
|
||||||
|
float pr = calculationProgress.getLinearProgress();
|
||||||
|
progressRoute.updateProgress((int) pr);
|
||||||
|
Thread t = currentRunningJob;
|
||||||
|
if (t instanceof RouteRecalculationThread && ((RouteRecalculationThread) t).params != params) {
|
||||||
|
// different calculation started
|
||||||
|
} else {
|
||||||
|
updateProgress(params);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
progressRoute.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRouteBeingCalculated() {
|
||||||
|
return currentRunningJob instanceof RouteRecalculationThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setNewRoute(final List<TransportRouteResult> res) {
|
||||||
|
app.runInUIThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ValueHolder<Boolean> showToast = new ValueHolder<>();
|
||||||
|
showToast.value = true;
|
||||||
|
Iterator<WeakReference<IRouteInformationListener>> it = listeners.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
WeakReference<IRouteInformationListener> ref = it.next();
|
||||||
|
IRouteInformationListener l = ref.get();
|
||||||
|
if (l == null) {
|
||||||
|
it.remove();
|
||||||
|
} else {
|
||||||
|
l.newRouteIsCalculated(true, showToast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (showToast.value && OsmandPlugin.isDevelopment()) {
|
||||||
|
String msg = "Public transport routes calculated: " + res.size();
|
||||||
|
app.showToastMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setFinalAndCurrentLocation(LatLon finalLocation, LatLon currentLocation) {
|
||||||
|
clearCurrentRoute(finalLocation);
|
||||||
|
// to update route
|
||||||
|
setCurrentLocation(currentLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void clearCurrentRoute(LatLon newFinalLocation) {
|
||||||
|
routes = null;
|
||||||
|
app.getWaypointHelper().setNewRoute(new RouteCalculationResult(""));
|
||||||
|
app.runInUIThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Iterator<WeakReference<IRouteInformationListener>> it = listeners.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
WeakReference<IRouteInformationListener> ref = it.next();
|
||||||
|
IRouteInformationListener l = ref.get();
|
||||||
|
if (l == null) {
|
||||||
|
it.remove();
|
||||||
|
} else {
|
||||||
|
l.routeWasCancelled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.endLocation = newFinalLocation;
|
||||||
|
if (currentRunningJob instanceof RouteRecalculationThread) {
|
||||||
|
((RouteRecalculationThread) currentRunningJob).stopCalculation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCurrentLocation(LatLon currentLocation) {
|
||||||
|
if (endLocation == null || currentLocation == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
startLocation = currentLocation;
|
||||||
|
recalculateRouteInBackground(currentLocation, endLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showMessage(final String msg) {
|
||||||
|
app.runInUIThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
app.showToastMessage(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface TransportRouteCalculationProgressCallback {
|
||||||
|
|
||||||
|
void start();
|
||||||
|
|
||||||
|
void updateProgress(int progress);
|
||||||
|
|
||||||
|
void finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TransportRouteCalculationParams {
|
||||||
|
|
||||||
|
public LatLon start;
|
||||||
|
public LatLon end;
|
||||||
|
|
||||||
|
public OsmandApplication ctx;
|
||||||
|
public RouteService type;
|
||||||
|
public boolean useSchedule;
|
||||||
|
public RouteCalculationProgress calculationProgress;
|
||||||
|
public TransportRouteCalculationResultListener resultListener;
|
||||||
|
|
||||||
|
public interface TransportRouteCalculationResultListener {
|
||||||
|
void onRouteCalculated(List<TransportRouteResult> route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RouteRecalculationThread extends Thread {
|
||||||
|
|
||||||
|
private final TransportRouteCalculationParams params;
|
||||||
|
private Thread prevRunningJob;
|
||||||
|
|
||||||
|
public RouteRecalculationThread(String name, TransportRouteCalculationParams params) {
|
||||||
|
super(name);
|
||||||
|
this.params = params;
|
||||||
|
if (params.calculationProgress == null) {
|
||||||
|
params.calculationProgress = new RouteCalculationProgress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopCalculation() {
|
||||||
|
params.calculationProgress.isCancelled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TransportRouteResult> calculateRouteImpl(TransportRouteCalculationParams params) throws IOException {
|
||||||
|
RoutingConfiguration.Builder config = params.ctx.getDefaultRoutingConfig();
|
||||||
|
BinaryMapIndexReader[] files = params.ctx.getResourceManager().getTransportRoutingMapFiles();
|
||||||
|
|
||||||
|
TransportRoutingConfiguration cfg = new TransportRoutingConfiguration(config);
|
||||||
|
cfg.useSchedule = params.useSchedule;
|
||||||
|
TransportRoutePlanner planner = new TransportRoutePlanner();
|
||||||
|
TransportRoutingContext ctx = new TransportRoutingContext(cfg, files);
|
||||||
|
return planner.buildRoute(ctx, params.start, params.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
synchronized (TransportRoutingHelper.this) {
|
||||||
|
currentRunningJob = this;
|
||||||
|
}
|
||||||
|
if (prevRunningJob != null) {
|
||||||
|
while (prevRunningJob.isAlive()) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(50);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
synchronized (TransportRoutingHelper.this) {
|
||||||
|
currentRunningJob = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TransportRouteResult> res = null;
|
||||||
|
String error = null;
|
||||||
|
try {
|
||||||
|
res = calculateRouteImpl(params);
|
||||||
|
} catch (IOException e) {
|
||||||
|
error = e.getMessage();
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
if (params.calculationProgress.isCancelled) {
|
||||||
|
synchronized (TransportRoutingHelper.this) {
|
||||||
|
currentRunningJob = null;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
synchronized (TransportRoutingHelper.this) {
|
||||||
|
routes = res;
|
||||||
|
if (res != null) {
|
||||||
|
if (params.resultListener != null) {
|
||||||
|
params.resultListener.onRouteCalculated(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentRunningJob = null;
|
||||||
|
}
|
||||||
|
if (res != null) {
|
||||||
|
setNewRoute(res);
|
||||||
|
} else if (error != null) {
|
||||||
|
lastRouteCalcError = app.getString(R.string.error_calculating_route) + ":\n" + error;
|
||||||
|
lastRouteCalcErrorShort = app.getString(R.string.error_calculating_route);
|
||||||
|
showMessage(lastRouteCalcError);
|
||||||
|
} else {
|
||||||
|
lastRouteCalcError = app.getString(R.string.empty_route_calculated);
|
||||||
|
lastRouteCalcErrorShort = app.getString(R.string.empty_route_calculated);
|
||||||
|
showMessage(lastRouteCalcError);
|
||||||
|
}
|
||||||
|
app.getNotificationHelper().refreshNotification(NAVIGATION);
|
||||||
|
lastTimeEvaluatedRoute = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWaitPrevJob(Thread prevRunningJob) {
|
||||||
|
this.prevRunningJob = prevRunningJob;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import android.graphics.PorterDuff.Mode;
|
||||||
import android.graphics.PorterDuffColorFilter;
|
import android.graphics.PorterDuffColorFilter;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.util.Pair;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
|
@ -137,14 +138,25 @@ public abstract class OsmandMapLayer {
|
||||||
return x >= lx && x <= rx && y >= ty && y <= by;
|
return x >= lx && x <= rx && y >= ty && y <= by;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int calculatePath(RotatedTileBox tb, TIntArrayList xs, TIntArrayList ys, Path path) {
|
public int calculatePath(RotatedTileBox tb, TIntArrayList xs, TIntArrayList ys, Path path) {
|
||||||
|
List<Pair<Path, Integer>> paths = new ArrayList<>();
|
||||||
|
int res = calculatePath(tb, xs, ys, null, paths);
|
||||||
|
if (paths.size() > 0) {
|
||||||
|
path.addPath(paths.get(0).first);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int calculatePath(RotatedTileBox tb, TIntArrayList xs, TIntArrayList ys, List<Integer> colors, List<Pair<Path, Integer>> paths) {
|
||||||
boolean segmentStarted = false;
|
boolean segmentStarted = false;
|
||||||
int prevX = xs.get(0);
|
int prevX = xs.get(0);
|
||||||
int prevY = ys.get(0);
|
int prevY = ys.get(0);
|
||||||
int height = tb.getPixHeight();
|
int height = tb.getPixHeight();
|
||||||
int width = tb.getPixWidth();
|
int width = tb.getPixWidth();
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
boolean hasColors = colors != null && colors.size() == xs.size();
|
||||||
|
int color = hasColors ? colors.get(0) : 0;
|
||||||
|
Path path = new Path();
|
||||||
boolean prevIn = isIn(prevX, prevY, 0, 0, width, height);
|
boolean prevIn = isIn(prevX, prevY, 0, 0, width, height);
|
||||||
for (int i = 1; i < xs.size(); i++) {
|
for (int i = 1; i < xs.size(); i++) {
|
||||||
int currX = xs.get(i);
|
int currX = xs.get(i);
|
||||||
|
@ -186,6 +198,21 @@ public abstract class OsmandMapLayer {
|
||||||
prevIn = currIn;
|
prevIn = currIn;
|
||||||
prevX = currX;
|
prevX = currX;
|
||||||
prevY = currY;
|
prevY = currY;
|
||||||
|
|
||||||
|
if (hasColors) {
|
||||||
|
int newColor = colors.get(i);
|
||||||
|
if (color != newColor) {
|
||||||
|
paths.add(new Pair<>(path, color));
|
||||||
|
path = new Path();
|
||||||
|
if (segmentStarted) {
|
||||||
|
path.moveTo(currX, currY);
|
||||||
|
}
|
||||||
|
color = newColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!path.isEmpty()) {
|
||||||
|
paths.add(new Pair<>(path, color));
|
||||||
}
|
}
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
@ -383,6 +410,8 @@ public abstract class OsmandMapLayer {
|
||||||
protected static class RenderingLineAttributes {
|
protected static class RenderingLineAttributes {
|
||||||
protected int cachedHash;
|
protected int cachedHash;
|
||||||
public Paint paint;
|
public Paint paint;
|
||||||
|
public Paint customColorPaint;
|
||||||
|
public int customColor = 0;
|
||||||
public int defaultWidth = 0;
|
public int defaultWidth = 0;
|
||||||
public int defaultColor = 0;
|
public int defaultColor = 0;
|
||||||
public boolean isPaint2;
|
public boolean isPaint2;
|
||||||
|
@ -402,6 +431,7 @@ public abstract class OsmandMapLayer {
|
||||||
public RenderingLineAttributes(String renderingAttribute) {
|
public RenderingLineAttributes(String renderingAttribute) {
|
||||||
this.renderingAttribute = renderingAttribute;
|
this.renderingAttribute = renderingAttribute;
|
||||||
paint = initPaint();
|
paint = initPaint();
|
||||||
|
customColorPaint = new Paint(paint);
|
||||||
paint2 = initPaint();
|
paint2 = initPaint();
|
||||||
paint3 = initPaint();
|
paint3 = initPaint();
|
||||||
paint_1 = initPaint();
|
paint_1 = initPaint();
|
||||||
|
@ -462,6 +492,7 @@ public abstract class OsmandMapLayer {
|
||||||
if (paint.getStrokeWidth() == 0 && defaultWidth != 0) {
|
if (paint.getStrokeWidth() == 0 && defaultWidth != 0) {
|
||||||
paint.setStrokeWidth(defaultWidth);
|
paint.setStrokeWidth(defaultWidth);
|
||||||
}
|
}
|
||||||
|
customColorPaint = new Paint(paint);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -486,7 +517,12 @@ public abstract class OsmandMapLayer {
|
||||||
if (isShadowPaint) {
|
if (isShadowPaint) {
|
||||||
canvas.drawPath(path, shadowPaint);
|
canvas.drawPath(path, shadowPaint);
|
||||||
}
|
}
|
||||||
canvas.drawPath(path, paint);
|
if (customColor != 0) {
|
||||||
|
customColorPaint.setColor(customColor);
|
||||||
|
canvas.drawPath(path, customColorPaint);
|
||||||
|
} else {
|
||||||
|
canvas.drawPath(path, paint);
|
||||||
|
}
|
||||||
if (isPaint2) {
|
if (isPaint2) {
|
||||||
canvas.drawPath(path, paint2);
|
canvas.drawPath(path, paint2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ import net.osmand.plus.activities.MapActivity;
|
||||||
import net.osmand.plus.poi.PoiUIFilter;
|
import net.osmand.plus.poi.PoiUIFilter;
|
||||||
import net.osmand.plus.render.RenderingIcons;
|
import net.osmand.plus.render.RenderingIcons;
|
||||||
import net.osmand.plus.routing.RoutingHelper;
|
import net.osmand.plus.routing.RoutingHelper;
|
||||||
import net.osmand.plus.routing.RoutingHelper.IRouteInformationListener;
|
import net.osmand.plus.routing.IRouteInformationListener;
|
||||||
import net.osmand.plus.views.MapTextLayer.MapTextProvider;
|
import net.osmand.plus.views.MapTextLayer.MapTextProvider;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,16 @@ import android.graphics.PointF;
|
||||||
import android.graphics.PorterDuff.Mode;
|
import android.graphics.PorterDuff.Mode;
|
||||||
import android.graphics.PorterDuffColorFilter;
|
import android.graphics.PorterDuffColorFilter;
|
||||||
import android.support.annotation.ColorInt;
|
import android.support.annotation.ColorInt;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
import net.osmand.Location;
|
import net.osmand.Location;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.data.QuadRect;
|
import net.osmand.data.QuadRect;
|
||||||
import net.osmand.data.RotatedTileBox;
|
import net.osmand.data.RotatedTileBox;
|
||||||
|
import net.osmand.data.TransportRoute;
|
||||||
|
import net.osmand.osm.edit.Node;
|
||||||
|
import net.osmand.osm.edit.OSMSettings;
|
||||||
|
import net.osmand.osm.edit.Way;
|
||||||
import net.osmand.plus.GPXUtilities.WptPt;
|
import net.osmand.plus.GPXUtilities.WptPt;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
|
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
|
||||||
|
@ -24,9 +29,15 @@ import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu.TrackChartPoints;
|
||||||
import net.osmand.plus.routing.RouteCalculationResult;
|
import net.osmand.plus.routing.RouteCalculationResult;
|
||||||
import net.osmand.plus.routing.RouteDirectionInfo;
|
import net.osmand.plus.routing.RouteDirectionInfo;
|
||||||
import net.osmand.plus.routing.RoutingHelper;
|
import net.osmand.plus.routing.RoutingHelper;
|
||||||
|
import net.osmand.plus.routing.TransportRoutingHelper;
|
||||||
|
import net.osmand.plus.transport.TransportStopRoute;
|
||||||
|
import net.osmand.plus.transport.TransportStopType;
|
||||||
|
import net.osmand.router.TransportRoutePlanner.TransportRouteResult;
|
||||||
|
import net.osmand.router.TransportRoutePlanner.TransportRouteResultSegment;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -42,11 +53,10 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
private OsmandMapTileView view;
|
private OsmandMapTileView view;
|
||||||
|
|
||||||
private final RoutingHelper helper;
|
private final RoutingHelper helper;
|
||||||
|
private final TransportRoutingHelper transportHelper;
|
||||||
// keep array lists created
|
// keep array lists created
|
||||||
private List<Location> actionPoints = new ArrayList<Location>();
|
private List<Location> actionPoints = new ArrayList<Location>();
|
||||||
|
|
||||||
private Path path;
|
|
||||||
|
|
||||||
// cache
|
// cache
|
||||||
private Bitmap coloredArrowUp;
|
private Bitmap coloredArrowUp;
|
||||||
private Bitmap actionArrow;
|
private Bitmap actionArrow;
|
||||||
|
@ -61,10 +71,12 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
private TrackChartPoints trackChartPoints;
|
private TrackChartPoints trackChartPoints;
|
||||||
|
|
||||||
private RenderingLineAttributes attrs;
|
private RenderingLineAttributes attrs;
|
||||||
|
private boolean nightMode;
|
||||||
|
|
||||||
|
|
||||||
public RouteLayer(RoutingHelper helper){
|
public RouteLayer(RoutingHelper helper) {
|
||||||
this.helper = helper;
|
this.helper = helper;
|
||||||
|
this.transportHelper = helper.getTransportRoutingHelper();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTrackChartPoints(TrackDetailsMenu.TrackChartPoints trackChartPoints) {
|
public void setTrackChartPoints(TrackDetailsMenu.TrackChartPoints trackChartPoints) {
|
||||||
|
@ -73,8 +85,7 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
|
|
||||||
private void initUI() {
|
private void initUI() {
|
||||||
actionArrow = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_action_arrow, null);
|
actionArrow = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_action_arrow, null);
|
||||||
path = new Path();
|
|
||||||
|
|
||||||
paintIcon = new Paint();
|
paintIcon = new Paint();
|
||||||
paintIcon.setFilterBitmap(true);
|
paintIcon.setFilterBitmap(true);
|
||||||
paintIcon.setAntiAlias(true);
|
paintIcon.setAntiAlias(true);
|
||||||
|
@ -119,7 +130,9 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
|
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
|
||||||
if (helper.getFinalLocation() != null && helper.getRoute().isCalculated()) {
|
if ((helper.isPublicTransportMode() && transportHelper.getRoutes() != null) ||
|
||||||
|
(helper.getFinalLocation() != null && helper.getRoute().isCalculated())) {
|
||||||
|
|
||||||
updateAttrs(settings, tileBox);
|
updateAttrs(settings, tileBox);
|
||||||
|
|
||||||
if(coloredArrowUp == null) {
|
if(coloredArrowUp == null) {
|
||||||
|
@ -178,6 +191,7 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
paintIconAction.setColorFilter(new PorterDuffColorFilter(attrs.paint3.getColor(), Mode.MULTIPLY));
|
paintIconAction.setColorFilter(new PorterDuffColorFilter(attrs.paint3.getColor(), Mode.MULTIPLY));
|
||||||
paintIcon.setColorFilter(new PorterDuffColorFilter(attrs.paint2.getColor(), Mode.MULTIPLY));
|
paintIcon.setColorFilter(new PorterDuffColorFilter(attrs.paint2.getColor(), Mode.MULTIPLY));
|
||||||
}
|
}
|
||||||
|
nightMode = settings != null && settings.isNightMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawXAxisPoints(Canvas canvas, RotatedTileBox tileBox) {
|
private void drawXAxisPoints(Canvas canvas, RotatedTileBox tileBox) {
|
||||||
|
@ -413,24 +427,79 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
|
|
||||||
private class RouteSimplificationGeometry {
|
private class RouteSimplificationGeometry {
|
||||||
RouteCalculationResult route;
|
RouteCalculationResult route;
|
||||||
|
TransportRouteResult transportRoute;
|
||||||
double mapDensity;
|
double mapDensity;
|
||||||
TreeMap<Integer, RouteGeometryZoom> zooms = new TreeMap<>();
|
TreeMap<Integer, RouteGeometryZoom> zooms = new TreeMap<>();
|
||||||
List<Location> locations = Collections.emptyList();
|
List<Location> locations = Collections.emptyList();
|
||||||
|
TreeMap<Integer, Integer> colorsMap = new TreeMap<>();
|
||||||
|
|
||||||
// cache arrays
|
// cache arrays
|
||||||
TIntArrayList tx = new TIntArrayList();
|
TIntArrayList tx = new TIntArrayList();
|
||||||
TIntArrayList ty = new TIntArrayList();
|
TIntArrayList ty = new TIntArrayList();
|
||||||
List<Double> angles = new ArrayList<>();
|
List<Double> angles = new ArrayList<>();
|
||||||
List<Double> distances = new ArrayList<>();
|
List<Double> distances = new ArrayList<>();
|
||||||
|
List<Integer> colors = new ArrayList<>();
|
||||||
|
|
||||||
|
private int getColor(int index) {
|
||||||
|
List<Integer> list = new ArrayList<>(colorsMap.keySet());
|
||||||
|
for (int i = list.size() -1; i >= 0; i--) {
|
||||||
|
int c = list.get(i);
|
||||||
|
if (c <= index) {
|
||||||
|
return colorsMap.get(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return attrs.paint.getColor();
|
||||||
|
}
|
||||||
|
|
||||||
public void updateRoute(RotatedTileBox tb, RouteCalculationResult route) {
|
public void updateRoute(RotatedTileBox tb, RouteCalculationResult route) {
|
||||||
if(tb.getMapDensity() != mapDensity || this.route != route) {
|
if(tb.getMapDensity() != mapDensity || this.route != route) {
|
||||||
this.route = route;
|
this.route = route;
|
||||||
if(route == null) {
|
if (route == null) {
|
||||||
locations = Collections.emptyList();
|
locations = Collections.emptyList();
|
||||||
} else {
|
} else {
|
||||||
locations = route.getImmutableAllLocations();
|
locations = route.getImmutableAllLocations();
|
||||||
}
|
}
|
||||||
|
colorsMap.clear();
|
||||||
|
this.mapDensity = tb.getMapDensity();
|
||||||
|
zooms.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateTransportRoute(RotatedTileBox tb, TransportRouteResult route) {
|
||||||
|
if (tb.getMapDensity() != mapDensity || this.transportRoute != route) {
|
||||||
|
this.transportRoute = route;
|
||||||
|
if (route == null) {
|
||||||
|
locations = Collections.emptyList();
|
||||||
|
colorsMap.clear();
|
||||||
|
} else {
|
||||||
|
LatLon start = transportHelper.getStartLocation();
|
||||||
|
LatLon end = transportHelper.getEndLocation();
|
||||||
|
List<Way> list = new ArrayList<>();
|
||||||
|
List<Integer> cols = new ArrayList<>();
|
||||||
|
calculateTransportResult(start, end, route, list, cols);
|
||||||
|
List<Location> locs = new ArrayList<>();
|
||||||
|
TreeMap<Integer, Integer> colsMap = new TreeMap<>();
|
||||||
|
int i = 0;
|
||||||
|
int k = 0;
|
||||||
|
if (list.size() > 0) {
|
||||||
|
for (Way w : list) {
|
||||||
|
colsMap.put(k, cols.get(i++));
|
||||||
|
//Location loc = new Location("");
|
||||||
|
//loc.setLatitude(w.getLatitude());
|
||||||
|
//loc.setLongitude(w.getLongitude());
|
||||||
|
//locs.add(loc);
|
||||||
|
for (Node n : w.getNodes()) {
|
||||||
|
Location ln = new Location("");
|
||||||
|
ln.setLatitude(n.getLatitude());
|
||||||
|
ln.setLongitude(n.getLongitude());
|
||||||
|
locs.add(ln);
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
locations = locs;
|
||||||
|
colorsMap = colsMap;
|
||||||
|
}
|
||||||
this.mapDensity = tb.getMapDensity();
|
this.mapDensity = tb.getMapDensity();
|
||||||
zooms.clear();
|
zooms.clear();
|
||||||
}
|
}
|
||||||
|
@ -452,14 +521,13 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
TByteArrayList simplification = geometryZoom.getSimplifyPoints();
|
TByteArrayList simplification = geometryZoom.getSimplifyPoints();
|
||||||
List<Double> odistances = geometryZoom.getDistances();
|
List<Double> odistances = geometryZoom.getDistances();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
clearArrays();
|
clearArrays();
|
||||||
|
int color = attrs.paint.getColor();
|
||||||
boolean previousVisible = false;
|
boolean previousVisible = false;
|
||||||
if (lastProjection != null) {
|
if (lastProjection != null) {
|
||||||
if (leftLongitude <= lastProjection.getLongitude() && lastProjection.getLongitude() <= rightLongitude
|
if (leftLongitude <= lastProjection.getLongitude() && lastProjection.getLongitude() <= rightLongitude
|
||||||
&& bottomLatitude <= lastProjection.getLatitude() && lastProjection.getLatitude() <= topLatitude) {
|
&& bottomLatitude <= lastProjection.getLatitude() && lastProjection.getLatitude() <= topLatitude) {
|
||||||
addLocation(tb, lastProjection, tx, ty, angles, distances, 0);
|
addLocation(tb, lastProjection, color, tx, ty, angles, distances, 0, colors);
|
||||||
previousVisible = true;
|
previousVisible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -467,7 +535,8 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
int previous = -1;
|
int previous = -1;
|
||||||
for (int i = currentRoute; i < routeNodes.size(); i++) {
|
for (int i = currentRoute; i < routeNodes.size(); i++) {
|
||||||
Location ls = routeNodes.get(i);
|
Location ls = routeNodes.get(i);
|
||||||
if(simplification.getQuick(i) == 0) {
|
color = getColor(i);
|
||||||
|
if (simplification.getQuick(i) == 0 && !colorsMap.containsKey(i)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (leftLongitude <= ls.getLongitude() && ls.getLongitude() <= rightLongitude && bottomLatitude <= ls.getLatitude()
|
if (leftLongitude <= ls.getLongitude() && ls.getLongitude() <= rightLongitude && bottomLatitude <= ls.getLatitude()
|
||||||
|
@ -481,23 +550,23 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
} else if (lastProjection != null) {
|
} else if (lastProjection != null) {
|
||||||
lt = lastProjection;
|
lt = lastProjection;
|
||||||
}
|
}
|
||||||
addLocation(tb, lt, tx, ty, angles, distances, 0); // first point
|
addLocation(tb, lt, color, tx, ty, angles, distances, 0, colors); // first point
|
||||||
}
|
}
|
||||||
addLocation(tb, ls, tx, ty, angles, distances, dist);
|
addLocation(tb, ls, color, tx, ty, angles, distances, dist, colors);
|
||||||
previousVisible = true;
|
previousVisible = true;
|
||||||
} else if (previousVisible) {
|
} else if (previousVisible) {
|
||||||
addLocation(tb, ls, tx, ty, angles, distances, previous == -1 ? 0 : odistances.get(i));
|
addLocation(tb, ls, color, tx, ty, angles, distances, previous == -1 ? 0 : odistances.get(i), colors);
|
||||||
double distToFinish = 0;
|
double distToFinish = 0;
|
||||||
for(int ki = i + 1; ki < odistances.size(); ki++) {
|
for(int ki = i + 1; ki < odistances.size(); ki++) {
|
||||||
distToFinish += odistances.get(ki);
|
distToFinish += odistances.get(ki);
|
||||||
}
|
}
|
||||||
drawRouteSegment(tb, canvas, tx, ty, angles, distances, distToFinish);
|
drawRouteSegment(tb, canvas, tx, ty, angles, distances, distToFinish, colors);
|
||||||
previousVisible = false;
|
previousVisible = false;
|
||||||
clearArrays();
|
clearArrays();
|
||||||
}
|
}
|
||||||
previous = i;
|
previous = i;
|
||||||
}
|
}
|
||||||
drawRouteSegment(tb, canvas, tx, ty, angles, distances, 0);
|
drawRouteSegment(tb, canvas, tx, ty, angles, distances, 0, colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearArrays() {
|
private void clearArrays() {
|
||||||
|
@ -505,10 +574,11 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
ty.clear();
|
ty.clear();
|
||||||
distances.clear();
|
distances.clear();
|
||||||
angles.clear();
|
angles.clear();
|
||||||
|
colors.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addLocation(RotatedTileBox tb, Location ls, TIntArrayList tx, TIntArrayList ty,
|
private void addLocation(RotatedTileBox tb, Location ls, int color, TIntArrayList tx, TIntArrayList ty,
|
||||||
List<Double> angles, List<Double> distances, double dist) {
|
List<Double> angles, List<Double> distances, double dist, List<Integer> colors) {
|
||||||
float x = tb.getPixXFromLatLon(ls.getLatitude(), ls.getLongitude());
|
float x = tb.getPixXFromLatLon(ls.getLatitude(), ls.getLongitude());
|
||||||
float y = tb.getPixYFromLatLon(ls.getLatitude(), ls.getLongitude());
|
float y = tb.getPixYFromLatLon(ls.getLatitude(), ls.getLongitude());
|
||||||
float px = x;
|
float px = x;
|
||||||
|
@ -531,21 +601,26 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
ty.add((int) y);
|
ty.add((int) y);
|
||||||
angles.add(angle);
|
angles.add(angle);
|
||||||
distances.add(distSegment);
|
distances.add(distSegment);
|
||||||
|
colors.add(color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RouteSimplificationGeometry routeGeometry = new RouteSimplificationGeometry();
|
RouteSimplificationGeometry routeGeometry = new RouteSimplificationGeometry();
|
||||||
|
|
||||||
private void drawRouteSegment(RotatedTileBox tb, Canvas canvas, TIntArrayList tx, TIntArrayList ty,
|
private void drawRouteSegment(RotatedTileBox tb, Canvas canvas, TIntArrayList tx, TIntArrayList ty,
|
||||||
List<Double> angles, List<Double> distances, double distToFinish) {
|
List<Double> angles, List<Double> distances, double distToFinish, List<Integer> colors) {
|
||||||
if(tx.size() < 2) {
|
if (tx.size() < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
path.reset();
|
List<Pair<Path, Integer>> paths = new ArrayList<>();
|
||||||
canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
||||||
calculatePath(tb, tx, ty, path);
|
calculatePath(tb, tx, ty, colors, paths);
|
||||||
attrs.drawPath(canvas, path);
|
for (Pair<Path, Integer> pc : paths) {
|
||||||
|
attrs.customColor = pc.second;
|
||||||
|
attrs.drawPath(canvas, pc.first);
|
||||||
|
}
|
||||||
|
attrs.customColor = 0;
|
||||||
if (tb.getZoomAnimation() == 0) {
|
if (tb.getZoomAnimation() == 0) {
|
||||||
drawArrowsOverPath(canvas, tb, tx, ty, angles, distances, coloredArrowUp, distToFinish);
|
drawArrowsOverPath(canvas, tb, tx, ty, angles, distances, coloredArrowUp, distToFinish);
|
||||||
}
|
}
|
||||||
|
@ -555,16 +630,32 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawLocations(RotatedTileBox tb, Canvas canvas, double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude) {
|
public void drawLocations(RotatedTileBox tb, Canvas canvas, double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude) {
|
||||||
RouteCalculationResult route = helper.getRoute();
|
if (helper.isPublicTransportMode()) {
|
||||||
routeGeometry.updateRoute(tb, route);
|
int currentRoute = transportHelper.getCurrentRoute();
|
||||||
routeGeometry.drawSegments(tb, canvas, topLatitude, leftLongitude, bottomLatitude, rightLongitude,
|
List<TransportRouteResult> routes = transportHelper.getRoutes();
|
||||||
helper.getLastProjection(), route == null ? 0 : route.getCurrentRoute());
|
TransportRouteResult route = routes != null && routes.size() > currentRoute ? routes.get(currentRoute) : null;
|
||||||
List<RouteDirectionInfo> rd = helper.getRouteDirections();
|
routeGeometry.updateRoute(tb, null);
|
||||||
Iterator<RouteDirectionInfo> it = rd.iterator();
|
routeGeometry.updateTransportRoute(tb, route);
|
||||||
if (tb.getZoom() >= 14) {
|
if (route != null) {
|
||||||
List<Location> actionPoints = calculateActionPoints(topLatitude, leftLongitude, bottomLatitude, rightLongitude, helper.getLastProjection(),
|
LatLon start = transportHelper.getStartLocation();
|
||||||
helper.getRoute().getRouteLocations(), helper.getRoute().getCurrentRoute(), it, tb.getZoom());
|
Location startLocation = new Location("transport");
|
||||||
drawAction(tb, canvas, actionPoints);
|
startLocation.setLatitude(start.getLatitude());
|
||||||
|
startLocation.setLongitude(start.getLongitude());
|
||||||
|
routeGeometry.drawSegments(tb, canvas, topLatitude, leftLongitude, bottomLatitude, rightLongitude, startLocation, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
RouteCalculationResult route = helper.getRoute();
|
||||||
|
routeGeometry.updateTransportRoute(tb, null);
|
||||||
|
routeGeometry.updateRoute(tb, route);
|
||||||
|
routeGeometry.drawSegments(tb, canvas, topLatitude, leftLongitude, bottomLatitude, rightLongitude,
|
||||||
|
helper.getLastProjection(), route == null ? 0 : route.getCurrentRoute());
|
||||||
|
List<RouteDirectionInfo> rd = helper.getRouteDirections();
|
||||||
|
Iterator<RouteDirectionInfo> it = rd.iterator();
|
||||||
|
if (tb.getZoom() >= 14) {
|
||||||
|
List<Location> actionPoints = calculateActionPoints(topLatitude, leftLongitude, bottomLatitude, rightLongitude, helper.getLastProjection(),
|
||||||
|
helper.getRoute().getRouteLocations(), helper.getRoute().getCurrentRoute(), it, tb.getZoom());
|
||||||
|
drawAction(tb, canvas, actionPoints);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,7 +801,49 @@ public class RouteLayer extends OsmandMapLayer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void calculateTransportResult(LatLon start, LatLon end, TransportRouteResult r, List<Way> res, List<Integer> colors) {
|
||||||
|
if (r != null) {
|
||||||
|
LatLon p = start;
|
||||||
|
for (TransportRouteResultSegment s : r.getSegments()) {
|
||||||
|
LatLon floc = s.getStart().getLocation();
|
||||||
|
addRouteWalk(p, floc, res, colors);
|
||||||
|
List<Way> geometry = s.getGeometry();
|
||||||
|
res.addAll(geometry);
|
||||||
|
addColors(s.route, geometry.size(), colors);
|
||||||
|
p = s.getEnd().getLocation();
|
||||||
|
}
|
||||||
|
addRouteWalk(p, end, res, colors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRouteWalk(LatLon s, LatLon e, List<Way> res, List<Integer> colors) {
|
||||||
|
double dist = MapUtils.getDistance(s, e);
|
||||||
|
if (dist > 50) {
|
||||||
|
Way way = new Way(-1);
|
||||||
|
way.putTag(OSMSettings.OSMTagKey.NAME.getValue(), String.format("Walk %.1f m", dist));
|
||||||
|
way.addNode(new Node(s.getLatitude(), s.getLongitude(), -1));
|
||||||
|
way.addNode(new Node(e.getLatitude(), e.getLongitude(), -1));
|
||||||
|
res.add(way);
|
||||||
|
addColors(null, 1, colors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addColors(TransportRoute route, int count, List<Integer> colors) {
|
||||||
|
int color;
|
||||||
|
if (route == null) {
|
||||||
|
color = attrs.paint.getColor();
|
||||||
|
} else {
|
||||||
|
TransportStopRoute r = new TransportStopRoute();
|
||||||
|
r.type = TransportStopType.findType(route.getType());
|
||||||
|
r.route = route;
|
||||||
|
color = r.getColor(helper.getApplication(), nightMode);
|
||||||
|
}
|
||||||
|
addColors(color, count, colors);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addColors(int color, int count, List<Integer> colors) {
|
||||||
|
Integer[] integers = new Integer[count];
|
||||||
|
Arrays.fill(integers, color);
|
||||||
|
colors.addAll(Arrays.asList(integers));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue