From 22e31559aa257403ba2259a77755688d019b0535 Mon Sep 17 00:00:00 2001 From: 0xRe1nk0 <0xre1nk0@gmail.com> Date: Mon, 13 May 2024 09:36:29 +0300 Subject: [PATCH 01/33] Fix using deprecated getDefaultDisplay from non-visual context --- .../net/osmand/plus/OsmandApplication.java | 38 ++++++++++++++++++- .../plus/base/MapViewTrackingUtilities.java | 9 ++--- .../osmand/plus/render/OsmandRenderer.java | 12 ++++-- .../plus/resources/ResourceManager.java | 8 +++- .../osmand/plus/views/MapViewWithLayers.java | 3 +- .../src/net/osmand/plus/views/OsmandMap.java | 3 +- .../osmand/plus/views/OsmandMapTileView.java | 3 +- .../views/corenative/NativeCoreContext.java | 3 +- .../plus/views/layers/ContextMenuLayer.java | 3 +- .../views/layers/DownloadedRegionsLayer.java | 3 +- .../views/layers/MapQuickActionLayer.java | 3 +- .../views/layers/TransportStopsLayer.java | 4 +- 12 files changed, 66 insertions(+), 26 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index af67ca0deb4..8903d660f21 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -1,5 +1,7 @@ package net.osmand.plus; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static net.osmand.IndexConstants.ROUTING_FILE_EXT; import static net.osmand.plus.settings.backend.ApplicationMode.valueOfStringKey; import static net.osmand.plus.settings.enums.MetricsConstants.KILOMETERS_AND_METERS; @@ -11,16 +13,21 @@ import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; +import android.hardware.display.DisplayManager; import android.os.AsyncTask; import android.os.Build; import android.os.Handler; import android.os.Message; +import android.view.Display; import android.view.View; +import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.annotation.UiContext; import androidx.car.app.CarToast; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleObserver; @@ -219,6 +226,8 @@ public class OsmandApplication extends MultiDexApplication { private boolean androidAutoInForeground; // Typeface + private Context uiContext; + @Override public void onCreate() { if (RestartActivity.isRestartProcess(this)) { @@ -241,6 +250,7 @@ public void onStop(@NonNull LifecycleOwner owner) { }; ProcessLifecycleOwner.get().getLifecycle().addObserver(appLifecycleObserver); + setupUIContext(); createInUiThread(); uiHandler = new Handler(); appCustomization = new OsmAndAppCustomization(); @@ -281,6 +291,14 @@ public void onStop(@NonNull LifecycleOwner owner) { BackupHelper.DEBUG = true;//PluginsHelper.isDevelopment(); } + private void setupUIContext() { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { + final DisplayManager dm = this.getSystemService(DisplayManager.class); + final Display primaryDisplay = dm.getDisplay(DEFAULT_DISPLAY); + uiContext = this.createDisplayContext(primaryDisplay).createWindowContext(TYPE_APPLICATION_OVERLAY, null); + } + } + public boolean isPlusVersionInApp() { return true; } @@ -308,7 +326,7 @@ public boolean isAppInForeground() { } private void createInUiThread() { - new Toast(this); // activate in UI thread to avoid further exceptions + new Toast(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R ? getWindowContext() : this); // activate in UI thread to avoid further exceptions new AsyncTask() { @Override protected Void doInBackground(View... params) { @@ -325,6 +343,24 @@ public UiUtilities getUIUtilities() { return iconsCache; } + @UiContext + @RequiresApi(Build.VERSION_CODES.R) + public Context getWindowContext(){ + return uiContext; + } + + public Display getContextDisplay() { + Display display; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { + DisplayManager displayManager = (DisplayManager) this.getSystemService(Context.DISPLAY_SERVICE); + display = displayManager.getDisplay(Display.DEFAULT_DISPLAY); + } else { + WindowManager wmgr = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); + display = wmgr.getDefaultDisplay(); + } + return display; + } + @Override public void onTerminate() { super.onTerminate(); diff --git a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java index 5d16fd56aeb..c5a259fcb5f 100644 --- a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java +++ b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java @@ -3,9 +3,8 @@ import static net.osmand.plus.settings.enums.CompassMode.COMPASS_DIRECTION; import static net.osmand.plus.views.AnimateDraggingMapThread.SKIP_ANIMATION_DP_THRESHOLD; -import android.content.Context; import android.os.AsyncTask; -import android.view.WindowManager; +import android.view.Display; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -135,10 +134,10 @@ public void setMapView(@Nullable OsmandMapTileView mapView) { mapDisplayPositionManager.setMapView(mapView); autoZoomBySpeedHelper.setMapView(mapView); if (mapView != null) { - WindowManager wm = (WindowManager) app.getSystemService(Context.WINDOW_SERVICE); + Display display = app.getContextDisplay(); int orientation = 0; - if (wm != null) { - orientation = wm.getDefaultDisplay().getRotation(); + if (display != null) { + orientation = display.getRotation(); } app.getLocationProvider().updateScreenOrientation(orientation); mapView.addMapLocationListener(this); diff --git a/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java b/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java index 01a3a43d541..a9cb9b73641 100644 --- a/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java +++ b/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java @@ -23,7 +23,8 @@ import android.os.Handler; import android.os.Looper; import android.util.DisplayMetrics; -import android.view.WindowManager; + +import androidx.annotation.NonNull; import net.osmand.NativeLibrary; import net.osmand.NativeLibrary.NativeSearchResult; @@ -34,6 +35,7 @@ import net.osmand.data.QuadRect; import net.osmand.data.QuadTree; import net.osmand.map.MapTileDownloader; +import net.osmand.plus.OsmandApplication; import net.osmand.render.RenderingRuleProperty; import net.osmand.render.RenderingRuleSearchRequest; import net.osmand.render.RenderingRulesStorage; @@ -144,8 +146,12 @@ public OsmandRenderer(Context context) { paint.setAntiAlias(true); dm = new DisplayMetrics(); - WindowManager wmgr = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - wmgr.getDefaultDisplay().getMetrics(dm); + getApplication().getContextDisplay().getMetrics(dm); + } + + @NonNull + public OsmandApplication getApplication() { + return (OsmandApplication) context.getApplicationContext(); } public PathEffect getDashEffect(RenderingContext rc, float[] cachedValues, float st){ diff --git a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java index 214fca8691a..682e34131f4 100644 --- a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java @@ -289,9 +289,8 @@ public ResourceManager(@NonNull OsmandApplication context) { tileDownloader = MapTileDownloader.getInstance(Version.getFullVersion(context)); resetStoreDirectory(); - WindowManager mgr = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); - mgr.getDefaultDisplay().getMetrics(dm); + getApplication().getContextDisplay().getMetrics(dm); // Only 8 MB (from 16 Mb whole mem) available for images : image 64K * 128 = 8 MB (8 bit), 64 - 16 bit, 32 - 32 bit // at least 3*9? float tiles = (dm.widthPixels / 256 + 2) * (dm.heightPixels / 256 + 2) * 3; @@ -304,6 +303,11 @@ public ResourceManager(@NonNull OsmandApplication context) { } } + @NonNull + public OsmandApplication getApplication() { + return (OsmandApplication) context.getApplicationContext(); + } + public BitmapTilesCache getBitmapTilesCache() { return bitmapTilesCache; } diff --git a/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java b/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java index 85d059b70af..8b213bedfc4 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java +++ b/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java @@ -114,9 +114,8 @@ private void setupAtlasMapRendererView() { mapRendererContext.setMapRendererView(null); } } - WindowManager mgr = (WindowManager) app.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); - mgr.getDefaultDisplay().getMetrics(dm); + app.getContextDisplay().getMetrics(dm); NativeCoreContext.setMapRendererContext(app, dm.density); mapRendererContext = NativeCoreContext.getMapRendererContext(); if (mapRendererContext != null) { diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMap.java b/OsmAnd/src/net/osmand/plus/views/OsmandMap.java index 26cf6ce148d..2d8cb0adabe 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMap.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMap.java @@ -60,8 +60,7 @@ public OsmandMap(@NonNull OsmandApplication app) { int height; NavigationSession carNavigationSession = app.getCarNavigationSession(); if (carNavigationSession == null) { - WindowManager wm = (WindowManager) app.getSystemService(Context.WINDOW_SERVICE); - Display display = wm.getDefaultDisplay(); + Display display = app.getContextDisplay(); Point screenDimensions = new Point(0, 0); display.getSize(screenDimensions); width = screenDimensions.x; diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java index ae586002050..36cfb93b325 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java @@ -300,9 +300,8 @@ public void init(@NonNull Context ctx, int width, int height) { animatedDraggingThread = new AnimateDraggingMapThread(this); animatedMapMarkersThread = new AnimateMapMarkersThread(this); - WindowManager mgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); dm = new DisplayMetrics(); - mgr.getDefaultDisplay().getMetrics(dm); + application.getContextDisplay().getMetrics(dm); LatLon ll = settings.getLastKnownMapLocation(); currentViewport = new RotatedTileBoxBuilder() .setLocation(ll.getLatitude(), ll.getLongitude()) diff --git a/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java b/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java index 27b3076871b..6ab928ab9cd 100644 --- a/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java +++ b/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java @@ -58,9 +58,8 @@ public static void init(@NonNull OsmandApplication app) { File directory = app.getAppPath(""); Logger.get().addLogSink(QIODeviceLogSink.createFileLogSink(new File(directory, LOG_FILE_NAME).getAbsolutePath())); - WindowManager mgr = (WindowManager) app.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); - mgr.getDefaultDisplay().getMetrics(dm); + app.getContextDisplay().getMetrics(dm); String cacheFilePath = new File(app.getCacheDir(), CACHE_FILE_NAME).getAbsolutePath(); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java index 5ccca2b1d88..d5dbd71be03 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java @@ -1,5 +1,6 @@ package net.osmand.plus.views.layers; +import static android.os.Build.*; import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_CHANGE_MARKER_POSITION; import static net.osmand.plus.views.layers.geometry.GeometryWayDrawer.VECTOR_LINE_SCALE_COEF; @@ -149,7 +150,7 @@ public void initLayer(@NonNull OsmandMapTileView view) { super.initLayer(view); Context context = getContext(); - contextMarker = new ImageView(context); + contextMarker = new ImageView(VERSION.SDK_INT >= VERSION_CODES.R ? getApplication().getWindowContext() : context); contextMarker.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); Drawable markerDrawable = AppCompatResources.getDrawable(context, R.drawable.map_pin_context_menu); contextMarker.setImageDrawable(markerDrawable); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/DownloadedRegionsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/DownloadedRegionsLayer.java index a0ad9f9ed43..55610b7b4a0 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/DownloadedRegionsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/DownloadedRegionsLayer.java @@ -174,9 +174,8 @@ public void initLayer(@NonNull OsmandMapTileView view) { paintBackuped = getPaint(getColor(R.color.region_backuped)); textPaint = new TextPaint(); - WindowManager wmgr = (WindowManager) view.getApplication().getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); - wmgr.getDefaultDisplay().getMetrics(dm); + app.getContextDisplay().getMetrics(dm); textPaint.setStrokeWidth(21 * dm.scaledDensity); textPaint.setAntiAlias(true); textPaint.setTextAlign(Paint.Align.CENTER); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java index af78a1ae8cc..0ff3395d240 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java @@ -4,6 +4,7 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.PointF; +import android.os.Build; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -79,7 +80,7 @@ public void initLayer(@NonNull OsmandMapTileView view) { super.initLayer(view); Context context = getContext(); - contextMarker = new ImageView(context); + contextMarker = new ImageView(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R ? getApplication().getWindowContext() : context); contextMarker.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT)); contextMarker.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.map_pin_context_menu)); contextMarker.setClickable(true); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/TransportStopsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/TransportStopsLayer.java index 53adb5cf24b..c50a5f27b2a 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/TransportStopsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/TransportStopsLayer.java @@ -7,7 +7,6 @@ import android.graphics.Path; import android.graphics.PointF; import android.util.DisplayMetrics; -import android.view.WindowManager; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; @@ -96,8 +95,7 @@ public void initLayer(@NonNull OsmandMapTileView view) { super.initLayer(view); DisplayMetrics dm = new DisplayMetrics(); - WindowManager wmgr = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); - wmgr.getDefaultDisplay().getMetrics(dm); + getApplication().getContextDisplay().getMetrics(dm); path = new Path(); attrs = new RenderingLineAttributes("transport_route"); attrs.defaultWidth = (int) (6 * view.getDensity()); From e8434627ca91319e7e590d5b82a50541bbba3547 Mon Sep 17 00:00:00 2001 From: 0xRe1nk0 <0xre1nk0@gmail.com> Date: Mon, 13 May 2024 09:37:04 +0300 Subject: [PATCH 02/33] Fix rendering style warning --- .../osmand/render/RenderingRulesStorage.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/render/RenderingRulesStorage.java b/OsmAnd-java/src/main/java/net/osmand/render/RenderingRulesStorage.java index 7cb9df80602..fbe997911c6 100644 --- a/OsmAnd-java/src/main/java/net/osmand/render/RenderingRulesStorage.java +++ b/OsmAnd-java/src/main/java/net/osmand/render/RenderingRulesStorage.java @@ -390,19 +390,21 @@ public void startElement(Map attrsMap, String name) throws XmlPu if(!renderingConstants.containsKey(attrsMap.get("name"))){ renderingConstants.put(attrsMap.get("name"), attrsMap.get("value")); } - } else if("renderingStyle".equals(name) && !addon){ //$NON-NLS-1$ - String depends = attrsMap.get("depends"); - if (depends != null && depends.length() > 0) { - this.dependsStorage = resolver.resolve(depends, resolver); - } - if (dependsStorage != null) { - // copy dictionary - dictionary = new ArrayList(dependsStorage.dictionary); - dictionaryMap = new LinkedHashMap(dependsStorage.dictionaryMap); - PROPS = new RenderingRuleStorageProperties(dependsStorage.PROPS); + } else if("renderingStyle".equals(name)){ //$NON-NLS-1$ + if(!addon){ + String depends = attrsMap.get("depends"); + if (depends != null && depends.length() > 0) { + this.dependsStorage = resolver.resolve(depends, resolver); + } + if (dependsStorage != null) { + // copy dictionary + dictionary = new ArrayList(dependsStorage.dictionary); + dictionaryMap = new LinkedHashMap(dependsStorage.dictionaryMap); + PROPS = new RenderingRuleStorageProperties(dependsStorage.PROPS); + } + internalRenderingName = attrsMap.get("name"); } - internalRenderingName = attrsMap.get("name"); - + } else if("renderer".equals(name)){ //$NON-NLS-1$ throw new XmlPullParserException("Rendering style is deprecated and no longer supported."); } else { From 83e3f4245cd61f2588fafac1d4a9c8499904e43d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jordi=20Mir=C3=B3?= Date: Sun, 19 May 2024 23:53:53 +0000 Subject: [PATCH 03/33] Translated using Weblate (Catalan) Currently translated at 78.1% (3989 of 5102 strings) --- OsmAnd/res/values-ca/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/OsmAnd/res/values-ca/strings.xml b/OsmAnd/res/values-ca/strings.xml index 4b96f4a40b2..ac2add235af 100644 --- a/OsmAnd/res/values-ca/strings.xml +++ b/OsmAnd/res/values-ca/strings.xml @@ -4493,4 +4493,11 @@ Utilitzar mapes de terreny Utilitzar carreteres properes Accentuació vertical + Mapes i Descàrregues + Tipus de classificació de la dificultat de les rutes. + Imatges a nivell de carrer + Classificació de la dificultat + Relleu en 3D + Mostrar rutes per a córrer + Rutes per a córrer \ No newline at end of file From 1a41d2c19f13257d400df2403b9989c6abd931e2 Mon Sep 17 00:00:00 2001 From: Jacob Date: Mon, 20 May 2024 00:06:17 +0000 Subject: [PATCH 04/33] Translated using Weblate (Swedish) Currently translated at 99.2% (5062 of 5102 strings) --- OsmAnd/res/values-sv/strings.xml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-sv/strings.xml b/OsmAnd/res/values-sv/strings.xml index 96ff06fa660..bc0340cab43 100644 --- a/OsmAnd/res/values-sv/strings.xml +++ b/OsmAnd/res/values-sv/strings.xml @@ -4478,8 +4478,8 @@ Ange tidsintervallet för medelhastigheten (används för beräknad ankomsttid). Andra markören Vägar stängda för varuleveranser kommer att undvikas. - Tunnlar för vattendrag - Dölj inte tunnlar för vattendrag + Ökad synlighet för tunnlar för vattendrag + Ökad synlighet för tunnlar för vattendrag Klättring Kunde inte ladda ned %1$s rastertiles. Välj lager @@ -5394,7 +5394,7 @@ Lägg till rad Kassera ändringarna? Töm papperskorgen - Detta kommer radera mappen \'%1$s\' och alla innehållande spår (%2$s). + Detta kommer radera mappen \'%1$s\' och alla %2$s innehållande spår. Radera omedelbart Detta kommer radera smarta mappen \"%1$s\". %1$s har raderats. @@ -5539,7 +5539,7 @@ Ruttlinjen färgläggs efter höjd. Ruttlinje färgläggs efter rörelsens hastighet. 3D-spår - Utforska spåret i interaktiv 3D! Visualiseria höjd, hastighet med mera direkt på kartan. + Utforska spåret i interaktiv 3D! Visualisera höjd, hastighet med mera direkt på kartan. Listan över saknade kartor baseras på den rutt som utgörs av en rak linje. För att få en korrekt lista över kartor kan OsmAnd räkna ut din rutt online på förhand. OsmAnd kan hämta höjddata från närliggande vägar eller terrängkartor. Tillämpa ändringar på existerande spår i mappen eller bara på nya? @@ -5554,4 +5554,10 @@ Tillåt visning av texter på karta ovanpå varandra Visa grafisk information om placering av varje karttext Karttexter + Skala + OSM-ID + Förbered en rutt + GPX approximering + Ruttberäkningstyp + Varje spår behåller sina egna parametrar. \ No newline at end of file From 39c4bce5255e3bffd6537a15831f2b01effefad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20=C3=96berg?= Date: Sun, 19 May 2024 18:52:27 +0000 Subject: [PATCH 05/33] Translated using Weblate (Swedish) Currently translated at 99.2% (5062 of 5102 strings) --- OsmAnd/res/values-sv/strings.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/OsmAnd/res/values-sv/strings.xml b/OsmAnd/res/values-sv/strings.xml index bc0340cab43..291d226001e 100644 --- a/OsmAnd/res/values-sv/strings.xml +++ b/OsmAnd/res/values-sv/strings.xml @@ -5560,4 +5560,25 @@ GPX approximering Ruttberäkningstyp Varje spår behåller sina egna parametrar. + Tamil (Indien) + Genom att ändra skalningsvärdet kan du förändra 3D-spårets höjd. + Genom att ändra på skalningsvärdet kan du framhäva 3D-reliefen. + Ladda upp lokala versioner + Rotera inte kartan genom gester i kartorienteringen Norr Uppåt + Välj hur avståndsinformation visas i navigations-widgetar (avstånd till punkt, nästa sväng, körfält). +\n +\nVälj \"%1$s\" för exakta tal, eller \"%2$s\" för ökad läsbarhet. + Är du säker på att du vill ta bort \"%1$s\" med alla tillagda åtgärder? + Visualiseras av + Fast höjd + Längst upp + Längst ned + Längst upp och längst ned + Väggfärg + Spårlinje + Nedåtgående gradient + Uppåtgående gradient + Ta bort knapp + Jämn + Diskret \ No newline at end of file From e9b16dbb92862c8848dc77d271214d29b7806637 Mon Sep 17 00:00:00 2001 From: Evgenii Martynenko Date: Sun, 19 May 2024 09:55:38 +0000 Subject: [PATCH 06/33] Translated using Weblate (Russian) Currently translated at 98.7% (5038 of 5102 strings) --- OsmAnd/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 81ffc084bab..75b500a4d79 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -5727,6 +5727,6 @@ Показать отладочную информацию Отображение графической информации о размещении каждого текста на карте Текста карты - Отключает все слои карты над векторной картой (требуется перезапуск). + Отключает все слои над векторной картой (требуется перезапуск). Отключить слои карты \ No newline at end of file From 7bf4539b5899be4768f0c23052e08c4ef0471518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ar=C5=ABnas=20Bastys?= Date: Sun, 19 May 2024 13:03:37 +0000 Subject: [PATCH 07/33] Translated using Weblate (Lithuanian) Currently translated at 52.7% (2693 of 5102 strings) --- OsmAnd/res/values-lt/strings.xml | 91 +++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 8 deletions(-) diff --git a/OsmAnd/res/values-lt/strings.xml b/OsmAnd/res/values-lt/strings.xml index bbaee78b59c..8df4c926b9b 100644 --- a/OsmAnd/res/values-lt/strings.xml +++ b/OsmAnd/res/values-lt/strings.xml @@ -97,7 +97,7 @@ Įjungia prieigos savybes. Įjungta Išjungta - Pagal globalius sistemos nustatymus + Pagal Android sistemos nustatymus Atgal į meniu Sumažinti Padidinti @@ -911,7 +911,7 @@ Audio/Video duomenys Paremkite finansiškai naujo funkcionalumo vystymą. Naudoti sistemos fotoaparato programą. - Nautodi fotoaparato programą + Naudoti fotoaparato programą OpenMaps ES Teikti pirmenybę greitkeliams Teikti pirmenybę… @@ -930,7 +930,7 @@ Kelionės įrašymas Nustatykite kaip įrašinėti savo maršrutus. Pritaikykite programėlės išvaizdą. - Išv. tema + Programos tema Prieigos nustatymai Nurodyti adresą Pasirinkti įsimintą vietą @@ -1432,7 +1432,7 @@ \nIlguma %2$s Dažni klausimai, paskutiniai keitimai ir kita. Navigacijos nustatymai - Pagrindiniai nutatymai + Pagrindiniai nustatymai OsmAnd suteikia galimybę naudotis žemėpiais bei offline navigacija. Pradęti maršruto planavimą po … @@ -1469,7 +1469,7 @@ Pastatų numeriai Nepavyko sukurti žemėlapių nurodytoje direktorijoje Nepavyko nukopijuoti failo - Išorinė saugykla + Išorinė atmintis Vidinė atmintis Žemėlapių saugykla Kopijuoti @@ -1495,7 +1495,7 @@ Vidinė programos atmintis Nurodyta rankiniu būdu Nurodykite transporto priemonės aukštį, leidžiamą maršrutuose. - Perskaičiuoti tik pradinę ilgos kelionės maršruto dalį. + Perskaičiuoja tik pradinę maršruto dalį, naudingą ilgoms kelionėms. Išjungtas Atsijungti Rašykite, norėdami pradėti paiešką @@ -1608,7 +1608,8 @@ Vengti priemiestinių traukinių Duomenų skydelio nustatymai Rodyti aktyvuojant - Parsiųsti žemėlapiai\n& navigacija + Parsiųsti žemėlapiai +\n& Navigacija Išsiųsti LV Eilučių kiekis Ar esate tikri\? @@ -1735,7 +1736,7 @@ Redaguoti LV Atsisiųsti tik naudojant Wi-Fi Atnaujinti tuoj pat - Programėlė neturi teisių įrašyti į atminties kortelę + OsmAnd neturi leidimo naudoti atminties kortelę Programėlė neturi teisių naudoti kamerą. Programėlė neturi teisių naudoti mikrofoną. Vaizdo kokybė @@ -3164,4 +3165,78 @@ Tai yra puikus būdas paremti OsmAnd ir OSM, jei jie jums patinka. Naudoti artumo jutiklį Naujas profilis Skaičiuoti + Senka baterija + Jutiklis bus pašalintas iš sąrašo. Šį jutiklį galėsite bet kada vėl susieti. + Apskaičiuoti aukštį + Pažengęs + Gauti aukščio duomenis + Atkurti iš OsmAnd Cloud + Atkurti numatytąją elementų tvarką + Žemėlapiai ir duomenys + Sistolinis + Temperatūra + Greitis + Bendras atstumas + Kalnų dviratis + Vidutinis + Žemėlapiai ir ištekliai + Atjungtas + Prijungtas + Pamiršti + Išoriniai jutikliai + Pasirinkite elementus, kurie bus importuojami. + UI pritaikymas + Bendras atstumas + Informacija + Atstumas + Prijungti + Išorinių jutiklių palaikymas + Baterija + Nėra aukščio duomenų + Leisti + Ekspertas + Duomenys + Pamiršti jutiklį + Baterija + Pulsas + Profilio išvaizda + Atsijungti nuo OsmAnd Cloud + Apie OsmAnd + Duomenų šaltinis + Kraujospūdis + Arterinis spaudimas + Širdies ritmas + Diastolinis + Ryšys + Žingsnio ilgis + Gauti duomenys + Tik esant reikalui + Pasirinkite bent vieną elementą + Ištrinti pasirinktus istorijos elementus? + Ištrinti %1$s istorijos elementus? + Išoriniai jutikliai + Atjungti + ANT + Greitis + Atsijungęs + Numatyta sistemos + Poruoti + Neturite šio tipo elementų + Pasirinkite išorinį valdymo įrenginį, pvz., klaviatūrą arba WunderLINQ. + BLE + Nepavyko gauti failų sąrašo iš serverio. + Jutiklio pavadinimas + Įrašyti duomenis iš išorinių jutiklių į GPX kelionės įrašymo metu. + Atstumas + Prisijunkite naudodami OAuth, kad galėtumėte naudoti osmedit funkcijas + Prisijungti su OAuth + Išoriniai įvesties įrenginiai + Ištrinti visus elementus + Jutikliai nerasti + Greitis + Pradedantysis + Atsijungti? +\nNorėdami sukurti atsarginę duomenų kopiją arba atkurti duomenis, turėsite prisijungti dar kartą. + Ištrinti paskyrą? + Ištrinti visus šiukšliadėžėje esančius elementus visam laikui? \ No newline at end of file From ab98f126668711103265dc7961c44fa3b7c3494d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20B=C3=A1thory?= Date: Sun, 19 May 2024 07:19:51 +0000 Subject: [PATCH 08/33] Translated using Weblate (Hungarian) Currently translated at 99.9% (5100 of 5102 strings) --- OsmAnd/res/values-hu/strings.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index 6d77d89c963..7370e095f0d 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -5334,14 +5334,14 @@ Belefoglalva Domborzati térképek (3D) Domborzatárnyékolás, lejtés - Siklásszám + Siklószám Átlagos siklószám - Mutatja a célpont eléréséhez szükséges siklásszámot. - Adja meg a siklásszám átlagának kiszámításához használt időintervallumot. + Mutatja a célpont eléréséhez szükséges siklószámot. + Adja meg a siklószám átlagának kiszámításához használt időintervallumot. %1$s : %2$s A widgetek a célhoz vezető vagy az aktuális útra vonatkozó átlagos siklószámot mutatják. - Siklásszám a célig - Megjeleníti az átlagos siklásszámot a megadott intervallumhoz. + Siklószám a célig + Megjeleníti az átlagos siklószámot a megadott intervallumhoz. Szenzor neve Kerék kerülete Kapcsolatfelvétel From 35f82e6b0f3e5097f4f35d33167ff0be11bb40b8 Mon Sep 17 00:00:00 2001 From: Franco Date: Sun, 19 May 2024 00:52:37 +0000 Subject: [PATCH 09/33] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (5102 of 5102 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 1a960be9a34..798880c3249 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -5739,4 +5739,7 @@ Textos del mapa Evitar adoquinado Evita pasar por caminos adoquinados + Desactiva todas las capas del mapa por encima del mapa vectorial (se debe reiniciar). + SPM + Desactivar capas del mapa \ No newline at end of file From 715eec3940dd2dc20bf9c0569bc8ee0ff44fea6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=98=86Verdulo?= Date: Sun, 19 May 2024 20:17:12 +0000 Subject: [PATCH 10/33] Translated using Weblate (Esperanto) Currently translated at 99.9% (5101 of 5102 strings) --- OsmAnd/res/values-eo/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index b0dc4d69a17..94dda0db74c 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -5718,4 +5718,6 @@ Surbaze de geometrio (C++) (rapide) Per ŝanĝi la valoron de skalo vi povas ŝanĝi alton de 3-dimensia spuro. paŝoj/min + Malaktivigi ĉiujn map-tavolojn super la vektora mapo (postulas restarton). + Malaktivigi surtavolojn \ No newline at end of file From 193935ded6b82fecedf3e7d3d72fd1c5057ca35a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ar=C5=ABnas=20Bastys?= Date: Sun, 19 May 2024 13:16:31 +0000 Subject: [PATCH 11/33] Translated using Weblate (Lithuanian) Currently translated at 51.2% (2493 of 4866 strings) --- OsmAnd/res/values-lt/phrases.xml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/OsmAnd/res/values-lt/phrases.xml b/OsmAnd/res/values-lt/phrases.xml index 8374746d933..a33c3d36256 100644 --- a/OsmAnd/res/values-lt/phrases.xml +++ b/OsmAnd/res/values-lt/phrases.xml @@ -2566,4 +2566,31 @@ Miegamasis;Miegamojo baldai Tinkama žygiams Taip + Būsena: siūloma + Būsena: alternatyvi + Būsena: naudojama + Būsena: laikina + Būsena: nenaudojama + Būsena: patvirtinta + Būsena: statoma + Būsena: pagrindinė + Būsena: sulaikytas + Pakilimas + Nusileidimas + Pirmyn ir atgal: taip + Kryptis + Pirmyn ir atgal: ne + Atstumas + Taip + Per + Pasienio zona + + Reaktyvinis A-1 kuras + Į + Dviračių tinklas + Būsena: rekomenduojama + Būsena: uždaryta + Būsena: apleista + Būsena: aktyvi + Būsena: apylanka \ No newline at end of file From 5a9d827836345cb43af70ccc866f7a8620beb7b5 Mon Sep 17 00:00:00 2001 From: 0xRe1nk0 <0xre1nk0@gmail.com> Date: Mon, 20 May 2024 10:14:34 +0300 Subject: [PATCH 12/33] Add "add action" screen --- .../fragment_add_category_quick_action.xml | 90 +++++++ .../res/layout/fragment_add_quick_action.xml | 110 ++++++++ .../osmand/plus/helpers/MapScrollHelper.java | 6 + .../quickaction/AddCategoryQuickAction.java | 151 +++++++++++ .../quickaction/AddQuickActionDialog.java | 110 -------- .../quickaction/AddQuickActionFragment.java | 245 ++++++++++++++++++ .../quickaction/AddQuickActionsAdapter.java | 129 +++++++++ .../quickaction/CreateEditActionDialog.java | 17 +- .../plus/quickaction/MapButtonsHelper.java | 139 ++++++++-- .../plus/quickaction/QuickActionIds.java | 10 +- .../quickaction/QuickActionListFragment.java | 4 +- .../plus/quickaction/QuickActionType.java | 8 + .../quickaction/QuickActionViewHolder.java | 74 ++++++ .../SelectMapViewQuickActionsBottomSheet.java | 2 +- .../actions/BaseMapScrollAction.java | 47 ++++ .../actions/BaseMapZoomAction.java | 43 +++ .../actions/BaseSwitchAppModeAction.java | 49 ++++ .../actions/MapScrollDownAction.java | 38 +++ .../actions/MapScrollLeftAction.java | 38 +++ .../actions/MapScrollRightAction.java | 38 +++ .../actions/MapScrollUpAction.java | 38 +++ .../quickaction/actions/MapZoomInAction.java | 34 +++ .../quickaction/actions/MapZoomOutAction.java | 34 +++ .../actions/MoveToMyLocationAction.java | 45 ++++ .../plus/quickaction/actions/NewAction.java | 4 +- .../actions/NextAppProfileAction.java | 34 +++ .../actions/PreviousAppProfileAction.java | 34 +++ 27 files changed, 1437 insertions(+), 134 deletions(-) create mode 100644 OsmAnd/res/layout/fragment_add_category_quick_action.xml create mode 100644 OsmAnd/res/layout/fragment_add_quick_action.xml create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/AddCategoryQuickAction.java delete mode 100644 OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionDialog.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionFragment.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionsAdapter.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/QuickActionViewHolder.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/BaseMapScrollAction.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/BaseMapZoomAction.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/BaseSwitchAppModeAction.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollDownAction.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollLeftAction.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollRightAction.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollUpAction.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/MapZoomInAction.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/MapZoomOutAction.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/MoveToMyLocationAction.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/NextAppProfileAction.java create mode 100644 OsmAnd/src/net/osmand/plus/quickaction/actions/PreviousAppProfileAction.java diff --git a/OsmAnd/res/layout/fragment_add_category_quick_action.xml b/OsmAnd/res/layout/fragment_add_category_quick_action.xml new file mode 100644 index 00000000000..581b0681e1b --- /dev/null +++ b/OsmAnd/res/layout/fragment_add_category_quick_action.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/fragment_add_quick_action.xml b/OsmAnd/res/layout/fragment_add_quick_action.xml new file mode 100644 index 00000000000..4d8997ec1a0 --- /dev/null +++ b/OsmAnd/res/layout/fragment_add_quick_action.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/helpers/MapScrollHelper.java b/OsmAnd/src/net/osmand/plus/helpers/MapScrollHelper.java index 5111bf1a777..20ac15dd817 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/MapScrollHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/MapScrollHelper.java @@ -15,6 +15,7 @@ import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -142,6 +143,11 @@ private void stopScroll() { } } + public void scrollMapAction(@NonNull ScrollDirection direction){ + scrollMap(Collections.singleton(direction)); + stopScroll(); + } + private void threadSleep() { try { Thread.sleep(SCROLL_PAUSE_MS); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/AddCategoryQuickAction.java b/OsmAnd/src/net/osmand/plus/quickaction/AddCategoryQuickAction.java new file mode 100644 index 00000000000..134b5fa0f08 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/AddCategoryQuickAction.java @@ -0,0 +1,151 @@ +package net.osmand.plus.quickaction; + +import static net.osmand.plus.quickaction.AddQuickActionFragment.QUICK_ACTION_BUTTON_KEY; + +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.base.BaseOsmAndFragment; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.utils.AndroidUtils; +import net.osmand.plus.utils.ColorUtilities; +import net.osmand.plus.views.mapwidgets.configure.buttons.QuickActionButtonState; + +import java.util.ArrayList; +import java.util.List; + +public class AddCategoryQuickAction extends BaseOsmAndFragment implements AddQuickActionsAdapter.ItemClickListener { + + public static final String TAG = AddCategoryQuickAction.class.getSimpleName(); + + public static final String QUICK_ACTION_CATEGORY_KEY = "quick_action_category_key"; + + private MapButtonsHelper mapButtonsHelper; + private QuickActionButtonState buttonState; + private QuickActionType categoryAction; + + public boolean getContentStatusBarNightMode() { + return nightMode; + } + + @Override + public int getStatusBarColorId() { + AndroidUiHelper.setStatusBarContentColor(getView(), nightMode); + return ColorUtilities.getListBgColorId(nightMode); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mapButtonsHelper = app.getMapButtonsHelper(); + + Bundle args = getArguments(); + String key = args != null ? args.getString(QUICK_ACTION_BUTTON_KEY) : null; + if (key != null) { + buttonState = mapButtonsHelper.getButtonStateById(key); + } + int categoryTypeId = args != null ? args.getInt(QUICK_ACTION_CATEGORY_KEY, -1) : -1; + if (categoryTypeId != -1) { + categoryAction = mapButtonsHelper.getCategoryActionTypeFromId(categoryTypeId); + } + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + updateNightMode(); + View view = themedInflater.inflate(R.layout.fragment_add_category_quick_action, container, false); + mapButtonsHelper = app.getMapButtonsHelper(); + if (Build.VERSION.SDK_INT < 30) { + AndroidUtils.addStatusBarPadding21v(requireMyActivity(), view); + } + setupToolbar(view); + setupContent(view); + + return view; + } + + private void setupToolbar(@NonNull View view) { + TextView title = view.findViewById(R.id.toolbar_title); + if (categoryAction != null) { + title.setText(app.getString(categoryAction.getNameRes())); + } + + ImageView backButton = view.findViewById(R.id.back_button); + backButton.setImageDrawable(getContentIcon(AndroidUtils.getNavigationIconResId(app))); + backButton.setOnClickListener(v -> dismiss()); + } + + private void setupContent(@NonNull View view) { + AddQuickActionsAdapter adapter = new AddQuickActionsAdapter(app, requireMapActivity(), this, nightMode); + adapter.setItems(getCategoryTypes()); + RecyclerView recyclerView = view.findViewById(R.id.content_list); + recyclerView.setLayoutManager(new LinearLayoutManager(app)); + recyclerView.setAdapter(adapter); + } + + @NonNull + private List getCategoryTypes() { + List actionTypes = new ArrayList<>(); + if (categoryAction != null) { + mapButtonsHelper.filterQuickActions(buttonState, categoryAction, actionTypes); + } + return actionTypes; + } + + private void dismiss() { + FragmentActivity activity = getActivity(); + if (activity != null) { + activity.onBackPressed(); + } + } + + @NonNull + public MapActivity requireMapActivity() { + FragmentActivity activity = getActivity(); + if (!(activity instanceof MapActivity)) { + throw new IllegalStateException("Fragment " + this + " not attached to an activity."); + } + return (MapActivity) activity; + } + + public static void showInstance(@NonNull FragmentManager manager, @NonNull QuickActionButtonState buttonState, int quickActionCategoryId) { + if (AndroidUtils.isFragmentCanBeAdded(manager, TAG)) { + Bundle bundle = new Bundle(); + bundle.putString(QUICK_ACTION_BUTTON_KEY, buttonState.getId()); + bundle.putInt(QUICK_ACTION_CATEGORY_KEY, quickActionCategoryId); + + AddCategoryQuickAction fragment = new AddCategoryQuickAction(); + fragment.setArguments(bundle); + manager.beginTransaction() + .add(R.id.fragmentContainer, fragment, TAG) + .addToBackStack(TAG) + .commitAllowingStateLoss(); + } + } + + @Override + public void onItemClick(@NonNull QuickActionType quickActionType) { + FragmentActivity activity = getActivity(); + if (activity != null) { + FragmentManager manager = activity.getSupportFragmentManager(); + if (quickActionType.getId() != 0) { + CreateEditActionDialog.showInstance(manager, buttonState, quickActionType.getId()); + } + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionDialog.java b/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionDialog.java deleted file mode 100644 index 585bd6f104f..00000000000 --- a/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionDialog.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.osmand.plus.quickaction; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; - -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; -import net.osmand.plus.base.MenuBottomSheetDialogFragment; -import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; -import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; -import net.osmand.plus.utils.AndroidUtils; -import net.osmand.plus.utils.UiUtilities; -import net.osmand.plus.views.mapwidgets.configure.buttons.QuickActionButtonState; - -import java.util.List; - -/** - * Created by rosty on 12/22/16. - */ - -public class AddQuickActionDialog extends MenuBottomSheetDialogFragment { - - private static final String TAG = AddQuickActionDialog.class.getSimpleName(); - public static final String QUICK_ACTION_BUTTON_KEY = "quick_action_button_key"; - - private MapButtonsHelper mapButtonsHelper; - private QuickActionButtonState buttonState; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - OsmandApplication app = requiredMyApplication(); - mapButtonsHelper = app.getMapButtonsHelper(); - - Bundle args = getArguments(); - String key = args != null ? args.getString(QUICK_ACTION_BUTTON_KEY) : null; - if (key != null) { - buttonState = mapButtonsHelper.getButtonStateById(key); - } - } - - @Override - public void createMenuItems(Bundle savedInstanceState) { - items.add(new TitleItem(getString(R.string.dialog_add_action_title))); - - LayoutInflater inflater = UiUtilities.getInflater(requireContext(), nightMode); - List actions = mapButtonsHelper.produceTypeActionsListWithHeaders(buttonState); - boolean firstHeader = true; - for (QuickActionType type : actions) { - if (type.getId() == 0) { - View itemView = inflater.inflate(R.layout.quick_action_add_dialog_header, null, false); - TextView title = itemView.findViewById(R.id.header); - View divider = itemView.findViewById(R.id.divider); - title.setText(type.getNameRes()); - divider.setVisibility(firstHeader ? View.GONE : View.VISIBLE); - items.add(new BaseBottomSheetItem.Builder() - .setCustomView(itemView) - .create()); - firstHeader = false; - } else { - addActionItem(type, inflater); - } - } - } - - private void addActionItem(@NonNull QuickActionType type, @NonNull LayoutInflater inflater) { - View itemView = inflater.inflate(R.layout.quick_action_add_dialog_item, null, false); - TextView title = itemView.findViewById(R.id.title); - ImageView icon = itemView.findViewById(R.id.image); - if (type.getActionNameRes() != 0) { - String name = getString(type.getNameRes()); - String actionName = getString(type.getActionNameRes()); - title.setText(getString(R.string.ltr_or_rtl_combine_via_dash, actionName, name)); - } else { - title.setText(type.getNameRes()); - } - icon.setImageResource(type.getIconRes()); - items.add(new BaseBottomSheetItem.Builder() - .setCustomView(itemView) - .setOnClickListener(view -> { - FragmentActivity activity = getActivity(); - if (activity != null) { - FragmentManager manager = activity.getSupportFragmentManager(); - CreateEditActionDialog.showInstance(manager, buttonState, type.getId()); - } - dismiss(); - }).create()); - } - - public static void showInstance(@NonNull FragmentManager manager, - @NonNull QuickActionButtonState buttonState, boolean usedOnMap) { - if (AndroidUtils.isFragmentCanBeAdded(manager, TAG)) { - Bundle bundle = new Bundle(); - bundle.putString(QUICK_ACTION_BUTTON_KEY, buttonState.getId()); - - AddQuickActionDialog fragment = new AddQuickActionDialog(); - fragment.setArguments(bundle); - fragment.setUsedOnMap(usedOnMap); - fragment.show(manager, TAG); - } - } -} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionFragment.java b/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionFragment.java new file mode 100644 index 00000000000..b1215041109 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionFragment.java @@ -0,0 +1,245 @@ +package net.osmand.plus.quickaction; + +import android.os.Build; +import android.os.Bundle; +import android.text.Editable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.activity.OnBackPressedCallback; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.base.BaseOsmAndFragment; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.utils.AndroidUtils; +import net.osmand.plus.utils.ColorUtilities; +import net.osmand.plus.views.mapwidgets.configure.buttons.QuickActionButtonState; +import net.osmand.plus.widgets.tools.SimpleTextWatcher; + +import java.util.List; +import java.util.Map; + +public class AddQuickActionFragment extends BaseOsmAndFragment implements AddQuickActionsAdapter.ItemClickListener, CreateEditActionDialog.AddQuickActionListener { + + public static final String TAG = AddQuickActionFragment.class.getSimpleName(); + + public static final String QUICK_ACTION_BUTTON_KEY = "quick_action_button_key"; + public static final String QUICK_ACTION_SEARCH_KEY = "quick_action_search_key"; + public static final String QUICK_ACTION_SEARCH_MODE_KEY = "quick_action_search_mode_key"; + + private AddQuickActionsAdapter adapter; + private ImageButton clearSearchQuery; + private EditText searchEditText; + private ImageView backButton; + private TextView title; + private ImageView searchButton; + + private MapButtonsHelper mapButtonsHelper; + private QuickActionButtonState buttonState; + private boolean searchMode = false; + + public boolean getContentStatusBarNightMode() { + return nightMode; + } + + @Override + public int getStatusBarColorId() { + AndroidUiHelper.setStatusBarContentColor(getView(), nightMode); + return ColorUtilities.getListBgColorId(nightMode); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mapButtonsHelper = app.getMapButtonsHelper(); + + Bundle args = getArguments(); + String key = args != null ? args.getString(QUICK_ACTION_BUTTON_KEY) : null; + if (key != null) { + buttonState = mapButtonsHelper.getButtonStateById(key); + } + if (savedInstanceState != null) { + searchMode = savedInstanceState.getBoolean(QUICK_ACTION_SEARCH_MODE_KEY, false); + } + + requireMapActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + onBackPressed(); + } + }); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + updateNightMode(); + View view = themedInflater.inflate(R.layout.fragment_add_quick_action, container, false); + if (Build.VERSION.SDK_INT < 30) { + AndroidUtils.addStatusBarPadding21v(requireMyActivity(), view); + } + setupSearchBar(view); + setupToolbar(view); + setupContent(view, savedInstanceState); + + return view; + } + + private void setupToolbar(@NonNull View view) { + Toolbar toolbar = view.findViewById(R.id.toolbar); + title = toolbar.findViewById(R.id.toolbar_title); + title.setText(R.string.dialog_add_action_title); + + backButton = toolbar.findViewById(R.id.back_button); + backButton.setOnClickListener(v -> onBackPressed()); + + searchButton = toolbar.findViewById(R.id.search_button); + searchButton.setOnClickListener(v -> setSearchMode(true)); + searchButton.setImageDrawable(getContentIcon(R.drawable.ic_action_search_dark)); + updateToolbar(); + } + + private void setupSearchBar(@NonNull View view) { + View searchContainer = view.findViewById(R.id.search_container); + clearSearchQuery = searchContainer.findViewById(R.id.clearButton); + clearSearchQuery.setVisibility(View.GONE); + clearSearchQuery.setImageDrawable(getContentIcon(R.drawable.ic_action_cancel)); + searchEditText = searchContainer.findViewById(R.id.searchEditText); + searchEditText.setHint(null); + searchEditText.addTextChangedListener(new SimpleTextWatcher() { + @Override + public void afterTextChanged(Editable query) { + adapter.filter(query.toString()); + AndroidUiHelper.updateVisibility(clearSearchQuery, query.length() > 0); + } + }); + clearSearchQuery.setOnClickListener((v) -> resetSearchQuery()); + } + + private void resetSearchQuery() { + adapter.filter(null); + searchEditText.setText(null); + } + + private void setSearchMode(boolean searchMode) { + this.searchMode = searchMode; + if (!searchMode) { + resetSearchQuery(); + } + updateToolbar(); + updateAdapter(); + } + + private void updateToolbar() { + backButton.setImageDrawable(getContentIcon(searchMode ? AndroidUtils.getNavigationIconResId(app) : R.drawable.ic_action_close)); + AndroidUiHelper.setVisibility(searchMode ? View.GONE : View.VISIBLE, searchButton, title); + AndroidUiHelper.setVisibility(searchMode ? View.VISIBLE : View.GONE, searchEditText); + if (searchMode) { + searchEditText.requestFocus(); + AndroidUtils.showSoftKeyboard(requireMapActivity(), searchEditText); + } else { + AndroidUtils.hideSoftKeyboard(requireActivity(), searchEditText); + AndroidUiHelper.updateVisibility(clearSearchQuery, false); + } + } + + private void setupContent(@NonNull View view, @Nullable Bundle savedInstanceState) { + adapter = new AddQuickActionsAdapter(app, requireMapActivity(), this, nightMode); + adapter.setMap(getAdapterItems()); + RecyclerView recyclerView = view.findViewById(R.id.content_list); + recyclerView.setLayoutManager(new LinearLayoutManager(app)); + recyclerView.setAdapter(adapter); + updateAdapter(); + + String searchQuery = savedInstanceState != null ? savedInstanceState.getString(QUICK_ACTION_SEARCH_KEY) : null; + if (searchQuery != null) { + adapter.filter(searchQuery); + } + } + + private void updateAdapter() { + adapter.setSearchMode(searchMode); + } + + @NonNull + private Map> getAdapterItems() { + return mapButtonsHelper.produceTypeActionsListWithHeaders(buttonState); + } + + private void onBackPressed() { + if (searchMode) { + setSearchMode(false); + } else { + dismiss(); + } + } + + private void dismiss() { + FragmentManager fragmentManager = requireMapActivity().getSupportFragmentManager(); + if (!fragmentManager.isStateSaved()) { + fragmentManager.popBackStackImmediate(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE); + } + } + + @NonNull + public MapActivity requireMapActivity() { + FragmentActivity activity = getActivity(); + if (!(activity instanceof MapActivity)) { + throw new IllegalStateException("Fragment " + this + " not attached to an activity."); + } + return (MapActivity) activity; + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + outState.putString(QUICK_ACTION_SEARCH_KEY, adapter.getSearchQuery()); + outState.putBoolean(QUICK_ACTION_SEARCH_MODE_KEY, searchMode); + super.onSaveInstanceState(outState); + } + + public static void showInstance(@NonNull FragmentManager manager, @NonNull QuickActionButtonState buttonState) { + if (AndroidUtils.isFragmentCanBeAdded(manager, TAG)) { + Bundle bundle = new Bundle(); + bundle.putString(QUICK_ACTION_BUTTON_KEY, buttonState.getId()); + + AddQuickActionFragment fragment = new AddQuickActionFragment(); + fragment.setArguments(bundle); + manager.beginTransaction() + .add(R.id.fragmentContainer, fragment, TAG) + .addToBackStack(TAG) + .commitAllowingStateLoss(); + } + } + + @Override + public void onItemClick(@NonNull QuickActionType quickActionType) { + FragmentActivity activity = getActivity(); + if (activity != null) { + FragmentManager manager = activity.getSupportFragmentManager(); + if (quickActionType.getId() != 0) { + CreateEditActionDialog.showInstance(manager, buttonState, quickActionType.getId()); + } else { + AddCategoryQuickAction.showInstance(manager, buttonState, quickActionType.getCategory()); + } + } + } + + @Override + public void onQuickActionAdded() { + dismiss(); + } +} + diff --git a/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionsAdapter.java b/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionsAdapter.java new file mode 100644 index 00000000000..aa6decb9a77 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionsAdapter.java @@ -0,0 +1,129 @@ +package net.osmand.plus.quickaction; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.utils.UiUtilities; +import net.osmand.util.Algorithms; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AddQuickActionsAdapter extends RecyclerView.Adapter { + private final OsmandApplication app; + private final Map> quickActionsMap = new HashMap<>(); + private final List items = new ArrayList<>(); + private boolean searchMode = false; + private String filterQuery; + + private final ItemClickListener listener; + private final LayoutInflater themedInflater; + private final boolean nightMode; + + public AddQuickActionsAdapter(@NonNull OsmandApplication app, @NonNull Context context, @Nullable ItemClickListener listener, boolean nightMode) { + this.app = app; + this.listener = listener; + this.nightMode = nightMode; + this.themedInflater = UiUtilities.getInflater(context, nightMode); + } + + public void setMap(@NonNull Map> quickActionsMap) { + this.quickActionsMap.clear(); + this.quickActionsMap.putAll(quickActionsMap); + setItemsFromMap(); + } + + public void setItems(@NonNull List items) { + this.items.clear(); + this.items.addAll(items); + this.items.sort((o1, o2) -> app.getMapButtonsHelper().compareNames(app.getString(o1.getNameRes()), app.getString(o2.getNameRes()))); + } + + private void setItemsFromMap() { + items.clear(); + if (searchMode) { + for (List typeActions : quickActionsMap.values()) { + if (Algorithms.isEmpty(filterQuery)) { + items.addAll(typeActions); + } else { + for (QuickActionType action : typeActions) { + if (app.getString(action.getNameRes()).toLowerCase().contains(filterQuery.toLowerCase())) { + items.add(action); + } + } + } + } + items.sort((o1, o2) -> app.getMapButtonsHelper().compareNames(app.getString(o1.getNameRes()), app.getString(o2.getNameRes()))); + } else { + quickActionsMap.keySet() + .stream() + .sorted((o1, o2) -> app.getMapButtonsHelper().compareNames(app.getString(o1.getNameRes()), app.getString(o2.getNameRes()))) + .forEach(items::add); + } + } + + public void filter(@Nullable String query) { + this.filterQuery = query; + setItemsFromMap(); + notifyDataSetChanged(); + } + + public String getSearchQuery() { + return filterQuery; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = themedInflater.inflate(R.layout.configure_screen_list_item, parent, false); + return new QuickActionViewHolder(view, nightMode); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof QuickActionViewHolder) { + QuickActionType item = items.get(position); + boolean lastItem = position == getItemCount() - 1; + int descriptionCount = 0; + if (!searchMode && item.getId() == 0) { + List typeActions = quickActionsMap.get(item); + if (typeActions != null) { + descriptionCount = typeActions.size(); + } + } + QuickActionViewHolder viewHolder = (QuickActionViewHolder) holder; + viewHolder.bindView(item, descriptionCount, lastItem); + viewHolder.itemView.setOnClickListener(v -> { + int adapterPosition = holder.getAdapterPosition(); + if (listener != null && adapterPosition != RecyclerView.NO_POSITION) { + listener.onItemClick(items.get(adapterPosition)); + } + }); + } + } + + @Override + public int getItemCount() { + return items.size(); + } + + public void setSearchMode(boolean searchMode) { + this.searchMode = searchMode; + setItemsFromMap(); + notifyDataSetChanged(); + } + + public interface ItemClickListener { + void onItemClick(@NonNull QuickActionType quickActionType); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/quickaction/CreateEditActionDialog.java b/OsmAnd/src/net/osmand/plus/quickaction/CreateEditActionDialog.java index 569d5083923..6fceb75ee3f 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/CreateEditActionDialog.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/CreateEditActionDialog.java @@ -1,6 +1,6 @@ package net.osmand.plus.quickaction; -import static net.osmand.plus.quickaction.AddQuickActionDialog.QUICK_ACTION_BUTTON_KEY; +import static net.osmand.plus.quickaction.AddQuickActionFragment.QUICK_ACTION_BUTTON_KEY; import static net.osmand.plus.quickaction.QuickActionListFragment.showConfirmDeleteAnActionBottomSheet; import android.app.Dialog; @@ -22,6 +22,7 @@ import androidx.appcompat.widget.Toolbar; import androidx.core.content.ContextCompat; import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; @@ -187,6 +188,7 @@ public void onClick(View view) { } else { mapButtonsHelper.updateQuickAction(buttonState, action); } + notifyOnActionAdded(); dismiss(); } else { action = mapButtonsHelper.generateUniqueActionName(actions, action); @@ -204,6 +206,15 @@ private void saveFirstTagWithEmptyValue() { }); } + private void notifyOnActionAdded() { + FragmentManager manager = getParentFragmentManager(); + for (Fragment fragment : manager.getFragments()) { + if (fragment instanceof AddQuickActionListener) { + ((AddQuickActionListener) fragment).onQuickActionAdded(); + } + } + } + private void showDuplicatedDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(requireContext()); builder.setTitle(R.string.quick_action_duplicate); @@ -215,6 +226,7 @@ private void showDuplicatedDialog() { mapButtonsHelper.updateQuickAction(buttonState, action); } CreateEditActionDialog.this.dismiss(); + notifyOnActionAdded(); dismiss(); }).create().show(); } @@ -287,4 +299,7 @@ public static void showInstance(@NonNull FragmentManager fragmentManager, dialog.show(fragmentManager, TAG); } } + public interface AddQuickActionListener { + void onQuickActionAdded(); + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/quickaction/MapButtonsHelper.java b/OsmAnd/src/net/osmand/plus/quickaction/MapButtonsHelper.java index 731b23c8ae8..76fc4688f91 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/MapButtonsHelper.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/MapButtonsHelper.java @@ -1,5 +1,6 @@ package net.osmand.plus.quickaction; +import static net.osmand.plus.quickaction.QuickActionType.CREATE_CATEGORY; import static net.osmand.plus.views.mapwidgets.configure.buttons.QuickActionButtonState.DEFAULT_BUTTON_ID; import androidx.annotation.NonNull; @@ -8,6 +9,8 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import net.osmand.Collator; +import net.osmand.OsmAndCollator; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.plugins.PluginsHelper; @@ -20,8 +23,12 @@ import net.osmand.plus.views.mapwidgets.configure.buttons.QuickActionButtonState; import net.osmand.util.Algorithms; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; @@ -41,19 +48,78 @@ public interface QuickActionUpdatesListener { void onActionsUpdated(); } + @Retention(RetentionPolicy.RUNTIME) + public @interface QuickActionCategoryType { + } + + @QuickActionCategoryType public static final QuickActionType TYPE_ADD_ITEMS = new QuickActionType(0, ""). - nameRes(R.string.quick_action_add_create_items).category(QuickActionType.CREATE_CATEGORY); + nameRes(R.string.quick_action_add_create_items).category(CREATE_CATEGORY); + @QuickActionCategoryType public static final QuickActionType TYPE_CONFIGURE_MAP = new QuickActionType(0, ""). - nameRes(R.string.quick_action_add_configure_map).category(QuickActionType.CONFIGURE_MAP); + nameRes(R.string.quick_action_add_configure_map).category(QuickActionType.CONFIGURE_MAP).iconRes(R.drawable.ic_layer_top); + @QuickActionCategoryType public static final QuickActionType TYPE_NAVIGATION = new QuickActionType(0, ""). - nameRes(R.string.shared_string_navigation).category(QuickActionType.NAVIGATION); + nameRes(R.string.shared_string_navigation).category(QuickActionType.NAVIGATION).iconRes(R.drawable.ic_action_gdirections_dark); + @QuickActionCategoryType public static final QuickActionType TYPE_CONFIGURE_SCREEN = new QuickActionType(0, ""). nameRes(R.string.map_widget_config).category(QuickActionType.CONFIGURE_SCREEN); + @QuickActionCategoryType public static final QuickActionType TYPE_SETTINGS = new QuickActionType(0, ""). - nameRes(R.string.shared_string_settings).category(QuickActionType.SETTINGS); + nameRes(R.string.shared_string_settings).category(QuickActionType.SETTINGS).iconRes(R.drawable.ic_action_settings); + @QuickActionCategoryType public static final QuickActionType TYPE_OPEN = new QuickActionType(0, ""). nameRes(R.string.shared_string_open).category(QuickActionType.OPEN); + @QuickActionCategoryType + public static final QuickActionType TYPE_AUDIO_VIDEO_NOTES = new QuickActionType(0, ""). + nameRes(R.string.audionotes_plugin_name).category(QuickActionType.AUDIO_VIDEO_NOTES).iconRes(R.drawable.ic_action_micro_dark); + @QuickActionCategoryType + public static final QuickActionType TYPE_FAVORITES = new QuickActionType(0, ""). + nameRes(R.string.shared_string_favorites).category(QuickActionType.FAVORITES).iconRes(R.drawable.ic_action_favorite); + @QuickActionCategoryType + public static final QuickActionType TYPE_MAP_APPEARANCE = new QuickActionType(0, ""). + nameRes(R.string.map_look_descr).category(QuickActionType.MAP_APPEARANCE).iconRes(R.drawable.ic_action_map_style); + @QuickActionCategoryType + public static final QuickActionType TYPE_MAP_INTERACTIONS = new QuickActionType(0, ""). + nameRes(R.string.key_event_category_map_interactions).category(QuickActionType.MAP_INTERACTIONS).iconRes(R.drawable.ic_action_settings); + @QuickActionCategoryType + public static final QuickActionType TYPE_OSM_EDITING = new QuickActionType(0, ""). + nameRes(R.string.osm_editing_plugin_name).category(QuickActionType.OSM_EDITING).iconRes(R.drawable.ic_action_openstreetmap_logo); + @QuickActionCategoryType + public static final QuickActionType TYPE_TOPOGRAPHY = new QuickActionType(0, ""). + nameRes(R.string.srtm_plugin_name).category(QuickActionType.TOPOGRAPHY).iconRes(R.drawable.ic_action_terrain); + @QuickActionCategoryType + public static final QuickActionType TYPE_TRACKS = new QuickActionType(0, ""). + nameRes(R.string.shared_string_tracks).category(QuickActionType.TRACKS).iconRes(R.drawable.ic_action_polygom_dark); + @QuickActionCategoryType + public static final QuickActionType TYPE_WEATHER = new QuickActionType(0, ""). + nameRes(R.string.shared_string_weather).category(QuickActionType.WEATHER).iconRes(R.drawable.ic_action_umbrella); + + public static List collectQuickActionCategoryType(Class typeClass) { + List annotatedFields = new ArrayList<>(); + Field[] fields = typeClass.getDeclaredFields(); + + for (Field field : fields) { + if (field.isAnnotationPresent(QuickActionCategoryType.class)) { + try { + annotatedFields.add((QuickActionType) field.get(null)); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + return annotatedFields; + } + @Nullable + public QuickActionType getCategoryActionTypeFromId(int typeId) { + for (QuickActionType type : collectQuickActionCategoryType(this.getClass())) { + if (type.getCategory() == typeId) { + return type; + } + } + return null; + } private final OsmandApplication app; private final OsmandSettings settings; @@ -68,6 +134,7 @@ public interface QuickActionUpdatesListener { private Map quickActionTypesInt = new TreeMap<>(); private Map quickActionTypesStr = new TreeMap<>(); private Set updatesListeners = new HashSet<>(); + private final Collator collator = OsmAndCollator.primaryCollator(); public MapButtonsHelper(@NonNull OsmandApplication app) { this.app = app; @@ -235,6 +302,13 @@ public void updateActionTypes() { allTypes.add(GPXAction.TYPE); allTypes.add(MarkerAction.TYPE); allTypes.add(RouteAction.TYPE); + allTypes.add(MapScrollUpAction.TYPE); + allTypes.add(MapScrollDownAction.TYPE); + allTypes.add(MapScrollLeftAction.TYPE); + allTypes.add(MapScrollRightAction.TYPE); + allTypes.add(MapZoomInAction.TYPE); + allTypes.add(MapZoomOutAction.TYPE); + allTypes.add(MoveToMyLocationAction.TYPE); // configure map allTypes.add(ShowHideFavoritesAction.TYPE); allTypes.add(ShowHideGpxTracksAction.TYPE); @@ -256,6 +330,8 @@ public void updateActionTypes() { allTypes.add(NavRemoveNextDestination.TYPE); // settings allTypes.add(DisplayPositionAction.TYPE); + allTypes.add(NextAppProfileAction.TYPE); + allTypes.add(PreviousAppProfileAction.TYPE); List enabledTypes = new ArrayList<>(allTypes); PluginsHelper.registerQuickActionTypesPlugins(allTypes, enabledTypes); @@ -312,23 +388,30 @@ public void copyQuickActionsFromMode(@NonNull ApplicationMode toAppMode, @NonNul } @NonNull - public List produceTypeActionsListWithHeaders(@NonNull QuickActionButtonState buttonState) { - List actionTypes = new ArrayList<>(); - filterQuickActions(buttonState, TYPE_ADD_ITEMS, actionTypes); - filterQuickActions(buttonState, TYPE_CONFIGURE_MAP, actionTypes); - filterQuickActions(buttonState, TYPE_NAVIGATION, actionTypes); + public Map> produceTypeActionsListWithHeaders(@NonNull QuickActionButtonState buttonState) { + Map> quickActions = new HashMap<>(); + + filterQuickActions(buttonState, TYPE_ADD_ITEMS, quickActions); + filterQuickActions(buttonState, TYPE_CONFIGURE_MAP, quickActions); + filterQuickActions(buttonState, TYPE_NAVIGATION, quickActions); // filterQuickActions(buttonState, TYPE_CONFIGURE_SCREEN, actionTypes); - filterQuickActions(buttonState, TYPE_SETTINGS, actionTypes); - filterQuickActions(buttonState, TYPE_OPEN, actionTypes); + filterQuickActions(buttonState, TYPE_SETTINGS, quickActions); - return actionTypes; - } + filterQuickActions(buttonState, TYPE_AUDIO_VIDEO_NOTES, quickActions); + filterQuickActions(buttonState, TYPE_FAVORITES, quickActions); + filterQuickActions(buttonState, TYPE_MAP_APPEARANCE, quickActions); + filterQuickActions(buttonState, TYPE_MAP_INTERACTIONS, quickActions); + filterQuickActions(buttonState, TYPE_OSM_EDITING, quickActions); + filterQuickActions(buttonState, TYPE_TOPOGRAPHY, quickActions); + filterQuickActions(buttonState, TYPE_TRACKS, quickActions); + filterQuickActions(buttonState, TYPE_WEATHER, quickActions); - private void filterQuickActions(@NonNull QuickActionButtonState buttonState, - @NonNull QuickActionType filter, - @NonNull List actionTypes) { - actionTypes.add(filter); + return quickActions; + } + public void filterQuickActions(@NonNull QuickActionButtonState buttonState, + @NonNull QuickActionType filter, + @NonNull List actionTypes) { Set set = new TreeSet<>(); for (QuickAction action : buttonState.getQuickActions()) { set.add(action.getActionType().getId()); @@ -347,6 +430,28 @@ private void filterQuickActions(@NonNull QuickActionButtonState buttonState, } } + private void filterQuickActions(@NonNull QuickActionButtonState buttonState, + @NonNull QuickActionType filter, + @NonNull Map> actionTypes) { + List categoryActions = actionTypes.get(filter); + if (categoryActions == null) { + categoryActions = new ArrayList<>(); + } else { + categoryActions.clear(); + } + + filterQuickActions(buttonState, filter, categoryActions); + + if (!Algorithms.isEmpty(categoryActions)) { + categoryActions.sort((o1, o2) -> compareNames(app.getString(o1.getNameRes()), app.getString(o2.getNameRes()))); + actionTypes.put(filter, categoryActions); + } + } + + public int compareNames(@NonNull String item1, @NonNull String item2) { + return collator.compare(item1, item2); + } + @Nullable public QuickAction newActionByStringType(String actionType) { QuickActionType quickActionType = quickActionTypesStr.get(actionType); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionIds.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionIds.java index 265528390db..32f9e2eaed1 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionIds.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionIds.java @@ -43,5 +43,13 @@ public class QuickActionIds { public static final int SHOW_HIDE_AIR_PRESSURE_LAYER_ACTION_ID = 43; public static final int OPEN_WEATHER_ACTION_ID = 44; public static final int LOCATION_SIMULATION_ACTION_ID = 45; - + public static final int MAP_SCROLL_UP_ACTION = 46; + public static final int MAP_SCROLL_DOWN_ACTION = 47; + public static final int MAP_SCROLL_LEFT_ACTION = 48; + public static final int MAP_SCROLL_RIGHT_ACTION = 49; + public static final int MAP_ZOOM_IN_ACTION = 50; + public static final int MAP_ZOOM_OUT_ACTION = 51; + public static final int MOVE_TO_MY_LOCATION_ACTION = 52; + public static final int NEXT_PROFILE_PROFILE_ACTION = 53; + public static final int PREVIOUS_PROFILE_PROFILE_ACTION = 54; } diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java index f26f88b78d2..166f901c32a 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java @@ -1,6 +1,6 @@ package net.osmand.plus.quickaction; -import static net.osmand.plus.quickaction.AddQuickActionDialog.QUICK_ACTION_BUTTON_KEY; +import static net.osmand.plus.quickaction.AddQuickActionFragment.QUICK_ACTION_BUTTON_KEY; import static net.osmand.plus.utils.UiUtilities.CompoundButtonType.TOOLBAR; import static net.osmand.plus.widgets.dialogbutton.DialogButtonType.SECONDARY; @@ -883,7 +883,7 @@ public interface OnStartDragListener { private void showAddQuickActionDialog() { FragmentManager manager = getFragmentManager(); if (manager != null) { - AddQuickActionDialog.showInstance(manager, buttonState, false); + AddQuickActionFragment.showInstance(manager, buttonState); } } diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionType.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionType.java index 27269fa171d..694ed1b0a6b 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionType.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionType.java @@ -14,6 +14,14 @@ public class QuickActionType { public static final int CONFIGURE_SCREEN = 3; public static final int SETTINGS = 4; public static final int OPEN = 5; + public static final int AUDIO_VIDEO_NOTES = 6; + public static final int FAVORITES = 7; + public static final int MAP_APPEARANCE = 8; + public static final int MAP_INTERACTIONS = 9; + public static final int OSM_EDITING = 10; + public static final int TOPOGRAPHY = 11; + public static final int TRACKS = 12; + public static final int WEATHER = 13; private final int id; private final String stringId; diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionViewHolder.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionViewHolder.java new file mode 100644 index 00000000000..a938347bb33 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionViewHolder.java @@ -0,0 +1,74 @@ +package net.osmand.plus.quickaction; + +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.utils.AndroidUtils; +import net.osmand.plus.utils.ColorUtilities; +import net.osmand.plus.utils.UiUtilities; + + +public class QuickActionViewHolder extends RecyclerView.ViewHolder { + + private final OsmandApplication app; + private final OsmandSettings settings; + private final boolean nightMode; + + private final ImageView iconView; + private final TextView title; + private final TextView description; + private final TextView itemsCountView; + private final View shortDivider; + + public QuickActionViewHolder(@NonNull View itemView, boolean nightMode) { + super(itemView); + app = (OsmandApplication) itemView.getContext().getApplicationContext(); + settings = app.getSettings(); + this.nightMode = nightMode; + + iconView = itemView.findViewById(R.id.icon); + title = itemView.findViewById(R.id.title); + description = itemView.findViewById(R.id.description); + itemsCountView = itemView.findViewById(R.id.items_count_descr); + shortDivider = itemView.findViewById(R.id.short_divider); + } + + public void bindView(@NonNull QuickActionType type, int itemsCount, boolean lastItem) { + if (type.getActionNameRes() != 0) { + String name = app.getString(type.getNameRes()); + String actionName = app.getString(type.getActionNameRes()); + title.setText(app.getString(R.string.ltr_or_rtl_combine_via_dash, actionName, name)); + } else { + title.setText(type.getNameRes()); + } + + ApplicationMode appMode = settings.getApplicationMode(); + int iconRes = type.getIconRes(); + if (iconRes != 0) { + Drawable icon = UiUtilities.createTintedDrawable(app, type.getIconRes(), ColorUtilities.getDefaultIconColor(app, nightMode)); + iconView.setImageDrawable(icon); + } + itemsCountView.setText(String.valueOf(itemsCount)); + + setupListItemBackground(appMode, nightMode); + AndroidUiHelper.updateVisibility(itemsCountView, itemsCount != 0); + AndroidUiHelper.updateVisibility(description, false); + AndroidUiHelper.updateVisibility(shortDivider, !lastItem); + } + + private void setupListItemBackground(@NonNull ApplicationMode mode, boolean nightMode) { + int color = mode.getProfileColor(nightMode); + Drawable background = UiUtilities.getColoredSelectableDrawable(app, color, 0.3f); + AndroidUtils.setBackground(itemView.findViewById(R.id.button_container), background); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/quickaction/SelectMapViewQuickActionsBottomSheet.java b/OsmAnd/src/net/osmand/plus/quickaction/SelectMapViewQuickActionsBottomSheet.java index 380091e2aff..0f3b6e0bd78 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/SelectMapViewQuickActionsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/SelectMapViewQuickActionsBottomSheet.java @@ -1,7 +1,7 @@ package net.osmand.plus.quickaction; -import static net.osmand.plus.quickaction.AddQuickActionDialog.QUICK_ACTION_BUTTON_KEY; +import static net.osmand.plus.quickaction.AddQuickActionFragment.QUICK_ACTION_BUTTON_KEY; import static net.osmand.plus.quickaction.SwitchableAction.KEY_ID; import android.app.Activity; diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/BaseMapScrollAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/BaseMapScrollAction.java new file mode 100644 index 00000000000..8c8d9a04390 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/BaseMapScrollAction.java @@ -0,0 +1,47 @@ +package net.osmand.plus.quickaction.actions; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; + +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.helpers.MapScrollHelper; +import net.osmand.plus.helpers.MapScrollHelper.ScrollDirection; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; + +public abstract class BaseMapScrollAction extends QuickAction { + + public BaseMapScrollAction(QuickActionType type) { + super(type); + } + + public BaseMapScrollAction(QuickAction quickAction) { + super(quickAction); + } + + @NonNull + protected abstract ScrollDirection getScrollingDirection(); + + @StringRes + public abstract int getQuickActionDescription(); + + @Override + public void execute(@NonNull MapActivity mapActivity) { + MapScrollHelper scrollHelper = mapActivity.getMapScrollHelper(); + scrollHelper.scrollMapAction(getScrollingDirection()); + } + + @Override + public void drawUI(@NonNull ViewGroup parent, @NonNull MapActivity mapActivity) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.quick_action_with_text, parent, false); + ((TextView) view.findViewById(R.id.text)).setText(mapActivity.getString(getQuickActionDescription())); + parent.addView(view); + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/BaseMapZoomAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/BaseMapZoomAction.java new file mode 100644 index 00000000000..44498975d6f --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/BaseMapZoomAction.java @@ -0,0 +1,43 @@ +package net.osmand.plus.quickaction.actions; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; + +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; + +public abstract class BaseMapZoomAction extends QuickAction { + + public BaseMapZoomAction(QuickActionType type) { + super(type); + } + + public BaseMapZoomAction(QuickAction quickAction) { + super(quickAction); + } + + protected abstract boolean shouldIncrement(); + + @StringRes + public abstract int getQuickActionDescription(); + + @Override + public void execute(@NonNull MapActivity mapActivity) { + mapActivity.getMyApplication().getOsmandMap().getMapView().changeZoomManually(shouldIncrement() ? 1 : -1); + } + + @Override + public void drawUI(@NonNull ViewGroup parent, @NonNull MapActivity mapActivity) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.quick_action_with_text, parent, false); + ((TextView) view.findViewById(R.id.text)).setText(mapActivity.getString(getQuickActionDescription())); + parent.addView(view); + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/BaseSwitchAppModeAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/BaseSwitchAppModeAction.java new file mode 100644 index 00000000000..9a88dbe0440 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/BaseSwitchAppModeAction.java @@ -0,0 +1,49 @@ +package net.osmand.plus.quickaction.actions; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; + +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; +import net.osmand.plus.settings.backend.OsmandSettings; + +public abstract class BaseSwitchAppModeAction extends QuickAction { + + public BaseSwitchAppModeAction(QuickActionType type) { + super(type); + } + + public BaseSwitchAppModeAction(QuickAction quickAction) { + super(quickAction); + } + + protected abstract boolean shouldChangeForward(); + + @StringRes + public abstract int getQuickActionDescription(); + + @Override + public void execute(@NonNull MapActivity mapActivity) { + OsmandSettings settings = mapActivity.getMyApplication().getSettings(); + if (shouldChangeForward()) { + settings.switchAppModeToNext(); + } else { + settings.switchAppModeToPrevious(); + } + } + + @Override + public void drawUI(@NonNull ViewGroup parent, @NonNull MapActivity mapActivity) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.quick_action_with_text, parent, false); + ((TextView) view.findViewById(R.id.text)).setText(mapActivity.getString(getQuickActionDescription())); + parent.addView(view); + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollDownAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollDownAction.java new file mode 100644 index 00000000000..b233fb2fe45 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollDownAction.java @@ -0,0 +1,38 @@ +package net.osmand.plus.quickaction.actions; + +import static net.osmand.plus.quickaction.QuickActionIds.MAP_SCROLL_DOWN_ACTION; + +import androidx.annotation.NonNull; + +import net.osmand.plus.R; +import net.osmand.plus.helpers.MapScrollHelper; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; + +public class MapScrollDownAction extends BaseMapScrollAction{ + + public static final QuickActionType TYPE = new QuickActionType(MAP_SCROLL_DOWN_ACTION, + "map.scroll.down", MapScrollDownAction.class) + .nameRes(R.string.key_event_action_move_down) + .iconRes(R.drawable.ic_action_arrow_down).nonEditable() + .category(QuickActionType.MAP_INTERACTIONS); + + public MapScrollDownAction() { + super(TYPE); + } + + public MapScrollDownAction(QuickAction quickAction) { + super(quickAction); + } + + @NonNull + @Override + protected MapScrollHelper.ScrollDirection getScrollingDirection() { + return MapScrollHelper.ScrollDirection.DOWN; + } + + @Override + public int getQuickActionDescription() { + return R.string.key_event_action_move_down; + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollLeftAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollLeftAction.java new file mode 100644 index 00000000000..53cc0d55767 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollLeftAction.java @@ -0,0 +1,38 @@ +package net.osmand.plus.quickaction.actions; + +import static net.osmand.plus.quickaction.QuickActionIds.MAP_SCROLL_LEFT_ACTION; + +import androidx.annotation.NonNull; + +import net.osmand.plus.R; +import net.osmand.plus.helpers.MapScrollHelper; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; + +public class MapScrollLeftAction extends BaseMapScrollAction{ + + public static final QuickActionType TYPE = new QuickActionType(MAP_SCROLL_LEFT_ACTION, + "map.scroll.left", MapScrollLeftAction.class) + .nameRes(R.string.key_event_action_move_left) + .iconRes(R.drawable.mm_special_arrow_left).nonEditable() + .category(QuickActionType.MAP_INTERACTIONS); + + public MapScrollLeftAction() { + super(TYPE); + } + + public MapScrollLeftAction(QuickAction quickAction) { + super(quickAction); + } + + @NonNull + @Override + protected MapScrollHelper.ScrollDirection getScrollingDirection() { + return MapScrollHelper.ScrollDirection.LEFT; + } + + @Override + public int getQuickActionDescription() { + return R.string.key_event_action_move_left; + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollRightAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollRightAction.java new file mode 100644 index 00000000000..e0646f53ac1 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollRightAction.java @@ -0,0 +1,38 @@ +package net.osmand.plus.quickaction.actions; + +import static net.osmand.plus.quickaction.QuickActionIds.MAP_SCROLL_RIGHT_ACTION; + +import androidx.annotation.NonNull; + +import net.osmand.plus.R; +import net.osmand.plus.helpers.MapScrollHelper; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; + +public class MapScrollRightAction extends BaseMapScrollAction{ + + public static final QuickActionType TYPE = new QuickActionType(MAP_SCROLL_RIGHT_ACTION, + "map.scroll.right", MapScrollRightAction.class) + .nameRes(R.string.key_event_action_move_right) + .iconRes(R.drawable.ic_arrow_right_16).nonEditable() + .category(QuickActionType.MAP_INTERACTIONS); + + public MapScrollRightAction() { + super(TYPE); + } + + public MapScrollRightAction(QuickAction quickAction) { + super(quickAction); + } + + @NonNull + @Override + protected MapScrollHelper.ScrollDirection getScrollingDirection() { + return MapScrollHelper.ScrollDirection.RIGHT; + } + + @Override + public int getQuickActionDescription() { + return R.string.key_event_action_move_right; + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollUpAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollUpAction.java new file mode 100644 index 00000000000..cb2349e117f --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapScrollUpAction.java @@ -0,0 +1,38 @@ +package net.osmand.plus.quickaction.actions; + +import static net.osmand.plus.quickaction.QuickActionIds.MAP_SCROLL_UP_ACTION; + +import androidx.annotation.NonNull; + +import net.osmand.plus.R; +import net.osmand.plus.helpers.MapScrollHelper; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; + +public class MapScrollUpAction extends BaseMapScrollAction{ + + public static final QuickActionType TYPE = new QuickActionType(MAP_SCROLL_UP_ACTION, + "map.scroll.up", MapScrollUpAction.class) + .nameRes(R.string.key_event_action_move_up) + .iconRes(R.drawable.ic_action_arrow_up).nonEditable() + .category(QuickActionType.MAP_INTERACTIONS); + + public MapScrollUpAction() { + super(TYPE); + } + + public MapScrollUpAction(QuickAction quickAction) { + super(quickAction); + } + + @NonNull + @Override + protected MapScrollHelper.ScrollDirection getScrollingDirection() { + return MapScrollHelper.ScrollDirection.UP; + } + + @Override + public int getQuickActionDescription() { + return R.string.key_event_action_move_up; + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapZoomInAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapZoomInAction.java new file mode 100644 index 00000000000..8ef3bf997a3 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapZoomInAction.java @@ -0,0 +1,34 @@ +package net.osmand.plus.quickaction.actions; + +import static net.osmand.plus.quickaction.QuickActionIds.MAP_ZOOM_IN_ACTION; + +import net.osmand.plus.R; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; + +public class MapZoomInAction extends BaseMapZoomAction { + + public static final QuickActionType TYPE = new QuickActionType(MAP_ZOOM_IN_ACTION, + "map.zoom.in", MapZoomInAction.class) + .nameRes(R.string.key_event_action_zoom_in) + .iconRes(R.drawable.ic_action_magnifier_plus).nonEditable() + .category(QuickActionType.MAP_INTERACTIONS); + + public MapZoomInAction() { + super(TYPE); + } + + public MapZoomInAction(QuickAction quickAction) { + super(quickAction); + } + + @Override + protected boolean shouldIncrement() { + return true; + } + + @Override + public int getQuickActionDescription() { + return R.string.key_event_action_zoom_in; + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapZoomOutAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapZoomOutAction.java new file mode 100644 index 00000000000..dd27f2efea2 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapZoomOutAction.java @@ -0,0 +1,34 @@ +package net.osmand.plus.quickaction.actions; + +import static net.osmand.plus.quickaction.QuickActionIds.MAP_ZOOM_OUT_ACTION; + +import net.osmand.plus.R; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; + +public class MapZoomOutAction extends BaseMapZoomAction { + + public static final QuickActionType TYPE = new QuickActionType(MAP_ZOOM_OUT_ACTION, + "map.zoom.out", MapZoomOutAction.class) + .nameRes(R.string.key_event_action_zoom_out) + .iconRes(R.drawable.ic_action_magnifier_plus).nonEditable() + .category(QuickActionType.MAP_INTERACTIONS); + + public MapZoomOutAction() { + super(TYPE); + } + + public MapZoomOutAction(QuickAction quickAction) { + super(quickAction); + } + + @Override + protected boolean shouldIncrement() { + return false; + } + + @Override + public int getQuickActionDescription() { + return R.string.key_event_action_zoom_out; + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MoveToMyLocationAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MoveToMyLocationAction.java new file mode 100644 index 00000000000..975c72f17ec --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MoveToMyLocationAction.java @@ -0,0 +1,45 @@ +package net.osmand.plus.quickaction.actions; + +import static net.osmand.plus.quickaction.QuickActionIds.MOVE_TO_MY_LOCATION_ACTION; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; + +public class MoveToMyLocationAction extends QuickAction { + + public static final QuickActionType TYPE = new QuickActionType(MOVE_TO_MY_LOCATION_ACTION, + "map.move.my_location", MoveToMyLocationAction.class) + .nameRes(R.string.key_event_action_move_to_my_location) + .iconRes(R.drawable.ic_action_my_location).nonEditable() + .category(QuickActionType.MAP_INTERACTIONS); + + public MoveToMyLocationAction() { + super(TYPE); + } + + public MoveToMyLocationAction(QuickAction quickAction) { + super(quickAction); + } + + @Override + public void execute(@NonNull MapActivity mapActivity) { + mapActivity.getMapViewTrackingUtilities().backToLocationImpl(); + } + + @Override + public void drawUI(@NonNull ViewGroup parent, @NonNull MapActivity mapActivity) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.quick_action_with_text, parent, false); + ((TextView) view.findViewById(R.id.text)).setText(mapActivity.getString(R.string.key_event_action_move_to_my_location)); + parent.addView(view); + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/NewAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/NewAction.java index 716aaa40caf..d711cbd8394 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/NewAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/NewAction.java @@ -7,7 +7,7 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.quickaction.AddQuickActionDialog; +import net.osmand.plus.quickaction.AddQuickActionFragment; import net.osmand.plus.quickaction.QuickAction; import net.osmand.plus.quickaction.QuickActionType; import net.osmand.plus.views.MapLayers; @@ -32,7 +32,7 @@ public void execute(@NonNull MapActivity mapActivity) { QuickActionButton selectedButton = mapLayers.getMapQuickActionLayer().getSelectedButton(); if (selectedButton != null) { FragmentManager manager = mapActivity.getSupportFragmentManager(); - AddQuickActionDialog.showInstance(manager, selectedButton.getButtonState(), true); + AddQuickActionFragment.showInstance(manager, selectedButton.getButtonState()); } } } diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/NextAppProfileAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/NextAppProfileAction.java new file mode 100644 index 00000000000..0b1c09bf8ff --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/NextAppProfileAction.java @@ -0,0 +1,34 @@ +package net.osmand.plus.quickaction.actions; + +import static net.osmand.plus.quickaction.QuickActionIds.NEXT_PROFILE_PROFILE_ACTION; + +import net.osmand.plus.R; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; + +public class NextAppProfileAction extends BaseSwitchAppModeAction { + + public static final QuickActionType TYPE = new QuickActionType(NEXT_PROFILE_PROFILE_ACTION, + "change.profile.next", NextAppProfileAction.class) + .nameRes(R.string.key_event_action_next_app_profile) + .iconRes(R.drawable.ic_action_settings).nonEditable() + .category(QuickActionType.SETTINGS); + + public NextAppProfileAction() { + super(TYPE); + } + + public NextAppProfileAction(QuickAction quickAction) { + super(quickAction); + } + + @Override + protected boolean shouldChangeForward() { + return true; + } + + @Override + public int getQuickActionDescription() { + return R.string.key_event_action_next_app_profile; + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/PreviousAppProfileAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/PreviousAppProfileAction.java new file mode 100644 index 00000000000..43307f45582 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/PreviousAppProfileAction.java @@ -0,0 +1,34 @@ +package net.osmand.plus.quickaction.actions; + +import static net.osmand.plus.quickaction.QuickActionIds.PREVIOUS_PROFILE_PROFILE_ACTION; + +import net.osmand.plus.R; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionType; + +public class PreviousAppProfileAction extends BaseSwitchAppModeAction { + + public static final QuickActionType TYPE = new QuickActionType(PREVIOUS_PROFILE_PROFILE_ACTION, + "change.profile.previous", PreviousAppProfileAction.class) + .nameRes(R.string.key_event_action_previous_app_profile) + .iconRes(R.drawable.ic_action_settings).nonEditable() + .category(QuickActionType.SETTINGS); + + public PreviousAppProfileAction() { + super(TYPE); + } + + public PreviousAppProfileAction(QuickAction quickAction) { + super(quickAction); + } + + @Override + protected boolean shouldChangeForward() { + return false; + } + + @Override + public int getQuickActionDescription() { + return R.string.key_event_action_previous_app_profile; + } +} From 3aa2c1360a5c00fc06c8c81813ff12a985c54b52 Mon Sep 17 00:00:00 2001 From: 0xRe1nk0 <0xre1nk0@gmail.com> Date: Mon, 20 May 2024 10:15:37 +0300 Subject: [PATCH 13/33] Change category in old quick actions --- .../net/osmand/plus/plugins/audionotes/TakeAudioNoteAction.java | 2 +- .../net/osmand/plus/plugins/audionotes/TakePhotoNoteAction.java | 2 +- .../net/osmand/plus/plugins/audionotes/TakeVideoNoteAction.java | 2 +- .../plus/plugins/osmedit/quickactions/AddOSMBugAction.java | 2 +- .../osmand/plus/plugins/osmedit/quickactions/AddPOIAction.java | 2 +- .../plus/plugins/osmedit/quickactions/ShowHideOSMBugAction.java | 2 +- OsmAnd/src/net/osmand/plus/plugins/parking/ParkingAction.java | 2 +- OsmAnd/src/net/osmand/plus/plugins/srtm/ContourLinesAction.java | 2 +- OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainAction.java | 2 +- .../osmand/plus/plugins/weather/actions/OpenWeatherAction.java | 2 +- .../plugins/weather/actions/ShowHideAirPressureLayerAction.java | 2 +- .../plus/plugins/weather/actions/ShowHideCloudLayerAction.java | 2 +- .../weather/actions/ShowHidePrecipitationLayerAction.java | 2 +- .../plugins/weather/actions/ShowHideTemperatureLayerAction.java | 2 +- .../plus/plugins/weather/actions/ShowHideWindLayerAction.java | 2 +- .../net/osmand/plus/quickaction/actions/DayNightModeAction.java | 2 +- .../src/net/osmand/plus/quickaction/actions/FavoriteAction.java | 2 +- OsmAnd/src/net/osmand/plus/quickaction/actions/GPXAction.java | 2 +- .../src/net/osmand/plus/quickaction/actions/MapStyleAction.java | 2 +- .../src/net/osmand/plus/quickaction/actions/MarkerAction.java | 2 +- OsmAnd/src/net/osmand/plus/quickaction/actions/RouteAction.java | 2 +- .../plus/quickaction/actions/ShowHideFavoritesAction.java | 2 +- .../plus/quickaction/actions/ShowHideGpxTracksAction.java | 2 +- .../osmand/plus/quickaction/actions/SwitchProfileAction.java | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakeAudioNoteAction.java b/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakeAudioNoteAction.java index 139b6dc013b..81b2bfeb055 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakeAudioNoteAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakeAudioNoteAction.java @@ -21,7 +21,7 @@ public class TakeAudioNoteAction extends QuickAction { public static final QuickActionType TYPE = new QuickActionType(TAKE_AUDIO_NOTE_ACTION_ID, "audio.note", TakeAudioNoteAction.class). nameRes(R.string.quick_action_take_audio_note).iconRes(R.drawable.ic_action_micro_dark).nonEditable(). - category(QuickActionType.CREATE_CATEGORY); + category(QuickActionType.AUDIO_VIDEO_NOTES); public TakeAudioNoteAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakePhotoNoteAction.java b/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakePhotoNoteAction.java index 185b775dd3b..5270cd32abd 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakePhotoNoteAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakePhotoNoteAction.java @@ -21,7 +21,7 @@ public class TakePhotoNoteAction extends QuickAction { public static final QuickActionType TYPE = new QuickActionType(TAKE_PHOTO_NOTE_ACTION_ID, "photo.note", TakePhotoNoteAction .class). nameRes(R.string.quick_action_take_photo_note).iconRes(R.drawable.ic_action_photo_dark).nonEditable(). - category(QuickActionType.CREATE_CATEGORY); + category(QuickActionType.AUDIO_VIDEO_NOTES); public TakePhotoNoteAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakeVideoNoteAction.java b/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakeVideoNoteAction.java index 77681b38d06..6e864467233 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakeVideoNoteAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/audionotes/TakeVideoNoteAction.java @@ -20,7 +20,7 @@ public class TakeVideoNoteAction extends QuickAction { public static final QuickActionType TYPE = new QuickActionType(TAKE_VIDEO_NOTE_ACTION_ID, "video.note", TakeVideoNoteAction.class). nameRes(R.string.quick_action_take_video_note).iconRes(R.drawable.ic_action_video_dark).nonEditable(). - category(QuickActionType.CREATE_CATEGORY); + category(QuickActionType.AUDIO_VIDEO_NOTES); public TakeVideoNoteAction() { diff --git a/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/AddOSMBugAction.java b/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/AddOSMBugAction.java index 8d940fad547..1aebf7a5666 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/AddOSMBugAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/AddOSMBugAction.java @@ -26,7 +26,7 @@ public class AddOSMBugAction extends QuickAction { public static final QuickActionType TYPE = new QuickActionType(ADD_OSM_BUG_ACTION_ID, "osmbug.add", AddOSMBugAction.class). nameRes(R.string.quick_action_add_osm_bug).iconRes(R.drawable.ic_action_osm_note_add) - .category(QuickActionType.CREATE_CATEGORY); + .category(QuickActionType.OSM_EDITING); public AddOSMBugAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/AddPOIAction.java b/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/AddPOIAction.java index 8183865a40d..a4f2bd96560 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/AddPOIAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/AddPOIAction.java @@ -76,7 +76,7 @@ public class AddPOIAction extends QuickAction { public static final QuickActionType TYPE = new QuickActionType(ADD_POI_ACTION_ID, "osmpoi.add", AddPOIAction.class). nameRes(R.string.quick_action_add_poi).iconRes(R.drawable.ic_action_plus_dark). - category(QuickActionType.CREATE_CATEGORY); + category(QuickActionType.OSM_EDITING); public static final String KEY_TAG = "key_tag"; public static final String KEY_DIALOG = "dialog"; diff --git a/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/ShowHideOSMBugAction.java b/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/ShowHideOSMBugAction.java index c7540b575e6..d55f58a2d8b 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/ShowHideOSMBugAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/osmedit/quickactions/ShowHideOSMBugAction.java @@ -23,7 +23,7 @@ public class ShowHideOSMBugAction extends QuickAction { "osmbug.showhide", ShowHideOSMBugAction.class) .nameActionRes(R.string.quick_action_show_hide_title) .nameRes(R.string.osm_notes).iconRes(R.drawable.ic_action_osm_note).nonEditable() - .category(QuickActionType.CONFIGURE_MAP); + .category(QuickActionType.OSM_EDITING); public ShowHideOSMBugAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/parking/ParkingAction.java b/OsmAnd/src/net/osmand/plus/plugins/parking/ParkingAction.java index 849d44902d3..0254eb4fc38 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/parking/ParkingAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/parking/ParkingAction.java @@ -21,7 +21,7 @@ public class ParkingAction extends QuickAction { public static final QuickActionType TYPE = new QuickActionType(PARKING_ACTION_ID, "parking.add", ParkingAction.class). nameRes(R.string.quick_action_add_parking).iconRes(R.drawable.ic_action_parking_dark).nonEditable(). - category(QuickActionType.CREATE_CATEGORY); + category(QuickActionType.CONFIGURE_MAP); public ParkingAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/ContourLinesAction.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/ContourLinesAction.java index 0d24860289c..412d2c10b9c 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/ContourLinesAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/ContourLinesAction.java @@ -27,7 +27,7 @@ public class ContourLinesAction extends QuickAction { "contourlines.showhide", ContourLinesAction.class) .nameActionRes(R.string.quick_action_show_hide_title) .nameRes(R.string.download_srtm_maps).iconRes(R.drawable.ic_plugin_srtm).nonEditable() - .category(QuickActionType.CONFIGURE_MAP); + .category(QuickActionType.TOPOGRAPHY); public ContourLinesAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainAction.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainAction.java index fb50a8cbe39..02f7454b096 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainAction.java @@ -22,7 +22,7 @@ public class TerrainAction extends QuickAction { public static final QuickActionType TYPE = new QuickActionType(TERRAIN_ACTION_ID, "terrain.showhide", TerrainAction.class).nameActionRes(R.string.quick_action_show_hide_title). nameRes(R.string.shared_string_terrain).iconRes(R.drawable.ic_action_hillshade_dark).nonEditable(). - category(QuickActionType.CONFIGURE_MAP); + category(QuickActionType.TOPOGRAPHY); public TerrainAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/OpenWeatherAction.java b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/OpenWeatherAction.java index 8a109e96dd3..ecb553778d0 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/OpenWeatherAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/OpenWeatherAction.java @@ -22,7 +22,7 @@ public class OpenWeatherAction extends QuickAction { "weather.forecast.open", OpenWeatherAction.class) .nameRes(R.string.open_weather_action) .iconRes(R.drawable.ic_action_umbrella).nonEditable() - .category(QuickActionType.OPEN); + .category(QuickActionType.WEATHER); public OpenWeatherAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideAirPressureLayerAction.java b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideAirPressureLayerAction.java index efef8bfb60b..cb3e134dafc 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideAirPressureLayerAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideAirPressureLayerAction.java @@ -14,7 +14,7 @@ public class ShowHideAirPressureLayerAction extends BaseWeatherQuickAction { .nameActionRes(R.string.quick_action_show_hide_title) .nameRes(R.string.pressure_layer) .iconRes(R.drawable.ic_action_air_pressure).nonEditable() - .category(QuickActionType.CONFIGURE_MAP); + .category(QuickActionType.WEATHER); public ShowHideAirPressureLayerAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideCloudLayerAction.java b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideCloudLayerAction.java index 7ce375277df..c8bff0f62a0 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideCloudLayerAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideCloudLayerAction.java @@ -14,7 +14,7 @@ public class ShowHideCloudLayerAction extends BaseWeatherQuickAction { .nameActionRes(R.string.quick_action_show_hide_title) .nameRes(R.string.cloud_layer) .iconRes(R.drawable.ic_action_clouds).nonEditable() - .category(QuickActionType.CONFIGURE_MAP); + .category(QuickActionType.WEATHER); public ShowHideCloudLayerAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHidePrecipitationLayerAction.java b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHidePrecipitationLayerAction.java index 3465aa52e7c..66c080722a8 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHidePrecipitationLayerAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHidePrecipitationLayerAction.java @@ -14,7 +14,7 @@ public class ShowHidePrecipitationLayerAction extends BaseWeatherQuickAction { .nameActionRes(R.string.quick_action_show_hide_title) .nameRes(R.string.precipitation_layer) .iconRes(R.drawable.ic_action_precipitation).nonEditable() - .category(QuickActionType.CONFIGURE_MAP); + .category(QuickActionType.WEATHER); public ShowHidePrecipitationLayerAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideTemperatureLayerAction.java b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideTemperatureLayerAction.java index e49915d00e3..6021692340d 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideTemperatureLayerAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideTemperatureLayerAction.java @@ -14,7 +14,7 @@ public class ShowHideTemperatureLayerAction extends BaseWeatherQuickAction { .nameActionRes(R.string.quick_action_show_hide_title) .nameRes(R.string.temperature_layer) .iconRes(R.drawable.ic_action_thermometer).nonEditable() - .category(QuickActionType.CONFIGURE_MAP); + .category(QuickActionType.WEATHER); public ShowHideTemperatureLayerAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideWindLayerAction.java b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideWindLayerAction.java index d2062c7e2a0..c2fbcfab3e0 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideWindLayerAction.java +++ b/OsmAnd/src/net/osmand/plus/plugins/weather/actions/ShowHideWindLayerAction.java @@ -14,7 +14,7 @@ public class ShowHideWindLayerAction extends BaseWeatherQuickAction { .nameActionRes(R.string.quick_action_show_hide_title) .nameRes(R.string.wind_layer) .iconRes(R.drawable.ic_action_wind).nonEditable() - .category(QuickActionType.CONFIGURE_MAP); + .category(QuickActionType.WEATHER); public ShowHideWindLayerAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/DayNightModeAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/DayNightModeAction.java index cfe5d11a2d0..058ed3db117 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/DayNightModeAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/DayNightModeAction.java @@ -22,7 +22,7 @@ public class DayNightModeAction extends QuickAction { public static final QuickActionType TYPE = new QuickActionType(DAY_NIGHT_MODE_ACTION_ID, "daynight.switch", DayNightModeAction.class). nameRes(R.string.quick_action_day_night_switch_mode).iconRes(R.drawable.ic_action_map_day).nonEditable(). - category(QuickActionType.NAVIGATION); + category(QuickActionType.MAP_APPEARANCE); public DayNightModeAction() {super(TYPE);} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java index d8de2c47a88..59a90e82178 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java @@ -37,7 +37,7 @@ public class FavoriteAction extends QuickAction { public static final QuickActionType TYPE = new QuickActionType(FAVORITE_ACTION_ID, "fav.add", FavoriteAction.class). nameRes(R.string.quick_action_add_favorite).iconRes(R.drawable.ic_action_favorite). - category(QuickActionType.CREATE_CATEGORY); + category(QuickActionType.FAVORITES); public static final String KEY_NAME = "name"; public static final String KEY_DIALOG = "dialog"; public static final String KEY_CATEGORY_NAME = "category_name"; diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/GPXAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/GPXAction.java index 554691d761e..f4de2eb9bef 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/GPXAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/GPXAction.java @@ -63,7 +63,7 @@ public class GPXAction extends QuickAction implements FileSelected { public static final QuickActionType TYPE = new QuickActionType(GPX_ACTION_ID, "gpx.add", GPXAction.class) .nameRes(R.string.quick_action_add_gpx) .iconRes(R.drawable.ic_action_gnew_label_dark) - .category(QuickActionType.CREATE_CATEGORY); + .category(QuickActionType.TRACKS); public static final String KEY_USE_SELECTED_GPX_FILE = "use_selected_gpx_file"; public static final String KEY_GPX_FILE_PATH = "gpx_file_path"; diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java index 75425c1dea4..8a3914ac33e 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java @@ -40,7 +40,7 @@ public class MapStyleAction extends SwitchableAction { public static final QuickActionType TYPE = new QuickActionType(MAP_STYLE_ACTION_ID, "mapstyle.change", MapStyleAction.class). nameRes(R.string.quick_action_map_style).iconRes(R.drawable.ic_map). - category(QuickActionType.CONFIGURE_MAP); + category(QuickActionType.MAP_APPEARANCE); public MapStyleAction() { diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MarkerAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MarkerAction.java index 52e6e63f11b..c5ca83c7147 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/MarkerAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MarkerAction.java @@ -21,7 +21,7 @@ public class MarkerAction extends QuickAction { public static final QuickActionType TYPE = new QuickActionType(MARKER_ACTION_ID, "marker.add", MarkerAction.class). nameRes(R.string.quick_action_add_marker).iconRes(R.drawable.ic_action_flag).nonEditable(). - category(QuickActionType.CREATE_CATEGORY); + category(QuickActionType.CONFIGURE_MAP); public MarkerAction() { diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/RouteAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/RouteAction.java index 528a10a34f4..858811af82b 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/RouteAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/RouteAction.java @@ -22,7 +22,7 @@ public class RouteAction extends QuickAction { .nameRes(R.string.plan_route_create_new_route) .iconRes(R.drawable.ic_action_plan_route) .nonEditable() - .category(QuickActionType.CREATE_CATEGORY); + .category(QuickActionType.NAVIGATION); public RouteAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHideFavoritesAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHideFavoritesAction.java index c864b0b0cee..b7975cc9931 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHideFavoritesAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHideFavoritesAction.java @@ -22,7 +22,7 @@ public class ShowHideFavoritesAction extends QuickAction { .nameActionRes(R.string.quick_action_show_hide_title) .nameRes(R.string.shared_string_favorites) .iconRes(R.drawable.ic_action_favorite).nonEditable() - .category(QuickActionType.CONFIGURE_MAP); + .category(QuickActionType.FAVORITES); public ShowHideFavoritesAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHideGpxTracksAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHideGpxTracksAction.java index 77f495d4bef..7570f03a97c 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHideGpxTracksAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHideGpxTracksAction.java @@ -22,7 +22,7 @@ public class ShowHideGpxTracksAction extends QuickAction { "gpx.showhide", ShowHideGpxTracksAction.class) .nameActionRes(R.string.quick_action_show_hide_title) .nameRes(R.string.show_gpx).iconRes(R.drawable.ic_action_polygom_dark).nonEditable() - .category(QuickActionType.CONFIGURE_MAP); + .category(QuickActionType.TRACKS); public ShowHideGpxTracksAction() { super(TYPE); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/SwitchProfileAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/SwitchProfileAction.java index ea79aac3747..34dec34776c 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/SwitchProfileAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/SwitchProfileAction.java @@ -39,7 +39,7 @@ public class SwitchProfileAction extends SwitchableAction { "profile.change", SwitchProfileAction.class) .nameRes(R.string.change_application_profile) .iconRes(R.drawable.ic_action_manage_profiles) - .category(QuickActionType.NAVIGATION); + .category(QuickActionType.SETTINGS); public SwitchProfileAction() { super(TYPE); From c251c315445e3e2a8fe85c5cf4d7e7bb49d49aa3 Mon Sep 17 00:00:00 2001 From: 0xRe1nk0 <0xre1nk0@gmail.com> Date: Mon, 20 May 2024 11:50:22 +0300 Subject: [PATCH 14/33] Fix searching by full action name --- .../quickaction/AddCategoryQuickAction.java | 11 +---------- .../quickaction/AddQuickActionFragment.java | 17 ++++------------- .../quickaction/AddQuickActionsAdapter.java | 8 ++++---- .../plus/quickaction/QuickActionType.java | 16 ++++++++++++++++ .../plus/quickaction/QuickActionViewHolder.java | 8 +------- 5 files changed, 26 insertions(+), 34 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/quickaction/AddCategoryQuickAction.java b/OsmAnd/src/net/osmand/plus/quickaction/AddCategoryQuickAction.java index 134b5fa0f08..e94a821ea30 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/AddCategoryQuickAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/AddCategoryQuickAction.java @@ -91,7 +91,7 @@ private void setupToolbar(@NonNull View view) { } private void setupContent(@NonNull View view) { - AddQuickActionsAdapter adapter = new AddQuickActionsAdapter(app, requireMapActivity(), this, nightMode); + AddQuickActionsAdapter adapter = new AddQuickActionsAdapter(app, requireActivity(), this, nightMode); adapter.setItems(getCategoryTypes()); RecyclerView recyclerView = view.findViewById(R.id.content_list); recyclerView.setLayoutManager(new LinearLayoutManager(app)); @@ -114,15 +114,6 @@ private void dismiss() { } } - @NonNull - public MapActivity requireMapActivity() { - FragmentActivity activity = getActivity(); - if (!(activity instanceof MapActivity)) { - throw new IllegalStateException("Fragment " + this + " not attached to an activity."); - } - return (MapActivity) activity; - } - public static void showInstance(@NonNull FragmentManager manager, @NonNull QuickActionButtonState buttonState, int quickActionCategoryId) { if (AndroidUtils.isFragmentCanBeAdded(manager, TAG)) { Bundle bundle = new Bundle(); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionFragment.java b/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionFragment.java index b1215041109..014a8d9b27c 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionFragment.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionFragment.java @@ -75,7 +75,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { searchMode = savedInstanceState.getBoolean(QUICK_ACTION_SEARCH_MODE_KEY, false); } - requireMapActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { + requireActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { onBackPressed(); @@ -149,7 +149,7 @@ private void updateToolbar() { AndroidUiHelper.setVisibility(searchMode ? View.VISIBLE : View.GONE, searchEditText); if (searchMode) { searchEditText.requestFocus(); - AndroidUtils.showSoftKeyboard(requireMapActivity(), searchEditText); + AndroidUtils.showSoftKeyboard(requireActivity(), searchEditText); } else { AndroidUtils.hideSoftKeyboard(requireActivity(), searchEditText); AndroidUiHelper.updateVisibility(clearSearchQuery, false); @@ -157,7 +157,7 @@ private void updateToolbar() { } private void setupContent(@NonNull View view, @Nullable Bundle savedInstanceState) { - adapter = new AddQuickActionsAdapter(app, requireMapActivity(), this, nightMode); + adapter = new AddQuickActionsAdapter(app, requireActivity(), this, nightMode); adapter.setMap(getAdapterItems()); RecyclerView recyclerView = view.findViewById(R.id.content_list); recyclerView.setLayoutManager(new LinearLayoutManager(app)); @@ -188,21 +188,12 @@ private void onBackPressed() { } private void dismiss() { - FragmentManager fragmentManager = requireMapActivity().getSupportFragmentManager(); + FragmentManager fragmentManager = requireActivity().getSupportFragmentManager(); if (!fragmentManager.isStateSaved()) { fragmentManager.popBackStackImmediate(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE); } } - @NonNull - public MapActivity requireMapActivity() { - FragmentActivity activity = getActivity(); - if (!(activity instanceof MapActivity)) { - throw new IllegalStateException("Fragment " + this + " not attached to an activity."); - } - return (MapActivity) activity; - } - @Override public void onSaveInstanceState(@NonNull Bundle outState) { outState.putString(QUICK_ACTION_SEARCH_KEY, adapter.getSearchQuery()); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionsAdapter.java b/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionsAdapter.java index aa6decb9a77..669445e2e20 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/AddQuickActionsAdapter.java @@ -46,7 +46,7 @@ public void setMap(@NonNull Map> quickAct public void setItems(@NonNull List items) { this.items.clear(); this.items.addAll(items); - this.items.sort((o1, o2) -> app.getMapButtonsHelper().compareNames(app.getString(o1.getNameRes()), app.getString(o2.getNameRes()))); + this.items.sort((o1, o2) -> app.getMapButtonsHelper().compareNames(o1.getFullName(app), o2.getFullName(app))); } private void setItemsFromMap() { @@ -57,17 +57,17 @@ private void setItemsFromMap() { items.addAll(typeActions); } else { for (QuickActionType action : typeActions) { - if (app.getString(action.getNameRes()).toLowerCase().contains(filterQuery.toLowerCase())) { + if (action.getFullName(app).toLowerCase().contains(filterQuery.toLowerCase())) { items.add(action); } } } } - items.sort((o1, o2) -> app.getMapButtonsHelper().compareNames(app.getString(o1.getNameRes()), app.getString(o2.getNameRes()))); + items.sort((o1, o2) -> app.getMapButtonsHelper().compareNames(o1.getFullName(app), o2.getFullName(app))); } else { quickActionsMap.keySet() .stream() - .sorted((o1, o2) -> app.getMapButtonsHelper().compareNames(app.getString(o1.getNameRes()), app.getString(o2.getNameRes()))) + .sorted((o1, o2) -> app.getMapButtonsHelper().compareNames(o1.getFullName(app), o2.getFullName(app))) .forEach(items::add); } } diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionType.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionType.java index 694ed1b0a6b..092d11c5ba0 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionType.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionType.java @@ -4,6 +4,9 @@ import androidx.annotation.NonNull; import androidx.annotation.StringRes; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; + import java.lang.reflect.InvocationTargetException; public class QuickActionType { @@ -125,4 +128,17 @@ public int getIconRes() { public int getCategory() { return category; } + + @NonNull + public String getFullName(@NonNull OsmandApplication app) { + String quickActionTypeName; + if (getActionNameRes() != 0) { + String name = app.getString(getNameRes()); + String actionName = app.getString(getActionNameRes()); + quickActionTypeName = app.getString(R.string.ltr_or_rtl_combine_via_dash, actionName, name); + } else { + quickActionTypeName = app.getString(getNameRes()); + } + return quickActionTypeName; + } } diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionViewHolder.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionViewHolder.java index a938347bb33..42d992eca86 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionViewHolder.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionViewHolder.java @@ -44,13 +44,7 @@ public QuickActionViewHolder(@NonNull View itemView, boolean nightMode) { } public void bindView(@NonNull QuickActionType type, int itemsCount, boolean lastItem) { - if (type.getActionNameRes() != 0) { - String name = app.getString(type.getNameRes()); - String actionName = app.getString(type.getActionNameRes()); - title.setText(app.getString(R.string.ltr_or_rtl_combine_via_dash, actionName, name)); - } else { - title.setText(type.getNameRes()); - } + title.setText(type.getFullName(app)); ApplicationMode appMode = settings.getApplicationMode(); int iconRes = type.getIconRes(); From 13fb75e972d7f2cb832c8eefa30497b26119a57c Mon Sep 17 00:00:00 2001 From: dmpr0 Date: Mon, 20 May 2024 12:11:39 +0300 Subject: [PATCH 15/33] Icons for new quick actions --- .../drawable/ic_action_magnifier_minus.xml | 13 ++++++++++ .../res/drawable/ic_action_map_move_down.xml | 14 +++++++++++ .../res/drawable/ic_action_map_move_left.xml | 14 +++++++++++ .../res/drawable/ic_action_map_move_right.xml | 14 +++++++++++ OsmAnd/res/drawable/ic_action_map_move_up.xml | 14 +++++++++++ .../res/drawable/ic_action_profile_next.xml | 24 +++++++++++++++++++ .../drawable/ic_action_profile_previous.xml | 24 +++++++++++++++++++ 7 files changed, 117 insertions(+) create mode 100644 OsmAnd/res/drawable/ic_action_magnifier_minus.xml create mode 100644 OsmAnd/res/drawable/ic_action_map_move_down.xml create mode 100644 OsmAnd/res/drawable/ic_action_map_move_left.xml create mode 100644 OsmAnd/res/drawable/ic_action_map_move_right.xml create mode 100644 OsmAnd/res/drawable/ic_action_map_move_up.xml create mode 100644 OsmAnd/res/drawable/ic_action_profile_next.xml create mode 100644 OsmAnd/res/drawable/ic_action_profile_previous.xml diff --git a/OsmAnd/res/drawable/ic_action_magnifier_minus.xml b/OsmAnd/res/drawable/ic_action_magnifier_minus.xml new file mode 100644 index 00000000000..5294e3afb52 --- /dev/null +++ b/OsmAnd/res/drawable/ic_action_magnifier_minus.xml @@ -0,0 +1,13 @@ + + + + diff --git a/OsmAnd/res/drawable/ic_action_map_move_down.xml b/OsmAnd/res/drawable/ic_action_map_move_down.xml new file mode 100644 index 00000000000..304c01943f2 --- /dev/null +++ b/OsmAnd/res/drawable/ic_action_map_move_down.xml @@ -0,0 +1,14 @@ + + + + diff --git a/OsmAnd/res/drawable/ic_action_map_move_left.xml b/OsmAnd/res/drawable/ic_action_map_move_left.xml new file mode 100644 index 00000000000..c029d427578 --- /dev/null +++ b/OsmAnd/res/drawable/ic_action_map_move_left.xml @@ -0,0 +1,14 @@ + + + + diff --git a/OsmAnd/res/drawable/ic_action_map_move_right.xml b/OsmAnd/res/drawable/ic_action_map_move_right.xml new file mode 100644 index 00000000000..dcdab19aad7 --- /dev/null +++ b/OsmAnd/res/drawable/ic_action_map_move_right.xml @@ -0,0 +1,14 @@ + + + + diff --git a/OsmAnd/res/drawable/ic_action_map_move_up.xml b/OsmAnd/res/drawable/ic_action_map_move_up.xml new file mode 100644 index 00000000000..083047e04ee --- /dev/null +++ b/OsmAnd/res/drawable/ic_action_map_move_up.xml @@ -0,0 +1,14 @@ + + + + diff --git a/OsmAnd/res/drawable/ic_action_profile_next.xml b/OsmAnd/res/drawable/ic_action_profile_next.xml new file mode 100644 index 00000000000..e5dad621bcc --- /dev/null +++ b/OsmAnd/res/drawable/ic_action_profile_next.xml @@ -0,0 +1,24 @@ + + + + + + + diff --git a/OsmAnd/res/drawable/ic_action_profile_previous.xml b/OsmAnd/res/drawable/ic_action_profile_previous.xml new file mode 100644 index 00000000000..80eec2d9f3e --- /dev/null +++ b/OsmAnd/res/drawable/ic_action_profile_previous.xml @@ -0,0 +1,24 @@ + + + + + + + From fdb54b21db61678611ea021c4ea6bf34721327e0 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 20 May 2024 15:53:53 +0300 Subject: [PATCH 16/33] Prepare for altitude image provider --- OsmAnd/res/values/strings.xml | 1 + .../development/OsmandDevelopmentPlugin.java | 2 +- .../osmand/plus/plugins/srtm/SRTMPlugin.java | 3 - .../plus/plugins/srtm/TerrainFragment.java | 8 ++- .../plus/plugins/srtm/TerrainLayer.java | 46 +++++++-------- .../osmand/plus/plugins/srtm/TerrainMode.java | 57 +++++++++++-------- 6 files changed, 63 insertions(+), 54 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index e9ae08bad2e..b1feb588f51 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -13,6 +13,7 @@ Disable map layers Disable all map layers above the vector map (restart required). + Altitude color maps are used to visualize relief. SPM Allow display on top Allow displaying map texts on top of each other diff --git a/OsmAnd/src/net/osmand/plus/plugins/development/OsmandDevelopmentPlugin.java b/OsmAnd/src/net/osmand/plus/plugins/development/OsmandDevelopmentPlugin.java index 75617847fe8..707239cdf68 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/development/OsmandDevelopmentPlugin.java +++ b/OsmAnd/src/net/osmand/plus/plugins/development/OsmandDevelopmentPlugin.java @@ -98,7 +98,7 @@ public OsmandDevelopmentPlugin(@NonNull OsmandApplication app) { useRasterSQLiteDbListener = change -> { SRTMPlugin plugin = getSrtmPlugin(); - if (plugin != null && plugin.isTerrainLayerEnabled() && (plugin.isHillshadeMode() || plugin.isSlopeMode())) { + if (plugin != null && plugin.isTerrainLayerEnabled()) { plugin.updateLayers(app, null); } }; diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/SRTMPlugin.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/SRTMPlugin.java index 5d56f526697..20a0acb88e3 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/SRTMPlugin.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/SRTMPlugin.java @@ -250,9 +250,6 @@ public void setTerrainLayerEnabled(boolean enabled) { TERRAIN.set(enabled); } - public boolean isSlopeMode() { - return getTerrainMode().isColor(); - } public boolean isHillshadeMode() { return getTerrainMode().isHillshade(); diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainFragment.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainFragment.java index 4d0f56f5e72..c0d6fdae7b1 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainFragment.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainFragment.java @@ -153,7 +153,7 @@ private void updateColorSchemeCard(TerrainMode mode) { String zoomLevels = minZoom + " - " + maxZoom; zoomLevelsTv.setText(zoomLevels); coloSchemeTv.setText(mode.getDescription()); - AndroidUiHelper.updateVisibility(legend, mode.isColor()); + AndroidUiHelper.updateVisibility(legend, mode.getType() == TerrainMode.TerrainType.SLOPE); } private void setupColorSchemeCard(@NonNull View root) { @@ -233,10 +233,10 @@ private void updateUiMode() { iconIv.setImageDrawable(uiUtilities.getPaintedIcon(R.drawable.ic_action_hillshade_dark, profileColor)); stateTv.setText(R.string.shared_string_enabled); - if (mode.isHillshade()) { + if (mode.getType() == TerrainMode.TerrainType.HILLSHADE) { descriptionTv.setText(R.string.hillshade_description); downloadDescriptionTv.setText(R.string.hillshade_download_description); - } else if (mode.isColor()) { + } else if (mode.getType() == TerrainMode.TerrainType.SLOPE) { descriptionTv.setText(R.string.slope_legend_description); String wikiString = getString(R.string.shared_string_wikipedia); String readMoreText = String.format( @@ -246,6 +246,8 @@ private void updateUiMode() { String wikiSlopeUrl = getString(R.string.url_wikipedia_slope); setupClickableText(descriptionTv, readMoreText, wikiString, wikiSlopeUrl, false); downloadDescriptionTv.setText(R.string.slope_download_description); + } else if (mode.getType() == TerrainMode.TerrainType.HEIGHT) { + descriptionTv.setText(R.string.height_legend_description); } downloadMapsCard.updateDownloadSection(getMapActivity()); } else { diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java index ef2be5c3087..3509a39cbd7 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java @@ -94,11 +94,8 @@ protected boolean setLayerProvider(@Nullable ITileSource map) { ? mapRendererContext.getGeoTiffCollection() : null; - if (mode.isColor() && terrainFromHeightmap && geoTiffCollection != null) { - layerProvider = createSlopeLayerProvider(mode, geoTiffCollection); - mapRenderer.setMapLayerProvider(layerIndex, layerProvider); - } else if (mode.isHillshade() && terrainFromHeightmap && geoTiffCollection != null) { - layerProvider = createHillshadeLayerProvider(mode, geoTiffCollection); + if (terrainFromHeightmap && geoTiffCollection != null) { + layerProvider = createGeoTiffLayerProvider(mode, geoTiffCollection); mapRenderer.setMapLayerProvider(layerIndex, layerProvider); } else { TileSourceProxyProvider prov = new TerrainTilesProvider(getApplication(), map, srtmPlugin); @@ -111,30 +108,33 @@ protected boolean setLayerProvider(@Nullable ITileSource map) { } @NonNull - private SlopeRasterMapLayerProvider createSlopeLayerProvider(TerrainMode mode, @NonNull GeoTiffCollection geoTiffCollection) { + private IRasterMapLayerProvider createGeoTiffLayerProvider(TerrainMode mode, @NonNull GeoTiffCollection geoTiffCollection) { OsmandApplication app = getApplication(); - String slopeColorFilename = app.getAppPath(HEIGHTMAP_INDEX_DIR + mode.getMainFile()).getAbsolutePath(); - SlopeRasterMapLayerProvider provider = new SlopeRasterMapLayerProvider(geoTiffCollection, slopeColorFilename); + File heightmapDir = app.getAppPath(HEIGHTMAP_INDEX_DIR); + String mainColorFilename = new File(heightmapDir, mode.getMainFile()).getAbsolutePath(); + IRasterMapLayerProvider provider; + if (mode.getType() == TerrainMode.TerrainType.HILLSHADE) { + String slopeSecondaryColorFilename = new File(heightmapDir, mode.getSecondFile()).getAbsolutePath(); + provider = + new HillshadeRasterMapLayerProvider(geoTiffCollection, mainColorFilename, slopeSecondaryColorFilename); + ((HillshadeRasterMapLayerProvider) provider).setMinVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMinZoom())); + ((HillshadeRasterMapLayerProvider) provider).setMaxVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMaxZoom())); + } else if (mode.getType() == TerrainMode.TerrainType.SLOPE) { + provider = new SlopeRasterMapLayerProvider(geoTiffCollection, mainColorFilename); + ((SlopeRasterMapLayerProvider) provider).setMinVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMinZoom())); + ((SlopeRasterMapLayerProvider) provider).setMaxVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMaxZoom())); + } else { + // TODO new height provider + provider = new SlopeRasterMapLayerProvider(geoTiffCollection, mainColorFilename); + ((SlopeRasterMapLayerProvider) provider).setMinVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMinZoom())); + ((SlopeRasterMapLayerProvider) provider).setMaxVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMaxZoom())); + } // provider.setKey(mode.getKey()); // opengl binding (cache should be key +'.cache') - provider.setMinVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMinZoom())); - provider.setMaxVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMaxZoom())); - return provider; - } - @NonNull - private HillshadeRasterMapLayerProvider createHillshadeLayerProvider(TerrainMode mode, @NonNull GeoTiffCollection geoTiffCollection) { - OsmandApplication app = getApplication(); - File heightmapDir = app.getAppPath(HEIGHTMAP_INDEX_DIR); - String hillshadeColorFilename = new File(heightmapDir, mode.getMainFile()).getAbsolutePath(); - String slopeSecondaryColorFilename = new File(heightmapDir, mode.getSecondFile()).getAbsolutePath(); - HillshadeRasterMapLayerProvider provider = - new HillshadeRasterMapLayerProvider(geoTiffCollection, hillshadeColorFilename, slopeSecondaryColorFilename); - // provider.setKey(mode.getKey()); // opengl binding (cache should be key +'.cache') - provider.setMinVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMinZoom())); - provider.setMaxVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMaxZoom())); return provider; } + @Override public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings drawSettings) { int zoom = tileBox.getZoom(); diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java index 39ea59fdbaa..25d8200bed3 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java @@ -21,33 +21,30 @@ public class TerrainMode { public static final String HILLSHADE_PREFIX = "hs_main_"; public static final String HILLSHADE_SCND_PREFIX = "hs_scnd_"; public static final String COLOR_SLOPE_PREFIX = "clr_"; + + public static final String HEIGHT_PREFIX = "height_"; public static final String EXT = ".txt"; -// public static final String SLOPE_MAIN_COLOR_FILENAME = "clr_slope.txt"; -// public static final String HILLSHADE_MAIN_COLOR_FILENAME = "hs_main_hillshade.txt"; -// public static final String SLOPE_SECONDARY_COLOR_FILENAME = "hs_scnd_hillshade.txt"; private static TerrainMode[] terrainModes; + public enum TerrainType { + HILLSHADE, SLOPE, HEIGHT + } + String translateName; private final CommonPreference MIN_ZOOM; private final CommonPreference MAX_ZOOM; private final CommonPreference TRANSPARENCY; - private final boolean hilshade; + private final TerrainType type; private final String key; - // hillshade, slope -// HILLSHADE_MIN_ZOOM = registerIntPreference("hillshade_min_zoom", 3).makeProfile(); -// HILLSHADE_MAX_ZOOM = registerIntPreference("hillshade_max_zoom", 17).makeProfile(); -// HILLSHADE_TRANSPARENCY = registerIntPreference("hillshade_transparency", 100).makeProfile(); -// SLOPE_MIN_ZOOM = registerIntPreference("slope_min_zoom", 3).makeProfile(); -// SLOPE_MAX_ZOOM = registerIntPreference("slope_max_zoom", 17).makeProfile(); -// SLOPE_TRANSPARENCY = registerIntPreference("slope_transparency", 80).makeProfile(); - public TerrainMode(OsmandApplication app, String key, String translateName, boolean hillshade) { - this.hilshade = hillshade; + + public TerrainMode(OsmandApplication app, String key, String translateName, TerrainType type) { + this.type = type; this.key = key; this.translateName = translateName; MIN_ZOOM = app.getSettings().registerIntPreference(key+"_min_zoom", 3).makeProfile(); MAX_ZOOM = app.getSettings().registerIntPreference(key+"_max_zoom", 17).makeProfile(); TRANSPARENCY = app.getSettings().registerIntPreference(key+"_transparency", - hillshade ? 100 : 80).makeProfile(); + type == TerrainType.HILLSHADE ? 100 : 80).makeProfile(); } @@ -56,9 +53,9 @@ public static TerrainMode[] values(OsmandApplication app) { return terrainModes; } TerrainMode hillshade = - new TerrainMode(app, HILLSHADE_KEY, app.getString(R.string.shared_string_hillshade), true); + new TerrainMode(app, HILLSHADE_KEY, app.getString(R.string.shared_string_hillshade), TerrainType.HILLSHADE); TerrainMode slope = - new TerrainMode(app, SLOPE_KEY, app.getString(R.string.shared_string_slope), false); + new TerrainMode(app, SLOPE_KEY, app.getString(R.string.shared_string_slope), TerrainType.SLOPE); List tms = new ArrayList<>(); // HILLSHADE first tms.add(hillshade); @@ -74,14 +71,20 @@ public static TerrainMode[] values(OsmandApplication app) { String key = nm.substring(HILLSHADE_PREFIX.length()); key = key.substring(0, key.length() - EXT.length()); if (!HILLSHADE_KEY.equals(key)) { - tms.add(new TerrainMode(app, key, Algorithms.capitalizeFirstLetter(key), true)); + tms.add(new TerrainMode(app, key, Algorithms.capitalizeFirstLetter(key), TerrainType.HILLSHADE)); } } else if (nm.startsWith(COLOR_SLOPE_PREFIX)) { String key = nm.substring(COLOR_SLOPE_PREFIX.length()); key = key.substring(0, key.length() - EXT.length()); if (!SLOPE_KEY.equals(key)) { - tms.add(new TerrainMode(app, key, Algorithms.capitalizeFirstLetter(key), false)); + tms.add(new TerrainMode(app, key, Algorithms.capitalizeFirstLetter(key), TerrainType.SLOPE)); } + } else if (nm.startsWith(HEIGHT_PREFIX)) { + String key = nm.substring(HEIGHT_PREFIX.length()); + key = key.substring(0, key.length() - EXT.length()); +// if (!SLOPE_KEY.equals(key)) { + tms.add(new TerrainMode(app, key, Algorithms.capitalizeFirstLetter(key), TerrainType.HEIGHT)); +// } } } } @@ -94,7 +97,7 @@ public static TerrainMode getByKey(String key) { for (TerrainMode m : terrainModes) { if (Algorithms.stringsEqual(m.getKey(), key)) { return m; - } else if (m.hilshade && hillshade == null) { + } else if (m.type == TerrainType.HILLSHADE && hillshade == null) { hillshade = m; } } @@ -102,19 +105,25 @@ public static TerrainMode getByKey(String key) { } public boolean isHillshade() { - return hilshade; + return type == TerrainType.HILLSHADE; } - public boolean isColor() { - return !hilshade; + public TerrainType getType() { + return type; } public String getMainFile() { - return (hilshade ? HILLSHADE_PREFIX : COLOR_SLOPE_PREFIX) + key + EXT; + String prefix = HILLSHADE_PREFIX; + if(type == TerrainType.HEIGHT) { + prefix = HEIGHT_PREFIX; + } else if(type == TerrainType.SLOPE) { + prefix = COLOR_SLOPE_PREFIX; + } + return prefix + key + EXT; } public String getSecondFile() { - return (hilshade ? HILLSHADE_SCND_PREFIX : "") + key + EXT; + return (isHillshade() ? HILLSHADE_SCND_PREFIX : "") + key + EXT; } public String getKey() { From 4b0412452cb7c56e3809bbfec88d28dd8d528e3c Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 20 May 2024 16:37:21 +0300 Subject: [PATCH 17/33] Rename constants for color palettes --- .../main/java/net/osmand/IndexConstants.java | 3 +-- OsmAnd/assets/bundled_assets.xml | 19 ++++++++++--------- OsmAnd/build-common.gradle | 15 ++++----------- .../osmand/plus/plugins/srtm/TerrainMode.java | 8 ++++---- .../plus/plugins/weather/WeatherBand.java | 10 +++++----- 5 files changed, 24 insertions(+), 31 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java index f0370304683..6ea79be7017 100644 --- a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java +++ b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java @@ -102,10 +102,9 @@ public class IndexConstants { public static final String TEMP_DIR = "temp/"; public static final String ROUTING_PROFILES_DIR = "routing/"; public static final String PLUGINS_DIR = "plugins/"; - public static final String HEIGHTMAP_INDEX_DIR = "heightmap/"; public static final String GEOTIFF_SQLITE_CACHE_DIR = "geotiff_sqlite_cache/"; public static final String GEOTIFF_DIR = "geotiff/"; - public static final String WEATHER_INDEX_DIR = "weather/"; + public static final String CLR_PALETTE_DIR = "color-palette/"; public static final String WEATHER_FORECAST_DIR = "weather_forecast/"; public static final String MODEL_3D_DIR = "models/"; diff --git a/OsmAnd/assets/bundled_assets.xml b/OsmAnd/assets/bundled_assets.xml index 6c31d0d6e97..16d72f538d3 100644 --- a/OsmAnd/assets/bundled_assets.xml +++ b/OsmAnd/assets/bundled_assets.xml @@ -119,14 +119,15 @@ - - - - - - - - - + + + + + + + + + + diff --git a/OsmAnd/build-common.gradle b/OsmAnd/build-common.gradle index 5bb1f8d7afc..fa0cbbf5407 100644 --- a/OsmAnd/build-common.gradle +++ b/OsmAnd/build-common.gradle @@ -192,15 +192,9 @@ task copyProjDb(type: Copy) { into "assets" } -task copyWeatherFiles(type: Copy) { - from "../../resources/weather" - into "assets/weather" - include "*.*" -} - -task copyHeightmapFiles(type: Copy) { - from "../../resources/heightmap" - into "assets/heightmap" +task copyColorPalettes(type: Copy) { + from "../../resources/color-palette" + into "assets/color-palette" include "*.*" } @@ -265,8 +259,7 @@ task collectExternalResources { copyLargePOIIcons, validateTranslate, copyProjDb, - copyWeatherFiles, - copyHeightmapFiles, + copyColorPalettes, copyPoiCategories, downloadWorldMiniBasemap, downloadDefaultWikivoyage, diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java index 25d8200bed3..191c9801d90 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java @@ -18,9 +18,9 @@ public class TerrainMode { private static final String HILLSHADE_KEY = "hillshade"; private static final String SLOPE_KEY = "slope"; - public static final String HILLSHADE_PREFIX = "hs_main_"; - public static final String HILLSHADE_SCND_PREFIX = "hs_scnd_"; - public static final String COLOR_SLOPE_PREFIX = "clr_"; + public static final String HILLSHADE_PREFIX = "hillshade_main_"; + public static final String HILLSHADE_SCND_PREFIX = "hillshade_color_"; + public static final String COLOR_SLOPE_PREFIX = "slope_"; public static final String HEIGHT_PREFIX = "height_"; public static final String EXT = ".txt"; @@ -60,7 +60,7 @@ public static TerrainMode[] values(OsmandApplication app) { // HILLSHADE first tms.add(hillshade); tms.add(slope); - File dir = app.getAppPath(IndexConstants.HEIGHTMAP_INDEX_DIR); + File dir = app.getAppPath(IndexConstants.CLR_PALETTE_DIR); if (dir.exists() && dir.listFiles() != null) { for (File lf : dir.listFiles()) { if(lf == null || !lf.getName().endsWith(EXT) ) { diff --git a/OsmAnd/src/net/osmand/plus/plugins/weather/WeatherBand.java b/OsmAnd/src/net/osmand/plus/plugins/weather/WeatherBand.java index 4d42f813337..6bc59db2a17 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/weather/WeatherBand.java +++ b/OsmAnd/src/net/osmand/plus/plugins/weather/WeatherBand.java @@ -462,15 +462,15 @@ public CommonPreference getAlphaPreference() { public String getColorFilePath() { switch (bandIndex) { case WEATHER_BAND_CLOUD: - return WEATHER_INDEX_DIR + "cloud_color.txt"; + return CLR_PALETTE_DIR + "weather_cloud.txt"; case WEATHER_BAND_TEMPERATURE: - return WEATHER_INDEX_DIR + "temperature_color.txt"; + return CLR_PALETTE_DIR + "weather_temperature.txt"; case WEATHER_BAND_PRESSURE: - return WEATHER_INDEX_DIR + "pressure_color.txt"; + return CLR_PALETTE_DIR + "weather_pressure.txt"; case WEATHER_BAND_WIND_SPEED: - return WEATHER_INDEX_DIR + "wind_color.txt"; + return CLR_PALETTE_DIR + "weather_wind.txt"; case WEATHER_BAND_PRECIPITATION: - return WEATHER_INDEX_DIR + "precip_color.txt"; + return CLR_PALETTE_DIR + "weather_precip.txt"; case WEATHER_BAND_UNDEFINED: return null; } From 8e73ec8b3e770405953b6617c1a27c1496f08417 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 20 May 2024 16:44:18 +0300 Subject: [PATCH 18/33] Rename constants for color palettes --- .../main/java/net/osmand/IndexConstants.java | 1 - .../plus/download/DownloadActivityType.java | 18 +----------------- .../plus/download/DownloadResources.java | 2 -- .../plus/download/local/LocalIndexHelper.java | 3 +-- .../plus/download/local/LocalItemUtils.java | 2 +- .../download/local/LocalOperationTask.java | 4 +--- .../controllers/MapDataMenuController.java | 4 +--- .../plus/plugins/weather/WeatherBand.java | 12 ++++++------ 8 files changed, 11 insertions(+), 35 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java index 6ea79be7017..671266143b4 100644 --- a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java +++ b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java @@ -37,7 +37,6 @@ public class IndexConstants { public static final String OSM_GZ_EXT = ".osm.gz"; public static final String HTML_EXT = ".html"; public static final String GEN_LOG_EXT = ".gen.log"; - public static final String HEIGHTMAP_SQLITE_EXT = ".sqlite"; public static final String DOWNLOAD_EXT = ".download"; public static final String TIF_EXT = ".tif"; public static final String TIFF_DB_EXT = ".tiff.db"; diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java b/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java index da60b53482a..9db2e950e8f 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java @@ -71,8 +71,6 @@ public class DownloadActivityType { new DownloadActivityType(R.string.shared_string_gpx_tracks, R.drawable.ic_action_polygom_dark, "gpx", 75); public static final DownloadActivityType SQLITE_FILE = new DownloadActivityType(R.string.shared_string_online_maps, "sqlite", 80); - public static final DownloadActivityType HEIGHTMAP_FILE_LEGACY = - new DownloadActivityType(R.string.download_heightmap_maps, R.drawable.ic_action_altitude, "heightmap", 85); public static final DownloadActivityType WEATHER_FORECAST = new DownloadActivityType(R.string.weather_forecast, R.drawable.ic_action_umbrella, "weather", 90); public static final DownloadActivityType GEOTIFF_FILE = @@ -167,8 +165,6 @@ public boolean isAccepted(String fileName) { return fileName.endsWith(IndexConstants.SQLITE_EXT); } else if (SLOPE_FILE == this) { return fileName.endsWith(IndexConstants.SQLITE_EXT); - } else if (HEIGHTMAP_FILE_LEGACY == this) { - return fileName.endsWith(IndexConstants.HEIGHTMAP_SQLITE_EXT); } else if (GEOTIFF_FILE == this) { return fileName.endsWith(IndexConstants.TIF_EXT); } else if (DEPTH_CONTOUR_FILE == this) { @@ -218,8 +214,6 @@ public File getDefaultDownloadFolder(OsmandApplication app, IndexItem indexItem) return app.getAppPath(IndexConstants.TILES_INDEX_DIR); } else if (SLOPE_FILE == this) { return app.getAppPath(IndexConstants.TILES_INDEX_DIR); - } else if (HEIGHTMAP_FILE_LEGACY == this) { - return app.getAppPath(IndexConstants.HEIGHTMAP_INDEX_DIR); } else if (GEOTIFF_FILE == this) { return app.getAppPath(IndexConstants.GEOTIFF_DIR); } else if (DEPTH_CONTOUR_FILE == this) { @@ -239,7 +233,6 @@ public File getDefaultDownloadFolder(OsmandApplication app, IndexItem indexItem) public boolean isZipStream() { return HILLSHADE_FILE != this && SLOPE_FILE != this - && HEIGHTMAP_FILE_LEGACY != this && GEOTIFF_FILE != this && SQLITE_FILE != this && WIKIVOYAGE_FILE != this @@ -289,8 +282,6 @@ public String getUnzipExtension(OsmandApplication ctx, IndexItem indexItem) { return IndexConstants.SQLITE_EXT; } else if (SQLITE_FILE == this) { return IndexConstants.SQLITE_EXT; - } else if (HEIGHTMAP_FILE_LEGACY == this) { - return IndexConstants.HEIGHTMAP_SQLITE_EXT; } else if (GEOTIFF_FILE == this) { return IndexConstants.TIF_EXT; } else if (DEPTH_CONTOUR_FILE == this) { @@ -328,7 +319,7 @@ public String getUrlSuffix(OsmandApplication ctx) { return "&inapp=depth"; } else if (this == GPX_FILE) { return "&gpx=yes"; - } else if (this == HEIGHTMAP_FILE_LEGACY || this == GEOTIFF_FILE) { + } else if (this == GEOTIFF_FILE) { return "&heightmap=yes"; } else if (this == DEPTH_MAP_FILE) { return "&depth=yes"; @@ -486,8 +477,6 @@ public String getTargetFileName(IndexItem item) { return fileName.replace('_', ' '); } else if (this == SLOPE_FILE) { return fileName.replace('_', ' '); - } else if (this == HEIGHTMAP_FILE_LEGACY) { - return fileName.replace('_', ' ').replace(".heightmap", ""); } else if (this == GEOTIFF_FILE) { return fileName.replace('_', ' '); } else if (this == SQLITE_FILE) { @@ -553,11 +542,6 @@ public String getBasename(@NonNull DownloadItem downloadItem) { return fileName.substring(0, fileName.length() - IndexConstants.SQLITE_EXT.length()) .replace(FileNameTranslationHelper.SLOPE + "_", ""); } - if (this == HEIGHTMAP_FILE_LEGACY) { - String heightmapSuffix = ".heightmap" + IndexConstants.HEIGHTMAP_SQLITE_EXT; - return fileName.substring(0, fileName.length() - heightmapSuffix.length()) - .replace(FileNameTranslationHelper.HEIGHTMAP + "_", ""); - } if (this == GEOTIFF_FILE) { return fileName.substring(0, fileName.length() - IndexConstants.TIF_EXT.length()) .replace(FileNameTranslationHelper.HEIGHTMAP + "_", ""); diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadResources.java b/OsmAnd/src/net/osmand/plus/download/DownloadResources.java index 4bc2ba30595..e62a177af2d 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadResources.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadResources.java @@ -184,8 +184,6 @@ private void initAlreadyLoadedFiles() { IndexConstants.BINARY_WIKIVOYAGE_MAP_INDEX_EXT, indexFileNames); listWithAlternatives(dateFormat, app.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR), IndexConstants.BINARY_TRAVEL_GUIDE_MAP_INDEX_EXT, indexFileNames); - listWithAlternatives(dateFormat, app.getAppPath(IndexConstants.HEIGHTMAP_INDEX_DIR), - IndexConstants.HEIGHTMAP_SQLITE_EXT, indexFileNames); listWithAlternatives(dateFormat, app.getAppPath(IndexConstants.GEOTIFF_DIR), IndexConstants.TIF_EXT, indexFileNames); diff --git a/OsmAnd/src/net/osmand/plus/download/local/LocalIndexHelper.java b/OsmAnd/src/net/osmand/plus/download/local/LocalIndexHelper.java index 372ac3a526d..5a5b365f808 100644 --- a/OsmAnd/src/net/osmand/plus/download/local/LocalIndexHelper.java +++ b/OsmAnd/src/net/osmand/plus/download/local/LocalIndexHelper.java @@ -216,7 +216,6 @@ public List getLocalIndexItems(boolean readFiles, boolean shouldUpdat break; case TILES_DATA: loadTilesData(app.getAppPath(TILES_INDEX_DIR), items, shouldUpdate, task); - loadTilesData(app.getAppPath(HEIGHTMAP_INDEX_DIR), items, shouldUpdate, task); break; case TTS_VOICE_DATA: case VOICE_DATA: @@ -315,7 +314,7 @@ private void loadTilesData(@NonNull File dir, @NonNull List items, for (File file : listFilesSorted(dir)) { if (file.isFile()) { String fileName = file.getName(); - boolean tilesData = CollectionUtils.endsWithAny(fileName, SQLiteTileSource.EXT, HEIGHTMAP_SQLITE_EXT); + boolean tilesData = CollectionUtils.endsWithAny(fileName, SQLiteTileSource.EXT); if (tilesData) { loadLocalData(file, TILES_DATA, items, shouldUpdate, task); } diff --git a/OsmAnd/src/net/osmand/plus/download/local/LocalItemUtils.java b/OsmAnd/src/net/osmand/plus/download/local/LocalItemUtils.java index acf506fc8b0..242acbc22e6 100644 --- a/OsmAnd/src/net/osmand/plus/download/local/LocalItemUtils.java +++ b/OsmAnd/src/net/osmand/plus/download/local/LocalItemUtils.java @@ -186,7 +186,7 @@ public static LocalItemType getItemType(@NonNull OsmandApplication app, @NonNull } else if (name.endsWith(THREEGP_EXTENSION) || name.endsWith(MPEG4_EXTENSION) || name.endsWith(IMG_EXTENSION)) { return MULTIMEDIA_NOTES; } else if (path.contains(TILES_INDEX_DIR)) { - if (name.endsWith(SQLiteTileSource.EXT) || name.endsWith(HEIGHTMAP_SQLITE_EXT)) { + if (name.endsWith(SQLiteTileSource.EXT)) { return TILES_DATA; } if (file.isDirectory()) { diff --git a/OsmAnd/src/net/osmand/plus/download/local/LocalOperationTask.java b/OsmAnd/src/net/osmand/plus/download/local/LocalOperationTask.java index 0166b0c694e..49cf8dba93c 100644 --- a/OsmAnd/src/net/osmand/plus/download/local/LocalOperationTask.java +++ b/OsmAnd/src/net/osmand/plus/download/local/LocalOperationTask.java @@ -201,9 +201,7 @@ private File getFileToRestore(@NonNull LocalItem item) { } else if (item.getType() == ROAD_DATA) { parent = app.getAppPath(ROADS_INDEX_DIR); } else if (item.getType() == TILES_DATA) { - if (fileName.endsWith(HEIGHTMAP_SQLITE_EXT)) { - parent = app.getAppPath(HEIGHTMAP_INDEX_DIR); - } else if (fileName.endsWith(TIF_EXT)) { + if (fileName.endsWith(TIF_EXT)) { parent = app.getAppPath(GEOTIFF_DIR); } else { parent = app.getAppPath(TILES_INDEX_DIR); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapDataMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapDataMenuController.java index 95c1c90d58c..afec82f2db5 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapDataMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapDataMenuController.java @@ -660,9 +660,7 @@ private File getFileToRestore(@NonNull LocalItem item) { } else if (item.getType() == LocalItemType.ROAD_DATA) { parent = app.getAppPath(IndexConstants.ROADS_INDEX_DIR); } else if (item.getType() == LocalItemType.TILES_DATA) { - if (fileName.endsWith(IndexConstants.HEIGHTMAP_SQLITE_EXT)) { - parent = app.getAppPath(IndexConstants.HEIGHTMAP_INDEX_DIR); - } else if (fileName.endsWith(IndexConstants.TIF_EXT)) { + if (fileName.endsWith(IndexConstants.TIF_EXT)) { parent = app.getAppPath(IndexConstants.GEOTIFF_DIR); } else { parent = app.getAppPath(IndexConstants.TILES_INDEX_DIR); diff --git a/OsmAnd/src/net/osmand/plus/plugins/weather/WeatherBand.java b/OsmAnd/src/net/osmand/plus/plugins/weather/WeatherBand.java index 6bc59db2a17..25c8d2a4e4f 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/weather/WeatherBand.java +++ b/OsmAnd/src/net/osmand/plus/plugins/weather/WeatherBand.java @@ -1,6 +1,5 @@ package net.osmand.plus.plugins.weather; -import static net.osmand.IndexConstants.WEATHER_INDEX_DIR; import static net.osmand.plus.plugins.weather.units.CloudUnit.PERCENT; import static net.osmand.plus.plugins.weather.units.PrecipitationUnit.INCHES; import static net.osmand.plus.plugins.weather.units.PrecipitationUnit.MILIMETERS; @@ -19,6 +18,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.core.jni.MapPresentationEnvironment; import net.osmand.core.jni.QListDouble; @@ -462,15 +462,15 @@ public CommonPreference getAlphaPreference() { public String getColorFilePath() { switch (bandIndex) { case WEATHER_BAND_CLOUD: - return CLR_PALETTE_DIR + "weather_cloud.txt"; + return IndexConstants.CLR_PALETTE_DIR + "weather_cloud.txt"; case WEATHER_BAND_TEMPERATURE: - return CLR_PALETTE_DIR + "weather_temperature.txt"; + return IndexConstants.CLR_PALETTE_DIR + "weather_temperature.txt"; case WEATHER_BAND_PRESSURE: - return CLR_PALETTE_DIR + "weather_pressure.txt"; + return IndexConstants.CLR_PALETTE_DIR + "weather_pressure.txt"; case WEATHER_BAND_WIND_SPEED: - return CLR_PALETTE_DIR + "weather_wind.txt"; + return IndexConstants.CLR_PALETTE_DIR + "weather_wind.txt"; case WEATHER_BAND_PRECIPITATION: - return CLR_PALETTE_DIR + "weather_precip.txt"; + return IndexConstants.CLR_PALETTE_DIR + "weather_precip.txt"; case WEATHER_BAND_UNDEFINED: return null; } From 2003392983aa20ac0a757ecf25f82536f197116d Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 20 May 2024 16:49:29 +0300 Subject: [PATCH 19/33] Fix compilation --- OsmAnd/src/net/osmand/plus/download/DownloadResources.java | 4 ---- OsmAnd/src/net/osmand/plus/download/IndexItem.java | 3 +-- OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java | 2 +- OsmAnd/src/net/osmand/plus/resources/ResourceManager.java | 7 ------- OsmAnd/src/net/osmand/plus/utils/FileUtils.java | 1 - 5 files changed, 2 insertions(+), 15 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadResources.java b/OsmAnd/src/net/osmand/plus/download/DownloadResources.java index e62a177af2d..10b49f7d300 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadResources.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadResources.java @@ -410,10 +410,6 @@ protected boolean prepareData(List resources) { } continue; } - if (type == DownloadActivityType.HEIGHTMAP_FILE_LEGACY) { - // Hide heightmaps of sqlite format - continue; - } if (type == DownloadActivityType.HILLSHADE_FILE || type == DownloadActivityType.SLOPE_FILE) { OsmandDevelopmentPlugin plugin = PluginsHelper.getPlugin(OsmandDevelopmentPlugin.class); if (app.useOpenGlRenderer() && plugin != null && !plugin.USE_RASTER_SQLITEDB.get()) { diff --git a/OsmAnd/src/net/osmand/plus/download/IndexItem.java b/OsmAnd/src/net/osmand/plus/download/IndexItem.java index 84d849b2cc9..61cbce5f87f 100644 --- a/OsmAnd/src/net/osmand/plus/download/IndexItem.java +++ b/OsmAnd/src/net/osmand/plus/download/IndexItem.java @@ -192,7 +192,7 @@ public String getTranslatedBasename() { return (FileNameTranslationHelper.HILL_SHADE + "_" + getBasename()).replace("_", " "); } else if (type == DownloadActivityType.SLOPE_FILE) { return (FileNameTranslationHelper.SLOPE + "_" + getBasename()).replace('_', ' '); - } else if (type == DownloadActivityType.HEIGHTMAP_FILE_LEGACY || type == DownloadActivityType.GEOTIFF_FILE) { + } else if (type == DownloadActivityType.GEOTIFF_FILE) { return (FileNameTranslationHelper.HEIGHTMAP + "_" + getBasename()).replace('_', ' '); } else { return getBasename(); @@ -230,7 +230,6 @@ public boolean isOutdated() { return outdated && getType() != DownloadActivityType.HILLSHADE_FILE && getType() != DownloadActivityType.SLOPE_FILE - && getType() != DownloadActivityType.HEIGHTMAP_FILE_LEGACY && getType() != DownloadActivityType.GEOTIFF_FILE; } diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java index 3509a39cbd7..c30b238af25 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java @@ -110,7 +110,7 @@ protected boolean setLayerProvider(@Nullable ITileSource map) { @NonNull private IRasterMapLayerProvider createGeoTiffLayerProvider(TerrainMode mode, @NonNull GeoTiffCollection geoTiffCollection) { OsmandApplication app = getApplication(); - File heightmapDir = app.getAppPath(HEIGHTMAP_INDEX_DIR); + File heightmapDir = app.getAppPath(IndexConstants.CLR_PALETTE_DIR); String mainColorFilename = new File(heightmapDir, mode.getMainFile()).getAbsolutePath(); IRasterMapLayerProvider provider; if (mode.getType() == TerrainMode.TerrainType.HILLSHADE) { diff --git a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java index 214fca8691a..52135d92a96 100644 --- a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java @@ -564,7 +564,6 @@ protected List doInBackground(Void... params) { warnings.addAll(indexingMaps(progress)); warnings.addAll(indexVoiceFiles(progress)); warnings.addAll(indexFontFiles(progress)); - warnings.addAll(indexWeatherFiles(progress)); warnings.addAll(PluginsHelper.onIndexingFiles(progress)); warnings.addAll(indexAdditionalMaps(progress)); @@ -636,12 +635,6 @@ public List indexFontFiles(@Nullable IProgress progress) { return warnings; } - public List indexWeatherFiles(@Nullable IProgress progress) { - File file = context.getAppPath(IndexConstants.WEATHER_INDEX_DIR); - file.mkdirs(); - return new ArrayList<>(); - } - public boolean isReloadingIndexes() { return reloadingIndexes; } diff --git a/OsmAnd/src/net/osmand/plus/utils/FileUtils.java b/OsmAnd/src/net/osmand/plus/utils/FileUtils.java index 3b5bc34ff0a..7d43d47dc95 100644 --- a/OsmAnd/src/net/osmand/plus/utils/FileUtils.java +++ b/OsmAnd/src/net/osmand/plus/utils/FileUtils.java @@ -367,7 +367,6 @@ public static void removeUnnecessaryFiles(@NonNull OsmandApplication app) { FileUtils.removeFilesWithExtensions(app.getAppPath(NAUTICAL_INDEX_DIR), false, DOWNLOAD_EXT); FileUtils.removeFilesWithExtensions(app.getAppPath(WIKI_INDEX_DIR), false, DOWNLOAD_EXT); FileUtils.removeFilesWithExtensions(app.getAppPath(WIKIVOYAGE_INDEX_DIR), false, DOWNLOAD_EXT); - FileUtils.removeFilesWithExtensions(app.getAppPath(HEIGHTMAP_INDEX_DIR), false, DOWNLOAD_EXT); FileUtils.removeFilesWithExtensions(app.getAppPath(GEOTIFF_DIR), false, DOWNLOAD_EXT); } From 4ebdbdba3e631b0070473665eaa900ccaa161657 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 20 May 2024 16:56:57 +0300 Subject: [PATCH 20/33] update key name --- .../plus/download/DownloadIndexesThread.java | 1 - .../osmand/plus/plugins/srtm/SRTMPlugin.java | 4 ++-- .../plus/plugins/srtm/TerrainLayer.java | 5 ++-- .../osmand/plus/plugins/srtm/TerrainMode.java | 24 ++++++++++--------- .../src/net/osmand/plus/utils/FileUtils.java | 1 - 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java index 5b8be33b09d..c14836a073c 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java @@ -618,7 +618,6 @@ private String reindexFiles(List filesToReindex) { List warnings = new ArrayList<>(); manager.indexVoiceFiles(this); manager.indexFontFiles(this); - manager.indexWeatherFiles(this); if (vectorMapsToReindex) { warnings = manager.indexingMaps(this, filesToReindex); } diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/SRTMPlugin.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/SRTMPlugin.java index 20a0acb88e3..c7bc2963caa 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/SRTMPlugin.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/SRTMPlugin.java @@ -106,7 +106,7 @@ public SRTMPlugin(OsmandApplication app) { TERRAIN = registerBooleanPreference("terrain_layer", true).makeProfile(); TerrainMode[] tms = TerrainMode.values(app); - TERRAIN_MODE = registerStringPreference("terrain_mode", tms.length == 0 ? "" : tms[0].getKey()).makeProfile(); + TERRAIN_MODE = registerStringPreference("terrain_mode", tms.length == 0 ? "" : tms[0].getKeyName()).makeProfile(); CONTOUR_LINES_ZOOM = registerStringPreference("contour_lines_zoom", null).makeProfile().cache(); @@ -260,7 +260,7 @@ public TerrainMode getTerrainMode() { } public void setTerrainMode(TerrainMode mode) { - TERRAIN_MODE.set(mode.getKey()); + TERRAIN_MODE.set(mode.getKeyName()); } public void setTerrainTransparency(int transparency, TerrainMode mode) { diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java index c30b238af25..3a97e172830 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java @@ -44,7 +44,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import static net.osmand.IndexConstants.HEIGHTMAP_INDEX_DIR; public class TerrainLayer extends MapTileLayer { @@ -266,7 +265,7 @@ private Map readFiles(OsmandApplication app, File tile for(File f : files) { if (f != null && f.getName().endsWith(IndexConstants.SQLITE_EXT) - && f.getName().toLowerCase().startsWith(mode.getKey())) { + && f.getName().toLowerCase().startsWith(mode.getKeyName())) { SQLiteTileSource ts = new SQLiteTileSource(app, f, new ArrayList<>()); rs.put(f.getName(), ts); fileModified.put(f.getName(), f.lastModified()); @@ -352,7 +351,7 @@ public boolean couldBeDownloadedFromInternet() { @Override public String getName() { - return Algorithms.capitalizeFirstLetter(mode.getKey().toLowerCase()); + return Algorithms.capitalizeFirstLetter(mode.getKeyName().toLowerCase()); } @Override diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java index 191c9801d90..10b78a42203 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java @@ -16,8 +16,7 @@ public class TerrainMode { - private static final String HILLSHADE_KEY = "hillshade"; - private static final String SLOPE_KEY = "slope"; + private static final String DEFAULT_KEY = "default"; public static final String HILLSHADE_PREFIX = "hillshade_main_"; public static final String HILLSHADE_SCND_PREFIX = "hillshade_color_"; public static final String COLOR_SLOPE_PREFIX = "slope_"; @@ -53,9 +52,9 @@ public static TerrainMode[] values(OsmandApplication app) { return terrainModes; } TerrainMode hillshade = - new TerrainMode(app, HILLSHADE_KEY, app.getString(R.string.shared_string_hillshade), TerrainType.HILLSHADE); + new TerrainMode(app, DEFAULT_KEY, app.getString(R.string.shared_string_hillshade), TerrainType.HILLSHADE); TerrainMode slope = - new TerrainMode(app, SLOPE_KEY, app.getString(R.string.shared_string_slope), TerrainType.SLOPE); + new TerrainMode(app, DEFAULT_KEY, app.getString(R.string.shared_string_slope), TerrainType.SLOPE); List tms = new ArrayList<>(); // HILLSHADE first tms.add(hillshade); @@ -70,21 +69,21 @@ public static TerrainMode[] values(OsmandApplication app) { if (nm.startsWith(HILLSHADE_PREFIX)) { String key = nm.substring(HILLSHADE_PREFIX.length()); key = key.substring(0, key.length() - EXT.length()); - if (!HILLSHADE_KEY.equals(key)) { + if (!DEFAULT_KEY.equals(key)) { tms.add(new TerrainMode(app, key, Algorithms.capitalizeFirstLetter(key), TerrainType.HILLSHADE)); } } else if (nm.startsWith(COLOR_SLOPE_PREFIX)) { String key = nm.substring(COLOR_SLOPE_PREFIX.length()); key = key.substring(0, key.length() - EXT.length()); - if (!SLOPE_KEY.equals(key)) { + if (!DEFAULT_KEY.equals(key)) { tms.add(new TerrainMode(app, key, Algorithms.capitalizeFirstLetter(key), TerrainType.SLOPE)); } } else if (nm.startsWith(HEIGHT_PREFIX)) { String key = nm.substring(HEIGHT_PREFIX.length()); key = key.substring(0, key.length() - EXT.length()); -// if (!SLOPE_KEY.equals(key)) { + if (!DEFAULT_KEY.equals(key)) { tms.add(new TerrainMode(app, key, Algorithms.capitalizeFirstLetter(key), TerrainType.HEIGHT)); -// } + } } } } @@ -95,7 +94,7 @@ public static TerrainMode[] values(OsmandApplication app) { public static TerrainMode getByKey(String key) { TerrainMode hillshade = null; for (TerrainMode m : terrainModes) { - if (Algorithms.stringsEqual(m.getKey(), key)) { + if (Algorithms.stringsEqual(m.getKeyName(), key)) { return m; } else if (m.type == TerrainType.HILLSHADE && hillshade == null) { hillshade = m; @@ -126,14 +125,17 @@ public String getSecondFile() { return (isHillshade() ? HILLSHADE_SCND_PREFIX : "") + key + EXT; } - public String getKey() { + public String getKeyName() { + if (key.equals(DEFAULT_KEY)) { + return type.name().toLowerCase(); + } return key; } // private static final String HILLSHADE_CACHE = "hillshade.cache"; // private static final String SLOPE_CACHE = "slope.cache"; public String getCacheFileName() { - return key +".cache"; + return type.name().toLowerCase() +".cache"; } public void setZoomValues(int minZoom, int maxZoom) { diff --git a/OsmAnd/src/net/osmand/plus/utils/FileUtils.java b/OsmAnd/src/net/osmand/plus/utils/FileUtils.java index 7d43d47dc95..c17e2385d8d 100644 --- a/OsmAnd/src/net/osmand/plus/utils/FileUtils.java +++ b/OsmAnd/src/net/osmand/plus/utils/FileUtils.java @@ -3,7 +3,6 @@ import static net.osmand.IndexConstants.BACKUP_INDEX_DIR; import static net.osmand.IndexConstants.DOWNLOAD_EXT; import static net.osmand.IndexConstants.GEOTIFF_DIR; -import static net.osmand.IndexConstants.HEIGHTMAP_INDEX_DIR; import static net.osmand.IndexConstants.LIVE_INDEX_DIR; import static net.osmand.IndexConstants.MAPS_PATH; import static net.osmand.IndexConstants.NAUTICAL_INDEX_DIR; From 543b719d0aba24aaf4f3fc18fa50ad3da7459b40 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 20 May 2024 17:40:22 +0300 Subject: [PATCH 21/33] Add terrain layer --- OsmAnd/.gitignore | 1 + OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/OsmAnd/.gitignore b/OsmAnd/.gitignore index 66888057cac..d9b458112d8 100644 --- a/OsmAnd/.gitignore +++ b/OsmAnd/.gitignore @@ -64,6 +64,7 @@ assets/ui-fonts/* assets/weather/* assets/proj.db assets/heightmap/* +assets/color-palette/* # Android Studio /.idea diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java index 3a97e172830..71ec576ed2e 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java @@ -14,6 +14,7 @@ import net.osmand.core.android.MapRendererView; import net.osmand.core.android.TileSourceProxyProvider; import net.osmand.core.jni.GeoTiffCollection; +import net.osmand.core.jni.HeightRasterMapLayerProvider; import net.osmand.core.jni.HillshadeRasterMapLayerProvider; import net.osmand.core.jni.IRasterMapLayerProvider; import net.osmand.core.jni.SlopeRasterMapLayerProvider; @@ -123,8 +124,7 @@ private IRasterMapLayerProvider createGeoTiffLayerProvider(TerrainMode mode, @No ((SlopeRasterMapLayerProvider) provider).setMinVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMinZoom())); ((SlopeRasterMapLayerProvider) provider).setMaxVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMaxZoom())); } else { - // TODO new height provider - provider = new SlopeRasterMapLayerProvider(geoTiffCollection, mainColorFilename); + provider = new HeightRasterMapLayerProvider(geoTiffCollection, mainColorFilename); ((SlopeRasterMapLayerProvider) provider).setMinVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMinZoom())); ((SlopeRasterMapLayerProvider) provider).setMaxVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMaxZoom())); } From bcefec60fe67513f9fe41895fcbda90bf23c0c67 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 20 May 2024 18:04:48 +0300 Subject: [PATCH 22/33] Refactor color pallette --- .../main/java/net/osmand/ColorPalette.java | 187 +++ .../java/net/osmand/router/RouteColorize.java | 1090 ++++++++--------- .../main/java/net/osmand/util/Algorithms.java | 36 +- 3 files changed, 706 insertions(+), 607 deletions(-) create mode 100644 OsmAnd-java/src/main/java/net/osmand/ColorPalette.java diff --git a/OsmAnd-java/src/main/java/net/osmand/ColorPalette.java b/OsmAnd-java/src/main/java/net/osmand/ColorPalette.java new file mode 100644 index 00000000000..5f502ad7d2d --- /dev/null +++ b/OsmAnd-java/src/main/java/net/osmand/ColorPalette.java @@ -0,0 +1,187 @@ +package net.osmand; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; + +import net.osmand.util.Algorithms; + + +public class ColorPalette { + + private static final Log LOG = PlatformUtil.getLog(ColorPalette.class); + + public static final int DARK_GREY = rgbaToDecimal(92, 92, 92, 255); + public static final int LIGHT_GREY = rgbaToDecimal(200, 200, 200, 255); + public static final int GREEN = rgbaToDecimal(90, 220, 95, 255); + public static final int YELLOW = rgbaToDecimal(212, 239, 50, 255); + public static final int RED = rgbaToDecimal(243, 55, 77, 255); + public static final int BLUE_SLOPE = rgbaToDecimal(0, 0, 255, 255); + public static final int CYAN_SLOPE = rgbaToDecimal(0, 255, 255, 255); + public static final int GREEN_SLOPE = rgbaToDecimal(46, 185, 0, 255); + public static final int WHITE = rgbaToDecimal(255, 255, 255, 255); + public static final int YELLOW_SLOPE = rgbaToDecimal(255, 222, 2, 255); + public static final int RED_SLOPE = rgbaToDecimal(255, 1, 1, 255); + public static final int PURPLE_SLOPE = rgbaToDecimal(130, 1, 255, 255); + + public static final int[] COLORS = new int[] {GREEN, YELLOW, RED}; + public static final int[] SLOPE_COLORS = new int[] {CYAN_SLOPE, GREEN_SLOPE, LIGHT_GREY, YELLOW_SLOPE, RED_SLOPE}; + + public static final double SLOPE_MIN_VALUE = -1.00;//-100% + public static final double SLOPE_MAX_VALUE = 1.0;//100% + //public static final double[][] SLOPE_PALETTE = {{SLOPE_MIN_VALUE, GREEN_SLOPE}, {0.0, WHITE}, {0.125, YELLOW_SLOPE}, {0.25, RED_SLOPE}, {SLOPE_MAX_VALUE, PURPLE_SLOPE}}; + public static final double[][] SLOPE_PALETTE = {{SLOPE_MIN_VALUE, BLUE_SLOPE}, {-0.15, CYAN_SLOPE}, {-0.05, GREEN_SLOPE}, {0.0, LIGHT_GREY}, {0.05, YELLOW_SLOPE}, {0.15, RED_SLOPE}, {SLOPE_MAX_VALUE, PURPLE_SLOPE}}; + + public static int rgbaToDecimal(int r, int g, int b, int a) { + int value = ((a & 0xFF) << 24) | + ((r & 0xFF) << 16) | + ((g & 0xFF) << 8) | + ((b & 0xFF) << 0); + return value; + } + + private static int getRed(int value) { + return (value >> 16) & 0xFF; + } + + private static int getGreen(int value) { + return (value >> 8) & 0xFF; + } + + private static int getBlue(int value) { + return (value >> 0) & 0xFF; + } + + private static int getAlpha(int value) { + return (value >> 24) & 0xff; + } + + public static int getTransparentColor() { + return rgbaToDecimal(0, 0, 0, 0); + } + + public static int getIntermediateColor(int minPaletteColor, int maxPaletteColor, double percent) { + double resultRed = getRed(minPaletteColor) + percent * (getRed(maxPaletteColor) - getRed(minPaletteColor)); + double resultGreen = getGreen(minPaletteColor) + + percent * (getGreen(maxPaletteColor) - getGreen(minPaletteColor)); + double resultBlue = getBlue(minPaletteColor) + percent * (getBlue(maxPaletteColor) - getBlue(minPaletteColor)); + double resultAlpha = getAlpha(minPaletteColor) + + percent * (getAlpha(maxPaletteColor) - getAlpha(minPaletteColor)); + return rgbaToDecimal((int) resultRed, (int) resultGreen, (int) resultBlue, (int) resultAlpha); + } + + public static double[][] getPaletteScale(double minValue, double maxValue) { + return new double[][] { { minValue, GREEN }, { (minValue + maxValue) / 2, YELLOW }, { maxValue, RED } }; + } + + public static int[] stringToGradientPalette(String str, String gradientScaleType) { + boolean isSlope = "gradient_slope_color".equals(gradientScaleType); + if (Algorithms.isBlank(str)) { + return isSlope ? SLOPE_COLORS : COLORS; + } + String[] arr = str.split(" "); + if (arr.length < 2) { + return isSlope ? SLOPE_COLORS : COLORS; + } + int[] colors = new int[arr.length]; + try { + for (int i = 0; i < arr.length; i++) { + colors[i] = Algorithms.parseColor(arr[i]); + } + } catch (IllegalArgumentException e) { + return isSlope ? SLOPE_COLORS :COLORS; + } + return colors; + } + + public static String gradientPaletteToString(int[] palette, String gradientScaleType) { + boolean isSlope = "gradient_slope_color".equals(gradientScaleType); + int[] src; + if (palette != null && palette.length >= 2) { + src = palette; + } else { + src = isSlope ? SLOPE_COLORS : COLORS; + } + StringBuilder stringPalette = new StringBuilder(); + for (int i = 0; i < src.length; i++) { + stringPalette.append(Algorithms.colorToString(src[i])); + if (i + 1 != src.length) { + stringPalette.append(" "); + } + } + return stringPalette.toString(); + } + + + public static class ColorValue { + int r; + int g; + int b; + int a; + double val; + + public static ColorValue rgba(double val, int r, int g, int b, int a) { + ColorValue clr = new ColorValue(); + clr.r = r; + clr.g = g; + clr.b = b; + clr.a = a; + clr.val = val; + return clr; + } + + @Override + public String toString() { + return "ColorValue [r=" + r + ", g=" + g + ", b=" + b + ", a=" + a + ", val=" + val + "]"; + } + + } + + public static String writeColorPalette(List palette) throws IOException { + StringBuilder bld = new StringBuilder(); + for (ColorValue v : palette) { + bld.append(v.val).append(",").append(v.r).append(",").append(v.g).append(",").append(v.b).append(",") + .append(v.a).append("\n"); + } + return bld.toString().trim(); + } + + public static List parseColorPalette(Reader reader) throws IOException { + List palette = new ArrayList<>(); + BufferedReader r = new BufferedReader(reader); + String line; + while ((line = r.readLine()) != null) { + String t = line.trim(); + if (t.startsWith("#")) { + continue; + } + String[] values = t.split(","); + if (values.length >= 4) { + try { + ColorValue rgba = ColorValue.rgba(Double.parseDouble(values[0]), Integer.parseInt(values[1]), + Integer.parseInt(values[2]), Integer.parseInt(values[3]), values.length >= 4 ? Integer.parseInt(values[4]) : 255); + palette.add(rgba); + } catch (NumberFormatException e) { + LOG.error(e.getMessage(), e); + } + } + } + return palette; + } + + + + + public static void main(String[] args) throws IOException { + List pls = ColorPalette.parseColorPalette(new FileReader("/Users/victorshcherb/osmand/repos/resources/color-palette/route_speed_default.txt")); + System.out.println(pls); + System.out.println(ColorPalette.writeColorPalette(pls)); + } + + +} diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java index 73672c4b203..5596e24d52c 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -5,6 +5,7 @@ import net.osmand.gpx.GPXUtilities.Track; import net.osmand.gpx.GPXUtilities.TrkSegment; import net.osmand.gpx.GPXUtilities.WptPt; +import net.osmand.ColorPalette; import net.osmand.PlatformUtil; import net.osmand.osm.edit.Node; import net.osmand.osm.edit.OsmMapUtils; @@ -18,578 +19,519 @@ public class RouteColorize { - public double[] latitudes; - public double[] longitudes; - public double[] values; - public double minValue; - public double maxValue; - public double[][] palette; - - private List dataList; - - public static final int DARK_GREY = rgbaToDecimal(92, 92, 92, 255); - public static final int LIGHT_GREY = rgbaToDecimal(200, 200, 200, 255); - public static final int GREEN = rgbaToDecimal(90, 220, 95, 255); - public static final int YELLOW = rgbaToDecimal(212, 239, 50, 255); - public static final int RED = rgbaToDecimal(243, 55, 77, 255); - public static final int BLUE_SLOPE = rgbaToDecimal(0, 0, 255, 255); - public static final int CYAN_SLOPE = rgbaToDecimal(0, 255, 255, 255); - public static final int GREEN_SLOPE = rgbaToDecimal(46, 185, 0, 255); - public static final int WHITE = rgbaToDecimal(255, 255, 255, 255); - public static final int YELLOW_SLOPE = rgbaToDecimal(255, 222, 2, 255); - public static final int RED_SLOPE = rgbaToDecimal(255, 1, 1, 255); - public static final int PURPLE_SLOPE = rgbaToDecimal(130, 1, 255, 255); - - public static final int[] COLORS = new int[] {GREEN, YELLOW, RED}; - public static final int[] SLOPE_COLORS = new int[] {CYAN_SLOPE, GREEN_SLOPE, LIGHT_GREY, YELLOW_SLOPE, RED_SLOPE}; - - public static final double SLOPE_MIN_VALUE = -1.00;//-100% - public static final double SLOPE_MAX_VALUE = 1.0;//100% - //public static final double[][] SLOPE_PALETTE = {{SLOPE_MIN_VALUE, GREEN_SLOPE}, {0.0, WHITE}, {0.125, YELLOW_SLOPE}, {0.25, RED_SLOPE}, {SLOPE_MAX_VALUE, PURPLE_SLOPE}}; - public static final double[][] SLOPE_PALETTE = {{SLOPE_MIN_VALUE, BLUE_SLOPE}, {-0.15, CYAN_SLOPE}, {-0.05, GREEN_SLOPE}, {0.0, LIGHT_GREY}, {0.05, YELLOW_SLOPE}, {0.15, RED_SLOPE}, {SLOPE_MAX_VALUE, PURPLE_SLOPE}}; - - private static final float DEFAULT_BASE = 17.2f; - public static double MAX_CORRECT_ELEVATION_DISTANCE = 100.0;// in meters - - public enum ColorizationType { - ELEVATION, - SPEED, - SLOPE, - NONE - } - - private final int VALUE_INDEX = 0; - private final int DECIMAL_COLOR_INDEX = 1;//sRGB decimal format - private final int RED_COLOR_INDEX = 1;//RGB - private final int GREEN_COLOR_INDEX = 2;//RGB - private final int BLUE_COLOR_INDEX = 3;//RGB - private final int ALPHA_COLOR_INDEX = 4;//RGBA - - private ColorizationType colorizationType; - - public static int SLOPE_RANGE = 150;//150 meters - private static final double MIN_DIFFERENCE_SLOPE = 0.05d;//5% - - private static final Log LOG = PlatformUtil.getLog(RouteColorize.class); - - /** - * @param minValue can be NaN - * @param maxValue can be NaN - * @param palette array {{value,color},...} - color in sRGB (decimal) format OR {{value,RED,GREEN,BLUE,ALPHA},...} - color in RGBA format - */ - public RouteColorize(double[] latitudes, double[] longitudes, double[] values, double minValue, double maxValue, double[][] palette) { - this.latitudes = latitudes; - this.longitudes = longitudes; - this.values = values; - this.minValue = minValue; - this.maxValue = maxValue; - this.palette = palette; - - if (Double.isNaN(minValue) || Double.isNaN(maxValue)) { - calculateMinMaxValue(); - } - checkPalette(); - sortPalette(); - } - - /** - * @param type ELEVATION, SPEED, SLOPE - */ - public RouteColorize(GPXFile gpxFile, ColorizationType type) { - this(gpxFile, null, type, 0); - } - - public RouteColorize(GPXFile gpxFile, GPXTrackAnalysis analysis, ColorizationType type, float maxProfileSpeed) { - - if (!gpxFile.hasTrkPt()) { - LOG.warn("GPX file is not consist of track points"); - return; - } - - List latList = new ArrayList<>(); - List lonList = new ArrayList<>(); - List valList = new ArrayList<>(); - int wptIdx = 0; - - if (analysis == null) { - long time = Algorithms.isEmpty(gpxFile.path) ? System.currentTimeMillis() : gpxFile.modifiedTime; - analysis = gpxFile.getAnalysis(time); - } - for (Track t : gpxFile.tracks) { - for (TrkSegment ts : t.segments) { - if (ts.generalSegment || ts.points.size() < 2) { - continue; - } - - for (WptPt p : ts.points) { - latList.add(p.lat); - lonList.add(p.lon); - if (type == ColorizationType.SPEED) { - valList.add((double) analysis.pointAttributes.get(wptIdx).speed); - } else { - valList.add((double) analysis.pointAttributes.get(wptIdx).elevation); - } - wptIdx++; - } - } - } - - colorizationType = type; - latitudes = listToArray(latList); - longitudes = listToArray(lonList); - - if (type == ColorizationType.SLOPE) { - values = calculateSlopesByElevations(latitudes, longitudes, listToArray(valList), SLOPE_RANGE); - } else { - values = listToArray(valList); - } - calculateMinMaxValue(analysis, maxProfileSpeed); - checkPalette(); - sortPalette(); - } - - /** - * Calculate slopes from elevations needs for right colorizing - * - * @param slopeRange - in what range calculate the derivative, usually we used 150 meters - * @return slopes array, in the begin and the end present NaN values! - */ - public double[] calculateSlopesByElevations(double[] latitudes, double[] longitudes, double[] elevations, double slopeRange) { - correctElevations(latitudes, longitudes, elevations); - double[] newElevations = elevations; - for (int i = 2; i < elevations.length - 2; i++) { - newElevations[i] = elevations[i - 2] - + elevations[i - 1] - + elevations[i] - + elevations[i + 1] - + elevations[i + 2]; - newElevations[i] /= 5; - } - elevations = newElevations; - - double[] slopes = new double[elevations.length]; - if (latitudes.length != longitudes.length || latitudes.length != elevations.length) { - LOG.warn("Sizes of arrays latitudes, longitudes and values are not match"); - return slopes; - } - - double[] distances = new double[elevations.length]; - double totalDistance = 0.0d; - distances[0] = totalDistance; - for (int i = 0; i < elevations.length - 1; i++) { - totalDistance += MapUtils.getDistance(latitudes[i], longitudes[i], latitudes[i + 1], longitudes[i + 1]); - distances[i + 1] = totalDistance; - } - - for (int i = 0; i < elevations.length; i++) { - if (distances[i] < slopeRange / 2 || distances[i] > totalDistance - slopeRange / 2) { - slopes[i] = Double.NaN; - } else { - double[] arg = findDerivativeArguments(distances, elevations, i, slopeRange); - slopes[i] = (arg[1] - arg[0]) / (arg[3] - arg[2]); - } - } - return slopes; - } - - private void correctElevations(double[] latitudes, double[] longitudes, double[] elevations) { - for (int i = 0; i < elevations.length; i++) { - if (Double.isNaN(elevations[i])) { - double leftDist = MAX_CORRECT_ELEVATION_DISTANCE; - double rightDist = MAX_CORRECT_ELEVATION_DISTANCE; - double leftElevation = Double.NaN; - double rightElevation = Double.NaN; - for (int left = i - 1; left > 0 && leftDist <= MAX_CORRECT_ELEVATION_DISTANCE; left--) { - if (!Double.isNaN(elevations[left])) { - double dist = MapUtils.getDistance(latitudes[left], longitudes[left], latitudes[i], longitudes[i]); - if (dist < leftDist) { - leftDist = dist; - leftElevation = elevations[left]; - } else { - break; - } - } - } - for (int right = i + 1; right < elevations.length && rightDist <= MAX_CORRECT_ELEVATION_DISTANCE; right++) { - if (!Double.isNaN(elevations[right])) { - double dist = MapUtils.getDistance(latitudes[right], longitudes[right], latitudes[i], longitudes[i]); - if (dist < rightDist) { - rightElevation = elevations[right]; - rightDist = dist; - } else { - break; - } - } - } - if (!Double.isNaN(leftElevation) && !Double.isNaN(rightElevation)) { - elevations[i] = (leftElevation + rightElevation) / 2; - } else if (Double.isNaN(leftElevation) && !Double.isNaN(rightElevation)) { - elevations[i] = rightElevation; - } else if (!Double.isNaN(leftElevation) && Double.isNaN(rightElevation)) { - elevations[i] = leftElevation; - } else { - for (int right = i + 1; right < elevations.length; right++) { - if (!Double.isNaN(elevations[right])) { - elevations[i] = elevations[right]; - break; - } - } - } - } - } - } - - public List getResult() { - List result = new ArrayList<>(); - for (int i = 0; i < latitudes.length; i++) { - result.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i])); - } - setColorsToPoints(result); - return result; - } - - public List getSimplifiedResult(int simplificationZoom) { - List simplifiedResult = simplify(simplificationZoom); - setColorsToPoints(simplifiedResult); - return simplifiedResult; - } - - private void setColorsToPoints(List points) { - for (RouteColorizationPoint point : points) { - point.color = getColorByValue(point.val); - } - } - - public int getColorByValue(double value) { - if (Double.isNaN(value)) { - return LIGHT_GREY; - } - for (int i = 0; i < palette.length - 1; i++) { - if (value == palette[i][VALUE_INDEX]) - return (int) palette[i][DECIMAL_COLOR_INDEX]; - if (value >= palette[i][VALUE_INDEX] && value <= palette[i + 1][VALUE_INDEX]) { - int minPaletteColor = (int) palette[i][DECIMAL_COLOR_INDEX]; - int maxPaletteColor = (int) palette[i + 1][DECIMAL_COLOR_INDEX]; - double minPaletteValue = palette[i][VALUE_INDEX]; - double maxPaletteValue = palette[i + 1][VALUE_INDEX]; - double percent = (value - minPaletteValue) / (maxPaletteValue - minPaletteValue); - return getIntermediateColor(minPaletteColor, maxPaletteColor, percent); - } - } - if (value <= palette[0][0]) { - return (int)palette[0][1]; - } else if (value >= palette[palette.length-1][0]) { - return (int) palette[palette.length-1][1]; - } - return getTransparentColor(); - } - - public void setPalette(double[][] palette) { - this.palette = palette; - checkPalette(); - sortPalette(); - } - - public void setPalette(int[] gradientPalette) { - if (gradientPalette == null || gradientPalette.length != 3) { - return; - } - setPalette(new double[][] { - {minValue, gradientPalette[0]}, - {(minValue + maxValue) / 2, gradientPalette[1]}, - {maxValue, gradientPalette[2]} - }); - } - - private int getTransparentColor() { - return rgbaToDecimal(0, 0, 0, 0); - } - - public List simplify(int simplificationZoom) { - if (dataList == null) { - dataList = new ArrayList<>(); - for (int i = 0; i < latitudes.length; i++) { - dataList.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i])); - } - } - List nodes = new ArrayList<>(); - List result = new ArrayList<>(); - for (RouteColorizationPoint data : dataList) { - nodes.add(new net.osmand.osm.edit.Node(data.lat, data.lon, data.id)); - } - - double epsilon = Math.pow(2.0, DEFAULT_BASE - simplificationZoom); - result.add(nodes.get(0)); - OsmMapUtils.simplifyDouglasPeucker(nodes, 0, nodes.size() - 1, result, epsilon); - - List simplified = new ArrayList<>(); - for (int i = 1; i < result.size(); i++) { - int prevId = (int) result.get(i - 1).getId(); - int currentId = (int) result.get(i).getId(); - List sublist = dataList.subList(prevId, currentId); - simplified.addAll(getExtremums(sublist)); - } - Node lastSurvivedPoint = result.get(result.size() - 1); - simplified.add(dataList.get((int) lastSurvivedPoint.getId())); - return simplified; - } - - private List getExtremums(List subDataList) { - if (subDataList.size() <= 2) { - return subDataList; - } - - List result = new ArrayList<>(); - double min; - double max; - min = max = subDataList.get(0).val; - for (RouteColorizationPoint pt : subDataList) { - if (min > pt.val) { - min = pt.val; - } - if (max < pt.val) { - max = pt.val; - } - } - - double diff = max - min; - - result.add(subDataList.get(0)); - for (int i = 1; i < subDataList.size() - 1; i++) { - double prev = subDataList.get(i - 1).val; - double current = subDataList.get(i).val; - double next = subDataList.get(i + 1).val; - RouteColorizationPoint currentData = subDataList.get(i); - - if ((current > prev && current > next) || (current < prev && current < next) - || (current < prev && current == next) || (current == prev && current < next) - || (current > prev && current == next) || (current == prev && current > next)) { - RouteColorizationPoint prevInResult; - if (result.size() > 0) { - prevInResult = result.get(0); - if (prevInResult.val / diff > MIN_DIFFERENCE_SLOPE) { - result.add(currentData); - } - } else - result.add(currentData); - } - } - result.add(subDataList.get(subDataList.size() - 1)); - return result; - } - - private void checkPalette() { - if (palette == null || palette.length < 2 || palette[0].length < 2 || palette[1].length < 2) { - LOG.info("Will use default palette"); - palette = getDefaultPalette(colorizationType); - } - double min; - double max = min = palette[0][VALUE_INDEX]; - int minIndex = 0; - int maxIndex = 0; - double[][] sRGBPalette = new double[palette.length][2]; - for (int i = 0; i < palette.length; i++) { - double[] p = palette[i]; - if (p.length == 2) { - sRGBPalette[i] = p; - } else if (p.length == 4) { - int color = rgbaToDecimal((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], (int) p[BLUE_COLOR_INDEX], 255); - sRGBPalette[i] = new double[]{p[VALUE_INDEX], color}; - } else if (p.length >= 5) { - int color = rgbaToDecimal((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], (int) p[BLUE_COLOR_INDEX], (int) p[ALPHA_COLOR_INDEX]); - sRGBPalette[i] = new double[]{p[VALUE_INDEX], color}; - } - if (p[VALUE_INDEX] > max) { - max = p[VALUE_INDEX]; - maxIndex = i; - } - if (p[VALUE_INDEX] < min) { - min = p[VALUE_INDEX]; - minIndex = i; - } - } - palette = sRGBPalette; - if (minValue < min) { - palette[minIndex][VALUE_INDEX] = minValue; - } - if (maxValue > max) { - palette[maxIndex][VALUE_INDEX] = maxValue; - } - } - - private void sortPalette() { - java.util.Arrays.sort(palette, new java.util.Comparator() { - public int compare(double[] a, double[] b) { - return Double.compare(a[VALUE_INDEX], b[VALUE_INDEX]); - } - }); - } - - /** - * @return double[minElevation, maxElevation, minDist, maxDist] - */ - private double[] findDerivativeArguments(double[] distances, double[] elevations, int index, double slopeRange) { - double[] result = new double[4]; - double minDist = distances[index] - slopeRange / 2; - double maxDist = distances[index] + slopeRange / 2; - result[0] = Double.NaN; - result[1] = Double.NaN; - result[2] = minDist; - result[3] = maxDist; - int closestMaxIndex = -1; - int closestMinIndex = -1; - for (int i = index; i < distances.length; i++) { - if (distances[i] == maxDist) { - result[1] = elevations[i]; - break; - } - if (distances[i] > maxDist) { - closestMaxIndex = i; - break; - } - } - for (int i = index; i >= 0; i--) { - if (distances[i] == minDist) { - result[0] = elevations[i]; - break; - } - if (distances[i] < minDist) { - closestMinIndex = i; - break; - } - } - if (closestMaxIndex > 0) { - double diff = distances[closestMaxIndex] - distances[closestMaxIndex - 1]; - double coef = (maxDist - distances[closestMaxIndex - 1]) / diff; - if (coef > 1 || coef < 0) { - LOG.warn("Coefficient fo max must be 0..1 , coef=" + coef); - } - result[1] = (1 - coef) * elevations[closestMaxIndex - 1] + coef * elevations[closestMaxIndex]; - } - if (closestMinIndex >= 0) { - double diff = distances[closestMinIndex + 1] - distances[closestMinIndex]; - double coef = (minDist - distances[closestMinIndex]) / diff; - if (coef > 1 || coef < 0) { - LOG.warn("Coefficient for min must be 0..1 , coef=" + coef); - } - result[0] = (1 - coef) * elevations[closestMinIndex] + coef * elevations[closestMinIndex + 1]; - } - if (Double.isNaN(result[0]) || Double.isNaN(result[1])) { - LOG.warn("Elevations wasn't calculated"); - } - return result; - } - - public static double getMinValue(ColorizationType type, GPXTrackAnalysis analysis) { - switch (type) { - case SPEED: - return 0.0; - case ELEVATION: - return analysis.getMinElevation(); - case SLOPE: - return SLOPE_MIN_VALUE; - default: - return -1; - } - } - - public static double getMaxValue(ColorizationType type, GPXTrackAnalysis analysis, double minValue, double maxProfileSpeed) { - switch (type) { - case SPEED: - return Math.max(analysis.getMaxSpeed(), maxProfileSpeed); - case ELEVATION: - return Math.max(analysis.getMaxElevation(), minValue + 50); - case SLOPE: - return SLOPE_MAX_VALUE; - default: - return -1; - } - } - - public static int getIntermediateColor(int minPaletteColor, int maxPaletteColor, double percent) { - double resultRed = getRed(minPaletteColor) + percent * (getRed(maxPaletteColor) - getRed(minPaletteColor)); - double resultGreen = getGreen(minPaletteColor) + percent * (getGreen(maxPaletteColor) - getGreen(minPaletteColor)); - double resultBlue = getBlue(minPaletteColor) + percent * (getBlue(maxPaletteColor) - getBlue(minPaletteColor)); - double resultAlpha = getAlpha(minPaletteColor) + percent * (getAlpha(maxPaletteColor) - getAlpha(minPaletteColor)); - return rgbaToDecimal((int) resultRed, (int) resultGreen, (int) resultBlue, (int) resultAlpha); - } - - private void calculateMinMaxValue() { - if (values.length == 0) - return; - minValue = maxValue = Double.NaN; - for (double value : values) { - if ((Double.isNaN(maxValue) || Double.isNaN(minValue)) && !Double.isNaN(value)) - maxValue = minValue = value; - if (minValue > value) - minValue = value; - if (maxValue < value) - maxValue = value; - } - } - - private void calculateMinMaxValue(GPXTrackAnalysis analysis, float maxProfileSpeed) { - calculateMinMaxValue(); - // set strict limitations for maxValue - maxValue = getMaxValue(colorizationType, analysis, minValue, maxProfileSpeed); - } - - private double[] listToArray(List doubleList) { - double[] result = new double[doubleList.size()]; - for (int i = 0; i < doubleList.size(); i++) { - result[i] = doubleList.get(i); - } - return result; - } - - private double[][] getDefaultPalette(ColorizationType colorizationType) { - if (colorizationType == ColorizationType.SLOPE) { - return SLOPE_PALETTE; - } else { - return new double[][] { - {minValue, GREEN}, - {(minValue + maxValue) / 2, YELLOW}, - {maxValue, RED} - }; - } - } - - private static int rgbaToDecimal(int r, int g, int b, int a) { - int value = ((a & 0xFF) << 24) | - ((r & 0xFF) << 16) | - ((g & 0xFF) << 8) | - ((b & 0xFF) << 0); - return value; - } - - private static int getRed(int value) { - return (value >> 16) & 0xFF; - } - - private static int getGreen(int value) { - return (value >> 8) & 0xFF; - } - - private static int getBlue(int value) { - return (value >> 0) & 0xFF; - } - - private static int getAlpha(int value) { - return (value >> 24) & 0xff; - } - - public static class RouteColorizationPoint { - public int id; - public double lat; - public double lon; - public double val; - public int color; - - public RouteColorizationPoint(int id, double lat, double lon, double val) { - this.id = id; - this.lat = lat; - this.lon = lon; - this.val = val; - } - } + public double[] latitudes; + public double[] longitudes; + public double[] values; + public double minValue; + public double maxValue; + public double[][] palette; + + private List dataList; + + private static final float DEFAULT_BASE = 17.2f; + public static double MAX_CORRECT_ELEVATION_DISTANCE = 100.0;// in meters + + public enum ColorizationType { + ELEVATION, SPEED, SLOPE, NONE + } + + private final int VALUE_INDEX = 0; + private final int DECIMAL_COLOR_INDEX = 1;// sRGB decimal format + private final int RED_COLOR_INDEX = 1;// RGB + private final int GREEN_COLOR_INDEX = 2;// RGB + private final int BLUE_COLOR_INDEX = 3;// RGB + private final int ALPHA_COLOR_INDEX = 4;// RGBA + + private ColorizationType colorizationType; + + public static int SLOPE_RANGE = 150;// 150 meters + private static final double MIN_DIFFERENCE_SLOPE = 0.05d;// 5% + + private static final Log LOG = PlatformUtil.getLog(RouteColorize.class); + + /** + * @param minValue can be NaN + * @param maxValue can be NaN + * @param palette array {{value,color},...} - color in sRGB (decimal) format OR + * {{value,RED,GREEN,BLUE,ALPHA},...} - color in RGBA format + */ + public RouteColorize(double[] latitudes, double[] longitudes, double[] values, double minValue, double maxValue, + double[][] palette) { + this.latitudes = latitudes; + this.longitudes = longitudes; + this.values = values; + this.minValue = minValue; + this.maxValue = maxValue; + this.palette = palette; + + if (Double.isNaN(minValue) || Double.isNaN(maxValue)) { + calculateMinMaxValue(); + } + checkPalette(); + sortPalette(); + } + + /** + * @param type ELEVATION, SPEED, SLOPE + */ + public RouteColorize(GPXFile gpxFile, ColorizationType type) { + this(gpxFile, null, type, 0); + } + + public RouteColorize(GPXFile gpxFile, GPXTrackAnalysis analysis, ColorizationType type, float maxProfileSpeed) { + + if (!gpxFile.hasTrkPt()) { + LOG.warn("GPX file is not consist of track points"); + return; + } + + List latList = new ArrayList<>(); + List lonList = new ArrayList<>(); + List valList = new ArrayList<>(); + int wptIdx = 0; + + if (analysis == null) { + long time = Algorithms.isEmpty(gpxFile.path) ? System.currentTimeMillis() : gpxFile.modifiedTime; + analysis = gpxFile.getAnalysis(time); + } + for (Track t : gpxFile.tracks) { + for (TrkSegment ts : t.segments) { + if (ts.generalSegment || ts.points.size() < 2) { + continue; + } + + for (WptPt p : ts.points) { + latList.add(p.lat); + lonList.add(p.lon); + if (type == ColorizationType.SPEED) { + valList.add((double) analysis.pointAttributes.get(wptIdx).speed); + } else { + valList.add((double) analysis.pointAttributes.get(wptIdx).elevation); + } + wptIdx++; + } + } + } + + colorizationType = type; + latitudes = listToArray(latList); + longitudes = listToArray(lonList); + + if (type == ColorizationType.SLOPE) { + values = calculateSlopesByElevations(latitudes, longitudes, listToArray(valList), SLOPE_RANGE); + } else { + values = listToArray(valList); + } + calculateMinMaxValue(analysis, maxProfileSpeed); + checkPalette(); + sortPalette(); + } + + /** + * Calculate slopes from elevations needs for right colorizing + * + * @param slopeRange - in what range calculate the derivative, usually we used + * 150 meters + * @return slopes array, in the begin and the end present NaN values! + */ + public double[] calculateSlopesByElevations(double[] latitudes, double[] longitudes, double[] elevations, + double slopeRange) { + correctElevations(latitudes, longitudes, elevations); + double[] newElevations = elevations; + for (int i = 2; i < elevations.length - 2; i++) { + newElevations[i] = elevations[i - 2] + elevations[i - 1] + elevations[i] + elevations[i + 1] + + elevations[i + 2]; + newElevations[i] /= 5; + } + elevations = newElevations; + + double[] slopes = new double[elevations.length]; + if (latitudes.length != longitudes.length || latitudes.length != elevations.length) { + LOG.warn("Sizes of arrays latitudes, longitudes and values are not match"); + return slopes; + } + + double[] distances = new double[elevations.length]; + double totalDistance = 0.0d; + distances[0] = totalDistance; + for (int i = 0; i < elevations.length - 1; i++) { + totalDistance += MapUtils.getDistance(latitudes[i], longitudes[i], latitudes[i + 1], longitudes[i + 1]); + distances[i + 1] = totalDistance; + } + + for (int i = 0; i < elevations.length; i++) { + if (distances[i] < slopeRange / 2 || distances[i] > totalDistance - slopeRange / 2) { + slopes[i] = Double.NaN; + } else { + double[] arg = findDerivativeArguments(distances, elevations, i, slopeRange); + slopes[i] = (arg[1] - arg[0]) / (arg[3] - arg[2]); + } + } + return slopes; + } + + private void correctElevations(double[] latitudes, double[] longitudes, double[] elevations) { + for (int i = 0; i < elevations.length; i++) { + if (Double.isNaN(elevations[i])) { + double leftDist = MAX_CORRECT_ELEVATION_DISTANCE; + double rightDist = MAX_CORRECT_ELEVATION_DISTANCE; + double leftElevation = Double.NaN; + double rightElevation = Double.NaN; + for (int left = i - 1; left > 0 && leftDist <= MAX_CORRECT_ELEVATION_DISTANCE; left--) { + if (!Double.isNaN(elevations[left])) { + double dist = MapUtils.getDistance(latitudes[left], longitudes[left], latitudes[i], + longitudes[i]); + if (dist < leftDist) { + leftDist = dist; + leftElevation = elevations[left]; + } else { + break; + } + } + } + for (int right = i + 1; right < elevations.length + && rightDist <= MAX_CORRECT_ELEVATION_DISTANCE; right++) { + if (!Double.isNaN(elevations[right])) { + double dist = MapUtils.getDistance(latitudes[right], longitudes[right], latitudes[i], + longitudes[i]); + if (dist < rightDist) { + rightElevation = elevations[right]; + rightDist = dist; + } else { + break; + } + } + } + if (!Double.isNaN(leftElevation) && !Double.isNaN(rightElevation)) { + elevations[i] = (leftElevation + rightElevation) / 2; + } else if (Double.isNaN(leftElevation) && !Double.isNaN(rightElevation)) { + elevations[i] = rightElevation; + } else if (!Double.isNaN(leftElevation) && Double.isNaN(rightElevation)) { + elevations[i] = leftElevation; + } else { + for (int right = i + 1; right < elevations.length; right++) { + if (!Double.isNaN(elevations[right])) { + elevations[i] = elevations[right]; + break; + } + } + } + } + } + } + + public List getResult() { + List result = new ArrayList<>(); + for (int i = 0; i < latitudes.length; i++) { + result.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i])); + } + setColorsToPoints(result); + return result; + } + + public List getSimplifiedResult(int simplificationZoom) { + List simplifiedResult = simplify(simplificationZoom); + setColorsToPoints(simplifiedResult); + return simplifiedResult; + } + + private void setColorsToPoints(List points) { + for (RouteColorizationPoint point : points) { + point.color = getColorByValue(point.val); + } + } + + public int getColorByValue(double value) { + if (Double.isNaN(value)) { + return ColorPalette.LIGHT_GREY; + } + for (int i = 0; i < palette.length - 1; i++) { + if (value == palette[i][VALUE_INDEX]) + return (int) palette[i][DECIMAL_COLOR_INDEX]; + if (value >= palette[i][VALUE_INDEX] && value <= palette[i + 1][VALUE_INDEX]) { + int minPaletteColor = (int) palette[i][DECIMAL_COLOR_INDEX]; + int maxPaletteColor = (int) palette[i + 1][DECIMAL_COLOR_INDEX]; + double minPaletteValue = palette[i][VALUE_INDEX]; + double maxPaletteValue = palette[i + 1][VALUE_INDEX]; + double percent = (value - minPaletteValue) / (maxPaletteValue - minPaletteValue); + return ColorPalette.getIntermediateColor(minPaletteColor, maxPaletteColor, percent); + } + } + if (value <= palette[0][0]) { + return (int) palette[0][1]; + } else if (value >= palette[palette.length - 1][0]) { + return (int) palette[palette.length - 1][1]; + } + return ColorPalette.getTransparentColor(); + } + + public void setPalette(double[][] palette) { + this.palette = palette; + checkPalette(); + sortPalette(); + } + + public void setPalette(int[] gradientPalette) { + if (gradientPalette == null || gradientPalette.length != 3) { + return; + } + setPalette(new double[][] { { minValue, gradientPalette[0] }, { (minValue + maxValue) / 2, gradientPalette[1] }, + { maxValue, gradientPalette[2] } }); + } + + public List simplify(int simplificationZoom) { + if (dataList == null) { + dataList = new ArrayList<>(); + for (int i = 0; i < latitudes.length; i++) { + dataList.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i])); + } + } + List nodes = new ArrayList<>(); + List result = new ArrayList<>(); + for (RouteColorizationPoint data : dataList) { + nodes.add(new net.osmand.osm.edit.Node(data.lat, data.lon, data.id)); + } + + double epsilon = Math.pow(2.0, DEFAULT_BASE - simplificationZoom); + result.add(nodes.get(0)); + OsmMapUtils.simplifyDouglasPeucker(nodes, 0, nodes.size() - 1, result, epsilon); + + List simplified = new ArrayList<>(); + for (int i = 1; i < result.size(); i++) { + int prevId = (int) result.get(i - 1).getId(); + int currentId = (int) result.get(i).getId(); + List sublist = dataList.subList(prevId, currentId); + simplified.addAll(getExtremums(sublist)); + } + Node lastSurvivedPoint = result.get(result.size() - 1); + simplified.add(dataList.get((int) lastSurvivedPoint.getId())); + return simplified; + } + + private List getExtremums(List subDataList) { + if (subDataList.size() <= 2) { + return subDataList; + } + + List result = new ArrayList<>(); + double min; + double max; + min = max = subDataList.get(0).val; + for (RouteColorizationPoint pt : subDataList) { + if (min > pt.val) { + min = pt.val; + } + if (max < pt.val) { + max = pt.val; + } + } + + double diff = max - min; + + result.add(subDataList.get(0)); + for (int i = 1; i < subDataList.size() - 1; i++) { + double prev = subDataList.get(i - 1).val; + double current = subDataList.get(i).val; + double next = subDataList.get(i + 1).val; + RouteColorizationPoint currentData = subDataList.get(i); + + if ((current > prev && current > next) || (current < prev && current < next) + || (current < prev && current == next) || (current == prev && current < next) + || (current > prev && current == next) || (current == prev && current > next)) { + RouteColorizationPoint prevInResult; + if (result.size() > 0) { + prevInResult = result.get(0); + if (prevInResult.val / diff > MIN_DIFFERENCE_SLOPE) { + result.add(currentData); + } + } else + result.add(currentData); + } + } + result.add(subDataList.get(subDataList.size() - 1)); + return result; + } + + private void checkPalette() { + if (palette == null || palette.length < 2 || palette[0].length < 2 || palette[1].length < 2) { + LOG.info("Will use default palette"); + palette = getDefaultPalette(colorizationType); + } + double min; + double max = min = palette[0][VALUE_INDEX]; + int minIndex = 0; + int maxIndex = 0; + double[][] sRGBPalette = new double[palette.length][2]; + for (int i = 0; i < palette.length; i++) { + double[] p = palette[i]; + if (p.length == 2) { + sRGBPalette[i] = p; + } else if (p.length == 4) { + int color = ColorPalette.rgbaToDecimal((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], + (int) p[BLUE_COLOR_INDEX], 255); + sRGBPalette[i] = new double[] { p[VALUE_INDEX], color }; + } else if (p.length >= 5) { + int color = ColorPalette.rgbaToDecimal((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], + (int) p[BLUE_COLOR_INDEX], (int) p[ALPHA_COLOR_INDEX]); + sRGBPalette[i] = new double[] { p[VALUE_INDEX], color }; + } + if (p[VALUE_INDEX] > max) { + max = p[VALUE_INDEX]; + maxIndex = i; + } + if (p[VALUE_INDEX] < min) { + min = p[VALUE_INDEX]; + minIndex = i; + } + } + palette = sRGBPalette; + if (minValue < min) { + palette[minIndex][VALUE_INDEX] = minValue; + } + if (maxValue > max) { + palette[maxIndex][VALUE_INDEX] = maxValue; + } + } + + private void sortPalette() { + java.util.Arrays.sort(palette, new java.util.Comparator() { + public int compare(double[] a, double[] b) { + return Double.compare(a[VALUE_INDEX], b[VALUE_INDEX]); + } + }); + } + + /** + * @return double[minElevation, maxElevation, minDist, maxDist] + */ + private double[] findDerivativeArguments(double[] distances, double[] elevations, int index, double slopeRange) { + double[] result = new double[4]; + double minDist = distances[index] - slopeRange / 2; + double maxDist = distances[index] + slopeRange / 2; + result[0] = Double.NaN; + result[1] = Double.NaN; + result[2] = minDist; + result[3] = maxDist; + int closestMaxIndex = -1; + int closestMinIndex = -1; + for (int i = index; i < distances.length; i++) { + if (distances[i] == maxDist) { + result[1] = elevations[i]; + break; + } + if (distances[i] > maxDist) { + closestMaxIndex = i; + break; + } + } + for (int i = index; i >= 0; i--) { + if (distances[i] == minDist) { + result[0] = elevations[i]; + break; + } + if (distances[i] < minDist) { + closestMinIndex = i; + break; + } + } + if (closestMaxIndex > 0) { + double diff = distances[closestMaxIndex] - distances[closestMaxIndex - 1]; + double coef = (maxDist - distances[closestMaxIndex - 1]) / diff; + if (coef > 1 || coef < 0) { + LOG.warn("Coefficient fo max must be 0..1 , coef=" + coef); + } + result[1] = (1 - coef) * elevations[closestMaxIndex - 1] + coef * elevations[closestMaxIndex]; + } + if (closestMinIndex >= 0) { + double diff = distances[closestMinIndex + 1] - distances[closestMinIndex]; + double coef = (minDist - distances[closestMinIndex]) / diff; + if (coef > 1 || coef < 0) { + LOG.warn("Coefficient for min must be 0..1 , coef=" + coef); + } + result[0] = (1 - coef) * elevations[closestMinIndex] + coef * elevations[closestMinIndex + 1]; + } + if (Double.isNaN(result[0]) || Double.isNaN(result[1])) { + LOG.warn("Elevations wasn't calculated"); + } + return result; + } + + public static double getMinValue(ColorizationType type, GPXTrackAnalysis analysis) { + switch (type) { + case SPEED: + return 0.0; + case ELEVATION: + return analysis.getMinElevation(); + case SLOPE: + return ColorPalette.SLOPE_MIN_VALUE; + default: + return -1; + } + } + + public static double getMaxValue(ColorizationType type, GPXTrackAnalysis analysis, double minValue, + double maxProfileSpeed) { + switch (type) { + case SPEED: + return Math.max(analysis.getMaxSpeed(), maxProfileSpeed); + case ELEVATION: + return Math.max(analysis.getMaxElevation(), minValue + 50); + case SLOPE: + return ColorPalette.SLOPE_MAX_VALUE; + default: + return -1; + } + } + + + private void calculateMinMaxValue() { + if (values.length == 0) + return; + minValue = maxValue = Double.NaN; + for (double value : values) { + if ((Double.isNaN(maxValue) || Double.isNaN(minValue)) && !Double.isNaN(value)) + maxValue = minValue = value; + if (minValue > value) + minValue = value; + if (maxValue < value) + maxValue = value; + } + } + + private void calculateMinMaxValue(GPXTrackAnalysis analysis, float maxProfileSpeed) { + calculateMinMaxValue(); + // set strict limitations for maxValue + maxValue = getMaxValue(colorizationType, analysis, minValue, maxProfileSpeed); + } + + private double[] listToArray(List doubleList) { + double[] result = new double[doubleList.size()]; + for (int i = 0; i < doubleList.size(); i++) { + result[i] = doubleList.get(i); + } + return result; + } + + private double[][] getDefaultPalette(ColorizationType colorizationType) { + if (colorizationType == ColorizationType.SLOPE) { + return ColorPalette.SLOPE_PALETTE; + } else { + return ColorPalette.getPaletteScale(minValue, maxValue); + } + } + + public static class RouteColorizationPoint { + public int id; + public double lat; + public double lon; + public double val; + public int color; + + public RouteColorizationPoint(int id, double lat, double lon, double val) { + this.id = id; + this.lat = lat; + this.lon = lon; + this.val = val; + } + } } diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java index 2e10509ac39..a95a903b4e0 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java @@ -3,12 +3,12 @@ import static net.osmand.util.CollectionUtils.startsWithAny; import net.osmand.CallbackWithObject; +import net.osmand.ColorPalette; import net.osmand.IProgress; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.data.LatLon; import net.osmand.data.QuadRect; -import net.osmand.router.RouteColorize; import org.apache.commons.logging.Log; import org.xmlpull.v1.XmlPullParser; @@ -1184,41 +1184,11 @@ public static boolean isValidMessageFormat(CharSequence sequence) { } public static int[] stringToGradientPalette(String str, String gradientScaleType) { - boolean isSlope = "gradient_slope_color".equals(gradientScaleType); - if (isBlank(str)) { - return isSlope ? RouteColorize.SLOPE_COLORS : RouteColorize.COLORS; - } - String[] arr = str.split(" "); - if (arr.length < 2) { - return isSlope ? RouteColorize.SLOPE_COLORS : RouteColorize.COLORS; - } - int[] colors = new int[arr.length]; - try { - for (int i = 0; i < arr.length; i++) { - colors[i] = parseColor(arr[i]); - } - } catch (IllegalArgumentException e) { - return isSlope ? RouteColorize.SLOPE_COLORS : RouteColorize.COLORS; - } - return colors; + return ColorPalette.stringToGradientPalette(str, gradientScaleType); } public static String gradientPaletteToString(int[] palette, String gradientScaleType) { - boolean isSlope = "gradient_slope_color".equals(gradientScaleType); - int[] src; - if (palette != null && palette.length >= 2) { - src = palette; - } else { - src = isSlope ? RouteColorize.SLOPE_COLORS : RouteColorize.COLORS; - } - StringBuilder stringPalette = new StringBuilder(); - for (int i = 0; i < src.length; i++) { - stringPalette.append(colorToString(src[i])); - if (i + 1 != src.length) { - stringPalette.append(" "); - } - } - return stringPalette.toString(); + return ColorPalette.gradientPaletteToString(palette, gradientScaleType); } public static boolean isUrl(String value) { From af32c018b5e5f0ec195e83e0fd37d8832dba88f0 Mon Sep 17 00:00:00 2001 From: chumv Date: Mon, 20 May 2024 18:12:27 +0300 Subject: [PATCH 23/33] Clear copy-pasted code for resume/pause navigation --- OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 7 +-- .../net/osmand/plus/NavigationService.java | 63 ++++++++++--------- .../dashboard/DashNavigationFragment.java | 9 +-- .../plus/helpers/ExternalApiHelper.java | 7 +-- .../notifications/NavigationNotification.java | 15 ++--- .../actions/NavResumePauseAction.java | 10 +-- .../osmand/plus/routing/RoutingHelper.java | 14 ++++- 7 files changed, 59 insertions(+), 66 deletions(-) diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 9ad5a302769..22c4e80c1bb 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -779,9 +779,7 @@ public void onReceive(Context context, Intent intent) { if (mapActivity != null) { RoutingHelper routingHelper = mapActivity.getRoutingHelper(); if (routingHelper.isRouteCalculated() && !routingHelper.isRoutePlanningMode()) { - routingHelper.setRoutePlanningMode(true); - routingHelper.setFollowingMode(false); - routingHelper.setPauseNavigation(true); + routingHelper.pauseNavigation(); } } } @@ -798,8 +796,7 @@ public void onReceive(Context context, Intent intent) { if (mapActivity != null) { RoutingHelper routingHelper = mapActivity.getRoutingHelper(); if (routingHelper.isRouteCalculated() && routingHelper.isRoutePlanningMode()) { - routingHelper.setRoutePlanningMode(false); - routingHelper.setFollowingMode(true); + routingHelper.resumeNavigation(); AndroidUtils.requestNotificationPermissionIfNeeded(mapActivity); } } diff --git a/OsmAnd/src/net/osmand/plus/NavigationService.java b/OsmAnd/src/net/osmand/plus/NavigationService.java index b9ae52966c4..790f4b445f1 100644 --- a/OsmAnd/src/net/osmand/plus/NavigationService.java +++ b/OsmAnd/src/net/osmand/plus/NavigationService.java @@ -1,5 +1,8 @@ package net.osmand.plus; +import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION; +import static net.osmand.plus.notifications.OsmandNotification.TOP_NOTIFICATION_SERVICE_ID; + import android.app.Notification; import android.app.Service; import android.content.Context; @@ -26,7 +29,6 @@ import net.osmand.plus.auto.screens.NavigationScreen; import net.osmand.plus.helpers.LocationCallback; import net.osmand.plus.helpers.LocationServiceHelper; -import net.osmand.plus.notifications.OsmandNotification; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.enums.LocationSource; @@ -51,6 +53,7 @@ public static class NavigationServiceBinder extends Binder { private final NavigationServiceBinder binder = new NavigationServiceBinder(); private OsmandSettings settings; + private RoutingHelper routingHelper; protected int usedBy; private OsmAndLocationProvider locationProvider; @@ -76,8 +79,8 @@ public boolean isUsed() { return usedBy != 0; } - public boolean isUsedByNavigation() { - return (usedBy & USED_BY_NAVIGATION) == USED_BY_NAVIGATION; + public boolean isUsedBy(int type) { + return (usedBy & type) == type; } public void addUsageIntent(int usageIntent) { @@ -88,7 +91,7 @@ public void stopIfNeeded(@NonNull Context context, int usageIntent) { if ((usedBy & usageIntent) > 0) { usedBy -= usageIntent; } - if (!isUsedByNavigation()) { + if (!isUsedBy(USED_BY_NAVIGATION)) { stopCarNavigation(); } if (usageIntent == USED_BY_CAR_APP) { @@ -111,6 +114,7 @@ private OsmandApplication getApp() { public int onStartCommand(Intent intent, int flags, int startId) { OsmandApplication app = getApp(); settings = app.getSettings(); + routingHelper = app.getRoutingHelper(); usedBy = intent.getIntExtra(USAGE_INTENT, 0); locationProvider = app.getLocationProvider(); @@ -123,29 +127,29 @@ public int onStartCommand(Intent intent, int flags, int startId) { } Notification notification = app.getNotificationHelper().buildTopNotification(); - if (notification != null) { - if (isUsedByNavigation()) { + boolean hasNotification = notification != null; + if (hasNotification) { + if (isUsedBy(USED_BY_NAVIGATION)) { startCarNavigation(); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - startForeground(OsmandNotification.TOP_NOTIFICATION_SERVICE_ID, notification, android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION); + startForeground(TOP_NOTIFICATION_SERVICE_ID, notification, FOREGROUND_SERVICE_TYPE_LOCATION); } else { - startForeground(OsmandNotification.TOP_NOTIFICATION_SERVICE_ID, notification); + startForeground(TOP_NOTIFICATION_SERVICE_ID, notification); } app.getNotificationHelper().refreshNotifications(); } else { notification = app.getNotificationHelper().buildErrorNotification(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - startForeground(OsmandNotification.TOP_NOTIFICATION_SERVICE_ID, notification, android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION); + startForeground(TOP_NOTIFICATION_SERVICE_ID, notification, FOREGROUND_SERVICE_TYPE_LOCATION); } else { - startForeground(OsmandNotification.TOP_NOTIFICATION_SERVICE_ID, notification); + startForeground(TOP_NOTIFICATION_SERVICE_ID, notification); } stopSelf(); - return START_NOT_STICKY; } requestLocationUpdates(); - return START_REDELIVER_INTENT; + return hasNotification ? START_REDELIVER_INTENT : START_NOT_STICKY; } @Override @@ -234,25 +238,23 @@ public void setCarContext(@Nullable CarContext carContext) { if (carContext != null) { this.tripHelper = new TripHelper(getApp()); this.navigationManager = carContext.getCarService(NavigationManager.class); - this.navigationManager.setNavigationManagerCallback( - new NavigationManagerCallback() { - @Override - public void onStopNavigation() { - getApp().stopNavigation(); - } - - @Override - public void onAutoDriveEnabled() { - CarToast.makeText(carContext, "Auto drive enabled", CarToast.LENGTH_LONG).show(); - if (!settings.simulateNavigation) { - OsmAndLocationSimulation sim = getApp().getLocationProvider().getLocationSimulation(); - sim.startStopRouteAnimation(null); - settings.simulateNavigation = true; - settings.simulateNavigationStartedFromAdb = true; - } - } - }); + this.navigationManager.setNavigationManagerCallback(new NavigationManagerCallback() { + @Override + public void onStopNavigation() { + getApp().stopNavigation(); + } + @Override + public void onAutoDriveEnabled() { + CarToast.makeText(carContext, "Auto drive enabled", CarToast.LENGTH_LONG).show(); + if (!settings.simulateNavigation) { + OsmAndLocationSimulation sim = getApp().getLocationProvider().getLocationSimulation(); + sim.startStopRouteAnimation(null); + settings.simulateNavigation = true; + settings.simulateNavigationStartedFromAdb = true; + } + } + }); // Uncomment if navigating // mNavigationManager.navigationStarted(); } else { @@ -301,7 +303,6 @@ public void stopCarNavigation() { public void updateCarNavigation(Location currentLocation) { OsmandApplication app = getApp(); - RoutingHelper routingHelper = app.getRoutingHelper(); TripHelper tripHelper = this.tripHelper; if (carNavigationActive && tripHelper != null && routingHelper.isRouteCalculated() && routingHelper.isFollowingMode()) { diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashNavigationFragment.java b/OsmAnd/src/net/osmand/plus/dashboard/DashNavigationFragment.java index 776811053a4..cc7b8a5f24f 100644 --- a/OsmAnd/src/net/osmand/plus/dashboard/DashNavigationFragment.java +++ b/OsmAnd/src/net/osmand/plus/dashboard/DashNavigationFragment.java @@ -117,13 +117,10 @@ private void updatePlayButton(RoutingHelper routingHelper, MapActivity map, Imag play.setContentDescription(getString(toContinueNavigation ? R.string.continue_navigation : R.string.pause_navigation)); play.setOnClickListener(v -> { - if(routingHelper.isRoutePlanningMode()) { - routingHelper.setRoutePlanningMode(false); - routingHelper.setFollowingMode(true); + if (routingHelper.isRoutePlanningMode()) { + routingHelper.resumeNavigation(); } else { - routingHelper.setRoutePlanningMode(true); - routingHelper.setFollowingMode(false); - routingHelper.setPauseNavigation(true); + routingHelper.pauseNavigation(); } updatePlayButton(routingHelper, map, play); AndroidUtils.requestNotificationPermissionIfNeeded(map); diff --git a/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java index 254204f07cc..a127f36955b 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java @@ -380,16 +380,13 @@ public void onDismiss(DialogInterface dialog) { } else if (API_CMD_PAUSE_NAVIGATION.equals(cmd)) { RoutingHelper routingHelper = mapActivity.getRoutingHelper(); if (routingHelper.isRouteCalculated() && !routingHelper.isRoutePlanningMode()) { - routingHelper.setRoutePlanningMode(true); - routingHelper.setFollowingMode(false); - routingHelper.setPauseNavigation(true); + routingHelper.pauseNavigation(); resultCode = Activity.RESULT_OK; } } else if (API_CMD_RESUME_NAVIGATION.equals(cmd)) { RoutingHelper routingHelper = mapActivity.getRoutingHelper(); if (routingHelper.isRouteCalculated() && routingHelper.isRoutePlanningMode()) { - routingHelper.setRoutePlanningMode(false); - routingHelper.setFollowingMode(true); + routingHelper.resumeNavigation(); AndroidUtils.requestNotificationPermissionIfNeeded(mapActivity); resultCode = Activity.RESULT_OK; } diff --git a/OsmAnd/src/net/osmand/plus/notifications/NavigationNotification.java b/OsmAnd/src/net/osmand/plus/notifications/NavigationNotification.java index 43fc87d99b3..e5c1e19f343 100644 --- a/OsmAnd/src/net/osmand/plus/notifications/NavigationNotification.java +++ b/OsmAnd/src/net/osmand/plus/notifications/NavigationNotification.java @@ -25,17 +25,17 @@ import net.osmand.Location; import net.osmand.plus.NavigationService; -import net.osmand.plus.utils.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.helpers.TargetPointsHelper.TargetPoint; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.auto.NavigationCarAppService; import net.osmand.plus.auto.NavigationSession; +import net.osmand.plus.helpers.TargetPointsHelper.TargetPoint; import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.utils.OsmAndFormatter; import net.osmand.plus.views.mapwidgets.TurnDrawable; import net.osmand.router.TurnType; import net.osmand.util.Algorithms; @@ -62,13 +62,9 @@ public NavigationNotification(OsmandApplication app) { public void init() { leftSide = app.getSettings().DRIVING_REGION.get().leftHandDriving; app.registerReceiver(new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - RoutingHelper routingHelper = app.getRoutingHelper(); - routingHelper.setRoutePlanningMode(true); - routingHelper.setFollowingMode(false); - routingHelper.setPauseNavigation(true); + app.getRoutingHelper().pauseNavigation(); } }, new IntentFilter(OSMAND_PAUSE_NAVIGATION_SERVICE_ACTION)); @@ -76,10 +72,7 @@ public void onReceive(Context context, Intent intent) { @Override public void onReceive(Context context, Intent intent) { - RoutingHelper routingHelper = app.getRoutingHelper(); - routingHelper.setRoutePlanningMode(false); - routingHelper.setFollowingMode(true); - routingHelper.setCurrentLocation(getLastKnownLocation(), false); + app.getRoutingHelper().resumeNavigation(); } }, new IntentFilter(OSMAND_RESUME_NAVIGATION_SERVICE_ACTION)); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/NavResumePauseAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/NavResumePauseAction.java index b6e2609b3f5..e6898fd8c5a 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/NavResumePauseAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/NavResumePauseAction.java @@ -21,7 +21,7 @@ public class NavResumePauseAction extends QuickAction { public static final QuickActionType TYPE = new QuickActionType(NAV_RESUME_PAUSE_ACTION_ID, - "nav.resumepause", NavResumePauseAction .class). + "nav.resumepause", NavResumePauseAction.class). nameRes(R.string.quick_action_resume_pause_navigation).iconRes(R.drawable.ic_play_dark).nonEditable(). category(QuickActionType.NAVIGATION); @@ -38,13 +38,9 @@ public NavResumePauseAction(QuickAction quickAction) { public void execute(@NonNull MapActivity mapActivity) { RoutingHelper routingHelper = mapActivity.getRoutingHelper(); if (routingHelper.isRoutePlanningMode()) { - routingHelper.setRoutePlanningMode(false); - routingHelper.setFollowingMode(true); - routingHelper.setCurrentLocation(mapActivity.getMyApplication().getLocationProvider().getLastKnownLocation(), false); + routingHelper.resumeNavigation(); } else { - routingHelper.setRoutePlanningMode(true); - routingHelper.setFollowingMode(false); - routingHelper.setPauseNavigation(true); + routingHelper.pauseNavigation(); } AndroidUtils.requestNotificationPermissionIfNeeded(mapActivity); mapActivity.getMapViewTrackingUtilities().switchRoutePlanningMode(); diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index 6435e669d63..c3697f77cba 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -3,13 +3,13 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.osmand.gpx.GPXFile; import net.osmand.Location; import net.osmand.LocationsHolder; import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; import net.osmand.data.LatLon; import net.osmand.data.ValueHolder; +import net.osmand.gpx.GPXFile; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -147,6 +147,18 @@ public String getLastRouteCalcErrorShort() { return routeRecalculationHelper.getLastRouteCalcErrorShort(); } + public void resumeNavigation() { + setRoutePlanningMode(false); + setFollowingMode(true); + setCurrentLocation(app.getLocationProvider().getLastKnownLocation(), false); + } + + public void pauseNavigation() { + setRoutePlanningMode(true); + setFollowingMode(false); + setPauseNavigation(true); + } + public void setPauseNavigation(boolean pause) { app.logRoutingEvent("setPauseNavigation pause " + pause); this.isPauseNavigation = pause; From 4ca2312b5423fad0d07d4f7d8a4e091dfc3cd1c2 Mon Sep 17 00:00:00 2001 From: chumv Date: Mon, 20 May 2024 18:12:56 +0300 Subject: [PATCH 24/33] Fix #19651 --- OsmAnd/src/net/osmand/plus/NavigationService.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/NavigationService.java b/OsmAnd/src/net/osmand/plus/NavigationService.java index 790f4b445f1..0ac82b9aa08 100644 --- a/OsmAnd/src/net/osmand/plus/NavigationService.java +++ b/OsmAnd/src/net/osmand/plus/NavigationService.java @@ -149,6 +149,11 @@ public int onStartCommand(Intent intent, int flags, int startId) { } requestLocationUpdates(); + if (isUsedBy(USED_BY_CAR_APP)) { + if (routingHelper.isRouteCalculated() && routingHelper.isPauseNavigation()) { + routingHelper.resumeNavigation(); + } + } return hasNotification ? START_REDELIVER_INTENT : START_NOT_STICKY; } @@ -241,7 +246,11 @@ public void setCarContext(@Nullable CarContext carContext) { this.navigationManager.setNavigationManagerCallback(new NavigationManagerCallback() { @Override public void onStopNavigation() { - getApp().stopNavigation(); + if (routingHelper.isRouteCalculated() && routingHelper.isFollowingMode()) { + routingHelper.pauseNavigation(); + } else { + getApp().stopNavigation(); + } } @Override From b22bdbdf84cabc69adf98e06d3be8f7cf08e76a8 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 20 May 2024 18:27:42 +0300 Subject: [PATCH 25/33] Fix compilation --- OsmAnd/src/net/osmand/plus/track/CachedTrack.java | 2 +- .../plus/views/layers/PreviewRouteLineLayer.java | 12 ++++++------ .../layers/geometry/MultiColoringGeometryWay.java | 5 +++-- .../geometry/MultiColoringGeometryWayDrawer.java | 3 ++- .../plus/views/layers/geometry/RouteGeometryWay.java | 3 ++- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/track/CachedTrack.java b/OsmAnd/src/net/osmand/plus/track/CachedTrack.java index 15a65d596d9..073cefcf1f9 100644 --- a/OsmAnd/src/net/osmand/plus/track/CachedTrack.java +++ b/OsmAnd/src/net/osmand/plus/track/CachedTrack.java @@ -1,7 +1,7 @@ package net.osmand.plus.track; import static net.osmand.plus.routing.ColoringStyleAlgorithms.isAvailableForDrawingTrack; -import static net.osmand.router.RouteColorize.LIGHT_GREY; +import static net.osmand.ColorPalette.LIGHT_GREY; import androidx.annotation.NonNull; import androidx.annotation.Nullable; diff --git a/OsmAnd/src/net/osmand/plus/views/layers/PreviewRouteLineLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/PreviewRouteLineLayer.java index 0ca209415ec..7c5f55eb90a 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/PreviewRouteLineLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/PreviewRouteLineLayer.java @@ -12,6 +12,7 @@ import android.graphics.Rect; import android.graphics.drawable.LayerDrawable; +import net.osmand.ColorPalette; import net.osmand.PlatformUtil; import net.osmand.data.QuadPoint; import net.osmand.data.RotatedTileBox; @@ -33,7 +34,6 @@ import net.osmand.router.RouteColorize; import net.osmand.router.RouteStatisticsHelper; import net.osmand.util.Algorithms; -import net.osmand.util.MapUtils; import org.apache.commons.logging.Log; @@ -199,7 +199,7 @@ private void fillPreviewLineArrays(List points) { private void fillAltitudeGradientArrays(List points) { - int[] colors = RouteColorize.COLORS; + int[] colors = ColorPalette.COLORS; GeometryGradientWayStyle style = null; for (int i = 1; i < points.size(); i++) { style = previewLineGeometry.getGradientWayStyle(); @@ -215,7 +215,7 @@ private void fillAltitudeGradientArrays(List points) { private void fillSlopeGradientArrays(List points) { List palette = new ArrayList<>(); - for (int color : RouteColorize.SLOPE_COLORS) { + for (int color : ColorPalette.SLOPE_COLORS) { palette.add(color); } List gradientLengthsRatio = Arrays.asList(0.145833, 0.130209, 0.291031); @@ -234,7 +234,7 @@ private void fillSlopeGradientArrays(List points) { style.nextColor = colors.get(i); } else { double coeff = currDist / (currDist + nextDist); - style.nextColor = RouteColorize.getIntermediateColor(colors.get(i - 1), colors.get(i + 1), coeff); + style.nextColor = ColorPalette.getIntermediateColor(colors.get(i - 1), colors.get(i + 1), coeff); } } points.get(points.size() - 1).style = points.get(points.size() - 2).style; @@ -433,7 +433,7 @@ private int getPreviewColor(int[] colors, int index, double coeff) { if (index == 0) { return colors[0]; } else if (index > 0 && index < colors.length) { - return RouteColorize.getIntermediateColor(colors[index - 1], colors[index], coeff); + return ColorPalette.getIntermediateColor(colors[index - 1], colors[index], coeff); } else if (index == colors.length) { return colors[index - 1]; } @@ -526,7 +526,7 @@ private int getTurnArrowColor(@NonNull List arrowPointsX, GeometryGradientWayStyle gradientStyle = (GeometryGradientWayStyle) (style); int startColor = gradientStyle.currColor; int endColor = gradientStyle.nextColor; - lineColor = RouteColorize.getIntermediateColor(startColor, endColor, offset); + lineColor = ColorPalette.getIntermediateColor(startColor, endColor, offset); } else { lineColor = style.getColor(getRouteLineColor()); } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWay.java index 8ae7125ad7c..b8c04432a23 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWay.java @@ -7,6 +7,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.ColorPalette; import net.osmand.Location; import net.osmand.data.LatLon; import net.osmand.data.RotatedTileBox; @@ -178,7 +179,7 @@ private List getRouteInfoAttributesColors(List locations, Lis RouteSegmentAttribute attribute = statisticComputer.classifySegment(routeInfoAttribute, -1, segment.getObject()); int color = attribute.getColor(); - color = color == 0 ? RouteColorize.LIGHT_GREY : color; + color = color == 0 ? net.osmand.ColorPalette.LIGHT_GREY : color; if (i == 0) { for (int j = 0; j < firstSegmentLocationIdx; j++) { @@ -271,7 +272,7 @@ protected boolean addInitialPoint(RotatedTileBox tb, double topLatitude, double double percent = MapUtils.getProjectionCoeff(currLat, currLon, prevLat, prevLon, nextLat, nextLon); int prevColor = locationProvider.getColor(startLocationIndex - 1); int nextColor = locationProvider.getColor(startLocationIndex); - gradientWayStyle.currColor = RouteColorize.getIntermediateColor(prevColor, nextColor, percent); + gradientWayStyle.currColor = ColorPalette.getIntermediateColor(prevColor, nextColor, percent); gradientWayStyle.nextColor = nextColor; } } else if (coloringType.isRouteInfoAttribute() && style instanceof GeometrySolidWayStyle) { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWayDrawer.java index bf79f595091..ee3ed57fc5a 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWayDrawer.java @@ -15,6 +15,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.ColorPalette; import net.osmand.core.jni.QListFColorARGB; import net.osmand.core.jni.VectorLinesCollection; import net.osmand.plus.routing.ColoringType; @@ -267,7 +268,7 @@ private void drawCircle(Canvas canvas, GeometrySolidWayStyle style) { private int getCircleColor(@NonNull GeometrySolidWayStyle style) { if (style instanceof GeometryGradientWayStyle) { GeometryGradientWayStyle gradientStyle = ((GeometryGradientWayStyle) style); - return RouteColorize.getIntermediateColor(gradientStyle.currColor, gradientStyle.nextColor, percent); + return ColorPalette.getIntermediateColor(gradientStyle.currColor, gradientStyle.nextColor, percent); } return style.getColor(0); } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java index 3dbdb63e809..b45527bfcff 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java @@ -4,6 +4,7 @@ import android.graphics.Canvas; import android.graphics.Paint; +import net.osmand.ColorPalette; import net.osmand.Location; import net.osmand.core.android.MapRendererView; import net.osmand.core.jni.PointI; @@ -435,7 +436,7 @@ private Integer getActionPointColor(@NonNull ActionPoint actionPoint) { } else { int startColor = gradientStyle.currColor; int endColor = gradientStyle.nextColor; - return RouteColorize.getIntermediateColor(startColor, endColor, actionPoint.normalizedOffset); + return ColorPalette.getIntermediateColor(startColor, endColor, actionPoint.normalizedOffset); } } else { return style.getColor(); From 5cb24de2441d97abd14a2d6807cb2aeace3ffd86 Mon Sep 17 00:00:00 2001 From: 99 efi Date: Mon, 20 May 2024 15:07:02 +0000 Subject: [PATCH 26/33] Translated using Weblate (Hungarian) Currently translated at 100.0% (5102 of 5102 strings) --- OsmAnd/res/values-hu/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index 7370e095f0d..87a031216fc 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -5722,4 +5722,6 @@ Macskakő elkerülése A skála értékének változtatásával módosíthatja a 3D nyomvonal magasságát. lépés/p + Tiltsa le az összes térképréteget a vektortérkép felett (újraindítás szükséges). + Térképrétegek letiltása \ No newline at end of file From 893643f43c6d587815ffd8ee42aba869176f6b8c Mon Sep 17 00:00:00 2001 From: Hotripak Date: Mon, 20 May 2024 08:57:53 +0000 Subject: [PATCH 27/33] Translated using Weblate (Ukrainian) Currently translated at 100.0% (5102 of 5102 strings) --- OsmAnd/res/values-uk/strings.xml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 1c2ca59d624..1842df64894 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -3238,7 +3238,7 @@ Надати перевагу дорогам без покриття. Правки OSM Увімк/вимк показ ізоліній на мапі. - Кнопка, що показує чи приховує рельєф на мапі. + Кнопка, щоб показати або приховати тінь на мапі. Не вдається запустити рушій TTS. Симуляція положення за допомогою записаного треку GPX. Експорт профілю @@ -5024,7 +5024,7 @@ Звуковий сигнал: простий гучний Звуковий сигнал: простий Востаннє синхронізовано - Залежить від орієнтації мапи: внизу — для орієнтації мапи за напрямком руху, по центру — для всіх інших. + Залежить від орієнтації мапи: внизу - для напрямку руху, в центрі - для всіх інших. Застосувати зміни Виберіть треки, щоб показати їх на мапі. За допомогою OsmAnd ви можете імпортувати, створювати або записувати файли треків. @@ -5082,7 +5082,7 @@ \n \n Додати вручну… - Спочатку менш тривалі + Спочатку найкоротша тривалість Спочатку більш тривалі Спочатку найкоротші Спочатку найдовші @@ -5216,7 +5216,7 @@ Не записано Новий трек Показати на мапі - Теку \"%1$s\" буде вилучено разом з усіма треками (%2$s) в ній. + Теку \"%1$s\" буде видалено разом з усіма доріжками %2$s, що в ній містяться. Вилучити теку\? Вилучити теку Датчиків не знайдено @@ -5388,7 +5388,7 @@ Кнопки мапи Віджети позначок Навігаційні віджети - Радіусна лінійка та лінійка + Радіус-лінійка та лінійка Містить лише дані про збої Ставте запитання, пропонуйте функції Відкрити обговорення на GitHub @@ -5461,7 +5461,7 @@ Назва відсутня Змінити фільтр Зберегти як розумну теку - Це видалить розумну теку \"%1$s\". + Це призведе до вилучення розумної папки \"%1$s\". Вкажіть інтервал часу для усереднення ковзання. • Android Auto: Додано 3D-режим \n @@ -5732,4 +5732,7 @@ Тексти мап Уникайте бруківки Уникайте бруківки + Вимкнути шари мапи + Вимкнути всі шари мапи над векторною мапою (потрібен перезапуск). + СПК \ No newline at end of file From 4eb6f0588738f0a84752b68776b6d1efa8942175 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 20 May 2024 22:10:48 +0300 Subject: [PATCH 28/33] Add colorizations to use user palettes --- .../main/java/net/osmand/ColorPalette.java | 300 ++++++++++-------- .../java/net/osmand/router/RouteColorize.java | 160 +++------- .../main/java/net/osmand/util/Algorithms.java | 8 - OsmAnd/assets/bundled_assets.xml | 4 + .../net/osmand/plus/track/CachedTrack.java | 20 +- .../geometry/MultiColoringGeometryWay.java | 18 +- .../layers/geometry/RouteGeometryWay.java | 2 - 7 files changed, 253 insertions(+), 259 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/ColorPalette.java b/OsmAnd-java/src/main/java/net/osmand/ColorPalette.java index 5f502ad7d2d..2ff96c09910 100644 --- a/OsmAnd-java/src/main/java/net/osmand/ColorPalette.java +++ b/OsmAnd-java/src/main/java/net/osmand/ColorPalette.java @@ -5,133 +5,151 @@ import java.io.IOException; import java.io.Reader; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.apache.commons.logging.Log; -import net.osmand.util.Algorithms; - - public class ColorPalette { private static final Log LOG = PlatformUtil.getLog(ColorPalette.class); - - public static final int DARK_GREY = rgbaToDecimal(92, 92, 92, 255); - public static final int LIGHT_GREY = rgbaToDecimal(200, 200, 200, 255); - public static final int GREEN = rgbaToDecimal(90, 220, 95, 255); - public static final int YELLOW = rgbaToDecimal(212, 239, 50, 255); - public static final int RED = rgbaToDecimal(243, 55, 77, 255); - public static final int BLUE_SLOPE = rgbaToDecimal(0, 0, 255, 255); - public static final int CYAN_SLOPE = rgbaToDecimal(0, 255, 255, 255); - public static final int GREEN_SLOPE = rgbaToDecimal(46, 185, 0, 255); - public static final int WHITE = rgbaToDecimal(255, 255, 255, 255); - public static final int YELLOW_SLOPE = rgbaToDecimal(255, 222, 2, 255); - public static final int RED_SLOPE = rgbaToDecimal(255, 1, 1, 255); - public static final int PURPLE_SLOPE = rgbaToDecimal(130, 1, 255, 255); - - public static final int[] COLORS = new int[] {GREEN, YELLOW, RED}; - public static final int[] SLOPE_COLORS = new int[] {CYAN_SLOPE, GREEN_SLOPE, LIGHT_GREY, YELLOW_SLOPE, RED_SLOPE}; - - public static final double SLOPE_MIN_VALUE = -1.00;//-100% - public static final double SLOPE_MAX_VALUE = 1.0;//100% - //public static final double[][] SLOPE_PALETTE = {{SLOPE_MIN_VALUE, GREEN_SLOPE}, {0.0, WHITE}, {0.125, YELLOW_SLOPE}, {0.25, RED_SLOPE}, {SLOPE_MAX_VALUE, PURPLE_SLOPE}}; - public static final double[][] SLOPE_PALETTE = {{SLOPE_MIN_VALUE, BLUE_SLOPE}, {-0.15, CYAN_SLOPE}, {-0.05, GREEN_SLOPE}, {0.0, LIGHT_GREY}, {0.05, YELLOW_SLOPE}, {0.15, RED_SLOPE}, {SLOPE_MAX_VALUE, PURPLE_SLOPE}}; - - public static int rgbaToDecimal(int r, int g, int b, int a) { - int value = ((a & 0xFF) << 24) | - ((r & 0xFF) << 16) | - ((g & 0xFF) << 8) | - ((b & 0xFF) << 0); - return value; - } - - private static int getRed(int value) { - return (value >> 16) & 0xFF; - } - - private static int getGreen(int value) { - return (value >> 8) & 0xFF; - } - - private static int getBlue(int value) { - return (value >> 0) & 0xFF; - } - - private static int getAlpha(int value) { - return (value >> 24) & 0xff; - } - - public static int getTransparentColor() { - return rgbaToDecimal(0, 0, 0, 0); + + public static final int DARK_GREY = rgbaToDecimal(92, 92, 92, 255); + public static final int LIGHT_GREY = rgbaToDecimal(200, 200, 200, 255); + public static final int GREEN = rgbaToDecimal(90, 220, 95, 255); + public static final int YELLOW = rgbaToDecimal(212, 239, 50, 255); + public static final int RED = rgbaToDecimal(243, 55, 77, 255); + public static final int BLUE_SLOPE = rgbaToDecimal(0, 0, 255, 255); + public static final int CYAN_SLOPE = rgbaToDecimal(0, 255, 255, 255); + public static final int GREEN_SLOPE = rgbaToDecimal(46, 185, 0, 255); + public static final int WHITE = rgbaToDecimal(255, 255, 255, 255); + public static final int YELLOW_SLOPE = rgbaToDecimal(255, 222, 2, 255); + public static final int RED_SLOPE = rgbaToDecimal(255, 1, 1, 255); + public static final int PURPLE_SLOPE = rgbaToDecimal(130, 1, 255, 255); + + public static final int[] COLORS = new int[] { GREEN, YELLOW, RED }; + public static final int[] SLOPE_COLORS = new int[] { CYAN_SLOPE, GREEN_SLOPE, LIGHT_GREY, YELLOW_SLOPE, RED_SLOPE }; + + public static final double SLOPE_MIN_VALUE = -1.00;// -100% + public static final double SLOPE_MAX_VALUE = 1.0;// 100% + + public static final ColorPalette SLOPE_PALETTE = parsePalette(new double[][] { { SLOPE_MIN_VALUE, BLUE_SLOPE }, + { -0.15, CYAN_SLOPE }, { -0.05, GREEN_SLOPE }, { 0.0, LIGHT_GREY }, { 0.05, YELLOW_SLOPE }, + { 0.15, RED_SLOPE }, { SLOPE_MAX_VALUE, PURPLE_SLOPE } }); + public static final ColorPalette MIN_MAX_PALETTE = parsePalette( + new double[][] { { 0, GREEN }, { 0.5, YELLOW }, { 1, RED } }); + + List colors = new ArrayList<>(); + + public ColorPalette() { } - - public static int getIntermediateColor(int minPaletteColor, int maxPaletteColor, double percent) { - double resultRed = getRed(minPaletteColor) + percent * (getRed(maxPaletteColor) - getRed(minPaletteColor)); - double resultGreen = getGreen(minPaletteColor) - + percent * (getGreen(maxPaletteColor) - getGreen(minPaletteColor)); - double resultBlue = getBlue(minPaletteColor) + percent * (getBlue(maxPaletteColor) - getBlue(minPaletteColor)); - double resultAlpha = getAlpha(minPaletteColor) - + percent * (getAlpha(maxPaletteColor) - getAlpha(minPaletteColor)); - return rgbaToDecimal((int) resultRed, (int) resultGreen, (int) resultBlue, (int) resultAlpha); + + // Scale palette to min / max value from (0, 1) + public ColorPalette(ColorPalette c, double minVal, double maxVal) { + for (ColorValue cv : c.colors) { + double val = cv.val * (maxVal - minVal) + minVal; + colors.add(new ColorValue(val, cv.clr)); + } } - public static double[][] getPaletteScale(double minValue, double maxValue) { - return new double[][] { { minValue, GREEN }, { (minValue + maxValue) / 2, YELLOW }, { maxValue, RED } }; + public List getColors() { + return colors; } - - public static int[] stringToGradientPalette(String str, String gradientScaleType) { - boolean isSlope = "gradient_slope_color".equals(gradientScaleType); - if (Algorithms.isBlank(str)) { - return isSlope ? SLOPE_COLORS : COLORS; - } - String[] arr = str.split(" "); - if (arr.length < 2) { - return isSlope ? SLOPE_COLORS : COLORS; + + public static int rgbaToDecimal(int r, int g, int b, int a) { + int value = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) << 0); + return value; + } + + public int getColorByValue(double value) { + if (Double.isNaN(value)) { + return ColorPalette.LIGHT_GREY; } - int[] colors = new int[arr.length]; - try { - for (int i = 0; i < arr.length; i++) { - colors[i] = Algorithms.parseColor(arr[i]); + for (int i = 0; i < colors.size() - 1; i++) { + ColorValue min = colors.get(i); + ColorValue max = colors.get(i + 1); + if (value == min.val) + return min.clr; + if (value >= min.val && value <= max.val) { + double percent = (value - min.val) / (max.val - min.val); + return getIntermediateColor(min, max, percent); } - } catch (IllegalArgumentException e) { - return isSlope ? SLOPE_COLORS :COLORS; } - return colors; + if (value <= colors.get(0).val) { + return colors.get(0).clr; + } else if (value >= colors.get(colors.size() - 1).val) { + return colors.get(colors.size() - 1).clr; + } + return ColorPalette.getTransparentColor(); } - public static String gradientPaletteToString(int[] palette, String gradientScaleType) { - boolean isSlope = "gradient_slope_color".equals(gradientScaleType); - int[] src; - if (palette != null && palette.length >= 2) { - src = palette; - } else { - src = isSlope ? SLOPE_COLORS : COLORS; - } - StringBuilder stringPalette = new StringBuilder(); - for (int i = 0; i < src.length; i++) { - stringPalette.append(Algorithms.colorToString(src[i])); - if (i + 1 != src.length) { - stringPalette.append(" "); - } + private int getIntermediateColor(ColorValue min, ColorValue max, double percent) { + double r = min.r + percent * (max.r - min.r); + double g = min.g + percent * (max.g - min.g); + double b = min.b + percent * (max.b - min.b); + double a = min.a + percent * (max.a - min.a); + return rgbaToDecimal((int) r, (int) g, (int) b, (int) a); + } + + public static int getIntermediateColor(int min, int max, double percent) { + double r = red(min) + percent * (red(max) - red(min)); + double g = green(min) + percent * (green(max) - green(min)); + double b = blue(min) + percent * (blue(max) - blue(min)); + double a = alpha(min) + percent * (alpha(max) - alpha(min)); + return rgbaToDecimal((int) r, (int) g, (int) b, (int) a); + } + + @Override + public String toString() { + return writeColorPalette(); + } + + public String writeColorPalette() { + StringBuilder bld = new StringBuilder(); + for (ColorValue v : colors) { + bld.append(v.val).append(","); + bld.append(v.r).append(",").append(v.g).append(",").append(v.b).append(",").append(v.a).append("\n"); } - return stringPalette.toString(); + return bld.toString().trim(); } + private void sortPalette() { + Collections.sort(colors, new java.util.Comparator() { + public int compare(ColorValue a, ColorValue b) { + return Double.compare(a.val, b.val); + } + }); + } + public static class ColorValue { - int r; - int g; - int b; - int a; - double val; - + public final int r; + public final int g; + public final int b; + public final int a; + public final double val; + public final int clr; + + public ColorValue(double val, int r, int g, int b, int a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + this.clr = rgbaToDecimal(r, g, b, a); + this.val = val; + } + + public ColorValue(double val, int clr) { + this.r = red(clr); + this.g = green(clr); + this.b = blue(clr); + this.a = alpha(clr); + this.clr = clr; + this.val = val; + } + public static ColorValue rgba(double val, int r, int g, int b, int a) { - ColorValue clr = new ColorValue(); - clr.r = r; - clr.g = g; - clr.b = b; - clr.a = a; - clr.val = val; + ColorValue clr = new ColorValue(val, r, g, b, a); return clr; } @@ -139,20 +157,31 @@ public static ColorValue rgba(double val, int r, int g, int b, int a) { public String toString() { return "ColorValue [r=" + r + ", g=" + g + ", b=" + b + ", a=" + a + ", val=" + val + "]"; } - + } - - public static String writeColorPalette(List palette) throws IOException { - StringBuilder bld = new StringBuilder(); - for (ColorValue v : palette) { - bld.append(v.val).append(",").append(v.r).append(",").append(v.g).append(",").append(v.b).append(",") - .append(v.a).append("\n"); + + public static ColorPalette parsePalette(double[]... vl) { + ColorPalette palette = new ColorPalette(); + for (double[] v : vl) { + ColorValue c = null; + if (v.length == 2) { + c = new ColorValue(v[0], (int) v[1]); + } else if (v.length == 4) { + c = new ColorValue(v[0], (int) v[1], (int) v[2], (int) v[3], 255); + } else if (v.length >= 5) { + c = new ColorValue(v[0], (int) v[1], (int) v[2], (int) v[3], (int) v[4]); + } + if (c != null) { + palette.colors.add(c); + } } - return bld.toString().trim(); + palette.sortPalette(); + return palette; } - public static List parseColorPalette(Reader reader) throws IOException { - List palette = new ArrayList<>(); + + public static ColorPalette parseColorPalette(Reader reader) throws IOException { + ColorPalette palette = new ColorPalette(); BufferedReader r = new BufferedReader(reader); String line; while ((line = r.readLine()) != null) { @@ -164,24 +193,43 @@ public static List parseColorPalette(Reader reader) throws IOExcepti if (values.length >= 4) { try { ColorValue rgba = ColorValue.rgba(Double.parseDouble(values[0]), Integer.parseInt(values[1]), - Integer.parseInt(values[2]), Integer.parseInt(values[3]), values.length >= 4 ? Integer.parseInt(values[4]) : 255); - palette.add(rgba); + Integer.parseInt(values[2]), Integer.parseInt(values[3]), + values.length >= 4 ? Integer.parseInt(values[4]) : 255); + palette.colors.add(rgba); } catch (NumberFormatException e) { LOG.error(e.getMessage(), e); } } } + palette.sortPalette(); return palette; } - - - - + + private static int red(int value) { + return (value >> 16) & 0xFF; + } + + private static int green(int value) { + return (value >> 8) & 0xFF; + } + + private static int blue(int value) { + return (value >> 0) & 0xFF; + } + + private static int alpha(int value) { + return (value >> 24) & 0xff; + } + + public static int getTransparentColor() { + return rgbaToDecimal(0, 0, 0, 0); + } + public static void main(String[] args) throws IOException { - List pls = ColorPalette.parseColorPalette(new FileReader("/Users/victorshcherb/osmand/repos/resources/color-palette/route_speed_default.txt")); - System.out.println(pls); - System.out.println(ColorPalette.writeColorPalette(pls)); + ColorPalette pls = ColorPalette + .parseColorPalette(new FileReader("../../resources/color-palette/route_speed_default.txt")); + System.out.println(pls.colors); + System.out.println(pls.writeColorPalette()); } - - + } diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java index 5596e24d52c..7abd49ac213 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -18,37 +18,27 @@ import java.util.List; public class RouteColorize { + + public static double MAX_CORRECT_ELEVATION_DISTANCE = 100.0;// in meters + public static int SLOPE_RANGE = 150;// 150 meters + private static final Log LOG = PlatformUtil.getLog(RouteColorize.class); + private static final float DEFAULT_BASE = 17.2f; + private static final double MIN_DIFFERENCE_SLOPE = 0.05d;// 5% - public double[] latitudes; - public double[] longitudes; - public double[] values; - public double minValue; - public double maxValue; - public double[][] palette; + private double[] latitudes; + private double[] longitudes; + private double[] values; + private double minValue; + private double maxValue; + private ColorPalette palette; private List dataList; - - private static final float DEFAULT_BASE = 17.2f; - public static double MAX_CORRECT_ELEVATION_DISTANCE = 100.0;// in meters + private ColorizationType colorizationType; public enum ColorizationType { ELEVATION, SPEED, SLOPE, NONE } - private final int VALUE_INDEX = 0; - private final int DECIMAL_COLOR_INDEX = 1;// sRGB decimal format - private final int RED_COLOR_INDEX = 1;// RGB - private final int GREEN_COLOR_INDEX = 2;// RGB - private final int BLUE_COLOR_INDEX = 3;// RGB - private final int ALPHA_COLOR_INDEX = 4;// RGBA - - private ColorizationType colorizationType; - - public static int SLOPE_RANGE = 150;// 150 meters - private static final double MIN_DIFFERENCE_SLOPE = 0.05d;// 5% - - private static final Log LOG = PlatformUtil.getLog(RouteColorize.class); - /** * @param minValue can be NaN * @param maxValue can be NaN @@ -56,40 +46,40 @@ public enum ColorizationType { * {{value,RED,GREEN,BLUE,ALPHA},...} - color in RGBA format */ public RouteColorize(double[] latitudes, double[] longitudes, double[] values, double minValue, double maxValue, - double[][] palette) { + ColorPalette palette) { this.latitudes = latitudes; this.longitudes = longitudes; this.values = values; this.minValue = minValue; this.maxValue = maxValue; this.palette = palette; - if (Double.isNaN(minValue) || Double.isNaN(maxValue)) { calculateMinMaxValue(); } - checkPalette(); - sortPalette(); + if (palette == null || palette.getColors().size() < 2) { + this.palette = new ColorPalette(ColorPalette.MIN_MAX_PALETTE, minValue, maxValue); + } else { + this.palette = palette; + } } /** * @param type ELEVATION, SPEED, SLOPE */ - public RouteColorize(GPXFile gpxFile, ColorizationType type) { - this(gpxFile, null, type, 0); + public RouteColorize(GPXFile gpxFile, ColorizationType type, ColorPalette palette) { + this(gpxFile, null, type, palette, 0); } - public RouteColorize(GPXFile gpxFile, GPXTrackAnalysis analysis, ColorizationType type, float maxProfileSpeed) { - + public RouteColorize(GPXFile gpxFile, GPXTrackAnalysis analysis, ColorizationType type, + ColorPalette palette, float maxProfileSpeed) { if (!gpxFile.hasTrkPt()) { LOG.warn("GPX file is not consist of track points"); return; } - List latList = new ArrayList<>(); List lonList = new ArrayList<>(); List valList = new ArrayList<>(); int wptIdx = 0; - if (analysis == null) { long time = Algorithms.isEmpty(gpxFile.path) ? System.currentTimeMillis() : gpxFile.modifiedTime; analysis = gpxFile.getAnalysis(time); @@ -123,8 +113,16 @@ public RouteColorize(GPXFile gpxFile, GPXTrackAnalysis analysis, ColorizationTyp values = listToArray(valList); } calculateMinMaxValue(analysis, maxProfileSpeed); - checkPalette(); - sortPalette(); + if (type == ColorizationType.SLOPE) { + this.palette = isValidPalette(palette) ? palette : ColorPalette.SLOPE_PALETTE; + } else { + this.palette = new ColorPalette(isValidPalette(palette) ? palette : ColorPalette.MIN_MAX_PALETTE, minValue, + maxValue); + } + } + + private boolean isValidPalette(ColorPalette palette) { + return palette != null && palette.getColors().size() >= 2; } /** @@ -237,46 +235,14 @@ public List getSimplifiedResult(int simplificationZoom) private void setColorsToPoints(List points) { for (RouteColorizationPoint point : points) { - point.color = getColorByValue(point.val); - } - } - - public int getColorByValue(double value) { - if (Double.isNaN(value)) { - return ColorPalette.LIGHT_GREY; - } - for (int i = 0; i < palette.length - 1; i++) { - if (value == palette[i][VALUE_INDEX]) - return (int) palette[i][DECIMAL_COLOR_INDEX]; - if (value >= palette[i][VALUE_INDEX] && value <= palette[i + 1][VALUE_INDEX]) { - int minPaletteColor = (int) palette[i][DECIMAL_COLOR_INDEX]; - int maxPaletteColor = (int) palette[i + 1][DECIMAL_COLOR_INDEX]; - double minPaletteValue = palette[i][VALUE_INDEX]; - double maxPaletteValue = palette[i + 1][VALUE_INDEX]; - double percent = (value - minPaletteValue) / (maxPaletteValue - minPaletteValue); - return ColorPalette.getIntermediateColor(minPaletteColor, maxPaletteColor, percent); - } - } - if (value <= palette[0][0]) { - return (int) palette[0][1]; - } else if (value >= palette[palette.length - 1][0]) { - return (int) palette[palette.length - 1][1]; + point.color = palette.getColorByValue(point.val); } - return ColorPalette.getTransparentColor(); - } - - public void setPalette(double[][] palette) { - this.palette = palette; - checkPalette(); - sortPalette(); } - public void setPalette(int[] gradientPalette) { - if (gradientPalette == null || gradientPalette.length != 3) { - return; + public void setPalette(ColorPalette palette) { + if (palette != null) { + this.palette = palette; } - setPalette(new double[][] { { minValue, gradientPalette[0] }, { (minValue + maxValue) / 2, gradientPalette[1] }, - { maxValue, gradientPalette[2] } }); } public List simplify(int simplificationZoom) { @@ -352,54 +318,6 @@ private List getExtremums(List s return result; } - private void checkPalette() { - if (palette == null || palette.length < 2 || palette[0].length < 2 || palette[1].length < 2) { - LOG.info("Will use default palette"); - palette = getDefaultPalette(colorizationType); - } - double min; - double max = min = palette[0][VALUE_INDEX]; - int minIndex = 0; - int maxIndex = 0; - double[][] sRGBPalette = new double[palette.length][2]; - for (int i = 0; i < palette.length; i++) { - double[] p = palette[i]; - if (p.length == 2) { - sRGBPalette[i] = p; - } else if (p.length == 4) { - int color = ColorPalette.rgbaToDecimal((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], - (int) p[BLUE_COLOR_INDEX], 255); - sRGBPalette[i] = new double[] { p[VALUE_INDEX], color }; - } else if (p.length >= 5) { - int color = ColorPalette.rgbaToDecimal((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], - (int) p[BLUE_COLOR_INDEX], (int) p[ALPHA_COLOR_INDEX]); - sRGBPalette[i] = new double[] { p[VALUE_INDEX], color }; - } - if (p[VALUE_INDEX] > max) { - max = p[VALUE_INDEX]; - maxIndex = i; - } - if (p[VALUE_INDEX] < min) { - min = p[VALUE_INDEX]; - minIndex = i; - } - } - palette = sRGBPalette; - if (minValue < min) { - palette[minIndex][VALUE_INDEX] = minValue; - } - if (maxValue > max) { - palette[maxIndex][VALUE_INDEX] = maxValue; - } - } - - private void sortPalette() { - java.util.Arrays.sort(palette, new java.util.Comparator() { - public int compare(double[] a, double[] b) { - return Double.compare(a[VALUE_INDEX], b[VALUE_INDEX]); - } - }); - } /** * @return double[minElevation, maxElevation, minDist, maxDist] @@ -512,11 +430,11 @@ private double[] listToArray(List doubleList) { return result; } - private double[][] getDefaultPalette(ColorizationType colorizationType) { + public static ColorPalette getDefaultPalette(ColorizationType colorizationType) { if (colorizationType == ColorizationType.SLOPE) { return ColorPalette.SLOPE_PALETTE; } else { - return ColorPalette.getPaletteScale(minValue, maxValue); + return ColorPalette.MIN_MAX_PALETTE; } } diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java index a95a903b4e0..4bcef11469d 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java @@ -3,7 +3,6 @@ import static net.osmand.util.CollectionUtils.startsWithAny; import net.osmand.CallbackWithObject; -import net.osmand.ColorPalette; import net.osmand.IProgress; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; @@ -1183,13 +1182,6 @@ public static boolean isValidMessageFormat(CharSequence sequence) { return false; } - public static int[] stringToGradientPalette(String str, String gradientScaleType) { - return ColorPalette.stringToGradientPalette(str, gradientScaleType); - } - - public static String gradientPaletteToString(int[] palette, String gradientScaleType) { - return ColorPalette.gradientPaletteToString(palette, gradientScaleType); - } public static boolean isUrl(String value) { String[] urlPrefixes = new String[] {"http://", "https://", "HTTP://", "HTTPS://"}; diff --git a/OsmAnd/assets/bundled_assets.xml b/OsmAnd/assets/bundled_assets.xml index 16d72f538d3..48aa9b3a4ca 100644 --- a/OsmAnd/assets/bundled_assets.xml +++ b/OsmAnd/assets/bundled_assets.xml @@ -130,4 +130,8 @@ + + + + diff --git a/OsmAnd/src/net/osmand/plus/track/CachedTrack.java b/OsmAnd/src/net/osmand/plus/track/CachedTrack.java index 073cefcf1f9..dbd6e55b7c8 100644 --- a/OsmAnd/src/net/osmand/plus/track/CachedTrack.java +++ b/OsmAnd/src/net/osmand/plus/track/CachedTrack.java @@ -6,6 +6,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.ColorPalette; +import net.osmand.IndexConstants; +import net.osmand.PlatformUtil; import net.osmand.gpx.GPXFile; import net.osmand.gpx.GPXTrackAnalysis; import net.osmand.gpx.GPXUtilities.TrkSegment; @@ -15,6 +18,7 @@ import net.osmand.plus.card.color.ColoringStyle; import net.osmand.plus.routing.ColoringType; import net.osmand.plus.track.helpers.SelectedGpxFile; +import net.osmand.plus.views.layers.geometry.MultiColoringGeometryWay; import net.osmand.render.RenderingRulesStorage; import net.osmand.router.RouteColorize; import net.osmand.router.RouteColorize.ColorizationType; @@ -22,6 +26,9 @@ import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteStatisticsHelper; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -134,7 +141,18 @@ private RouteColorize createGpxColorization(@NonNull GradientScaleType scaleType GPXTrackAnalysis trackAnalysis = selectedGpxFile.getTrackAnalysisToDisplay(app); ColorizationType colorizationType = scaleType.toColorizationType(); float maxSpeed = app.getSettings().getApplicationMode().getMaxSpeed(); - return new RouteColorize(gpxFile, trackAnalysis, colorizationType, maxSpeed); + File filePalette = app.getAppPath(IndexConstants.CLR_PALETTE_DIR + + "route_" + colorizationType.name().toLowerCase() + "_default.txt"); + ColorPalette colorPalette = null; + try { + if (filePalette.exists()) { + colorPalette = ColorPalette.parseColorPalette(new FileReader(filePalette)); + } + } catch (IOException e) { + PlatformUtil.getLog(CachedTrack.class).error("Error reading color file ", + e); + } + return new RouteColorize(gpxFile, trackAnalysis, colorizationType, colorPalette, maxSpeed); } @NonNull diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWay.java index b8c04432a23..4a4a057f118 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiColoringGeometryWay.java @@ -8,7 +8,9 @@ import androidx.annotation.Nullable; import net.osmand.ColorPalette; +import net.osmand.IndexConstants; import net.osmand.Location; +import net.osmand.PlatformUtil; import net.osmand.data.LatLon; import net.osmand.data.RotatedTileBox; import net.osmand.gpx.GPXFile; @@ -35,6 +37,9 @@ import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -125,7 +130,18 @@ protected void updateGradientWay(RotatedTileBox tb, List locations) { GradientScaleType gradientScaleType = coloringType.toGradientScaleType(); if (gradientScaleType != null) { ColorizationType colorizationType = gradientScaleType.toColorizationType(); - RouteColorize routeColorize = new RouteColorize(gpxFile, null, colorizationType, 0); + File filePalette = getContext().getApp().getAppPath(IndexConstants.CLR_PALETTE_DIR + + "route_" + colorizationType.name().toLowerCase() + "_default.txt"); + ColorPalette colorPalette = null; + try { + if (filePalette.exists()) { + colorPalette = ColorPalette.parseColorPalette(new FileReader(filePalette)); + } + } catch (IOException e) { + PlatformUtil.getLog(MultiColoringGeometryWay.class).error("Error reading color file ", + e); + } + RouteColorize routeColorize = new RouteColorize(gpxFile, null, colorizationType, colorPalette, 0); List points = routeColorize.getResult(); updateWay(new GradientGeometryWayProvider(routeColorize, points, null), createGradientStyles(points), tb); } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java index b45527bfcff..2549e9f2aaa 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java @@ -418,11 +418,9 @@ private Integer getActionPointColor(@NonNull ActionPoint actionPoint) { } for (Segment segment : cachedSegments) { - if (!segment.isCompleted()) { return null; } - int pointOrder = segment.getPointOrders(actionPoint.index); if (pointOrder == -1) { return null; From 7e461e1cbf9d2440f49d6e3061d9790a4d6fec7a Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 21 May 2024 00:08:01 +0300 Subject: [PATCH 29/33] Add colorizations to use user palettes --- OsmAnd/assets/bundled_assets.xml | 6 +++--- .../net/osmand/plus/plugins/srtm/TerrainLayer.java | 10 ++++++---- .../net/osmand/plus/plugins/srtm/TerrainMode.java | 13 ++++++++----- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/OsmAnd/assets/bundled_assets.xml b/OsmAnd/assets/bundled_assets.xml index 48aa9b3a4ca..ce36b429acf 100644 --- a/OsmAnd/assets/bundled_assets.xml +++ b/OsmAnd/assets/bundled_assets.xml @@ -122,9 +122,9 @@ - - - + + + diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java index 71ec576ed2e..5e6712f5ec1 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java @@ -96,7 +96,9 @@ protected boolean setLayerProvider(@Nullable ITileSource map) { if (terrainFromHeightmap && geoTiffCollection != null) { layerProvider = createGeoTiffLayerProvider(mode, geoTiffCollection); - mapRenderer.setMapLayerProvider(layerIndex, layerProvider); + if (layerProvider != null) { + mapRenderer.setMapLayerProvider(layerIndex, layerProvider); + } } else { TileSourceProxyProvider prov = new TerrainTilesProvider(getApplication(), map, srtmPlugin); mapRenderer.setMapLayerProvider(layerIndex, prov.instantiateProxy(true)); @@ -123,10 +125,10 @@ private IRasterMapLayerProvider createGeoTiffLayerProvider(TerrainMode mode, @No provider = new SlopeRasterMapLayerProvider(geoTiffCollection, mainColorFilename); ((SlopeRasterMapLayerProvider) provider).setMinVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMinZoom())); ((SlopeRasterMapLayerProvider) provider).setMaxVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMaxZoom())); - } else { + } else if (mode.getType() == TerrainMode.TerrainType.HEIGHT) { provider = new HeightRasterMapLayerProvider(geoTiffCollection, mainColorFilename); - ((SlopeRasterMapLayerProvider) provider).setMinVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMinZoom())); - ((SlopeRasterMapLayerProvider) provider).setMaxVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMaxZoom())); + ((HeightRasterMapLayerProvider) provider).setMinVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMinZoom())); + ((HeightRasterMapLayerProvider) provider).setMaxVisibleZoom(ZoomLevel.swigToEnum(srtmPlugin.getTerrainMaxZoom())); } // provider.setKey(mode.getKey()); // opengl binding (cache should be key +'.cache') diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java index 10b78a42203..da112b64721 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainMode.java @@ -62,27 +62,30 @@ public static TerrainMode[] values(OsmandApplication app) { File dir = app.getAppPath(IndexConstants.CLR_PALETTE_DIR); if (dir.exists() && dir.listFiles() != null) { for (File lf : dir.listFiles()) { - if(lf == null || !lf.getName().endsWith(EXT) ) { + if (lf == null || !lf.getName().endsWith(EXT)) { continue; } String nm = lf.getName(); if (nm.startsWith(HILLSHADE_PREFIX)) { String key = nm.substring(HILLSHADE_PREFIX.length()); key = key.substring(0, key.length() - EXT.length()); + String name = Algorithms.capitalizeFirstLetter(key).replace('_', ' '); if (!DEFAULT_KEY.equals(key)) { - tms.add(new TerrainMode(app, key, Algorithms.capitalizeFirstLetter(key), TerrainType.HILLSHADE)); + tms.add(new TerrainMode(app, key, name, TerrainType.HILLSHADE)); } } else if (nm.startsWith(COLOR_SLOPE_PREFIX)) { String key = nm.substring(COLOR_SLOPE_PREFIX.length()); key = key.substring(0, key.length() - EXT.length()); + String name = Algorithms.capitalizeFirstLetter(key).replace('_', ' '); if (!DEFAULT_KEY.equals(key)) { - tms.add(new TerrainMode(app, key, Algorithms.capitalizeFirstLetter(key), TerrainType.SLOPE)); + tms.add(new TerrainMode(app, key, name, TerrainType.SLOPE)); } } else if (nm.startsWith(HEIGHT_PREFIX)) { String key = nm.substring(HEIGHT_PREFIX.length()); key = key.substring(0, key.length() - EXT.length()); + String name = Algorithms.capitalizeFirstLetter(key).replace('_', ' '); if (!DEFAULT_KEY.equals(key)) { - tms.add(new TerrainMode(app, key, Algorithms.capitalizeFirstLetter(key), TerrainType.HEIGHT)); + tms.add(new TerrainMode(app, key, name, TerrainType.HEIGHT)); } } } @@ -113,7 +116,7 @@ public TerrainType getType() { public String getMainFile() { String prefix = HILLSHADE_PREFIX; - if(type == TerrainType.HEIGHT) { + if (type == TerrainType.HEIGHT) { prefix = HEIGHT_PREFIX; } else if(type == TerrainType.SLOPE) { prefix = COLOR_SLOPE_PREFIX; From 6a72a74939e0e214d7c32931c72004297898eaa9 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 21 May 2024 00:10:03 +0300 Subject: [PATCH 30/33] Fix compilation --- OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java index 5e6712f5ec1..9055b68996f 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java +++ b/OsmAnd/src/net/osmand/plus/plugins/srtm/TerrainLayer.java @@ -114,7 +114,7 @@ private IRasterMapLayerProvider createGeoTiffLayerProvider(TerrainMode mode, @No OsmandApplication app = getApplication(); File heightmapDir = app.getAppPath(IndexConstants.CLR_PALETTE_DIR); String mainColorFilename = new File(heightmapDir, mode.getMainFile()).getAbsolutePath(); - IRasterMapLayerProvider provider; + IRasterMapLayerProvider provider = null; if (mode.getType() == TerrainMode.TerrainType.HILLSHADE) { String slopeSecondaryColorFilename = new File(heightmapDir, mode.getSecondFile()).getAbsolutePath(); provider = From 6462a4b65210f0abf6a6b85ffcc4f9c46585eabc Mon Sep 17 00:00:00 2001 From: mcliquid Date: Mon, 20 May 2024 18:48:44 +0000 Subject: [PATCH 31/33] Translated using Weblate (German) Currently translated at 100.0% (5103 of 5103 strings) --- OsmAnd/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index e46d4f163c8..150385f8a7c 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -5730,4 +5730,5 @@ SPM Alle Kartenebenen über der Vektorkarte deaktivieren (Neustart erforderlich). Kartenebenen deaktivieren + Höhen-Farbkarten werden verwendet, um Relief zu visualisieren. \ No newline at end of file From 211415e3cb6e9fa99f8269d491573aa8505e945f Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Mon, 20 May 2024 17:51:01 +0000 Subject: [PATCH 32/33] Translated using Weblate (Spanish) Currently translated at 100.0% (5103 of 5103 strings) --- OsmAnd/res/values-es/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-es/strings.xml b/OsmAnd/res/values-es/strings.xml index 0a10147dc3d..373ecd10854 100644 --- a/OsmAnd/res/values-es/strings.xml +++ b/OsmAnd/res/values-es/strings.xml @@ -5727,4 +5727,5 @@ PPM Deshabilitar capas de mapas Deshabilite todas las capas del mapa sobre el mapa vectorial (es necesario reiniciar). + Los mapas de color de altitud se utilizan para visualizar el relieve. \ No newline at end of file From 56c8f9668ac332214530721c3d5dde78e0e543f3 Mon Sep 17 00:00:00 2001 From: chumv Date: Tue, 21 May 2024 13:20:21 +0300 Subject: [PATCH 33/33] Move display methods to AndroidUtils --- .../osmand/render/RenderingRulesStorage.java | 7 ++-- .../net/osmand/plus/OsmandApplication.java | 39 +------------------ .../plus/base/MapViewTrackingUtilities.java | 3 +- .../osmand/plus/render/OsmandRenderer.java | 11 +----- .../plus/resources/ResourceManager.java | 9 +---- .../net/osmand/plus/utils/AndroidUtils.java | 23 +++++++++++ .../osmand/plus/views/MapViewWithLayers.java | 18 ++++----- .../src/net/osmand/plus/views/OsmandMap.java | 9 ++--- .../osmand/plus/views/OsmandMapTileView.java | 19 +++++---- .../views/corenative/NativeCoreContext.java | 5 +-- .../plus/views/layers/ContextMenuLayer.java | 5 +-- .../views/layers/DownloadedRegionsLayer.java | 8 ++-- .../views/layers/MapQuickActionLayer.java | 6 +-- .../views/layers/TransportStopsLayer.java | 6 +-- 14 files changed, 67 insertions(+), 101 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/render/RenderingRulesStorage.java b/OsmAnd-java/src/main/java/net/osmand/render/RenderingRulesStorage.java index fbe997911c6..6f620474c77 100644 --- a/OsmAnd-java/src/main/java/net/osmand/render/RenderingRulesStorage.java +++ b/OsmAnd-java/src/main/java/net/osmand/render/RenderingRulesStorage.java @@ -390,8 +390,8 @@ public void startElement(Map attrsMap, String name) throws XmlPu if(!renderingConstants.containsKey(attrsMap.get("name"))){ renderingConstants.put(attrsMap.get("name"), attrsMap.get("value")); } - } else if("renderingStyle".equals(name)){ //$NON-NLS-1$ - if(!addon){ + } else if ("renderingStyle".equals(name)) { //$NON-NLS-1$ + if (!addon) { String depends = attrsMap.get("depends"); if (depends != null && depends.length() > 0) { this.dependsStorage = resolver.resolve(depends, resolver); @@ -404,8 +404,7 @@ public void startElement(Map attrsMap, String name) throws XmlPu } internalRenderingName = attrsMap.get("name"); } - - } else if("renderer".equals(name)){ //$NON-NLS-1$ + } else if ("renderer".equals(name)) { //$NON-NLS-1$ throw new XmlPullParserException("Rendering style is deprecated and no longer supported."); } else { log.warn("Unknown tag : " + name); //$NON-NLS-1$ diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 8903d660f21..d73da7923ae 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -1,7 +1,5 @@ package net.osmand.plus; -import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static net.osmand.IndexConstants.ROUTING_FILE_EXT; import static net.osmand.plus.settings.backend.ApplicationMode.valueOfStringKey; import static net.osmand.plus.settings.enums.MetricsConstants.KILOMETERS_AND_METERS; @@ -13,21 +11,16 @@ import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; -import android.hardware.display.DisplayManager; import android.os.AsyncTask; import android.os.Build; import android.os.Handler; import android.os.Message; -import android.view.Display; import android.view.View; -import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import androidx.annotation.UiContext; import androidx.car.app.CarToast; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleObserver; @@ -114,6 +107,7 @@ import net.osmand.plus.track.helpers.GpxDbHelper; import net.osmand.plus.track.helpers.GpxDisplayHelper; import net.osmand.plus.track.helpers.GpxSelectionHelper; +import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.FileUtils; import net.osmand.plus.utils.UiUtilities; import net.osmand.plus.views.OsmandMap; @@ -226,8 +220,6 @@ public class OsmandApplication extends MultiDexApplication { private boolean androidAutoInForeground; // Typeface - private Context uiContext; - @Override public void onCreate() { if (RestartActivity.isRestartProcess(this)) { @@ -250,7 +242,6 @@ public void onStop(@NonNull LifecycleOwner owner) { }; ProcessLifecycleOwner.get().getLifecycle().addObserver(appLifecycleObserver); - setupUIContext(); createInUiThread(); uiHandler = new Handler(); appCustomization = new OsmAndAppCustomization(); @@ -291,14 +282,6 @@ public void onStop(@NonNull LifecycleOwner owner) { BackupHelper.DEBUG = true;//PluginsHelper.isDevelopment(); } - private void setupUIContext() { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { - final DisplayManager dm = this.getSystemService(DisplayManager.class); - final Display primaryDisplay = dm.getDisplay(DEFAULT_DISPLAY); - uiContext = this.createDisplayContext(primaryDisplay).createWindowContext(TYPE_APPLICATION_OVERLAY, null); - } - } - public boolean isPlusVersionInApp() { return true; } @@ -326,7 +309,7 @@ public boolean isAppInForeground() { } private void createInUiThread() { - new Toast(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R ? getWindowContext() : this); // activate in UI thread to avoid further exceptions + new Toast(AndroidUtils.createDisplayContext(this)); // activate in UI thread to avoid further exceptions new AsyncTask() { @Override protected Void doInBackground(View... params) { @@ -343,24 +326,6 @@ public UiUtilities getUIUtilities() { return iconsCache; } - @UiContext - @RequiresApi(Build.VERSION_CODES.R) - public Context getWindowContext(){ - return uiContext; - } - - public Display getContextDisplay() { - Display display; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { - DisplayManager displayManager = (DisplayManager) this.getSystemService(Context.DISPLAY_SERVICE); - display = displayManager.getDisplay(Display.DEFAULT_DISPLAY); - } else { - WindowManager wmgr = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); - display = wmgr.getDefaultDisplay(); - } - return display; - } - @Override public void onTerminate() { super.onTerminate(); diff --git a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java index c5a259fcb5f..cecdaac7a1d 100644 --- a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java +++ b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java @@ -38,6 +38,7 @@ import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.enums.CompassMode; import net.osmand.plus.settings.enums.DrivingRegion; +import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.NativeUtilities; import net.osmand.plus.views.AnimateDraggingMapThread; import net.osmand.plus.views.AutoZoomBySpeedHelper; @@ -134,7 +135,7 @@ public void setMapView(@Nullable OsmandMapTileView mapView) { mapDisplayPositionManager.setMapView(mapView); autoZoomBySpeedHelper.setMapView(mapView); if (mapView != null) { - Display display = app.getContextDisplay(); + Display display = AndroidUtils.getDisplay(app); int orientation = 0; if (display != null) { orientation = display.getRotation(); diff --git a/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java b/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java index a9cb9b73641..9a3ed61c345 100644 --- a/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java +++ b/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java @@ -24,8 +24,6 @@ import android.os.Looper; import android.util.DisplayMetrics; -import androidx.annotation.NonNull; - import net.osmand.NativeLibrary; import net.osmand.NativeLibrary.NativeSearchResult; import net.osmand.PlatformUtil; @@ -35,7 +33,7 @@ import net.osmand.data.QuadRect; import net.osmand.data.QuadTree; import net.osmand.map.MapTileDownloader; -import net.osmand.plus.OsmandApplication; +import net.osmand.plus.utils.AndroidUtils; import net.osmand.render.RenderingRuleProperty; import net.osmand.render.RenderingRuleSearchRequest; import net.osmand.render.RenderingRulesStorage; @@ -146,12 +144,7 @@ public OsmandRenderer(Context context) { paint.setAntiAlias(true); dm = new DisplayMetrics(); - getApplication().getContextDisplay().getMetrics(dm); - } - - @NonNull - public OsmandApplication getApplication() { - return (OsmandApplication) context.getApplicationContext(); + AndroidUtils.getDisplay(context).getMetrics(dm); } public PathEffect getDashEffect(RenderingContext rc, float[] cachedValues, float st){ diff --git a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java index a80469b187c..fea85714b87 100644 --- a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java @@ -7,13 +7,11 @@ import static net.osmand.plus.AppInitEvents.ASSETS_COPIED; import static net.osmand.plus.AppInitEvents.MAPS_INITIALIZED; -import android.content.Context; import android.content.res.AssetManager; import android.database.sqlite.SQLiteException; import android.os.AsyncTask; import android.os.HandlerThread; import android.util.DisplayMetrics; -import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -290,7 +288,7 @@ public ResourceManager(@NonNull OsmandApplication context) { resetStoreDirectory(); DisplayMetrics dm = new DisplayMetrics(); - getApplication().getContextDisplay().getMetrics(dm); + AndroidUtils.getDisplay(context).getMetrics(dm); // Only 8 MB (from 16 Mb whole mem) available for images : image 64K * 128 = 8 MB (8 bit), 64 - 16 bit, 32 - 32 bit // at least 3*9? float tiles = (dm.widthPixels / 256 + 2) * (dm.heightPixels / 256 + 2) * 3; @@ -303,11 +301,6 @@ public ResourceManager(@NonNull OsmandApplication context) { } } - @NonNull - public OsmandApplication getApplication() { - return (OsmandApplication) context.getApplicationContext(); - } - public BitmapTilesCache getBitmapTilesCache() { return bitmapTilesCache; } diff --git a/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java b/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java index 666a5b418c6..6cd5b11df5f 100644 --- a/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java +++ b/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java @@ -9,6 +9,7 @@ import static android.graphics.Paint.FILTER_BITMAP_FLAG; import static android.util.TypedValue.COMPLEX_UNIT_DIP; import static android.util.TypedValue.COMPLEX_UNIT_SP; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import android.Manifest; import android.annotation.SuppressLint; @@ -36,6 +37,7 @@ import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.StateListDrawable; import android.graphics.drawable.VectorDrawable; +import android.hardware.display.DisplayManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -53,6 +55,7 @@ import android.text.style.URLSpan; import android.util.DisplayMetrics; import android.util.TypedValue; +import android.view.Display; import android.view.DisplayCutout; import android.view.Gravity; import android.view.MotionEvent; @@ -60,6 +63,7 @@ import android.view.ViewGroup; import android.view.ViewParent; import android.view.ViewTreeObserver; +import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.FrameLayout; import android.widget.ImageView; @@ -1416,4 +1420,23 @@ public static boolean isBluetoothEnabled(@NonNull Context context) { BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter(); return bluetoothAdapter != null && bluetoothAdapter.isEnabled(); } + + public static Display getDisplay(@NonNull Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + DisplayManager manager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); + return manager.getDisplay(Display.DEFAULT_DISPLAY); + } else { + WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + return manager.getDefaultDisplay(); + } + } + + @NonNull + public static Context createDisplayContext(@NonNull Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + return context.createDisplayContext(getDisplay(context)) + .createWindowContext(TYPE_APPLICATION_OVERLAY, null); + } + return context; + } } diff --git a/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java b/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java index 8b213bedfc4..d05fd58ef14 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java +++ b/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java @@ -6,7 +6,6 @@ import android.util.DisplayMetrics; import android.view.View; import android.view.ViewStub; -import android.view.WindowManager; import android.widget.FrameLayout; import androidx.annotation.NonNull; @@ -15,16 +14,14 @@ import net.osmand.core.android.AtlasMapRendererView; import net.osmand.core.android.MapRendererContext; import net.osmand.core.android.MapRendererView; -import net.osmand.core.jni.MapRendererDebugSettings; import net.osmand.core.jni.ZoomLevel; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.auto.NavigationSession; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.inapp.InAppPurchaseUtils; -import net.osmand.plus.plugins.PluginsHelper; -import net.osmand.plus.plugins.development.OsmandDevelopmentPlugin; import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.UiUtilities; import net.osmand.plus.views.OsmandMap.RenderingViewSetupListener; import net.osmand.plus.views.corenative.NativeCoreContext; @@ -114,15 +111,16 @@ private void setupAtlasMapRendererView() { mapRendererContext.setMapRendererView(null); } } - DisplayMetrics dm = new DisplayMetrics(); - app.getContextDisplay().getMetrics(dm); - NativeCoreContext.setMapRendererContext(app, dm.density); + DisplayMetrics metrics = new DisplayMetrics(); + AndroidUtils.getDisplay(getContext()).getMetrics(metrics); + NativeCoreContext.setMapRendererContext(app, metrics.density); mapRendererContext = NativeCoreContext.getMapRendererContext(); if (mapRendererContext != null) { - if (atlasMapRendererView == null) - atlasMapRendererView = (AtlasMapRendererView) stub.inflate(); - else + if (atlasMapRendererView == null) { + atlasMapRendererView = (AtlasMapRendererView) stub.inflate(); + } else { atlasMapRendererView.handleOnCreate(null); + } atlasMapRendererView.setupRenderer(getContext(), 0, 0, mapRendererView); atlasMapRendererView.setMinZoomLevel(ZoomLevel.swigToEnum(mapView.getMinZoom())); atlasMapRendererView.setMaxZoomLevel(ZoomLevel.swigToEnum(mapView.getMaxZoom())); diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMap.java b/OsmAnd/src/net/osmand/plus/views/OsmandMap.java index 2d8cb0adabe..f4a29e16d19 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMap.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMap.java @@ -1,9 +1,9 @@ package net.osmand.plus.views; -import android.content.Context; import android.graphics.Point; import android.view.Display; -import android.view.WindowManager; + +import androidx.annotation.NonNull; import net.osmand.Location; import net.osmand.data.RotatedTileBox; @@ -16,14 +16,11 @@ import net.osmand.plus.resources.ResourceManager; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.utils.AndroidUtils; -import net.osmand.util.Algorithms; import net.osmand.util.CollectionUtils; import java.util.ArrayList; import java.util.List; -import androidx.annotation.NonNull; - public class OsmandMap { private final OsmandApplication app; @@ -60,7 +57,7 @@ public OsmandMap(@NonNull OsmandApplication app) { int height; NavigationSession carNavigationSession = app.getCarNavigationSession(); if (carNavigationSession == null) { - Display display = app.getContextDisplay(); + Display display = AndroidUtils.getDisplay(app); Point screenDimensions = new Point(0, 0); display.getSize(screenDimensions); width = screenDimensions.x; diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java index 5eac5f3665a..127006ee62e 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java @@ -1,6 +1,9 @@ package net.osmand.plus.views; +import static net.osmand.plus.views.layers.base.BaseMapLayer.DEFAULT_MAX_ZOOM; +import static net.osmand.plus.views.layers.base.BaseMapLayer.DEFAULT_MIN_ZOOM; + import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; @@ -25,9 +28,11 @@ import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; -import android.view.WindowManager; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import net.osmand.PlatformUtil; import net.osmand.StateChangedListener; import net.osmand.core.android.MapRendererView; @@ -44,14 +49,14 @@ import net.osmand.map.IMapLocationListener; import net.osmand.map.MapTileDownloader.DownloadRequest; import net.osmand.map.MapTileDownloader.IMapDownloaderCallback; -import net.osmand.plus.AppInitializer; import net.osmand.plus.AppInitializeListener; +import net.osmand.plus.AppInitializer; import net.osmand.plus.OsmAndConstants; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.auto.views.CarSurfaceView; import net.osmand.plus.auto.SurfaceRenderer; +import net.osmand.plus.auto.views.CarSurfaceView; import net.osmand.plus.base.MapViewTrackingUtilities; import net.osmand.plus.helpers.MapDisplayPositionManager; import net.osmand.plus.helpers.TwoFingerTapDetector; @@ -85,12 +90,6 @@ import java.util.List; import java.util.Map; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import static net.osmand.plus.views.layers.base.BaseMapLayer.DEFAULT_MAX_ZOOM; -import static net.osmand.plus.views.layers.base.BaseMapLayer.DEFAULT_MIN_ZOOM; - public class OsmandMapTileView implements IMapDownloaderCallback { public static final float DEFAULT_ELEVATION_ANGLE = 90; @@ -305,7 +304,7 @@ public void init(@NonNull Context ctx, int width, int height) { animatedMapMarkersThread = new AnimateMapMarkersThread(this); dm = new DisplayMetrics(); - application.getContextDisplay().getMetrics(dm); + AndroidUtils.getDisplay(ctx).getMetrics(dm); LatLon ll = settings.getLastKnownMapLocation(); currentViewport = new RotatedTileBoxBuilder() .setLocation(ll.getLatitude(), ll.getLongitude()) diff --git a/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java b/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java index 6ab928ab9cd..9e24b03762b 100644 --- a/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java +++ b/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java @@ -1,8 +1,6 @@ package net.osmand.plus.views.corenative; -import android.content.Context; import android.util.DisplayMetrics; -import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -22,6 +20,7 @@ import net.osmand.plus.plugins.PluginsHelper; import net.osmand.plus.plugins.openseamaps.NauticalMapsPlugin; import net.osmand.plus.plugins.srtm.SRTMPlugin; +import net.osmand.plus.utils.AndroidUtils; import java.io.File; import java.util.HashMap; @@ -59,7 +58,7 @@ public static void init(@NonNull OsmandApplication app) { Logger.get().addLogSink(QIODeviceLogSink.createFileLogSink(new File(directory, LOG_FILE_NAME).getAbsolutePath())); DisplayMetrics dm = new DisplayMetrics(); - app.getContextDisplay().getMetrics(dm); + AndroidUtils.getDisplay(app).getMetrics(dm); String cacheFilePath = new File(app.getCacheDir(), CACHE_FILE_NAME).getAbsolutePath(); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java index d5dbd71be03..9ef6e4a6600 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java @@ -1,6 +1,5 @@ package net.osmand.plus.views.layers; -import static android.os.Build.*; import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_CHANGE_MARKER_POSITION; import static net.osmand.plus.views.layers.geometry.GeometryWayDrawer.VECTOR_LINE_SCALE_COEF; @@ -149,8 +148,8 @@ public void destroyLayer() { public void initLayer(@NonNull OsmandMapTileView view) { super.initLayer(view); - Context context = getContext(); - contextMarker = new ImageView(VERSION.SDK_INT >= VERSION_CODES.R ? getApplication().getWindowContext() : context); + Context context = AndroidUtils.createDisplayContext(getContext()); + contextMarker = new ImageView(AndroidUtils.createDisplayContext(context)); contextMarker.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); Drawable markerDrawable = AppCompatResources.getDrawable(context, R.drawable.map_pin_context_menu); contextMarker.setImageDrawable(markerDrawable); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/DownloadedRegionsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/DownloadedRegionsLayer.java index 55610b7b4a0..aa8f926ee4f 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/DownloadedRegionsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/DownloadedRegionsLayer.java @@ -12,7 +12,6 @@ import android.graphics.PointF; import android.text.TextPaint; import android.util.DisplayMetrics; -import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -48,6 +47,7 @@ import net.osmand.plus.plugins.PluginsHelper; import net.osmand.plus.resources.ResourceManager; import net.osmand.plus.resources.ResourceManager.ResourceListener; +import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.NativeUtilities; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.layers.ContextMenuLayer.IContextMenuProvider; @@ -174,9 +174,9 @@ public void initLayer(@NonNull OsmandMapTileView view) { paintBackuped = getPaint(getColor(R.color.region_backuped)); textPaint = new TextPaint(); - DisplayMetrics dm = new DisplayMetrics(); - app.getContextDisplay().getMetrics(dm); - textPaint.setStrokeWidth(21 * dm.scaledDensity); + DisplayMetrics metrics = new DisplayMetrics(); + AndroidUtils.getDisplay(app).getMetrics(metrics); + textPaint.setStrokeWidth(21 * metrics.scaledDensity); textPaint.setAntiAlias(true); textPaint.setTextAlign(Paint.Align.CENTER); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java index 0ff3395d240..397fe7ffacd 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java @@ -4,7 +4,6 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.PointF; -import android.os.Build; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -34,6 +33,7 @@ import net.osmand.plus.quickaction.QuickActionsWidget; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.enums.MapPosition; +import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.NativeUtilities; import net.osmand.plus.utils.UiUtilities; import net.osmand.plus.views.OsmandMapTileView; @@ -79,8 +79,8 @@ public MapQuickActionLayer(@NonNull Context context) { public void initLayer(@NonNull OsmandMapTileView view) { super.initLayer(view); - Context context = getContext(); - contextMarker = new ImageView(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R ? getApplication().getWindowContext() : context); + Context context = AndroidUtils.createDisplayContext(getContext()); + contextMarker = new ImageView(context); contextMarker.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT)); contextMarker.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.map_pin_context_menu)); contextMarker.setClickable(true); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/TransportStopsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/TransportStopsLayer.java index c50a5f27b2a..208c51baac4 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/TransportStopsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/TransportStopsLayer.java @@ -30,9 +30,9 @@ import net.osmand.data.TransportStop; import net.osmand.osm.edit.Node; import net.osmand.osm.edit.Way; +import net.osmand.plus.AppInitEvents; import net.osmand.plus.AppInitializeListener; import net.osmand.plus.AppInitializer; -import net.osmand.plus.AppInitEvents; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.render.RenderingIcons; @@ -40,6 +40,7 @@ import net.osmand.plus.settings.backend.preferences.CommonPreference; import net.osmand.plus.transport.TransportStopRoute; import net.osmand.plus.transport.TransportStopType; +import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.NativeUtilities; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.PointImageDrawable; @@ -48,7 +49,6 @@ import net.osmand.plus.views.layers.base.OsmandMapLayer; import net.osmand.plus.views.layers.core.TransportStopsTileProvider; import net.osmand.plus.views.layers.core.TransportStopsTileProvider.StopsCollectionPoint; -import net.osmand.plus.views.layers.geometry.GeometryWay; import net.osmand.plus.views.layers.geometry.GeometryWayPathAlgorithms; import net.osmand.util.MapUtils; @@ -95,7 +95,7 @@ public void initLayer(@NonNull OsmandMapTileView view) { super.initLayer(view); DisplayMetrics dm = new DisplayMetrics(); - getApplication().getContextDisplay().getMetrics(dm); + AndroidUtils.getDisplay(getContext()).getMetrics(dm); path = new Path(); attrs = new RenderingLineAttributes("transport_route"); attrs.defaultWidth = (int) (6 * view.getDensity());