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

@ -1,3 +1,4 @@
{"id":"tilfluktsrom-5vc","title":"Brukerens retningspil i kartet er hvit og forsvinner på lyse underlag","description":"Mirror av Forgejo-issue #16.\n\nNår brukeren beveger seg raskt nok til at OSMDroid bytter fra person- til retningspil-ikonet i MyLocationNewOverlay, blir pilen tilnærmet usynlig: heltrukken hvit uten kontur eller skygge. På lyse tiles (snø, sand, brede veifyll, lyse OSM-temaer) forsvinner den helt.\n\nÅrsak: MainActivity.kt:190 instansierer MyLocationNewOverlay uten å overstyre setDirectionIcon()/setPersonIcon() — OSMDroid bruker da stock hvite bitmaps.\n\nForslag:\n- Egen vector i res/drawable/ic_user_direction.xml med kontrastfarget fyll + motsatt-farge kontur\n- Kall myLocationOverlay.setDirectionIcon(...) + setPersonIcon(...) eksplisitt\n- Vurder halo-ring (blå pil i hvit ring, Google Maps-stil) for variert underlag\n- Sjekk PWA-en (Leaflet) for samme problem\n\nTilgjengelighet:\n- ≥3:1 kontrast mot både lyse og mørke tiles (WCAG 2.2 AA, ikke-tekstlig innhold)\n- Ikke avhengig av farge alene; konturen sikrer at formen faktisk synes\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/16","acceptance_criteria":"Pilen og person-ikonet i MyLocationNewOverlay er tydelig synlig mot både lyse og mørke kartunderlag (≥3:1 kontrast). Verifisert manuelt på minst ett lyst og ett mørkt kartområde, både stillestående (person) og i bevegelse (pil).","status":"in_progress","priority":2,"issue_type":"bug","assignee":"Ole-Morten Duesund","owner":"olemd@glemt.net","created_at":"2026-04-29T14:06:57Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T14:09:43Z","started_at":"2026-04-29T14:09:43Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"id":"tilfluktsrom-5s7","title":"PWA: manuell testing mangler","description":"Mirror av Forgejo-issue #1.\n\nPWA-versjonen (pwa/) er skrevet, men ikke manuelt testet i nettleser. Enhetstestene passerer, men appen må verifiseres i praksis:\n\n- Start utviklingsserver og test i Chrome/Firefox\n- Test offline-modus (service worker)\n- Test kompass (iOS Safari + Android Chrome)\n- Test installasjon via «Legg til på startskjerm»\n- Test kartbufring og offline kartvisning\n- Test på fysisk iPhone (iOS-spesifikk kompasshåndtering)\n- Test i18n (norsk bokmål, nynorsk, engelsk)\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/1","status":"closed","priority":2,"issue_type":"task","owner":"olemd@glemt.net","created_at":"2026-04-29T13:57:04Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T14:02:57Z","closed_at":"2026-04-29T14:02:57Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"id":"tilfluktsrom-nt8","title":"Åpne i kartapp for gangvei til tilfluktsrom","description":"Mirror av Forgejo-issue #2.\n\nLegg til knapp (på bunnark og/eller kompassvisning) som åpner gangveibeskrivelse til valgt tilfluktsrom i ekstern kartapp.\n\nImplementasjon:\n- ACTION_VIEW intent med geo: URI: geo:lat,lon?q=lat,lon(Tilfluktsrom - adresse)\n- geo: håndteres av tilgjengelig kartapp (OsmAnd, Organic Maps, Google Maps, ...)\n- OsmAnd og Organic Maps støtter offline-navigasjon med geo: — ideelt for degradert nett\n- IKKE hardkode Google Maps-URL-er — bruk geo:\n- Faller pent tilbake hvis ingen kartapp er installert (Toast med koordinater å kopiere)\n- Knapp ved siden av tilfluktsrom-adresse i bunnarket\n\nI en akuttsituasjon er det å finne tilfluktsrommet på kartet bare halve problemet — du må vite gangveien dit. geo:-intent fungerer med offline-kapable kartapper, kritisk når nettet er nede.\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/2","status":"open","priority":2,"issue_type":"feature","owner":"olemd@glemt.net","created_at":"2026-04-29T13:57:03Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T13:57:03Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"id":"tilfluktsrom-gmu","title":"Test og ferdigstill PWA-versjonen","description":"Mirror av Forgejo-issue #7.\n\nFå den eksisterende PWA-en i pwa/-katalogen til å fungere og testet som webfallback.\n\nStatus:\n- Vite + TypeScript + Leaflet + idb + vite-plugin-pwa\n- Shelter-data forhåndsprosesseres ved bygg (scripts/fetch-shelters.ts)\n- Markert som ikke-testet i README (issue #1)\n\nOppgaver:\n- bun install + bun run dev — fikse byggefeil\n- Verifiser at bun run fetch-shelters genererer public/data/shelters.json\n- Test offline (service worker)\n- Test på mobilnettleser (iOS Safari, Android Chrome)\n- Deploy til statisk hosting\n- Lenke til PWA fra Android-appens om-side eller README\n\nWebfallback for iOS-brukere og folk uten Android-app. Også raskest tilgang i en akuttsituasjon.\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/7","status":"closed","priority":2,"issue_type":"task","owner":"olemd@glemt.net","created_at":"2026-04-29T13:56:46Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T14:02:57Z","closed_at":"2026-04-29T14:02:57Z","close_reason":"Closed","dependency_count":0,"dependent_count":1,"comment_count":0}

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>