diff --git a/OsmAnd-java/src/net/osmand/binary/RouteDataObject.java b/OsmAnd-java/src/net/osmand/binary/RouteDataObject.java index 6bf172ad4a..c599e471fe 100644 --- a/OsmAnd-java/src/net/osmand/binary/RouteDataObject.java +++ b/OsmAnd-java/src/net/osmand/binary/RouteDataObject.java @@ -236,6 +236,7 @@ public class RouteDataObject { } return null; } + public String getName(String lang){ return getName(lang, false); @@ -684,6 +685,18 @@ public class RouteDataObject { } return direction; } + + public boolean isRoadDeleted() { + int[] pt = getTypes(); + int sz = pt.length; + for (int i = 0; i < sz; i++) { + RouteTypeRule r = region.quickGetEncodingRule(pt[i]); + if ("osmand_change".equals(r.getTag()) && "delete".equals(r.getValue())) { + return true; + } + } + return false; + } public boolean isStopApplicable(boolean direction, int intId, int startPointInd, int endPointInd) { int[] pt = getPointTypes(intId); diff --git a/OsmAnd-java/src/net/osmand/router/RouteCalculationProgress.java b/OsmAnd-java/src/net/osmand/router/RouteCalculationProgress.java index 21f47411cf..b34c2fd5bb 100644 --- a/OsmAnd-java/src/net/osmand/router/RouteCalculationProgress.java +++ b/OsmAnd-java/src/net/osmand/router/RouteCalculationProgress.java @@ -15,6 +15,37 @@ public class RouteCalculationProgress { public int loadedTiles = 0; public int visitedSegments = 0; + public int totalIterations = 1; + public int iteration = -1; + public boolean isCancelled; public boolean requestPrivateAccessRouting; + + private static final float INITIAL_PROGRESS = 0.05f; + private static final float FIRST_ITERATION = 0.72f; + + public float getLinearProgress() { + float p = Math.max(distanceFromBegin, distanceFromEnd); + float all = totalEstimatedDistance * 1.35f; + float pr = 0; + if (all > 0) { + pr = Math.min(p * p / (all * all), 1); + } + float progress = INITIAL_PROGRESS; + if (totalIterations > 1) { + if (iteration < 1) { + progress = pr * FIRST_ITERATION + INITIAL_PROGRESS; + } else { + progress = (INITIAL_PROGRESS + FIRST_ITERATION) + pr * (1 - FIRST_ITERATION - INITIAL_PROGRESS); + } + } else { + progress = INITIAL_PROGRESS + pr * (1 - INITIAL_PROGRESS); + } + return Math.min(progress * 100f, 99); + } + + public void nextIteration() { + iteration++; + totalEstimatedDistance = 0; + } } diff --git a/OsmAnd-java/src/net/osmand/router/RoutePlannerFrontEnd.java b/OsmAnd-java/src/net/osmand/router/RoutePlannerFrontEnd.java index d2779cdfb4..17d29c872a 100644 --- a/OsmAnd-java/src/net/osmand/router/RoutePlannerFrontEnd.java +++ b/OsmAnd-java/src/net/osmand/router/RoutePlannerFrontEnd.java @@ -158,6 +158,7 @@ public class RoutePlannerFrontEnd { } if (ctx.calculationMode == RouteCalculationMode.COMPLEX && routeDirection == null && maxDistance > ctx.config.DEVIATION_RADIUS * 6) { + ctx.calculationProgress.totalIterations++; RoutingContext nctx = buildRoutingContext(ctx.config, ctx.nativeLib, ctx.getMaps(), RouteCalculationMode.BASE); nctx.calculationProgress = ctx.calculationProgress; List ls = searchRoute(nctx, start, end, intermediates); @@ -175,6 +176,7 @@ public class RoutePlannerFrontEnd { if (routeDirection != null) { ctx.precalculatedRouteDirection = routeDirection.adopt(ctx); } + ctx.calculationProgress.nextIteration(); List res = runNativeRouting(ctx, recalculationEnd); if (res != null) { new RouteResultPreparation().printResults(ctx, start, end, res); @@ -197,6 +199,7 @@ public class RoutePlannerFrontEnd { if (!addSegment(end, ctx, indexNotFound++, points)) { return null; } + ctx.calculationProgress.nextIteration(); List res = searchRoute(ctx, points, routeDirection); // make start and end more precise makeStartEndPointsPrecise(res, start, end, intermediates); diff --git a/OsmAnd-java/src/net/osmand/router/RouteResultPreparation.java b/OsmAnd-java/src/net/osmand/router/RouteResultPreparation.java index e4a1d69649..a066d14946 100644 --- a/OsmAnd-java/src/net/osmand/router/RouteResultPreparation.java +++ b/OsmAnd-java/src/net/osmand/router/RouteResultPreparation.java @@ -743,9 +743,9 @@ public class RouteResultPreparation { } } } - if(straightActiveLen == target.activeLen) { + if(straightActiveBegin != -1 && straightActiveLen <= target.activeLen) { active.activeStartIndex = straightActiveBegin; - active.activeEndIndex = straightActiveBegin + target.activeLen - 1; + active.activeEndIndex = straightActiveBegin + straightActiveLen - 1; changed = true; } else { // cause the next-turn goes forward exclude left most and right most lane diff --git a/OsmAnd-java/src/net/osmand/router/RouteSegmentResult.java b/OsmAnd-java/src/net/osmand/router/RouteSegmentResult.java index 77db8130f2..6ee9fbbb52 100644 --- a/OsmAnd-java/src/net/osmand/router/RouteSegmentResult.java +++ b/OsmAnd-java/src/net/osmand/router/RouteSegmentResult.java @@ -71,6 +71,9 @@ public class RouteSegmentResult { } public void attachRoute(int roadIndex, RouteSegmentResult r){ + if(r.getObject().isRoadDeleted()) { + return; + } int st = Math.abs(roadIndex - startPointIndex); if(attachedRoutes[st] == null) { attachedRoutes[st] = new ArrayList(); diff --git a/OsmAnd-java/src/net/osmand/router/TurnType.java b/OsmAnd-java/src/net/osmand/router/TurnType.java index 873825c0ea..c1f4e4bd88 100644 --- a/OsmAnd-java/src/net/osmand/router/TurnType.java +++ b/OsmAnd-java/src/net/osmand/router/TurnType.java @@ -416,11 +416,13 @@ public class TurnType { public static int convertType(String lane) { int turn; // merge should be recognized as continue route (but it could displayed differently) - if (lane.equals("none") || lane.equals("through") - || lane.equals("merge_to_left") - || lane.equals("merge_to_right")) { + if(lane.equals("merge_to_left")) { turn = TurnType.C; - } else if (lane.equals("slight_right") ) { + } else if(lane.equals("merge_to_right")) { + turn = TurnType.C; + } else if (lane.equals("none") || lane.equals("through")) { + turn = TurnType.C; + } else if (lane.equals("slight_right")) { turn = TurnType.TSLR; } else if (lane.equals("slight_left") ) { turn = TurnType.TSLL; diff --git a/OsmAnd-java/test/resources/test_turn_lanes.json b/OsmAnd-java/test/resources/test_turn_lanes.json index 8598eee117..b743a2e731 100644 --- a/OsmAnd-java/test/resources/test_turn_lanes.json +++ b/OsmAnd-java/test/resources/test_turn_lanes.json @@ -595,8 +595,8 @@ }, "expectedResults": { "222244": "TL|TL|+C,TR", - "222243": "TL|TL|+C|C|TSLR", - "222164": "TL|TL|+C|C" + "222243": "TL|TL|+C|+C|TSLR", + "222164": "TL|TL|+C|+C" } }, { diff --git a/OsmAnd/AndroidManifest.xml b/OsmAnd/AndroidManifest.xml index e4fbaefde5..79b475c02c 100644 --- a/OsmAnd/AndroidManifest.xml +++ b/OsmAnd/AndroidManifest.xml @@ -756,7 +756,23 @@ - + + + + + + + + + + + + + + + + + diff --git a/OsmAnd/res/layout-land/map_hud_bottom.xml b/OsmAnd/res/layout-land/map_hud_bottom.xml index a624492a3a..680be73185 100644 --- a/OsmAnd/res/layout-land/map_hud_bottom.xml +++ b/OsmAnd/res/layout-land/map_hud_bottom.xml @@ -192,39 +192,19 @@ android:contentDescription="@string/shared_string_hide" android:src="@drawable/headliner_close"/> + + + - - - - - - - - - - - @@ -274,6 +254,7 @@ + - diff --git a/OsmAnd/res/layout/gpx_item_list_header.xml b/OsmAnd/res/layout/gpx_item_list_header.xml index 376ce670ed..cf4990ba48 100644 --- a/OsmAnd/res/layout/gpx_item_list_header.xml +++ b/OsmAnd/res/layout/gpx_item_list_header.xml @@ -180,4 +180,14 @@ + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/map_context_menu_fragment.xml b/OsmAnd/res/layout/map_context_menu_fragment.xml index 6ebfddcc10..bfb51ff362 100644 --- a/OsmAnd/res/layout/map_context_menu_fragment.xml +++ b/OsmAnd/res/layout/map_context_menu_fragment.xml @@ -122,7 +122,7 @@ @@ -137,7 +137,12 @@ android:paddingBottom="3dp" android:paddingLeft="@dimen/context_menu_padding_margin_default" android:paddingRight="@dimen/context_menu_padding_margin_default"> - + + + + diff --git a/OsmAnd/res/layout/map_hud_bottom.xml b/OsmAnd/res/layout/map_hud_bottom.xml index 12067945c8..143794a913 100644 --- a/OsmAnd/res/layout/map_hud_bottom.xml +++ b/OsmAnd/res/layout/map_hud_bottom.xml @@ -231,9 +231,21 @@ tools:src="@drawable/ic_action_test_light"/> + + - @@ -251,36 +263,6 @@ android:layout_width="match_parent" android:layout_height="match_parent"/> - - - - - - - - - \ No newline at end of file diff --git a/OsmAnd/res/layout/map_hud_top.xml b/OsmAnd/res/layout/map_hud_top.xml index 27ce58301f..654bb611ec 100644 --- a/OsmAnd/res/layout/map_hud_top.xml +++ b/OsmAnd/res/layout/map_hud_top.xml @@ -647,16 +647,6 @@ - diff --git a/OsmAnd/res/values/colors.xml b/OsmAnd/res/values/colors.xml index e822e91cf3..d678640ada 100644 --- a/OsmAnd/res/values/colors.xml +++ b/OsmAnd/res/values/colors.xml @@ -111,6 +111,9 @@ #536dfe #485dd9 + #f0f0f0 + #1b1d1f + #39464d #CC080B0D diff --git a/OsmAnd/src/net/osmand/AndroidUtils.java b/OsmAnd/src/net/osmand/AndroidUtils.java index f1b05985e4..3ef7cd913f 100644 --- a/OsmAnd/src/net/osmand/AndroidUtils.java +++ b/OsmAnd/src/net/osmand/AndroidUtils.java @@ -10,7 +10,10 @@ import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PointF; +import android.graphics.drawable.ClipDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.LayerDrawable; +import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.StateListDrawable; import android.net.Uri; import android.os.Build; @@ -31,6 +34,7 @@ import android.text.style.ImageSpan; import android.text.style.URLSpan; import android.util.DisplayMetrics; import android.util.TypedValue; +import android.view.Gravity; import android.view.View; import android.view.ViewParent; import android.view.inputmethod.InputMethodManager; @@ -251,6 +255,24 @@ public class AndroidUtils { return res; } + public static LayerDrawable createProgressDrawable(@ColorInt int bgColor, @ColorInt int progressColor) { + ShapeDrawable bg = new ShapeDrawable(); + bg.getPaint().setColor(bgColor); + + ShapeDrawable progress = new ShapeDrawable(); + progress.getPaint().setColor(progressColor); + + LayerDrawable res = new LayerDrawable(new Drawable[]{ + bg, + new ClipDrawable(progress, Gravity.START, ClipDrawable.HORIZONTAL) + }); + + res.setId(0, android.R.id.background); + res.setId(1, android.R.id.progress); + + return res; + } + public static void setSnackbarTextColor(Snackbar snackbar, @ColorRes int colorId) { View view = snackbar.getView(); TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_action); diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index 9fb04f29ba..aacab9a87a 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -13,7 +13,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.os.Build; import android.support.v7.app.AlertDialog; - +import android.util.Log; import net.osmand.IProgress; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; @@ -67,7 +67,6 @@ import java.util.Locale; import java.util.Random; import btools.routingapp.BRouterServiceConnection; - import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getPendingIntent; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLiveUpdatesOn; @@ -178,6 +177,8 @@ public class AppInitializer implements IProgress { startPrefs.edit().putString(VERSION_INSTALLED, Version.getFullVersion(app)).commit(); appVersionChanged = true; } + app.getSettings().SHOW_TRAVEL_UPDATE_CARD.set(true); + app.getSettings().SHOW_TRAVEL_NEEDED_MAPS_CARD.set(true); initSettings = true; } @@ -352,7 +353,8 @@ public class AppInitializer implements IProgress { Integer in = (Integer) f.get(null); return app.getString(in); } - } catch (Exception e) { + } catch (Throwable e) { + LOG.info("No translation: " + keyName); } return null; } diff --git a/OsmAnd/src/net/osmand/plus/GPXUtilities.java b/OsmAnd/src/net/osmand/plus/GPXUtilities.java index b7a2168538..0edaec5933 100644 --- a/OsmAnd/src/net/osmand/plus/GPXUtilities.java +++ b/OsmAnd/src/net/osmand/plus/GPXUtilities.java @@ -1231,7 +1231,9 @@ public class GPXUtilities { public static String writeGpxFile(File fout, GPXFile file, OsmandApplication ctx) { Writer output = null; try { - fout.getParentFile().mkdirs(); + if(fout.getParentFile() != null) { + fout.getParentFile().mkdirs(); + } output = new OutputStreamWriter(new FileOutputStream(fout), "UTF-8"); //$NON-NLS-1$ String msg = writeGpx(output, file, ctx); if(Algorithms.isEmpty(file.path)) { diff --git a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java index fb843bbf35..bd08eb16d7 100644 --- a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java +++ b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java @@ -244,7 +244,10 @@ public class GpxSelectionHelper { return dg; } - private static void processGroupTrack(OsmandApplication app, GpxDisplayGroup group) { + private static void processGroupTrack(@NonNull OsmandApplication app, @NonNull GpxDisplayGroup group) { + if (group.track == null) { + return; + } List list = group.getModifiableList(); String timeSpanClr = Algorithms.colorToString(ContextCompat.getColor(app, R.color.gpx_time_span_color)); String speedClr = Algorithms.colorToString(ContextCompat.getColor(app, R.color.gpx_speed)); @@ -252,7 +255,6 @@ public class GpxSelectionHelper { String descClr = Algorithms.colorToString(ContextCompat.getColor(app, R.color.gpx_altitude_desc)); String distanceClr = Algorithms.colorToString(ContextCompat.getColor(app, R.color.gpx_distance_color)); final float eleThreshold = 3; -// int t = 1; for (TrkSegment r : group.track.segments) { if (r.points.size() == 0) { continue; diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java index 5b2611e2c2..c98be15d2e 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java @@ -5,6 +5,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; import net.osmand.GeoidAltitudeCorrection; import net.osmand.PlatformUtil; @@ -70,12 +71,12 @@ public class OsmAndLocationProvider implements SensorEventListener { private static final int GPS_DIST_REQUEST = 0; private static final int NOT_SWITCH_TO_NETWORK_WHEN_GPS_LOST_MS = 12000; - private static final long STALE_LOCATION_TIMEOUT = 1000 * 60 * 5; // 5 minutes - private static final long STALE_LOCATION_TIMEOUT_FOR_UI = 1000 * 60 * 15; // 15 minutes + private static final long LOCATION_TIMEOUT_TO_BE_STALE = 1000 * 60 * 2; // 2 minutes + private static final long STALE_LOCATION_TIMEOUT_TO_BE_GONE = 1000 * 60 * 20; // 20 minutes private static final int REQUESTS_BEFORE_CHECK_LOCATION = 100; - private int locationRequestsCounter; - private int staleLocationRequestsCounter; + private AtomicInteger locationRequestsCounter = new AtomicInteger(); + private AtomicInteger staleLocationRequestsCounter = new AtomicInteger(); private net.osmand.Location cachedLocation; @@ -690,7 +691,8 @@ public class OsmAndLocationProvider implements SensorEventListener { private void scheduleCheckIfGpsLost(final net.osmand.Location location) { final RoutingHelper routingHelper = app.getRoutingHelper(); - if (location != null) { + if (location != null && routingHelper.isFollowingMode() && routingHelper.getLeftDistance() > 0 + && simulatePosition == null) { final long fixTime = location.getTime(); app.runMessageInUIThreadAndCancelPrevious(LOST_LOCATION_MSG_ID, new Runnable() { @@ -702,31 +704,30 @@ public class OsmAndLocationProvider implements SensorEventListener { return; } gpsSignalLost = true; - if (routingHelper.isFollowingMode() && routingHelper.getLeftDistance() > 0) { + if (routingHelper.isFollowingMode() && routingHelper.getLeftDistance() > 0 + && simulatePosition == null) { routingHelper.getVoiceRouter().gpsLocationLost(); + setLocation(null); } - setLocation(null); } }, LOST_LOCATION_CHECK_DELAY); - if (routingHelper.isFollowingMode() && routingHelper.getLeftDistance() > 0 && simulatePosition == null) { - app.runMessageInUIThreadAndCancelPrevious(START_SIMULATE_LOCATION_MSG_ID, new Runnable() { + app.runMessageInUIThreadAndCancelPrevious(START_SIMULATE_LOCATION_MSG_ID, new Runnable() { - @Override - public void run() { - net.osmand.Location lastKnown = getLastKnownLocation(); - if (lastKnown != null && lastKnown.getTime() > fixTime) { - // false positive case, still strange how we got here with removeMessages - return; - } - List tunnel = routingHelper.getUpcomingTunnel(1000); - if(tunnel != null) { - simulatePosition = new SimulationProvider(); - simulatePosition.startSimulation(tunnel, location); - simulatePositionImpl(); - } + @Override + public void run() { + net.osmand.Location lastKnown = getLastKnownLocation(); + if (lastKnown != null && lastKnown.getTime() > fixTime) { + // false positive case, still strange how we got here with removeMessages + return; } - }, START_LOCATION_SIMULATION_DELAY); - } + List tunnel = routingHelper.getUpcomingTunnel(1000); + if(tunnel != null) { + simulatePosition = new SimulationProvider(); + simulatePosition.startSimulation(tunnel, location); + simulatePositionImpl(); + } + } + }, START_LOCATION_SIMULATION_DELAY); } } @@ -869,15 +870,14 @@ public class OsmAndLocationProvider implements SensorEventListener { } public net.osmand.Location getLastKnownLocation() { - net.osmand.Location location = this.location; - if (location != null && locationRequestsCounter == 0 - && System.currentTimeMillis() - location.getTime() > STALE_LOCATION_TIMEOUT) { - location = null; - } - if (locationRequestsCounter == REQUESTS_BEFORE_CHECK_LOCATION) { - locationRequestsCounter = 0; - } else { - locationRequestsCounter++; + net.osmand.Location loc = this.location; + if (loc != null) { + int counter = locationRequestsCounter.incrementAndGet(); + if (counter >= REQUESTS_BEFORE_CHECK_LOCATION && locationRequestsCounter.compareAndSet(counter, 0)) { + if (System.currentTimeMillis() - loc.getTime() > LOCATION_TIMEOUT_TO_BE_STALE) { + location = null; + } + } } return location; } @@ -885,19 +885,17 @@ public class OsmAndLocationProvider implements SensorEventListener { @Nullable public net.osmand.Location getLastStaleKnownLocation() { net.osmand.Location newLoc = getLastKnownLocation(); - if (newLoc == null) { - if (staleLocationRequestsCounter == 0 && cachedLocation != null - && System.currentTimeMillis() - cachedLocation.getTime() > STALE_LOCATION_TIMEOUT_FOR_UI) { - cachedLocation = null; + if (newLoc == null && cachedLocation != null) { + int counter = staleLocationRequestsCounter.incrementAndGet(); + if (counter >= REQUESTS_BEFORE_CHECK_LOCATION && staleLocationRequestsCounter.compareAndSet(counter, 0)) { + net.osmand.Location cached = cachedLocation; + if (cached != null && System.currentTimeMillis() - cached.getTime() > STALE_LOCATION_TIMEOUT_TO_BE_GONE) { + cachedLocation = null; + } } } else { cachedLocation = newLoc; } - if (staleLocationRequestsCounter == REQUESTS_BEFORE_CHECK_LOCATION) { - staleLocationRequestsCounter = 0; - } else { - staleLocationRequestsCounter++; - } return cachedLocation; } diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 33c424033a..242d543373 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -3006,6 +3006,9 @@ public class OsmandSettings { public final OsmandPreference SELECTED_TRAVEL_BOOK = new StringPreference("selected_travel_book", "").makeGlobal(); + public final OsmandPreference SHOW_TRAVEL_UPDATE_CARD = new BooleanPreference("show_travel_update_card", true).makeGlobal(); + public final OsmandPreference SHOW_TRAVEL_NEEDED_MAPS_CARD = new BooleanPreference("show_travel_needed_maps_card", true).makeGlobal(); + public final ListStringPreference TRANSPORT_DEFAULT_SETTINGS = (ListStringPreference) new ListStringPreference("transport_default_settings", "transportStops", ",").makeProfile(); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 57303e6765..1338099cdd 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -281,8 +281,8 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven } }; app.getResourceManager().getMapTileDownloader().addDownloaderCallback(downloaderCallback); - createProgressBarForRouting(); mapLayers.createLayers(mapView); + createProgressBarForRouting(); updateStatusBarColor(); // This situtation could be when navigation suddenly crashed and after restarting // it tries to continue the last route @@ -433,6 +433,15 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven app.getRoutingHelper().setProgressBar(new RouteCalculationProgressCallback() { + @Override + public void start() { + boolean night = getMyApplication().getDaynightHelper().isNightModeForMapControls(); + int bgColor = ContextCompat.getColor(app, night + ? R.color.map_progress_bar_bg_dark : R.color.map_progress_bar_bg_light); + pb.setProgressDrawable(AndroidUtils + .createProgressDrawable(bgColor, mapLayers.getRouteLayer().getRouteLineColor(night))); + } + @Override public void updateProgress(int progress) { mapLayers.getMapControlsLayer().getMapRouteInfoMenu().updateRouteCalculationProgress(progress); @@ -440,6 +449,10 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven if (pbExtView.getVisibility() == View.VISIBLE) { pbExtView.setVisibility(View.GONE); } + if (MapRouteInfoMenu.isVisible()) { + pb.setVisibility(View.GONE); + return; + } if (pb.getVisibility() == View.GONE) { pb.setVisibility(View.VISIBLE); } diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java index 3a44bbaf61..27ae09febe 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java @@ -568,6 +568,10 @@ public class MapActivityLayers { return activity.getString(resId); } + public RouteLayer getRouteLayer() { + return routeLayer; + } + public PointNavigationLayer getNavigationLayer() { return navigationLayer; } diff --git a/OsmAnd/src/net/osmand/plus/activities/OsmandActionBarActivity.java b/OsmAnd/src/net/osmand/plus/activities/OsmandActionBarActivity.java index 5162339969..91af8c103b 100644 --- a/OsmAnd/src/net/osmand/plus/activities/OsmandActionBarActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/OsmandActionBarActivity.java @@ -19,8 +19,7 @@ public class OsmandActionBarActivity extends OsmandInAppPurchaseActivity { //should be called after set content view protected void setupHomeButton(){ - Drawable back = ((OsmandApplication)getApplication()).getIconsCache().getIcon(R.drawable.ic_arrow_back); - back.setColorFilter(ContextCompat.getColor(this, R.color.color_white), PorterDuff.Mode.MULTIPLY); + Drawable back = ((OsmandApplication)getApplication()).getIconsCache().getIcon(R.drawable.ic_arrow_back, R.color.color_white); final ActionBar supportActionBar = getSupportActionBar(); if (supportActionBar != null) { supportActionBar.setHomeButtonEnabled(true); diff --git a/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java b/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java index 0df1d42f74..4e42e4dbee 100644 --- a/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java @@ -34,6 +34,7 @@ import net.osmand.plus.R; import net.osmand.plus.measurementtool.NewGpxData; import net.osmand.plus.myplaces.FavoritesActivity; import net.osmand.plus.myplaces.SplitSegmentDialogFragment; +import net.osmand.plus.myplaces.TrackActivityFragmentAdapter; import net.osmand.plus.myplaces.TrackBitmapDrawer; import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener; import net.osmand.plus.myplaces.TrackPointFragment; @@ -51,6 +52,7 @@ public class TrackActivity extends TabActivity { public static final String OPEN_POINTS_TAB = "OPEN_POINTS_TAB"; public static final String OPEN_TRACKS_LIST = "OPEN_TRACKS_LIST"; public static final String CURRENT_RECORDING = "CURRENT_RECORDING"; + public static final String SHOW_TEMPORARILY = "SHOW_TEMPORARILY"; protected List> fragList = new ArrayList<>(); private OsmandApplication app; private TrackBitmapDrawer trackBitmapDrawer; @@ -320,6 +322,19 @@ public class TrackActivity extends TabActivity { } } + public void updateHeader(Fragment sender) { + for (WeakReference f : fragList) { + Fragment frag = f.get(); + if (frag != sender) { + if (frag instanceof TrackSegmentFragment) { + ((TrackSegmentFragment) frag).updateHeader(); + } else if (frag instanceof TrackPointFragment) { + ((TrackPointFragment) frag).updateHeader(); + } + } + } + } + @Override public void onBackPressed() { if (openTracksList) { @@ -440,6 +455,7 @@ public class TrackActivity extends TabActivity { private OsmandApplication app; private WeakReference activityRef; private File file; + private boolean showTemporarily; private TrackActivity getTrackActivity() { return activityRef.get(); @@ -455,6 +471,11 @@ public class TrackActivity extends TabActivity { TrackActivity activity = getTrackActivity(); if (activity != null) { activity.setSupportProgressBarIndeterminateVisibility(true); + Intent intent = activity.getIntent(); + if (intent != null && intent.hasExtra(SHOW_TEMPORARILY)) { + showTemporarily = true; + intent.removeExtra(SHOW_TEMPORARILY); + } } } @@ -491,7 +512,9 @@ public class TrackActivity extends TabActivity { TrackActivity activity = getTrackActivity(); if (activity != null) { activity.setSupportProgressBarIndeterminateVisibility(false); - + if (showTemporarily && result != null) { + app.getSelectedGpxHelper().selectGpxFile(result, false, false); + } if (!activity.stopped) { activity.onGPXFileReady(result); } diff --git a/OsmAnd/src/net/osmand/plus/api/SQLiteAPIImpl.java b/OsmAnd/src/net/osmand/plus/api/SQLiteAPIImpl.java index 8ed2827e6b..7199388596 100644 --- a/OsmAnd/src/net/osmand/plus/api/SQLiteAPIImpl.java +++ b/OsmAnd/src/net/osmand/plus/api/SQLiteAPIImpl.java @@ -1,15 +1,19 @@ package net.osmand.plus.api; +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; + +import org.apache.commons.logging.Log; + import android.annotation.SuppressLint; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; -import net.osmand.plus.OsmandApplication; - public class SQLiteAPIImpl implements SQLiteAPI { private OsmandApplication app; + private static final Log LOG = PlatformUtil.getLog(SQLiteAPIImpl.class); public SQLiteAPIImpl(OsmandApplication app) { this.app = app; @@ -18,9 +22,13 @@ public class SQLiteAPIImpl implements SQLiteAPI { @SuppressLint("InlinedApi") @Override public SQLiteConnection getOrCreateDatabase(String name, boolean readOnly) { - android.database.sqlite.SQLiteDatabase db = app.openOrCreateDatabase(name, - Context.MODE_PRIVATE | - (readOnly ? 0 : Context.MODE_ENABLE_WRITE_AHEAD_LOGGING), null); + android.database.sqlite.SQLiteDatabase db = null; + try { + db = app.openOrCreateDatabase(name, Context.MODE_PRIVATE + | (readOnly ? 0 : Context.MODE_ENABLE_WRITE_AHEAD_LOGGING), null); + } catch (RuntimeException e) { + LOG.error(e.getMessage(), e); + } if(db == null) { return null; } diff --git a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java index 887027c7d9..13376edd5b 100644 --- a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java +++ b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java @@ -907,27 +907,26 @@ public class AudioVideoNotesPlugin extends OsmandPlugin { } } - public void recordVideo(final double lat, final double lon, final MapActivity mapActivity, final boolean forceExternal) { - if (AV_EXTERNAL_RECORDER.get() || forceExternal) { - captureVideoExternal(lat, lon, mapActivity); - } else { - if (ActivityCompat.checkSelfPermission(mapActivity, Manifest.permission.CAMERA) - == PackageManager.PERMISSION_GRANTED - && ActivityCompat.checkSelfPermission(mapActivity, Manifest.permission.RECORD_AUDIO) - == PackageManager.PERMISSION_GRANTED) { + public void recordVideo(final double lat, final double lon, final MapActivity mapActivity, + final boolean forceExternal) { + if (ActivityCompat.checkSelfPermission(mapActivity, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(mapActivity, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) { + if (AV_EXTERNAL_RECORDER.get() || forceExternal) { + captureVideoExternal(lat, lon, mapActivity); + } else { openCamera(); if (cam != null) { initRecMenu(AVActionType.REC_VIDEO, lat, lon); recordVideoCamera(lat, lon, mapActivity); } - } else { - actionLat = lat; - actionLon = lon; - ActivityCompat.requestPermissions(mapActivity, - new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, - CAMERA_FOR_VIDEO_REQUEST_CODE); } + } else { + actionLat = lat; + actionLon = lon; + ActivityCompat.requestPermissions(mapActivity, new String[] { Manifest.permission.CAMERA, + Manifest.permission.RECORD_AUDIO }, CAMERA_FOR_VIDEO_REQUEST_CODE); } + } public void recordVideoCamera(final double lat, final double lon, final MapActivity mapActivity) { diff --git a/OsmAnd/src/net/osmand/plus/dialogs/SelectMapStyleBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/SelectMapStyleBottomSheetDialogFragment.java index fac225ad56..faf98230b4 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/SelectMapStyleBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/SelectMapStyleBottomSheetDialogFragment.java @@ -67,10 +67,16 @@ public class SelectMapStyleBottomSheetDialogFragment extends MenuBottomSheetDial stylesMap = generateStylesMap(context); if (savedInstanceState == null) { - selectedStyle = getMyApplication().getRendererRegistry().getCurrentSelectedRenderer().getName(); + RenderingRulesStorage current = getMyApplication().getRendererRegistry().getCurrentSelectedRenderer(); + if (current != null) { + selectedStyle = current.getName(); + } } else { selectedStyle = savedInstanceState.getString(SELECTED_STYLE_KEY); } + if(selectedStyle == null) { + selectedStyle = RendererRegistry.DEFAULT_RENDER; + } rbColorList = AndroidUtils.createCheckedColorStateList(context, R.color.icon_color, getActiveColorId()); diff --git a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java index 3ccc4f4cf9..321c697869 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java @@ -381,7 +381,7 @@ public class GpxUiHelper { public void onClick(DialogInterface dialog, int which) { int position = selectedPosition[0]; - if (position != -1) { + if (position != -1 && position < list.size()) { if (showCurrentGpx && position == 0) { callbackWithObject.processResult(null); app.getSettings().LAST_SELECTED_GPX_TRACK_FOR_NEW_POINT.set(null); diff --git a/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java b/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java index 266e034af1..9ba7d1a58a 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java @@ -33,7 +33,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; -import java.util.EnumSet; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -54,6 +53,7 @@ public class WaypointHelper { private static final int LONG_ANNOUNCE_RADIUS = 700; private static final int SHORT_ANNOUNCE_RADIUS = 150; private static final int ALARMS_ANNOUNCE_RADIUS = 150; + private static final int ALARMS_SHORT_ANNOUNCE_RADIUS = 100; // don't annoy users by lots of announcements private static final int APPROACH_POI_LIMIT = 1; @@ -70,8 +70,9 @@ public class WaypointHelper { public static final int[] SEARCH_RADIUS_VALUES = {50, 100, 200, 500, 1000, 2000, 5000}; private static final double DISTANCE_IGNORE_DOUBLE_SPEEDCAMS = 150; - private List> locationPoints = new ArrayList>(); - private ConcurrentHashMap locationPointsStates = new ConcurrentHashMap(); + private List> locationPoints = new ArrayList<>(); + private ConcurrentHashMap locationPointsStates = new ConcurrentHashMap<>(); + private ConcurrentHashMap lastAnnouncedAlarms = new ConcurrentHashMap<>(); private TIntArrayList pointsProgress = new TIntArrayList(); private RouteCalculationResult route; @@ -342,6 +343,8 @@ public class WaypointHelper { kIterator++; } pointsProgress.set(type, kIterator); + + VoiceRouter voiceRouter = getVoiceRouter(); while (kIterator < lp.size()) { LocationPointWrapper lwp = lp.get(kIterator); if (type == ALARMS && lwp.routeIndex < currentRoute) { @@ -356,18 +359,43 @@ public class WaypointHelper { double d1 = Math.max(0.0, MapUtils.getDistance(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude(), point.getLatitude(), point.getLongitude()) - lwp.getDeviationDistance()); Integer state = locationPointsStates.get(point); - if (state != null && state.intValue() == ANNOUNCED_ONCE - && getVoiceRouter().isDistanceLess(lastKnownLocation.getSpeed(), d1, SHORT_ANNOUNCE_RADIUS, 0f)) { + if (state != null && state == ANNOUNCED_ONCE + && voiceRouter.isDistanceLess(lastKnownLocation.getSpeed(), d1, SHORT_ANNOUNCE_RADIUS, 0f)) { locationPointsStates.put(point, ANNOUNCED_DONE); announcePoints.add(lwp); } else if (type != ALARMS && (state == null || state == NOT_ANNOUNCED) - && getVoiceRouter().isDistanceLess(lastKnownLocation.getSpeed(), d1, LONG_ANNOUNCE_RADIUS, 0f)) { - locationPointsStates.put(point, ANNOUNCED_ONCE); - approachPoints.add(lwp); - } else if (type == ALARMS && (state == null || state == NOT_ANNOUNCED) - && getVoiceRouter().isDistanceLess(lastKnownLocation.getSpeed(), d1, ALARMS_ANNOUNCE_RADIUS, 0f)) { + && voiceRouter.isDistanceLess(lastKnownLocation.getSpeed(), d1, LONG_ANNOUNCE_RADIUS, 0f)) { locationPointsStates.put(point, ANNOUNCED_ONCE); approachPoints.add(lwp); + } else if (type == ALARMS && (state == null || state == NOT_ANNOUNCED)) { + AlarmInfo alarm = (AlarmInfo) point; + AlarmInfoType t = alarm.getType(); + int announceRadius; + boolean filter = false; + switch (t) { + case TRAFFIC_CALMING: + announceRadius = ALARMS_SHORT_ANNOUNCE_RADIUS; + filter = true; + break; + default: + announceRadius = ALARMS_ANNOUNCE_RADIUS; + break; + } + boolean proceed = voiceRouter.isDistanceLess(lastKnownLocation.getSpeed(), d1, announceRadius, 0f); + if (proceed && filter) { + AlarmInfo lastAlarm = lastAnnouncedAlarms.get(t); + if (lastAlarm != null) { + double dist = MapUtils.getDistance(lastAlarm.getLatitude(), lastAlarm.getLongitude(), alarm.getLatitude(), alarm.getLongitude()); + if (dist < ALARMS_SHORT_ANNOUNCE_RADIUS) { + locationPointsStates.put(point, ANNOUNCED_DONE); + proceed = false; + } + } + } + if (proceed) { + locationPointsStates.put(point, ANNOUNCED_ONCE); + approachPoints.add(lwp); + } } } kIterator++; @@ -377,13 +405,13 @@ public class WaypointHelper { announcePoints = announcePoints.subList(0, ANNOUNCE_POI_LIMIT); } if (type == WAYPOINTS) { - getVoiceRouter().announceWaypoint(announcePoints); + voiceRouter.announceWaypoint(announcePoints); } else if (type == POI) { - getVoiceRouter().announcePoi(announcePoints); + voiceRouter.announcePoi(announcePoints); } else if (type == ALARMS) { // nothing to announce } else if (type == FAVORITES) { - getVoiceRouter().announceFavorite(announcePoints); + voiceRouter.announceFavorite(announcePoints); } } if (!approachPoints.isEmpty()) { @@ -391,19 +419,17 @@ public class WaypointHelper { approachPoints = approachPoints.subList(0, APPROACH_POI_LIMIT); } if (type == WAYPOINTS) { - getVoiceRouter().approachWaypoint(lastKnownLocation, approachPoints); + voiceRouter.approachWaypoint(lastKnownLocation, approachPoints); } else if (type == POI) { - getVoiceRouter().approachPoi(lastKnownLocation, approachPoints); + voiceRouter.approachPoi(lastKnownLocation, approachPoints); } else if (type == ALARMS) { - EnumSet ait = EnumSet.noneOf(AlarmInfoType.class); for (LocationPointWrapper pw : approachPoints) { - ait.add(((AlarmInfo) pw.point).getType()); - } - for (AlarmInfoType t : ait) { - app.getRoutingHelper().getVoiceRouter().announceAlarm(new AlarmInfo(t, -1), lastKnownLocation.getSpeed()); + AlarmInfo alarm = (AlarmInfo) pw.point; + voiceRouter.announceAlarm(new AlarmInfo(alarm.getType(), -1), lastKnownLocation.getSpeed()); + lastAnnouncedAlarms.put(alarm.getType(), alarm); } } else if (type == FAVORITES) { - getVoiceRouter().approachFavorite(lastKnownLocation, approachPoints); + voiceRouter.approachFavorite(lastKnownLocation, approachPoints); } } } @@ -455,6 +481,7 @@ public class WaypointHelper { public void clearAllVisiblePoints() { this.locationPointsStates.clear(); + this.lastAnnouncedAlarms.clear(); this.locationPoints = new ArrayList>(); } @@ -544,6 +571,7 @@ public class WaypointHelper { protected synchronized void setLocationPoints(List> locationPoints, RouteCalculationResult route) { this.locationPoints = locationPoints; this.locationPointsStates.clear(); + this.lastAnnouncedAlarms.clear(); TIntArrayList list = new TIntArrayList(locationPoints.size()); list.fill(0, locationPoints.size(), 0); this.pointsProgress = list; diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java index 06b4717b21..4d6132baf1 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java @@ -1287,7 +1287,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo } int line3Height = 0; - View line3Container = view.findViewById(R.id.additional_info_row); + View line3Container = view.findViewById(R.id.additional_info_row_container); if (line3Container.getVisibility() == View.VISIBLE) { line3Height = line3Container.getMeasuredHeight(); } @@ -1520,10 +1520,13 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo && compassView.getVisibility() == View.INVISIBLE && titleButtonContainer.getVisibility() == View.GONE && downloadButtonsContainer.getVisibility() == View.GONE - && titleBottomButtonContainer.getVisibility() == View.GONE - && titleProgressContainer.getVisibility() == View.VISIBLE) { + && titleBottomButtonContainer.getVisibility() == View.GONE) { + if (titleProgressContainer.getVisibility() == View.VISIBLE) { + view.findViewById(R.id.additional_info_row_container).setVisibility(View.GONE); + } view.findViewById(R.id.additional_info_row).setVisibility(View.GONE); } else { + view.findViewById(R.id.additional_info_row_container).setVisibility(View.VISIBLE); view.findViewById(R.id.additional_info_row).setVisibility(View.VISIBLE); } } @@ -1909,6 +1912,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo private void doAfterMenuStateChange(int previousState, int newState) { updateCompassVisibility(); updateAdditionalInfoVisibility(); + runLayoutListener(); } } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index 6bd5beaf65..3605b06f02 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -13,6 +13,7 @@ import android.net.Uri; import android.os.AsyncTask; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; +import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v7.view.ContextThemeWrapper; import android.text.ClipboardManager; import android.text.TextUtils; @@ -752,7 +753,10 @@ public class MenuBuilder { public Drawable getRowIcon(Context ctx, String fileName) { Drawable d = RenderingIcons.getBigIcon(ctx, fileName); if (d != null) { - d.setColorFilter(app.getResources().getColor(light ? R.color.ctx_menu_bottom_view_icon_light : R.color.ctx_menu_bottom_view_icon_dark), PorterDuff.Mode.SRC_IN); + d = DrawableCompat.wrap(d); + d.mutate(); + d.setColorFilter(app.getResources().getColor(light + ? R.color.ctx_menu_bottom_view_icon_light : R.color.ctx_menu_bottom_view_icon_dark), PorterDuff.Mode.SRC_IN); return d; } else { return null; diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java index 6e820a0622..6479301de4 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java @@ -11,7 +11,6 @@ import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.view.ContextThemeWrapper; -import android.text.Html; import android.text.TextUtils; import android.text.util.Linkify; import android.view.Gravity; @@ -26,6 +25,7 @@ import net.osmand.data.Amenity; import net.osmand.data.PointDescription; import net.osmand.osm.AbstractPoiType; import net.osmand.osm.MapPoiTypes; +import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiType; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; @@ -35,13 +35,13 @@ import net.osmand.plus.Version; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.mapcontextmenu.MenuBuilder; -import net.osmand.plus.wikipedia.WikiArticleHelper; -import net.osmand.plus.wikipedia.WikipediaArticleWikiLinkFragment; -import net.osmand.plus.wikipedia.WikipediaDialogFragment; import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.views.POIMapLayer; import net.osmand.plus.widgets.TextViewEx; +import net.osmand.plus.wikipedia.WikiArticleHelper; +import net.osmand.plus.wikipedia.WikipediaArticleWikiLinkFragment; +import net.osmand.plus.wikipedia.WikipediaDialogFragment; import net.osmand.util.Algorithms; import net.osmand.util.OpeningHoursParser; @@ -50,6 +50,7 @@ import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -345,6 +346,7 @@ public class AmenityMenuBuilder extends MenuBuilder { Map> poiAdditionalCategories = new HashMap<>(); AmenityInfoRow cuisineRow = null; + List collectedPoiTypes = new ArrayList<>(); for (Map.Entry e : amenity.getAdditionalInfo().entrySet()) { int iconId = 0; @@ -363,14 +365,15 @@ public class AmenityMenuBuilder extends MenuBuilder { boolean isWiki = false; boolean isText = false; boolean isDescription = false; - boolean needLinks = !("population".equals(key) - || "height".equals(key)); + boolean needLinks = !("population".equals(key) || "height".equals(key)); boolean isPhoneNumber = false; boolean isUrl = false; boolean isCuisine = false; int poiTypeOrder = 0; String poiTypeKeyName = ""; + PoiType poiType = amenity.getType().getPoiTypeByKeyName(key); + AbstractPoiType pt = poiTypes.getAnyPoiAdditionalTypeByKey(key); if (pt == null && !Algorithms.isEmpty(vl) && vl.length() < 50) { pt = poiTypes.getAnyPoiAdditionalTypeByKey(key + "_" + vl); @@ -474,6 +477,8 @@ public class AmenityMenuBuilder extends MenuBuilder { iconId = R.drawable.ic_action_poi_name; } else if (key.equals("operator") || key.equals("brand")) { iconId = R.drawable.ic_action_poi_brand; + } else if (key.equals("internet_access_fee_yes")) { + iconId = R.drawable.ic_action_internet_access_fee; } else { iconId = R.drawable.ic_action_info_dark; } @@ -500,6 +505,8 @@ public class AmenityMenuBuilder extends MenuBuilder { if (icon == null && isText && iconId == 0) { iconId = R.drawable.ic_action_note_dark; } + } else if (poiType != null) { + collectedPoiTypes.add(poiType); } else { textPrefix = Algorithms.capitalizeFirstLetterAndLowercase(e.getKey()); vl = amenity.unzipContent(e.getValue()); @@ -523,12 +530,10 @@ public class AmenityMenuBuilder extends MenuBuilder { } if (isDescription) { descriptions.add(row); - } else { - if (!isCuisine) { - infoRows.add(row); - } else { - cuisineRow = row; - } + } else if (isCuisine) { + cuisineRow = row; + } else if (poiType == null) { + infoRows.add(row); } } @@ -567,12 +572,27 @@ public class AmenityMenuBuilder extends MenuBuilder { sb.append(pt.getTranslation()); } boolean cuisineOrDish = categoryName.equals(Amenity.CUISINE) || categoryName.equals(Amenity.DISH); - CollapsableView collapsableView = getPoiAdditionalCollapsableView(view.getContext(), true, categoryTypes, cuisineOrDish ? cuisineRow : null); + CollapsableView collapsableView = getPoiTypeCollapsableView(view.getContext(), true, categoryTypes, true, cuisineOrDish ? cuisineRow : null); infoRows.add(new AmenityInfoRow(poiAdditionalCategoryName, icon, pType.getPoiAdditionalCategoryTranslation(), sb.toString(), true, collapsableView, 0, false, false, false, pType.getOrder(), pType.getKeyName(), false, false, false, 1)); } } + if (collectedPoiTypes.size() > 0) { + CollapsableView collapsableView = getPoiTypeCollapsableView(view.getContext(), true, collectedPoiTypes, false, null); + PoiCategory poiCategory = amenity.getType(); + Drawable icon = getRowIcon(view.getContext(), poiCategory.getIconKeyName()); + StringBuilder sb = new StringBuilder(); + for (PoiType pt : collectedPoiTypes) { + if (sb.length() > 0) { + sb.append(" • "); + } + sb.append(pt.getTranslation()); + } + infoRows.add(new AmenityInfoRow(poiCategory.getKeyName(), icon, poiCategory.getTranslation(), sb.toString(), true, collapsableView, + 0, false, false, false, 40, poiCategory.getKeyName(), false, false, false, 1)); + } + Collections.sort(infoRows, new Comparator() { @Override public int compare(AmenityInfoRow row1, AmenityInfoRow row2) { @@ -610,7 +630,7 @@ public class AmenityMenuBuilder extends MenuBuilder { if (processNearstWiki() && nearestWiki.size() > 0) { AmenityInfoRow wikiInfo = new AmenityInfoRow( - "nearest_wiki", R.drawable.ic_action_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", true, + "nearest_wiki", R.drawable.ic_plugin_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", true, getCollapsableWikiView(view.getContext(), true), 0, false, false, false, 1000, null, false, false, false, 0); buildAmenityRow(view, wikiInfo); @@ -663,9 +683,9 @@ public class AmenityMenuBuilder extends MenuBuilder { return params; } - private CollapsableView getPoiAdditionalCollapsableView( - final Context context, boolean collapsed, - @NonNull final List categoryTypes, AmenityInfoRow textCuisineRow) { + private CollapsableView getPoiTypeCollapsableView(final Context context, boolean collapsed, + @NonNull final List categoryTypes, + final boolean poiAdditional, AmenityInfoRow textRow) { final List buttons = new ArrayList<>(); @@ -683,9 +703,15 @@ public class AmenityMenuBuilder extends MenuBuilder { PoiUIFilter filter = app.getPoiFilters().getFilterById(PoiUIFilter.STD_PREFIX + amenity.getType().getKeyName()); if (filter != null) { filter.clearFilter(); - filter.setTypeToAccept(amenity.getType(), true); - filter.updateTypesToAccept(pt); - filter.setFilterByName(pt.getKeyName().replace('_', ':').toLowerCase()); + if (poiAdditional) { + filter.setTypeToAccept(amenity.getType(), true); + filter.updateTypesToAccept(pt); + filter.setFilterByName(pt.getKeyName().replace('_', ':').toLowerCase()); + } else { + LinkedHashSet accept = new LinkedHashSet<>(); + accept.add(pt.getKeyName()); + filter.selectSubTypesToAccept(amenity.getType(), accept); + } getMapActivity().showQuickSearch(filter); } } @@ -698,9 +724,9 @@ public class AmenityMenuBuilder extends MenuBuilder { view.addView(button); } - if (textCuisineRow != null) { + if (textRow != null) { TextViewEx button = buildButtonInCollapsableView(context, true, false, false); - String name = textCuisineRow.textPrefix + ": " + textCuisineRow.text.toLowerCase(); + String name = textRow.textPrefix + ": " + textRow.text.toLowerCase(); button.setText(name); view.addView(button); } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragment.java index 436ccc3a6d..ea1cdc9fb2 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragment.java @@ -183,6 +183,9 @@ public class FavoritePointEditorFragment extends PointEditorFragment { } else { helper.editFavouriteName(favorite, name, category, description); } + if(getMapActivity() == null) { + return; + } getMapActivity().refreshMap(); if (needDismiss) { dismiss(false); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MarkersPlanRouteContext.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MarkersPlanRouteContext.java index 1b77f6f079..361586f311 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MarkersPlanRouteContext.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MarkersPlanRouteContext.java @@ -218,6 +218,12 @@ public class MarkersPlanRouteContext { params.ctx = app; params.calculationProgress = calculationProgress = new RouteCalculationProgress(); params.calculationProgressCallback = new RoutingHelper.RouteCalculationProgressCallback() { + + @Override + public void start() { + + } + @Override public void updateProgress(int progress) { int pairs = calculatedPairs + snapToRoadPairsToCalculate.size(); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java index 34dd0b1e5a..fb61e0c3e2 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java @@ -284,6 +284,12 @@ public class MeasurementEditingContext { params.ctx = application; params.calculationProgress = calculationProgress = new RouteCalculationProgress(); params.calculationProgressCallback = new RoutingHelper.RouteCalculationProgressCallback() { + + @Override + public void start() { + + } + @Override public void updateProgress(int progress) { int pairs = calculatedPairs + snapToRoadPairsToCalculate.size(); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java index 5724d816d9..97e7f44bbe 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java @@ -1,6 +1,7 @@ package net.osmand.plus.myplaces; import android.content.Context; +import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.os.AsyncTask; @@ -36,6 +37,7 @@ import net.osmand.plus.GPXUtilities.WptPt; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; +import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandSettings; @@ -238,10 +240,19 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { GPXFile gpx = getGpx(); WptPt pointToShow = gpx != null ? gpx.findPointToShow() : null; if (activity != null && pointToShow != null) { + boolean gpxFileSelected = isGpxFileSelected(gpx); + if (!gpxFileSelected) { + Intent intent = activity.getIntent(); + if (intent != null) { + intent.putExtra(TrackActivity.SHOW_TEMPORARILY, true); + } + } + setTrackVisibilityOnMap(true); + LatLon location = new LatLon(pointToShow.getLatitude(), pointToShow.getLongitude()); final OsmandSettings settings = app.getSettings(); - String trackName = ""; + String trackName; if (gpx.showCurrentTrack) { trackName = app.getString(R.string.shared_string_currently_recording_track); } else if (gpxDataItem != null) { @@ -265,15 +276,14 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { final View splitIntervalView = headerView.findViewById(R.id.split_interval_view); final View colorView = headerView.findViewById(R.id.color_view); vis = (SwitchCompat) headerView.findViewById(R.id.showOnMapToggle); + final View bottomDivider = headerView.findViewById(R.id.bottom_divider); GPXFile gpxFile = getGpx(); - final boolean selected = gpxFile != null && - ((gpxFile.showCurrentTrack && app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null) || - (gpxFile.path != null && app.getSelectedGpxHelper().getSelectedFileByPath(gpxFile.path) != null)); + boolean gpxFileSelected = isGpxFileSelected(gpxFile); boolean hasPath = gpxFile != null && (gpxFile.tracks.size() > 0 || gpxFile.routes.size() > 0); TrackActivity activity = getTrackActivity(); TrackBitmapDrawer trackDrawer = getTrackBitmapDrawer(); - if (activity != null && trackDrawer!= null) { + if (activity != null && trackDrawer != null) { if (trackDrawer.isNonInitialized()) { if (trackDrawer.initAndDraw()) { imageView.setVisibility(View.VISIBLE); @@ -285,31 +295,33 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { } } - if (showMapOnly) { - headerView.findViewById(R.id.track_settings_view).setVisibility(View.GONE); - } else { - vis.setChecked(selected); - vis.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (!isChecked) { - selectedSplitInterval = 0; - } - GPXFile gpxFile = getGpx(); - if (gpxFile != null) { - GpxSelectionHelper.SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpxFile, vis.isChecked(), false); - final List groups = getDisplayGroups(); - if (groups.size() > 0) { - updateSplit(groups, vis.isChecked() ? sf : null); - if (getGpxDataItem() != null) { - updateSplitInDatabase(); - } - } - } + vis.setChecked(gpxFileSelected); + vis.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (!isChecked) { + selectedSplitInterval = 0; + } + setTrackVisibilityOnMap(vis.isChecked()); + if (!showMapOnly) { updateSplitIntervalView(splitIntervalView); updateColorView(colorView); } - }); + TrackActivity trackActivity = getTrackActivity(); + if (trackActivity != null) { + trackActivity.updateHeader(fragment); + } + } + }); + + if (showMapOnly) { + splitIntervalView.setVisibility(View.GONE); + splitColorView.setVisibility(View.GONE); + divider.setVisibility(View.GONE); + bottomDivider.setVisibility(View.VISIBLE); + } else { + bottomDivider.setVisibility(View.GONE); + updateColorView(colorView); colorView.setOnClickListener(new View.OnClickListener() { @Override @@ -338,7 +350,7 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { int clr = item.getColor(); if (vis.isChecked()) { if (gpx != null) { - GpxSelectionHelper.SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, vis.isChecked(), false); + SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, vis.isChecked(), false); if (clr != 0 && sf.getModifiableGpxFile() != null) { sf.getModifiableGpxFile().setColor(clr); if (getGpxDataItem() != null) { @@ -388,17 +400,7 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { selectedSplitInterval = position; - GPXFile gpx = getGpx(); - if (gpx != null) { - GpxSelectionHelper.SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, vis.isChecked(), false); - final List groups = getDisplayGroups(); - if (groups.size() > 0) { - updateSplit(groups, vis.isChecked() ? sf : null); - if (getGpxDataItem() != null) { - updateSplitInDatabase(); - } - } - } + setTrackVisibilityOnMap(vis.isChecked()); splitListPopupWindow.dismiss(); updateSplitIntervalView(splitIntervalView); } @@ -420,6 +422,29 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { } } + public boolean isGpxFileSelected(GPXFile gpxFile) { + return gpxFile != null && + ((gpxFile.showCurrentTrack && app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null) || + (gpxFile.path != null && app.getSelectedGpxHelper().getSelectedFileByPath(gpxFile.path) != null)); + } + + private void setTrackVisibilityOnMap(boolean visible) { + GPXFile gpxFile = getGpx(); + if (gpxFile != null) { + GpxSelectionHelper gpxHelper = app.getSelectedGpxHelper(); + SelectedGpxFile sf = gpxHelper.selectGpxFile(gpxFile, visible, false); + if (gpxFile.hasTrkPt()) { + List groups = getDisplayGroups(); + if (groups.size() > 0) { + updateSplit(groups, visible ? sf : null); + if (getGpxDataItem() != null) { + updateSplitInDatabase(); + } + } + } + } + } + @Nullable private QuadRect getRect() { TrackActivity activity = getTrackActivity(); @@ -574,7 +599,7 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { addOptionSplit(3600, false, groups); } - private void updateSplit(@NonNull List groups, @Nullable GpxSelectionHelper.SelectedGpxFile sf) { + private void updateSplit(@NonNull List groups, @Nullable SelectedGpxFile sf) { TrackActivity activity = getTrackActivity(); if (activity != null) { new SplitTrackAsyncTask(activity, this, sf, groups) @@ -582,27 +607,29 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { } } - private void addOptionSplit(int value, boolean distance, List model) { - if (distance) { - double dvalue = OsmAndFormatter.calculateRoundedDist(value, app); - options.add(OsmAndFormatter.getFormattedDistance((float) dvalue, app)); - distanceSplit.add(dvalue); - timeSplit.add(-1); - if (Math.abs(model.get(0).getSplitDistance() - dvalue) < 1) { - selectedSplitInterval = distanceSplit.size() - 1; - } - } else { - if (value < 60) { - options.add(value + " " + app.getString(R.string.int_seconds)); - } else if (value % 60 == 0) { - options.add((value / 60) + " " + app.getString(R.string.int_min)); + private void addOptionSplit(int value, boolean distance, @NonNull List model) { + if (model.size() > 0) { + if (distance) { + double dvalue = OsmAndFormatter.calculateRoundedDist(value, app); + options.add(OsmAndFormatter.getFormattedDistance((float) dvalue, app)); + distanceSplit.add(dvalue); + timeSplit.add(-1); + if (Math.abs(model.get(0).getSplitDistance() - dvalue) < 1) { + selectedSplitInterval = distanceSplit.size() - 1; + } } else { - options.add((value / 60f) + " " + app.getString(R.string.int_min)); - } - distanceSplit.add(-1d); - timeSplit.add(value); - if (model.get(0).getSplitTime() == value) { - selectedSplitInterval = distanceSplit.size() - 1; + if (value < 60) { + options.add(value + " " + app.getString(R.string.int_seconds)); + } else if (value % 60 == 0) { + options.add((value / 60) + " " + app.getString(R.string.int_min)); + } else { + options.add((value / 60f) + " " + app.getString(R.string.int_min)); + } + distanceSplit.add(-1d); + timeSplit.add(value); + if (model.get(0).getSplitTime() == value) { + selectedSplitInterval = distanceSplit.size() - 1; + } } } } @@ -629,7 +656,7 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { public void updateSplitView() { GPXFile gpxFile = getGpx(); if (gpxFile != null) { - GpxSelectionHelper.SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpxFile, + SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpxFile, ((SwitchCompat) headerView.findViewById(R.id.showOnMapToggle)).isChecked(), false); final List groups = getDisplayGroups(); if (groups.size() > 0) { @@ -749,7 +776,7 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { } private static class SplitTrackAsyncTask extends AsyncTask { - private final GpxSelectionHelper.SelectedGpxFile selectedGpx; + private final SelectedGpxFile selectedGpx; private OsmandApplication app; private final WeakReference activityRef; private final WeakReference fragmentAdapterRef; @@ -761,7 +788,7 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { SplitTrackAsyncTask(@NonNull TrackActivity activity, @NonNull TrackActivityFragmentAdapter fragmentAdapter, - @Nullable GpxSelectionHelper.SelectedGpxFile selectedGpx, + @Nullable SelectedGpxFile selectedGpx, @NonNull List groups) { activityRef = new WeakReference<>(activity); fragmentAdapterRef = new WeakReference<>(fragmentAdapter); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackBitmapDrawer.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackBitmapDrawer.java index a1999f454e..de4df5d6b3 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackBitmapDrawer.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackBitmapDrawer.java @@ -266,7 +266,7 @@ public class TrackBitmapDrawer { float x = tileBox.getPixXFromLatLon(o.lat, o.lon); float y = tileBox.getPixYFromLatLon(o.lat, o.lon); - int pointColor = o.getColor(fileColor); + int pointColor = o.getColor(fileColor) | 0xff000000; paintIcon.setColorFilter(new PorterDuffColorFilter(pointColor, PorterDuff.Mode.MULTIPLY)); canvas.drawBitmap(pointSmall, x - pointSmall.getWidth() / 2, y - pointSmall.getHeight() / 2, paintIcon); } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java index 6ee6bed9fe..a40b433830 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java @@ -633,8 +633,19 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements } updateSelectionMode(actionMode); } else { - if (item.group.getGpx() != null) { - app.getSelectedGpxHelper().setGpxFileToDisplay(item.group.getGpx()); + GPXFile gpx = item.group.getGpx(); + if (gpx != null) { + TrackActivity trackActivity = getTrackActivity(); + if (trackActivity != null && fragmentAdapter != null) { + boolean gpxFileSelected = fragmentAdapter.isGpxFileSelected(gpx); + if (!gpxFileSelected) { + Intent intent = trackActivity.getIntent(); + if (intent != null) { + intent.putExtra(TrackActivity.SHOW_TEMPORARILY, true); + } + } + } + app.getSelectedGpxHelper().setGpxFileToDisplay(gpx); } final OsmandSettings settings = app.getSettings(); LatLon location = new LatLon(item.locationStart.lat, item.locationStart.lon); @@ -675,6 +686,12 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements } } + public void updateHeader() { + if (fragmentAdapter != null) { + fragmentAdapter.updateHeader(0); + } + } + class PointGPXAdapter extends OsmandBaseExpandableListAdapter implements Filterable { Map> itemGroups = new LinkedHashMap<>(); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java index 47b4013e83..c49f2a6ef4 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java @@ -253,7 +253,7 @@ public class TrackSegmentFragment extends OsmAndListFragment implements TrackBit } } - private void updateHeader() { + public void updateHeader() { if (fragmentAdapter != null) { fragmentAdapter.updateHeader(adapter.getCount()); } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/AdvancedEditPoiFragment.java b/OsmAnd/src/net/osmand/plus/osmedit/AdvancedEditPoiFragment.java index 64fd505d75..dab14a0284 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/AdvancedEditPoiFragment.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/AdvancedEditPoiFragment.java @@ -143,7 +143,12 @@ public class AdvancedEditPoiFragment extends BaseOsmAndFragment amenityTagTextView.setText(pt.getEditOsmTag()); amenityTextView.setText(pt.getEditOsmValue()); } else { - amenityTagTextView.setText(getData().getPoiCategory().getDefaultTag()); + PoiCategory category = getData().getPoiCategory(); + if (category != null) { + amenityTagTextView.setText(category.getDefaultTag()); + } else { + amenityTagTextView.setText(R.string.tag_poi_amenity); + } amenityTextView.setText(getData().getPoiTypeString()); } } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/EditPoiData.java b/OsmAnd/src/net/osmand/plus/osmedit/EditPoiData.java index d64264c9eb..f818a30175 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/EditPoiData.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/EditPoiData.java @@ -1,5 +1,7 @@ package net.osmand.plus.osmedit; +import android.support.annotation.Nullable; + import net.osmand.PlatformUtil; import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiType; @@ -52,7 +54,7 @@ public class EditPoiData { } } - + @Nullable public PoiCategory getPoiCategory() { return category; } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/EditPoiDialogFragment.java b/OsmAnd/src/net/osmand/plus/osmedit/EditPoiDialogFragment.java index 4532a1349f..21d76332e9 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/EditPoiDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/EditPoiDialogFragment.java @@ -273,7 +273,10 @@ public class EditPoiDialogFragment extends BaseOsmAndDialogFragment { if (!getEditPoiData().isInEdit()) { getEditPoiData().updateTypeTag(s.toString(), true); if (!getMyApplication().isApplicationInitializing()) { - poiTypeTextInputLayout.setHint(editPoiData.getPoiCategory().getTranslation()); + PoiCategory category = editPoiData.getPoiCategory(); + if (category != null) { + poiTypeTextInputLayout.setHint(category.getTranslation()); + } } } } @@ -289,9 +292,10 @@ public class EditPoiDialogFragment extends BaseOsmAndDialogFragment { if (event.getX() >= (editText.getRight() - editText.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width() - editText.getPaddingRight())) { - if (editPoiData.getPoiCategory() != null) { + PoiCategory category = editPoiData.getPoiCategory(); + if (category != null) { PoiSubTypeDialogFragment dialogFragment = - PoiSubTypeDialogFragment.createInstance(editPoiData.getPoiCategory()); + PoiSubTypeDialogFragment.createInstance(category); dialogFragment.setOnItemSelectListener(new PoiSubTypeDialogFragment.OnItemSelectListener() { @Override public void select(String category) { @@ -466,8 +470,10 @@ public class EditPoiDialogFragment extends BaseOsmAndDialogFragment { node.removeTag(EditPoiData.REMOVE_TAG_PREFIX + poiType.getOsmTag2()); } } else if (!Algorithms.isEmpty(poiTypeTag)) { - node.putTagNoLC(editPoiData.getPoiCategory().getDefaultTag(), poiTypeTag); - + PoiCategory category = editPoiData.getPoiCategory(); + if (category != null) { + node.putTagNoLC(category.getDefaultTag(), poiTypeTag); + } } if (offlineEdit && !Algorithms.isEmpty(poiTypeTag)) { node.putTagNoLC(EditPoiData.POI_TYPE_TAG, poiTypeTag); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java index a0adce7a5c..913903d041 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java @@ -109,8 +109,7 @@ public class QuickActionListFragment extends BaseOsmAndFragment implements Quick private void setUpToolbar(View view) { Toolbar toolbar = (Toolbar) view.findViewById(R.id.custom_toolbar); - Drawable back = getMyApplication().getIconsCache().getIcon(R.drawable.ic_arrow_back); - back.setColorFilter(ContextCompat.getColor(getContext(), R.color.color_white), PorterDuff.Mode.MULTIPLY); + Drawable back = getMyApplication().getIconsCache().getIcon(R.drawable.ic_arrow_back, R.color.color_white); toolbar.setNavigationIcon(back); toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up); toolbar.setNavigationOnClickListener(new View.OnClickListener() { diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/AddPOIAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/AddPOIAction.java index d264656730..7eac6c5123 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/AddPOIAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/AddPOIAction.java @@ -117,8 +117,10 @@ public class AddPOIAction extends QuickAction { newNode.putTagNoLC(poiType.getOsmTag2(), poiType.getOsmValue2()); } } else if (!Algorithms.isEmpty(tag.getValue())) { - newNode.putTagNoLC(editPoiData.getPoiCategory().getDefaultTag(), tag.getValue()); - + PoiCategory category = editPoiData.getPoiCategory(); + if (category != null) { + newNode.putTagNoLC(category.getDefaultTag(), tag.getValue()); + } } if (offlineEdit && !Algorithms.isEmpty(tag.getValue())) { newNode.putTagNoLC(tag.getKey(), tag.getValue()); diff --git a/OsmAnd/src/net/osmand/plus/resources/IncrementalChangesManager.java b/OsmAnd/src/net/osmand/plus/resources/IncrementalChangesManager.java index bfa84f2fdf..fba620ff0b 100644 --- a/OsmAnd/src/net/osmand/plus/resources/IncrementalChangesManager.java +++ b/OsmAnd/src/net/osmand/plus/resources/IncrementalChangesManager.java @@ -94,6 +94,9 @@ public class IncrementalChangesManager { RegionUpdate monthRu = regionUpdateFiles.monthUpdates.get(month); while (it.hasNext()) { RegionUpdate ru = it.next(); + if(ru == null) { + continue; + } if (ru.obfCreated < dateCreated || (monthRu != null && ru.obfCreated < monthRu.obfCreated)) { log.info("Delete overlapping day update " + ru.file.getName()); @@ -161,10 +164,12 @@ public class IncrementalChangesManager { if(date.endsWith("00")) { monthUpdates.put(monthYear, ru); } else { - if (!dayUpdates.containsKey(monthYear)) { - dayUpdates.put(monthYear, new ArrayList()); + List list = dayUpdates.get(monthYear); + if (list == null) { + list = new ArrayList(); } - dayUpdates.get(monthYear).add(ru); + list.add(ru); + dayUpdates.put(monthYear, list); } return true; } diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java index 90287ed9ba..afd6f7afd2 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java @@ -5,6 +5,7 @@ import android.content.Context; import net.osmand.Location; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule; +import net.osmand.binary.RouteDataObject; import net.osmand.data.LatLon; import net.osmand.data.LocationPoint; import net.osmand.plus.ApplicationMode; @@ -13,6 +14,7 @@ import net.osmand.plus.R; import net.osmand.plus.routing.AlarmInfo.AlarmInfoType; import net.osmand.router.RouteSegmentResult; import net.osmand.router.TurnType; +import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import java.util.ArrayList; @@ -74,7 +76,7 @@ public class RouteCalculationResult { addMissingTurnsToRoute(locations, localDirections, params.start,params.end, params.mode, params.ctx, params.leftSide); // if there is no closest points to start - add it - introduceFirstPointAndLastPoint(locations, localDirections, null, params.start, params.end); + introduceFirstPointAndLastPoint(locations, localDirections, null, params.start, params.end, params.ctx); } this.appMode = params.mode; this.locations = Collections.unmodifiableList(locations); @@ -99,7 +101,7 @@ public class RouteCalculationResult { List locations = new ArrayList(); ArrayList alarms = new ArrayList(); List segments = convertVectorResult(computeDirections, locations, list, alarms, ctx); - introduceFirstPointAndLastPoint(locations, computeDirections, segments, start, end); + introduceFirstPointAndLastPoint(locations, computeDirections, segments, start, end, ctx); this.locations = Collections.unmodifiableList(locations); this.segments = Collections.unmodifiableList(segments); @@ -584,8 +586,9 @@ public class RouteCalculationResult { * If beginning is too far from start point, then introduce GO Ahead * @param end */ - private static void introduceFirstPointAndLastPoint(List locations, List directions, List segs, Location start, - LatLon end) { + private static void introduceFirstPointAndLastPoint(List locations, List directions, + List segs, Location start, LatLon end, + OsmandApplication ctx) { if (!locations.isEmpty() && locations.get(0).distanceTo(start) > 50) { // add start point locations.add(0, start); @@ -619,6 +622,16 @@ public class RouteCalculationResult { } // Wrong AvgSpeed for the last turn can cause significantly wrong total travel time if calculated route ends on a GPX route segment (then last turn is where GPX is joined again) RouteDirectionInfo info = new RouteDirectionInfo(lastDirInf != null ? lastDirInf.getAverageSpeed() : 1, TurnType.valueOf(type, false)); + if (segs != null) { + RouteSegmentResult lastSegmentResult = segs.get(segs.size() - 1); + RouteDataObject routeDataObject = lastSegmentResult.getObject(); + info.setRef(routeDataObject.getRef(ctx.getSettings().MAP_PREFERRED_LOCALE.get(), + ctx.getSettings().MAP_TRANSLITERATE_NAMES.get(), lastSegmentResult.isForwardDirection())); + info.setStreetName(routeDataObject.getName(ctx.getSettings().MAP_PREFERRED_LOCALE.get(), + ctx.getSettings().MAP_TRANSLITERATE_NAMES.get())); + info.setDestinationName(routeDataObject.getDestinationName(ctx.getSettings().MAP_PREFERRED_LOCALE.get(), + ctx.getSettings().MAP_TRANSLITERATE_NAMES.get(), lastSegmentResult.isForwardDirection())); + } info.distance = 0; info.afterLeftTime = 0; info.routePointOffset = locations.size() - 1; @@ -688,7 +701,19 @@ public class RouteCalculationResult { } return null; } - + + public RouteSegmentResult getNextStreetSegmentResult() { + int cs = currentRoute > 0 ? currentRoute - 1 : 0; + while(cs < segments.size()) { + RouteSegmentResult segmentResult = segments.get(cs); + if (!Algorithms.isEmpty(segmentResult.getObject().getName())) { + return segmentResult; + } + cs++; + } + return null; + } + public List getUpcomingTunnel(float distToStart) { int cs = currentRoute > 0 ? currentRoute - 1 : 0; if(cs < segments.size()) { diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index 29006d7be0..689777d5b3 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -783,19 +783,40 @@ public class RoutingHelper { } RouteSegmentResult rs = getCurrentSegmentResult(); if(rs != null) { - String nm = rs.getObject().getName(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get()); - String rf = rs.getObject().getRef(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get(), rs.isForwardDirection()); - String dn = rs.getObject().getDestinationName(settings.MAP_PREFERRED_LOCALE.get(), - settings.MAP_TRANSLITERATE_NAMES.get(), rs.isForwardDirection()); - return formatStreetName(nm, rf, dn, "»"); + String name = getRouteSegmentStreetName(rs); + if (!Algorithms.isEmpty(name)) { + return name; + } + } + rs = getNextStreetSegmentResult(); + if(rs != null) { + String name = getRouteSegmentStreetName(rs); + if (!Algorithms.isEmpty(name)) { + if(next != null) { + next[0] = TurnType.valueOf(TurnType.C, false); + } + return name; + } } return null; } - public RouteSegmentResult getCurrentSegmentResult() { + private String getRouteSegmentStreetName(RouteSegmentResult rs) { + String nm = rs.getObject().getName(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get()); + String rf = rs.getObject().getRef(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get(), rs.isForwardDirection()); + String dn = rs.getObject().getDestinationName(settings.MAP_PREFERRED_LOCALE.get(), + settings.MAP_TRANSLITERATE_NAMES.get(), rs.isForwardDirection()); + return formatStreetName(nm, rf, dn, "»"); + } + + public RouteSegmentResult getCurrentSegmentResult() { return route.getCurrentSegmentResult(); } + public RouteSegmentResult getNextStreetSegmentResult() { + return route.getNextStreetSegmentResult(); + } + public List getUpcomingTunnel(float distToStart) { return route.getUpcomingTunnel(distToStart); } @@ -962,6 +983,7 @@ public class RoutingHelper { "Calculating route", params, paramsChanged); //$NON-NLS-1$ currentRunningJob = newThread; if (updateProgress) { + startProgress(params); updateProgress(params); } if (prevRunningJob != null) { @@ -971,6 +993,14 @@ public class RoutingHelper { } } + private void startProgress(final RouteCalculationParams params) { + if (params.calculationProgressCallback != null) { + params.calculationProgressCallback.start(); + } else if (progressRoute != null) { + progressRoute.start(); + } + } + private void updateProgress(final RouteCalculationParams params) { final RouteCalculationProgressCallback progressRoute; if (params.calculationProgressCallback != null) { @@ -985,14 +1015,8 @@ public class RoutingHelper { public void run() { RouteCalculationProgress calculationProgress = params.calculationProgress; if (isRouteBeingCalculated()) { - float p = Math.max(calculationProgress.distanceFromBegin, calculationProgress.distanceFromEnd); - float all = calculationProgress.totalEstimatedDistance * 1.25f; - if (all > 0) { - int t = (int) Math.min(p * p / (all * all) * 100f, 99); - progressRoute.updateProgress(t); - } else { - progressRoute.updateProgress(0); - } + float pr = calculationProgress.getLinearProgress(); + progressRoute.updateProgress((int) pr); Thread t = currentRunningJob; if(t instanceof RouteRecalculationThread && ((RouteRecalculationThread) t).params != params) { // different calculation started @@ -1026,10 +1050,13 @@ public class RoutingHelper { public interface RouteCalculationProgressCallback { - // set visibility - public void updateProgress(int progress); - public void requestPrivateAccessRouting(); - public void finish(); + void start(); + + void updateProgress(int progress); + + void requestPrivateAccessRouting(); + + void finish(); } diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java index 5969853e95..767e0cd10e 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java @@ -313,6 +313,9 @@ public abstract class OsmandMapLayer { } } + public void layerOnPreExecute() { + } + public void layerOnPostExecute() { } @@ -350,6 +353,7 @@ public abstract class OsmandMapLayer { @Override protected void onPreExecute() { currentTask = this; + layerOnPreExecute(); } @Override diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java index 58fb851fd5..7b0c5479fa 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java @@ -373,7 +373,10 @@ public class OsmandMapTileView implements IMapDownloaderCallback { if (mainLayer != null) { animatedDraggingThread.stopAnimating(); currentViewport.setZoomAndAnimation(zoom, 0, 0); - currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0); + if (zoom <= LOWEST_ZOOM_TO_ROTATE) { + rotate = 0; + } + currentViewport.setRotate(rotate); refreshMap(); } } @@ -383,7 +386,10 @@ public class OsmandMapTileView implements IMapDownloaderCallback { animatedDraggingThread.stopAnimating(); currentViewport.setZoomAndAnimation(zoom, 0); currentViewport.setMapDensity(mapDensity); - currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0); + if (zoom <= LOWEST_ZOOM_TO_ROTATE) { + rotate = 0; + } + currentViewport.setRotate(rotate); refreshMap(); } } @@ -899,7 +905,10 @@ public class OsmandMapTileView implements IMapDownloaderCallback { protected void zoomToAnimate(int zoom, double zoomToAnimate, boolean notify) { if (mainLayer != null && getMaxZoom() >= zoom && getMinZoom() <= zoom) { currentViewport.setZoomAndAnimation(zoom, zoomToAnimate); - currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0); + if (zoom <= LOWEST_ZOOM_TO_ROTATE) { + rotate = 0; + } + currentViewport.setRotate(rotate); refreshMap(); if (notify && locationListener != null) { locationListener.locationChanged(getLatitude(), getLongitude(), this); diff --git a/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java b/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java index 731534a28b..311e452981 100644 --- a/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java @@ -94,16 +94,20 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon return super.isInterrupted(); } + + @Override + public void layerOnPreExecute() { + calculatedFilters = new TreeSet<>(filters); + } + @Override public void layerOnPostExecute() { - filters = calculatedFilters; activity.getMapView().refreshMap(); } @Override protected List calculateResult(RotatedTileBox tileBox) { QuadRect latLonBounds = tileBox.getLatLonBounds(); - calculatedFilters = filters; if (calculatedFilters.isEmpty() || latLonBounds == null) { return new ArrayList<>(); } diff --git a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java index ce9cf273b4..dd7349b754 100644 --- a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java @@ -1,13 +1,17 @@ package net.osmand.plus.views; -import gnu.trove.list.array.TByteArrayList; -import gnu.trove.list.array.TIntArrayList; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.TreeMap; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Paint.Cap; +import android.graphics.Path; +import android.graphics.PointF; +import android.graphics.PorterDuff.Mode; +import android.graphics.PorterDuffColorFilter; +import android.support.annotation.ColorInt; import net.osmand.Location; import net.osmand.data.LatLon; @@ -21,17 +25,15 @@ import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RoutingHelper; import net.osmand.util.MapUtils; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Paint.Cap; -import android.graphics.Path; -import android.graphics.PointF; -import android.graphics.PorterDuff.Mode; -import android.graphics.PorterDuffColorFilter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.TreeMap; + +import gnu.trove.list.array.TByteArrayList; +import gnu.trove.list.array.TIntArrayList; public class RouteLayer extends OsmandMapLayer { @@ -118,13 +120,7 @@ public class RouteLayer extends OsmandMapLayer { @Override public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { if (helper.getFinalLocation() != null && helper.getRoute().isCalculated()) { - boolean updatePaints = attrs.updatePaints(view, settings, tileBox); - attrs.isPaint3 = false; - attrs.isPaint2 = false; - if(updatePaints) { - paintIconAction.setColorFilter(new PorterDuffColorFilter(attrs.paint3.getColor(), Mode.MULTIPLY)); - paintIcon.setColorFilter(new PorterDuffColorFilter(attrs.paint2.getColor(), Mode.MULTIPLY)); - } + updateAttrs(settings, tileBox); if(coloredArrowUp == null) { Bitmap originalArrowUp = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_route_direction_arrow, null); @@ -174,6 +170,16 @@ public class RouteLayer extends OsmandMapLayer { } + private void updateAttrs(DrawSettings settings, RotatedTileBox tileBox) { + boolean updatePaints = attrs.updatePaints(view, settings, tileBox); + attrs.isPaint3 = false; + attrs.isPaint2 = false; + if(updatePaints) { + paintIconAction.setColorFilter(new PorterDuffColorFilter(attrs.paint3.getColor(), Mode.MULTIPLY)); + paintIcon.setColorFilter(new PorterDuffColorFilter(attrs.paint2.getColor(), Mode.MULTIPLY)); + } + } + private void drawXAxisPoints(Canvas canvas, RotatedTileBox tileBox) { QuadRect latLonBounds = tileBox.getLatLonBounds(); List xAxisPoints = trackChartPoints.getXAxisPoints(); @@ -242,6 +248,12 @@ public class RouteLayer extends OsmandMapLayer { } } } + + @ColorInt + public int getRouteLineColor(boolean night) { + updateAttrs(new DrawSettings(night), view.getCurrentRotatedTileBox()); + return attrs.paint.getColor(); + } private void cullRamerDouglasPeucker(TByteArrayList survivor, List points, int start, int end, double epsillon) { diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java index e17c31b794..0edd5072d6 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java @@ -764,7 +764,6 @@ public class RouteInfoWidgetsFactory { private int dist; private LanesDrawable lanesDrawable; private View centerInfo; - private View progress; private int shadowRadius; public LanesControl(final MapActivity map, final OsmandMapTileView view) { @@ -772,7 +771,6 @@ public class RouteInfoWidgetsFactory { lanesText = (TextView) map.findViewById(R.id.map_lanes_dist_text); lanesShadowText = (TextView) map.findViewById(R.id.map_lanes_dist_text_shadow); centerInfo = (View) map.findViewById(R.id.map_center_info); - progress = (View) map.findViewById(R.id.map_horizontal_progress); lanesDrawable = new LanesDrawable(map, map.getMapView().getScaleCoefficient()); lanesView.setImageDrawable(lanesDrawable); trackingUtilities = map.getMapViewTrackingUtilities(); @@ -859,7 +857,7 @@ public class RouteInfoWidgetsFactory { updateVisibility(lanesShadowText, visible && shadowRadius > 0); updateVisibility(lanesText, visible); updateVisibility(lanesView, visible); - updateVisibility(centerInfo, visible || progress.getVisibility() == View.VISIBLE); + updateVisibility(centerInfo, visible); return true; } } diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleHelper.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleHelper.java index 34637e9cdf..28bbdc8c06 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleHelper.java @@ -31,6 +31,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.lang.ref.WeakReference; import java.net.URLDecoder; +import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; @@ -324,4 +325,27 @@ public class WikiArticleHelper { return res.toString(); } + + public static String buildTravelUrl(String url, String lang) { + String title = url.replace(" ", "_"); + try { + title = URLEncoder.encode(title, "UTF-8"); + } catch (UnsupportedEncodingException e) { + System.err.println(e.getMessage()); + } + return "https://osmand.net/travel?title=" + title + "&lang=" + lang; + } + + public static String decodeTitleFromTravelUrl(String url) { + String title = ""; + try { + if (!Algorithms.isEmpty(url)) { + title = url.replace("_", " "); + title = URLDecoder.decode(title, "UTF-8"); + } + } catch (UnsupportedEncodingException e) { + System.err.println(e.getMessage()); + } + return title; + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java index 3f6b611952..6f69d2c332 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java @@ -16,6 +16,7 @@ import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.view.Gravity; import android.view.LayoutInflater; +import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -34,6 +35,7 @@ import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.development.OsmandDevelopmentPlugin; import net.osmand.plus.helpers.FileNameTranslationHelper; import net.osmand.plus.wikipedia.WikiArticleBaseDialogFragment; +import net.osmand.plus.wikipedia.WikiArticleHelper; import net.osmand.plus.wikivoyage.WikivoyageShowPicturesDialogFragment; import net.osmand.plus.wikivoyage.WikivoyageWebViewClient; import net.osmand.plus.wikivoyage.data.TravelArticle; @@ -60,7 +62,9 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme private static final String SELECTED_LANG_KEY = "selected_lang_key"; private static final String EMPTY_URL = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4//"; - + + private static final int MENU_ITEM_SHARE = 0; + private long tripId = NO_VALUE; private ArrayList langs; private String selectedLang; @@ -299,7 +303,10 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme webViewClient.setArticle(article); articleToolbarText.setText(article.getTitle()); if (article.getGpxFile() != null && article.getGpxFile().getPointsSize() > 0) { + trackButton.setVisibility(View.VISIBLE); trackButton.setText(getString(R.string.shared_string_gpx_points) + " (" + article.getGpxFile().getPointsSize() + ")"); + } else { + trackButton.setVisibility(View.GONE); } TravelLocalDataHelper ldh = getMyApplication().getTravelDbHelper().getLocalDataHelper(); @@ -426,4 +433,31 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme fragmentManager.popBackStackImmediate(pop, 0); } } -} + + @Override + protected void setupToolbar(Toolbar toolbar) { + super.setupToolbar(toolbar); + toolbar.setOverflowIcon(getIcon(R.drawable.ic_overflow_menu_white, R.color.icon_color)); + + Menu menu = toolbar.getMenu(); + MenuItem.OnMenuItemClickListener itemClickListener = new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + OsmandApplication app = getMyApplication(); + if (app != null) { + int itemId = item.getItemId(); + if (itemId == MENU_ITEM_SHARE) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.putExtra(Intent.EXTRA_TEXT, WikiArticleHelper.buildTravelUrl(article.getTitle(), article.getLang())); + intent.setType("text/plain"); + startActivity(Intent.createChooser(intent, getString(R.string.shared_string_share))); + return true; + } + } + return false; + } + }; + MenuItem itemShow = menu.add(0, MENU_ITEM_SHARE, 0, R.string.shared_string_share); + itemShow.setOnMenuItemClickListener(itemClickListener); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java index 047a66fd16..7f4ac20953 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java @@ -214,7 +214,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv boolean outdated = mainIndexItem != null && mainIndexItem.isOutdated(); File selectedTravelBook = app.getTravelDbHelper().getSelectedTravelBook(); - if (selectedTravelBook == null || outdated) { + if (selectedTravelBook == null || (outdated && app.getSettings().SHOW_TRAVEL_UPDATE_CARD.get())) { boolean showOtherMaps = false; if (selectedTravelBook == null) { List items = downloadThread.getIndexes().getWikivoyageItems(); @@ -238,6 +238,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv downloadThread.cancelDownload(mainIndexItem); adapter.updateDownloadUpdateCard(false); } else if (!downloadUpdateCard.isDownload()) { + app.getSettings().SHOW_TRAVEL_UPDATE_CARD.set(false); removeDownloadUpdateCard(); } else if (downloadUpdateCard.isShowOtherMapsBtn()) { Activity activity = getActivity(); @@ -258,7 +259,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv private void addNeededMapsCard() { final OsmandApplication app = getMyApplication(); - if (app != null && !neededIndexItems.isEmpty() && adapter != null) { + if (app != null && !neededIndexItems.isEmpty() && adapter != null && app.getSettings().SHOW_TRAVEL_NEEDED_MAPS_CARD.get()) { neededMapsCard = new TravelNeededMapsCard(app, nightMode, neededIndexItems); neededMapsCard.setListener(new TravelNeededMapsCard.CardListener() { @Override @@ -277,6 +278,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv adapter.updateNeededMapsCard(false); } } else { + app.getSettings().SHOW_TRAVEL_NEEDED_MAPS_CARD.set(false); removeNeededMapsCard(); } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesTabFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesTabFragment.java index 409d98a125..dd52004994 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesTabFragment.java @@ -83,7 +83,7 @@ public class SavedArticlesTabFragment extends BaseOsmAndFragment implements Trav @Override public void savedArticlesUpdated() { - if (adapter != null) { + if (adapter != null && isAdded()) { List newItems = getItems(); SavedArticlesDiffCallback diffCallback = new SavedArticlesDiffCallback(adapter.getItems(), newItems); DiffUtil.DiffResult diffRes = DiffUtil.calculateDiff(diffCallback); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java index 2dcea8130a..de11593ba1 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java @@ -3,6 +3,7 @@ package net.osmand.plus.wikivoyage.explore; import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; +import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; @@ -31,10 +32,12 @@ import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.TabActivity; import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents; +import net.osmand.plus.wikipedia.WikiArticleHelper; import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment; import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelDbHelper; import net.osmand.plus.wikivoyage.search.WikivoyageSearchDialogFragment; +import net.osmand.util.Algorithms; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -168,21 +171,41 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv super.onResume(); Intent intent = getIntent(); if (intent != null) { - int currentItem = intent.getIntExtra(TAB_SELECTED, 0); - if (currentItem == SAVED_ARTICLES_POSITION) { - BottomNavigationView bottomNav = (BottomNavigationView) findViewById(R.id.bottom_navigation); - bottomNav.setSelectedItemId(R.id.action_saved_articles); - } - long cityId = intent.getLongExtra(CITY_ID_KEY, -1); - String selectedLang = intent.getStringExtra(SELECTED_LANG_KEY); - if (cityId != -1) { - WikivoyageArticleDialogFragment.showInstance(app, getSupportFragmentManager(), cityId, selectedLang); + Uri data = intent.getData(); + if (data != null && ("http".equalsIgnoreCase(data.getScheme()) || "https".equalsIgnoreCase(data.getScheme()))) { + parseLaunchIntentLink(data); + } else { + int currentItem = intent.getIntExtra(TAB_SELECTED, 0); + if (currentItem == SAVED_ARTICLES_POSITION) { + BottomNavigationView bottomNav = (BottomNavigationView) findViewById(R.id.bottom_navigation); + bottomNav.setSelectedItemId(R.id.action_saved_articles); + } + long articleId = intent.getLongExtra(CITY_ID_KEY, -1); + String selectedLang = intent.getStringExtra(SELECTED_LANG_KEY); + if (articleId != -1) { + WikivoyageArticleDialogFragment.showInstance(app, getSupportFragmentManager(), articleId, selectedLang); + } } setIntent(null); } getMyApplication().getDownloadThread().setUiActivity(this); } + protected void parseLaunchIntentLink(Uri data) { + String host = data.getHost(); + String path = data.getPath(); + if (host != null && path != null && host.contains("osmand.net") && path.startsWith("/travel")) { + String title = WikiArticleHelper.decodeTitleFromTravelUrl(data.getQueryParameter("title")); + String selectedLang = data.getQueryParameter("lang"); + if (!Algorithms.isEmpty(title) && !Algorithms.isEmpty(selectedLang)) { + long articleId = app.getTravelDbHelper().getArticleId(title, selectedLang); + if (articleId != 0) { + WikivoyageArticleDialogFragment.showInstance(app, getSupportFragmentManager(), articleId, selectedLang); + } + } + } + } + @Override protected void onPause() { super.onPause(); @@ -298,7 +321,8 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv private void updateFragments() { ExploreTabFragment exploreTabFragment = getExploreTabFragment(); SavedArticlesTabFragment savedArticlesTabFragment = getSavedArticlesTabFragment(); - if (exploreTabFragment != null && savedArticlesTabFragment != null) { + if (exploreTabFragment != null && savedArticlesTabFragment != null + && exploreTabFragment.isAdded() && savedArticlesTabFragment.isAdded()) { exploreTabFragment.populateData(); savedArticlesTabFragment.savedArticlesUpdated(); updateNeeded = false; diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java index 78afb435c6..9a3f67781b 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java @@ -84,9 +84,11 @@ public class TravelDownloadUpdateCard extends BaseTravelCard { } public void updateProgresBar() { - DownloadUpdateVH holder = ref.get(); - if (holder != null && holder.itemView.isShown()) { - updateProgressBar(holder); + if(ref != null) { + DownloadUpdateVH holder = ref.get(); + if (holder != null && holder.itemView.isShown()) { + updateProgressBar(holder); + } } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelNeededMapsCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelNeededMapsCard.java index 28636655bf..65a1562295 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelNeededMapsCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelNeededMapsCard.java @@ -72,9 +72,11 @@ public class TravelNeededMapsCard extends BaseTravelCard { } public void updateView() { - NeededMapsVH holder = ref.get(); - if (holder != null && holder.itemView.isShown()) { - updateView(holder); + if (ref != null) { + NeededMapsVH holder = ref.get(); + if (holder != null && holder.itemView.isShown()) { + updateView(holder); + } } }