Fiks usynlig retningspil for brukerlokasjon på lyse kart

OSMDroid sin MyLocationNewOverlay brukte stock hvit person- og pil-
bitmap, som forsvant på lyse tiles (snø, sand, lyse OSM-temaer). Bytter
inn appens orange tema med hvit halo og myk skygge — silhuetten holder
≥3:1 kontrast (WCAG 2.2 AA, ikke-tekstlig innhold) mot både lyse og
mørke underlag.

- ic_user_dot.xml: stillestående (orange dot, hvit ring)
- ic_user_arrow.xml: i bevegelse (orange chevron, hvit kontur)
- drawableToBitmap-helper konverterer vector → Bitmap for OSMDroid
- setPersonAnchor/setDirectionAnchor (0.5, 0.5) sentrerer rotasjon

Forgejo: #16
This commit is contained in:
Ole-Morten Duesund 2026-04-29 16:14:53 +02:00
commit d2291a2d35
4 changed files with 68 additions and 2 deletions

View file

@ -5,6 +5,8 @@ import android.content.Context
import android.content.Intent
import android.view.HapticFeedbackConstants
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
@ -186,14 +188,37 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
false // Don't consume the event
}
// Add user location overlay
// Add user location overlay. OSMDroid's stock person/arrow bitmaps
// are pure white and disappear on light tiles - replace with
// app-themed icons that have a white halo + drop shadow so the
// silhouette stays visible on any tile theme (Forgejo #16).
myLocationOverlay = MyLocationNewOverlay(
GpsMyLocationProvider(this@MainActivity), this
)
).apply {
drawableToBitmap(R.drawable.ic_user_dot, sizeDp = 24)?.let {
setPersonIcon(it)
setPersonAnchor(0.5f, 0.5f)
}
drawableToBitmap(R.drawable.ic_user_arrow, sizeDp = 32)?.let {
setDirectionIcon(it)
setDirectionAnchor(0.5f, 0.5f)
}
}
overlays.add(myLocationOverlay)
}
}
private fun drawableToBitmap(@androidx.annotation.DrawableRes resId: Int, sizeDp: Int): Bitmap? {
val drawable = ContextCompat.getDrawable(this, resId) ?: return null
val sizePx = (sizeDp * resources.displayMetrics.density).toInt().coerceAtLeast(1)
val bitmap = Bitmap.createBitmap(sizePx, sizePx, Bitmap.Config.ARGB_8888)
Canvas(bitmap).also { canvas ->
drawable.setBounds(0, 0, sizePx, sizePx)
drawable.draw(canvas)
}
return bitmap
}
private fun setupShelterList() {
shelterAdapter = ShelterListAdapter { swd ->
userSelectedShelter = true

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- User direction marker (moving): orange chevron with white halo + shadow.
Points up at 0deg; OSMDroid rotates by bearing. The triple stack (shadow,
white outline, orange fill) ensures the silhouette is visible against
any tile theme - addresses Forgejo #16. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:fillColor="#55000000"
android:pathData="M16,2.5 L29.5,29 L16,22.5 L2.5,29 Z" />
<path
android:fillColor="#FFFFFFFF"
android:pathData="M16,3 L29,28.5 L16,22 L3,28.5 Z" />
<path
android:fillColor="#FFFF6B35"
android:pathData="M16,7 L25.5,26 L16,21.5 L6.5,26 Z" />
</vector>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- User location marker (stationary): orange dot, white halo, soft shadow.
White ring guarantees >=3:1 contrast against dark tiles; orange core
stays visible against light tiles; shadow keeps the silhouette readable
when both layers happen to land on near-white snow/sand. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#33000000"
android:pathData="M12,12 m-11,0 a11,11 0 1,0 22,0 a11,11 0 1,0 -22,0 z" />
<path
android:fillColor="#FFFFFFFF"
android:pathData="M12,12 m-9.5,0 a9.5,9.5 0 1,0 19,0 a9.5,9.5 0 1,0 -19,0 z" />
<path
android:fillColor="#FFFF6B35"
android:pathData="M12,12 m-6,0 a6,6 0 1,0 12,0 a6,6 0 1,0 -12,0 z" />
</vector>