From 5a78a309bf70aefae7b4936ee7c6c25198f565c7 Mon Sep 17 00:00:00 2001 From: Andrey Novikov Date: Wed, 13 Mar 2024 15:40:17 +0300 Subject: [PATCH] Location pointer type, size and color --- .../main/assets/shaders/location_pointer.glsl | 81 +++++++++++-------- .../main/java/mobi/maptrek/Configuration.java | 16 ++++ .../main/java/mobi/maptrek/MainActivity.java | 22 ++++- .../fragments/preferences/Location.java | 30 +++++++ .../mobi/maptrek/layers/LocationOverlay.java | 52 +++++++++++- app/src/main/res/values/arrays.xml | 5 ++ app/src/main/res/values/integers.xml | 2 + app/src/main/res/values/strings.xml | 4 + app/src/main/res/values/sysarrays.xml | 5 ++ app/src/main/res/xml/preferences.xml | 5 ++ app/src/main/res/xml/preferences_location.xml | 27 +++++++ 11 files changed, 212 insertions(+), 37 deletions(-) create mode 100644 app/src/main/java/mobi/maptrek/fragments/preferences/Location.java create mode 100644 app/src/main/res/xml/preferences_location.xml diff --git a/app/src/main/assets/shaders/location_pointer.glsl b/app/src/main/assets/shaders/location_pointer.glsl index e21b868b..9d6a3868 100644 --- a/app/src/main/assets/shaders/location_pointer.glsl +++ b/app/src/main/assets/shaders/location_pointer.glsl @@ -6,8 +6,9 @@ uniform float u_phase; uniform float u_scale; attribute vec2 a_pos; varying vec2 v_tex; + void main() { - gl_Position = u_mvp * vec4(40.0 * a_pos * u_scale * u_phase, 0.0, 1.0); + gl_Position = u_mvp * vec4(a_pos * u_scale * u_phase, 0.0, 1.0); v_tex = a_pos; } @@ -17,9 +18,11 @@ $$ precision mediump float; #endif varying vec2 v_tex; +uniform float u_scale; uniform float u_phase; uniform float u_type; uniform vec2 u_dir; +uniform vec4 u_color; // Computes the signed distance from a line float line_distance(vec2 p, vec2 p1, vec2 p2) { @@ -32,12 +35,10 @@ float line_distance(vec2 p, vec2 p1, vec2 p2) { float arrow(vec2 texcoord) { - float width = 0.35; - float size = 0.8; - float d1 = line_distance(texcoord, -size*vec2(+1.0,-width), vec2(0.0, 0.0)); - float d2 = line_distance(texcoord, -size*vec2(+1.0,-width), -vec2(0.85*size,0.0)); - float d3 = line_distance(texcoord, -size*vec2(+1.0,+width), vec2(0.0, 0.0)); - float d4 = line_distance(texcoord, -size*vec2(+1.0,+width), -vec2(0.85*size,0.0)); + float d1 = line_distance(texcoord, -vec2(0.85,-0.3), +vec2(0.0, 0.0)); + float d2 = line_distance(texcoord, -vec2(0.85,-0.3), -vec2(0.72,0.0)); + float d3 = line_distance(texcoord, -vec2(0.85,+0.3), +vec2(0.0, 0.0)); + float d4 = line_distance(texcoord, -vec2(0.85,+0.3), -vec2(0.72,0.0)); return max( max(-d1, d3), - max(-d2,d4)); } @@ -61,31 +62,47 @@ float stroke(float distance, float linewidth, float antialias) } void main() { - float len = 1.0 - length(v_tex); - if (u_dir.x == 0.0 && u_dir.y == 0.0){ - gl_FragColor = vec4(1.0, 0.34, 0.13, 1.0) * len; - } else if (u_type == 1.0) { - /// outer ring - float a = smoothstep(0.0, 0.02, len); - /// inner ring - float b = 0.5 * smoothstep(0.04, 0.05, len); - /// center point - float c = 0.5 * (1.0 - smoothstep(0.14, 0.16, 1.0 - len)); - vec2 dir = normalize(v_tex); - float d = 1.0 - dot(dir, u_dir); - /// 0.5 width of viewshed - d = clamp(step(0.5, d), 0.4, 0.7); - /// - subtract inner from outer to create the outline - /// - multiply by viewshed - /// - add center point - a = d * (a - (b + c)) + c; - gl_FragColor = vec4(1.0, 0.34, 0.13, 1.0) * a; - } else { - vec2 coord = vec2(u_dir.x*v_tex.x + u_dir.y*v_tex.y, - u_dir.y*v_tex.x - u_dir.x*v_tex.y); + float len = 1.0 - length(v_tex); + if (u_dir.x == 0.0 && u_dir.y == 0.0) { + gl_FragColor = u_color * len; + } else if (u_type == 2.0) { + // outer ring + float a = smoothstep(0.0, 2.0 / u_scale, len); + // inner ring + float b = 0.8 * smoothstep(3.0 / u_scale, 4.0 / u_scale, len); + // center point + float c = 0.5 * (1.0 - smoothstep(14.0 / u_scale, 16.0 / u_scale, 1.0 - len)); + vec2 dir = normalize(v_tex); + float d = dot(dir, u_dir); + // 0.5 width of viewshed + d = clamp(smoothstep(0.7, 0.7 + 2.0 / u_scale, d) * len, 0.0, 1.0); + // - subtract inner from outer to create the outline + // - multiply by viewshed + // - add center point + a = max(d, (a - (b + c)) + c) + c; + gl_FragColor = u_color * a; + } else if (u_type == 1.0) { + // outer ring + float a = smoothstep(0.0, 2.0 / u_scale, len); + // inner ring + float b = 0.5 * smoothstep(4.0 / u_scale, 5.0 / u_scale, len); + // center point + float c = 0.5 * (1.0 - smoothstep(14.0 / u_scale, 16.0 / u_scale, 1.0 - len)); + vec2 dir = normalize(v_tex); + float d = 1.0 - dot(dir, u_dir); + // 0.5 width of viewshed + d = clamp(step(0.5, d), 0.4, 0.7); + // - subtract inner from outer to create the outline + // - multiply by viewshed + // - add center point + a = d * (a - (b + c)) + c; + gl_FragColor = u_color * a; + } else { + vec2 coord = vec2(u_dir.x*v_tex.x + u_dir.y*v_tex.y, + u_dir.y*v_tex.x - u_dir.x*v_tex.y); - float a = stroke(arrow(coord), 0.1, 0.02); + float a = stroke(arrow(coord), 1.0 / sqrt(u_scale), 0.2 / sqrt(u_scale)); - gl_FragColor = vec4(1.0, 0.34, 0.13, 1.0) * a; - } + gl_FragColor = u_color * a; + } } diff --git a/app/src/main/java/mobi/maptrek/Configuration.java b/app/src/main/java/mobi/maptrek/Configuration.java index ced8927b..bdf66551 100644 --- a/app/src/main/java/mobi/maptrek/Configuration.java +++ b/app/src/main/java/mobi/maptrek/Configuration.java @@ -17,6 +17,7 @@ package mobi.maptrek; import android.content.SharedPreferences; +import android.graphics.Color; import android.text.TextUtils; import androidx.annotation.NonNull; @@ -94,6 +95,9 @@ public class Configuration { private static final String PREF_SKIING_TIMES = "skiing_times"; private static final String PREF_HIGHLIGHTED_TYPE = "highlighted_type"; + public static final String PREF_POINTER_TYPE = "pointer_type"; + public static final String PREF_POINTER_SIZE = "pointer_size"; + public static final String PREF_POINTER_COLOR = "pointer_color"; public static final String PREF_PLACE_COLOR = "place_color"; public static final String PREF_PLACE_TITLES = "place_titles"; public static final String PREF_TRACK_COLOR = "track_color"; @@ -524,6 +528,18 @@ public static void setHighlightedType(int type) { saveInt(PREF_HIGHLIGHTED_TYPE, type); } + public static int getPointerType() { + return Integer.parseInt(loadString(PREF_POINTER_TYPE, "0")); + } + + public static int getPointerSize() { + return loadInt(PREF_POINTER_SIZE, 25); + } + + public static int getPointerColor() { + return loadInt(PREF_POINTER_COLOR, Color.RED); + } + public static void resetMapState() { remove(PREF_LATITUDE); remove(PREF_LONGITUDE); diff --git a/app/src/main/java/mobi/maptrek/MainActivity.java b/app/src/main/java/mobi/maptrek/MainActivity.java index bab27b5d..1c54d876 100644 --- a/app/src/main/java/mobi/maptrek/MainActivity.java +++ b/app/src/main/java/mobi/maptrek/MainActivity.java @@ -640,7 +640,12 @@ public void onChildViewRemoved(View parent, View child) { DefaultMapScaleBar mapScaleBar = new DefaultMapScaleBar(mMap, MapTrek.density * .75f, paintColor, strokeColor); mMapScaleBarLayer = new MapScaleBarLayer(mMap, mapScaleBar); mCrosshairLayer = new CrosshairLayer(mMap, MapTrek.density, paintColor, () -> Configuration.setPosition(mMap.getMapPosition())); - mLocationOverlay = new LocationOverlay(mMap, MapTrek.density); + + int type = Configuration.getPointerType(); + int size = Configuration.getPointerSize(); + int color = Configuration.getPointerColor(); + mLocationOverlay = new LocationOverlay(mMap, type, size, color, MapTrek.density); + layers.add(mMapScaleBarLayer, MAP_OVERLAYS); layers.add(mCrosshairLayer, MAP_OVERLAYS); layers.add(mLocationOverlay, MAP_POSITIONAL); @@ -4530,6 +4535,21 @@ public void onConfigurationChanged(Configuration.ChangedEvent event) { mHillshadeLayer.setBitmapAlpha(1 - transparency * 0.01f); break; } + case Configuration.PREF_POINTER_TYPE: { + int type = Configuration.getPointerType(); + mLocationOverlay.setType(type); + break; + } + case Configuration.PREF_POINTER_SIZE: { + int size = Configuration.getPointerSize(); + mLocationOverlay.setSize(size); + break; + } + case Configuration.PREF_POINTER_COLOR: { + int color = Configuration.getPointerColor(); + mLocationOverlay.setColor(color); + break; + } case Configuration.PREF_PLACE_COLOR: { // Items with default color do not have markers for (MarkerItem item : mMarkerLayer.getItems()) { diff --git a/app/src/main/java/mobi/maptrek/fragments/preferences/Location.java b/app/src/main/java/mobi/maptrek/fragments/preferences/Location.java new file mode 100644 index 00000000..8dc68bed --- /dev/null +++ b/app/src/main/java/mobi/maptrek/fragments/preferences/Location.java @@ -0,0 +1,30 @@ +/* + * Copyright 2024 Andrey Novikov + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + * + */ + +package mobi.maptrek.fragments.preferences; + +import android.os.Bundle; + +import androidx.annotation.Nullable; + +import mobi.maptrek.R; + +public class Location extends BasePreferences { + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + addPreferencesFromResource(R.xml.preferences_location); + } +} diff --git a/app/src/main/java/mobi/maptrek/layers/LocationOverlay.java b/app/src/main/java/mobi/maptrek/layers/LocationOverlay.java index 73378853..bf5af039 100644 --- a/app/src/main/java/mobi/maptrek/layers/LocationOverlay.java +++ b/app/src/main/java/mobi/maptrek/layers/LocationOverlay.java @@ -1,7 +1,7 @@ /* * Copyright 2013 Ahmad Saleem * Copyright 2013 Hannes Janetzek - * Copyright 2016 Andrey Novikov + * Copyright 2024 Andrey Novikov * * This program is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free Software @@ -20,6 +20,7 @@ import android.os.SystemClock; import org.oscim.backend.GL; +import org.oscim.backend.canvas.Color; import org.oscim.core.Box; import org.oscim.core.MercatorProjection; import org.oscim.core.Point; @@ -28,6 +29,7 @@ import org.oscim.map.Map; import org.oscim.renderer.GLShader; import org.oscim.renderer.GLState; +import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLViewport; import org.oscim.renderer.LayerRenderer; import org.oscim.renderer.MapRenderer; @@ -40,10 +42,25 @@ public class LocationOverlay extends Layer { private final Point mLocation = new Point(); private float mBearing; - public LocationOverlay(Map map, float scale) { + public LocationOverlay(Map map, int type, int size, int color, float scale) { super(map); mRenderer = new LocationIndicator(scale); setEnabled(false); + setType(type); + setSize(size); + setColor(color); + } + + public void setType(int type) { + ((LocationIndicator) mRenderer).setType(type); + } + + public void setSize(int size) { + ((LocationIndicator) mRenderer).setSize(size); + } + + public void setColor(int color) { + ((LocationIndicator) mRenderer).setColor(color); } public void setPosition(double latitude, double longitude, float bearing) { @@ -89,10 +106,15 @@ private class LocationIndicator extends LayerRenderer { private int hPhase; private int hDirection; private int hType; + private int hColor; + private static final int COLOR = 0xffff5722; private final static long ANIM_RATE = 50; private final static long INTERVAL = 8000; + private int mType = 0; + private int mSize = 20; + private final float[] mColors = new float[4]; private final Point mIndicatorPosition = new Point(); private final Box mBBox = new Box(); @@ -109,6 +131,23 @@ private class LocationIndicator extends LayerRenderer { LocationIndicator(float scale) { super(); mScale = scale; + setColor(COLOR); + } + + public void setType(int type) { + mType = type; + } + + public void setSize(int size) { + mSize = size; + } + + public void setColor(int color) { + float a = Color.aToFloat(color); + mColors[0] = a * Color.rToFloat(color); + mColors[1] = a * Color.gToFloat(color); + mColors[2] = a * Color.bToFloat(color); + mColors[3] = a; } public boolean isVisible() { @@ -190,7 +229,7 @@ public void render(GLViewport v) { v.mvp.multiplyMM(v.viewproj, v.mvp); v.mvp.setAsUniform(hMatrixPosition); - gl.uniform1f(hScale, mScale); + gl.uniform1f(hScale, mSize * mScale * (mType == 0 ? 1.5f : 1f)); if (mLocationIsVisible) { animate(false); @@ -213,11 +252,15 @@ else if (rotation < -180) } // Pointer type - gl.uniform1f(hType, 0); + gl.uniform1f(hType, mType); + + // Pointer color + GLUtils.glUniform4fv(hColor, 1, mColors); gl.drawArrays(GL.TRIANGLE_STRIP, 0, 4); } + /** @noinspection UnusedReturnValue*/ private boolean init() { int shader = GLShader.loadShader("location_pointer"); if (shader == 0) @@ -230,6 +273,7 @@ private boolean init() { hScale = gl.getUniformLocation(shader, "u_scale"); hDirection = gl.getUniformLocation(shader, "u_dir"); hType = gl.getUniformLocation(shader, "u_type"); + hColor = gl.getUniformLocation(shader, "u_color"); return true; } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index e2d9aba5..f42f9313 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -102,4 +102,9 @@ Cycling Skiing + + Arrow + Circle A + Circle B + diff --git a/app/src/main/res/values/integers.xml b/app/src/main/res/values/integers.xml index b49890a6..ab6d5121 100644 --- a/app/src/main/res/values/integers.xml +++ b/app/src/main/res/values/integers.xml @@ -5,4 +5,6 @@ 0 5 8 + 0 + 25 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 99a73b30..eb8e80d9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -325,11 +325,15 @@ Show titles Accessibility badges Exit confirmation + Location Places, tracks, routes Default color Line width Active route color Active line width + Pointer type + Pointer size + Pointer color Localities Roads diff --git a/app/src/main/res/values/sysarrays.xml b/app/src/main/res/values/sysarrays.xml index cb4641c5..43db74be 100644 --- a/app/src/main/res/values/sysarrays.xml +++ b/app/src/main/res/values/sysarrays.xml @@ -62,4 +62,9 @@ urban topo + + 0 + 1 + 2 + diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 2f557bdf..9133f68d 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -11,6 +11,11 @@ android:key="preferences_units" android:title="@string/pref_units" app:iconSpaceReserved="false" /> + + + + + + \ No newline at end of file