diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..c544235 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,455 @@ +# Architecture + +This document describes the architecture of Tilfluktsrom, a Norwegian emergency shelter finder available as an Android app and a Progressive Web App (PWA). Both platforms share the same design philosophy — offline-first, no hard external dependencies — but are implemented independently. + +## Table of Contents + +- [Design Principles](#design-principles) +- [Data Pipeline](#data-pipeline) +- [Android App](#android-app) + - [Package Structure](#package-structure) + - [Data Layer](#data-layer) + - [Location & Navigation](#location--navigation) + - [Compass System](#compass-system) + - [Map & Tile Caching](#map--tile-caching) + - [Build Variants](#build-variants) + - [Home Screen Widget](#home-screen-widget) + - [Deep Linking](#deep-linking) +- [Progressive Web App](#progressive-web-app) + - [Module Structure](#module-structure) + - [Build System](#build-system) + - [Data Layer (PWA)](#data-layer-pwa) + - [Location & Compass (PWA)](#location--compass-pwa) + - [Map & Offline Tiles (PWA)](#map--offline-tiles-pwa) + - [Service Worker](#service-worker) + - [UI Components](#ui-components) +- [Shared Algorithms](#shared-algorithms) + - [UTM33N → WGS84 Conversion](#utm33n--wgs84-conversion) + - [Haversine Distance & Bearing](#haversine-distance--bearing) +- [Offline Capability Summary](#offline-capability-summary) +- [Security & Privacy](#security--privacy) +- [Internationalization](#internationalization) + +--- + +## Design Principles + +### Offline-First +This is an emergency app. Core functionality — finding the nearest shelter, compass navigation, distance display — must work without internet after initial setup. Network is used only for initial data download, periodic refresh, and map tile caching. + +### De-Google Compatibility (Android) +The Android app runs on devices without Google Play Services (LineageOS, GrapheneOS, /e/OS). Every Google-specific API has an AOSP fallback. Play Services improve accuracy and battery life when available, but are never required. + +### Minimal Dependencies +Both platforms use few, well-chosen libraries. No heavy frameworks, no external CDNs at runtime. The PWA bundles everything locally; the Android app uses only OSMDroid, Room, OkHttp, and WorkManager. + +### Data Sovereignty +Shelter data comes directly from Geonorge (the Norwegian mapping authority). No intermediate servers. The app fetches, converts, and caches the data locally. + +--- + +## Data Pipeline + +Both platforms consume the same upstream data source: + +``` +Geonorge ZIP (EPSG:25833 UTM33N) + ↓ Download (~320KB) + ↓ Extract GeoJSON from ZIP + ↓ Parse features + ↓ Convert UTM33N → WGS84 (Karney method) + ↓ Validate (Norway bounding box, required fields) + ↓ Store locally +``` + +**Source URL:** `https://nedlasting.geonorge.no/geonorge/Samfunnssikkerhet/TilfluktsromOffentlige/GeoJSON/Samfunnssikkerhet_0000_Norge_25833_TilfluktsromOffentlige_GeoJSON.zip` + +**Fields per shelter:** + +| Field | Description | +|------------|--------------------------------------| +| `lokalId` | Unique identifier (UUID) | +| `romnr` | Shelter room number | +| `plasser` | Capacity (number of people) | +| `adresse` | Street address | +| `latitude` | WGS84 latitude (converted from UTM) | +| `longitude`| WGS84 longitude (converted from UTM) | + +**When conversion happens:** +- **Android:** At runtime during data download (`ShelterGeoJsonParser`) +- **PWA:** At build time (`scripts/fetch-shelters.ts`), output is pre-converted `shelters.json` + +--- + +## Android App + +**Language:** Kotlin · **Min SDK:** 26 (Android 8.0) · **Target SDK:** 35 +**Build:** Gradle 8.7, AGP 8.5.2, KSP for Room annotation processing + +### Package Structure + +``` +no.naiv.tilfluktsrom/ +├── TilfluktsromApp.kt # Application class (OSMDroid config) +├── MainActivity.kt # Central UI controller (~870 lines) +├── data/ +│ ├── Shelter.kt # Room entity +│ ├── ShelterDatabase.kt # Room database singleton +│ ├── ShelterDao.kt # Data access object (Flow queries) +│ ├── ShelterRepository.kt # Repository: bundled seed + network refresh +│ ├── ShelterGeoJsonParser.kt # GeoJSON ZIP → Shelter list +│ └── MapCacheManager.kt # Offline map tile pre-caching +├── location/ +│ ├── LocationProvider.kt # GPS provider (flavor-specific) +│ └── ShelterFinder.kt # Nearest N shelters by Haversine +├── ui/ +│ ├── DirectionArrowView.kt # Custom compass arrow View +│ ├── ShelterListAdapter.kt # RecyclerView adapter for shelter list +│ ├── CivilDefenseInfoDialog.kt # Emergency instructions +│ └── AboutDialog.kt # Privacy and copyright +├── util/ +│ ├── CoordinateConverter.kt # UTM33N → WGS84 (Karney method) +│ └── DistanceUtils.kt # Haversine distance and bearing +└── widget/ + ├── ShelterWidgetProvider.kt # Home screen widget (flavor-specific) + └── WidgetUpdateWorker.kt # WorkManager periodic update +``` + +Files under `location/` and `widget/` have separate implementations per build variant: +- `app/src/standard/java/` — Google Play Services variant +- `app/src/fdroid/java/` — AOSP-only variant + +### Data Layer + +**Storage:** Room (SQLite) with a single `shelters` table. + +**Loading strategy (three-layer fallback):** + +1. **Bundled asset** (`assets/shelters.json`): Pre-converted WGS84 data, loaded on first launch via `ShelterRepository.seedFromAsset()`. Marked as stale (timestamp=0) so a network refresh is attempted when possible. + +2. **Room database**: ~556 shelters cached locally. Reactive updates via Kotlin Flow. Atomic refresh: `deleteAll()` + `insertAll()` in a single transaction. + +3. **Network refresh**: Downloads the Geonorge ZIP via OkHttp, parses with `ShelterGeoJsonParser`. Staleness threshold: 7 days. Runs in the background; failure does not block the UI. + +**GeoJSON parsing pipeline:** +``` +OkHttp response stream + → ZipInputStream (find .geojson entry, 10MB size limit) + → JSON parsing (features array) + → Per feature: + → Extract UTM33N coordinates + → CoordinateConverter.utm33nToWgs84() + → Validate: lokalId not blank, plasser ≥ 0, within Norway bounds + → Create Shelter entity (skip malformed features with warning) +``` + +### Location & Navigation + +**LocationProvider** abstracts GPS access with two flavor implementations: + +| Flavor | Primary | Fallback | +|-----------|----------------------------------|-------------------| +| standard | FusedLocationProviderClient | LocationManager | +| fdroid | LocationManager | — | + +Both emit location updates via Kotlin Flow. Update interval: 5 seconds, fastest 2 seconds. + +**ShelterFinder** takes the user's position and all shelters, computes Haversine distance and initial bearing for each, sorts by distance, and returns the N nearest (default: 3) as `ShelterWithDistance` objects. + +### Compass System + +**Sensor priority:** +1. Rotation Vector sensor (`TYPE_ROTATION_VECTOR`) — most accurate, single sensor +2. Accelerometer + Magnetometer — low-pass filtered (α=0.25) for smoothing +3. No compass available — error message shown + +**Direction calculation:** +``` +arrowAngle = shelterBearing − deviceHeading +``` + +**DirectionArrowView** is a custom View that draws: +- A large arrow rotated by `arrowAngle`, pointing toward the shelter +- An optional north indicator on the perimeter for compass calibration + +### Map & Tile Caching + +**Map library:** OSMDroid (OpenStreetMap, no Google dependency). + +**Tile caching:** OSMDroid's built-in `SqlTileWriter` passively caches every tile loaded. `MapCacheManager` supplements this with active pre-caching: + +- Pans the MapView across a 3×3 grid at zoom levels 10, 12, 14, 16 +- 300ms delay between pans (respects OSM tile usage policy) +- Covers ~15km radius around the user +- Progress reported via callback for UI display + +Tile cache stored in app-specific internal storage (`osmdroidBasePath`). + +### Build Variants + +``` +productFlavors { + standard { } // Google Play Services + AOSP fallback + fdroid { } // AOSP only +} +``` + +The `standard` flavor adds `com.google.android.gms:play-services-location`. Runtime detection via `GoogleApiAvailability` determines which code path runs. + +Both flavors produce identical user experiences — `standard` achieves faster GPS fixes and better battery efficiency when Play Services are present. + +### Home Screen Widget + +**ShelterWidgetProvider** displays the nearest shelter's address, capacity, and distance. Updated by: + +1. **MainActivity** — sends latest location on each GPS update +2. **WorkManager** — `WidgetUpdateWorker` runs every 15 minutes, requests a fresh location fix +3. **Manual** — user taps refresh button on the widget + +**Location resolution (priority order):** +1. Location from intent (WorkManager or MainActivity) +2. FusedLocationProviderClient cache (standard) +3. Active GPS request (10s timeout) +4. LocationManager cache +5. SharedPreferences saved location (max 24h old) + +### Deep Linking + +**HTTPS App Links:** `https://tilfluktsrom.naiv.no/shelter/{lokalId}` + +The domain is configured in one place: `DEEP_LINK_DOMAIN` in `build.gradle.kts` (exposed as `BuildConfig.DEEP_LINK_DOMAIN` and manifest placeholder `${deepLinkHost}`). + +- `autoVerify="true"` on the HTTPS intent filter triggers Android's App Links verification at install time +- Verification requires `/.well-known/assetlinks.json` to be served by the PWA (in `pwa/public/.well-known/`) +- If the app is installed and verified, `/shelter/*` links open the app directly (no disambiguation dialog) +- If not installed, the link opens in the browser, where the PWA handles it + +Share messages include the HTTPS URL, which SMS apps auto-link as a tappable URL. + +--- + +## Progressive Web App + +**Stack:** TypeScript, Vite 5, Leaflet, idb (IndexedDB wrapper), vite-plugin-pwa +**Package manager:** bun + +### Module Structure + +``` +pwa/ +├── index.html # SPA shell, CSP headers, semantic layout +├── vite.config.ts # Build config, PWA plugin, tile caching rules +├── manifest.webmanifest # PWA metadata and icons +├── scripts/ +│ └── fetch-shelters.ts # Build-time: download + convert shelter data +├── public/ +│ └── data/shelters.json # Pre-processed shelter data (build artifact) +└── src/ + ├── main.ts # Entry point, SW registration, locale init + ├── app.ts # Main controller (~400 lines) + ├── types.ts # Shelter, ShelterWithDistance, LatLon interfaces + ├── data/ + │ ├── shelter-repository.ts # Fetch + IndexedDB storage + │ └── shelter-db.ts # IndexedDB wrapper (idb library) + ├── location/ + │ ├── location-provider.ts # navigator.geolocation wrapper + │ ├── compass-provider.ts # DeviceOrientationEvent (iOS/Android) + │ └── shelter-finder.ts # Haversine nearest-N calculation + ├── ui/ + │ ├── map-view.ts # Leaflet map, custom SVG markers + │ ├── compass-view.ts # Canvas-based direction arrow + │ ├── shelter-list.ts # Bottom sheet shelter list + │ ├── loading-overlay.ts # Modal spinner / cache prompt + │ ├── about-dialog.ts # Privacy, data info, cache clear + │ ├── civil-defense-dialog.ts # DSB 5-step emergency guide + │ └── status-bar.ts # Status text and refresh button + ├── cache/ + │ └── map-cache-manager.ts # Tile pre-caching via programmatic panning + ├── i18n/ + │ ├── i18n.ts # Locale detection, string substitution + │ ├── en.ts # English strings + │ ├── nb.ts # Bokmål strings + │ └── nn.ts # Nynorsk strings + ├── util/ + │ └── distance-utils.ts # Haversine distance, bearing, formatting + └── main.css # Dark theme, Leaflet overrides, dialogs +``` + +### Build System + +**Vite** bundles the app with content-hashed filenames for cache busting. + +**Key configuration:** +- Base path: `./` (relative, deployable anywhere) +- `__BUILD_REVISION__` define: ISO timestamp injected at build time, used to invalidate service worker caches +- **vite-plugin-pwa**: Generates the service worker with Workbox. Precaches all static assets. Runtime-caches OSM tile requests with CacheFirst strategy (30-day expiry, max 5000 entries). + +**Build-time data preprocessing:** +`scripts/fetch-shelters.ts` downloads the Geonorge ZIP, extracts the GeoJSON, converts UTM33N→WGS84, validates, and writes `public/data/shelters.json`. This means coordinate conversion is a build step, not a runtime cost. + +```bash +bun run fetch-shelters # Download and convert shelter data +bun run build # TypeScript check + Vite build + SW generation +``` + +### Data Layer (PWA) + +**Storage:** IndexedDB via the `idb` library. + +**Schema:** +- Object store `shelters` (keyPath: `lokalId`) — full shelter records +- Object store `metadata` — `lastUpdate` timestamp + +**Loading strategy:** +1. Check IndexedDB for cached shelters +2. If empty or stale (>7 days): fetch `shelters.json` (precached by service worker) +3. Replace all records in a single transaction +4. Reactive: UI reads from IndexedDB after load + +Unlike the Android app, the PWA does not perform coordinate conversion at runtime — `shelters.json` is pre-converted at build time and served as a static asset. + +### Location & Compass (PWA) + +**Location:** `navigator.geolocation.watchPosition()` with high accuracy enabled, 10s maximum age, 30s timeout. + +**Compass:** DeviceOrientationEvent with platform-specific handling: + +| Platform | API | Heading Source | +|----------------|------------------------------|--------------------------| +| iOS Safari | `deviceorientation` | `webkitCompassHeading` | +| Android Chrome | `deviceorientationabsolute` | `(360 − alpha) % 360` | + +iOS 13+ requires an explicit permission request (`DeviceOrientationEvent.requestPermission()`), triggered by a user gesture. + +Low-pass filter (smoothing factor 0.3) with 0/360° wraparound handling ensures fluid rotation. + +### Map & Offline Tiles (PWA) + +**Map library:** Leaflet with OpenStreetMap tiles. No CDN — Leaflet is bundled from `node_modules`. + +**Custom markers:** SVG-based `divIcon` elements — orange house with "T" for shelters, blue circle for user location. Selected shelter uses a larger yellow marker. + +**Auto-fit logic:** When a shelter is selected, the map fits bounds to show both user and shelter (30% padding), unless the user has manually panned or zoomed. A "reset view" button appears after manual interaction. + +**Tile pre-caching:** `MapCacheManager` uses the same approach as the Android app — programmatically pans the map across a 3×3 grid at 4 zoom levels. The service worker's runtime cache intercepts and stores the tile requests. Cache location stored in localStorage (rounded to ~11km precision for privacy). + +### Service Worker + +Generated by vite-plugin-pwa (Workbox): + +- **Precaching:** All static assets (JS, CSS, HTML, JSON, images) with content-hash versioning +- **Runtime caching:** OSM tiles from `{a,b,c}.tile.openstreetmap.org` with CacheFirst strategy, 30-day TTL, max 5000 entries +- **Navigation fallback:** Serves `index.html` for all navigation requests (SPA behavior) +- **Auto-update:** New service worker activates automatically; `controllerchange` event notifies the user + +`main.ts` injects the build revision into the service worker context, ensuring each build invalidates stale caches. It also requests persistent storage (`navigator.storage.persist()`) to prevent the browser from evicting cached data. + +### UI Components + +The PWA uses no framework — all UI is vanilla TypeScript manipulating the DOM. + +| Component | Description | +|--------------------------|----------------------------------------------------------| +| `app.ts` | Main controller: wires components, manages state | +| `map-view.ts` | Leaflet map with custom markers, auto-fit, interaction tracking | +| `compass-view.ts` | Canvas-rendered arrow with north indicator, requestAnimationFrame | +| `shelter-list.ts` | Bottom sheet with 3 nearest shelters, click selection | +| `loading-overlay.ts` | Modal: spinner during load, OK/Skip for cache prompt | +| `about-dialog.ts` | Privacy statement, data sources, "clear cache" button | +| `civil-defense-dialog.ts`| DSB emergency instructions (5 steps) | +| `status-bar.ts` | Data freshness indicator, refresh button | + +Dialogs are created dynamically and implement focus management (save/restore previous focus, trap focus inside modal). + +--- + +## Shared Algorithms + +Both platforms implement these algorithms independently (no shared code), ensuring each platform has zero runtime dependencies on the other. + +### UTM33N → WGS84 Conversion + +**Algorithm:** Karney series expansion method. + +Converts EUREF89 / UTM zone 33N (EPSG:25833) to WGS84 (EPSG:4326). + +**Constants:** +- Semi-major axis: 6,378,137 m +- Flattening: 1/298.257223563 +- UTM zone 33 central meridian: 15° E +- Scale factor: 0.9996 +- False easting: 500,000 m + +**Steps:** +1. Remove false easting/northing +2. Compute footprint latitude using series expansion +3. Apply iterative corrections for latitude and longitude +4. Add central meridian offset + +**Validation:** Reject results outside Norway bounding box (57–72°N, 3–33°E). + +**Implementations:** +- Android: `util/CoordinateConverter.kt` (runtime) +- PWA: `scripts/fetch-shelters.ts` (build-time) + +### Haversine Distance & Bearing + +**Distance** between two WGS84 points: +``` +a = sin²(Δφ/2) + cos(φ₁) · cos(φ₂) · sin²(Δλ/2) +d = 2R · atan2(√a, √(1−a)) +``` +Where R = 6,371 km (Earth mean radius). + +**Initial bearing** from point 1 to point 2: +``` +θ = atan2(sin(Δλ) · cos(φ₂), cos(φ₁) · sin(φ₂) − sin(φ₁) · cos(φ₂) · cos(Δλ)) +``` +Result in degrees: 0° = north, 90° = east, 180° = south, 270° = west. + +**Implementations:** +- Android: `util/DistanceUtils.kt` +- PWA: `util/distance-utils.ts` + +--- + +## Offline Capability Summary + +| Capability | Android | PWA | +|-------------------------|----------------------------------|------------------------------------| +| Shelter data | Room DB + bundled asset seed | IndexedDB + precached JSON | +| Map tiles | OSMDroid SqlTileWriter + active pre-cache | Service worker CacheFirst + active pre-cache | +| GPS | Device hardware (no network) | Device hardware (no network) | +| Compass | Device sensors | DeviceOrientationEvent | +| Distance/bearing math | Local computation | Local computation | +| Network required for | Initial refresh, new tiles | Initial page load, new tiles | +| Staleness threshold | 7 days | 7 days | + +--- + +## Security & Privacy + +- **No tracking:** No analytics, no telemetry, no external requests beyond Geonorge data and OSM tiles +- **No user accounts:** No registration, no login, no server-side storage +- **Location stays local:** GPS coordinates are used only for distance calculation and never transmitted +- **HTTPS enforced:** Android network security config restricts to TLS; PWA CSP headers restrict connections +- **ZIP bomb protection:** 10MB limit on uncompressed GeoJSON (Android parser) +- **CSP headers (PWA):** Restrictive Content-Security-Policy blocks external scripts; `img-src` allows only OSM tile servers +- **Input validation:** Shelter data validated at parse time (bounds check, required fields, non-negative capacity) +- **Minimal permissions:** Location only; no contacts, camera, storage (except legacy tile cache on Android ≤9) + +--- + +## Internationalization + +Both platforms support three languages: + +| Language | Android | PWA | +|---------------------|----------------------|----------------| +| English (default) | `values/strings.xml` | `i18n/en.ts` | +| Norwegian Bokmål | `values-nb/strings.xml` | `i18n/nb.ts` | +| Norwegian Nynorsk | `values-nn/strings.xml` | `i18n/nn.ts` | + +**Android:** Uses Android's built-in locale resolution. Per-app language selection supported on Android 13+ via `locales_config.xml`. + +**PWA:** Detects browser language (`navigator.language`). String substitution supports `%d` (number) and `%s` (string) placeholders. Falls back to English for unsupported locales. diff --git a/CLAUDE.md b/CLAUDE.md index a5b4d4d..df4f859 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -58,10 +58,26 @@ no.naiv.tilfluktsrom/ - **fdroid**: AOSP-only, no Google dependencies ## Distribution -- **Forgejo** (primary): `kode.naiv.no/olemd/tilfluktsrom` — releases with both APK variants +- **Forgejo** (primary): `kode.naiv.no/olemd/tilfluktsrom` — releases with both APK variants + PWA tarball - **GitHub** (mirror): `github.com/olemd/tilfluktsrom` — automatically mirrored from Forgejo, do not push manually - **F-Droid**: Metadata maintained in a separate fdroiddata repo (GitLab fork). F-Droid builds from source using the `fdroid` variant and signs with the F-Droid key. +## Release Process +When creating a new release: +1. Bump `versionCode` and `versionName` in `app/build.gradle.kts` +2. Update User-Agent string in `ShelterRepository.kt` to match new version +3. Build Android APKs: `./gradlew assembleStandardRelease assembleFdroidRelease` +4. Build PWA: `cd pwa && bun scripts/fetch-shelters.ts && bun run build && tar -czf /tmp/tilfluktsrom-vX.Y.Z-pwa.tar.gz -C dist .` +5. Commit, push, then create Forgejo release with all three artifacts: + ```bash + fj release create --create-tag vX.Y.Z --branch main \ + --attach "/tmp/tilfluktsrom-vX.Y.Z-standard.apk:tilfluktsrom-vX.Y.Z-standard.apk" \ + --attach "/tmp/tilfluktsrom-vX.Y.Z-fdroid.apk:tilfluktsrom-vX.Y.Z-fdroid.apk" \ + --body "release notes" "vX.Y.Z" + fj release asset create vX.Y.Z /tmp/tilfluktsrom-vX.Y.Z-pwa.tar.gz tilfluktsrom-vX.Y.Z-pwa.tar.gz + ``` +6. Install on phone: `adb install -r app/build/outputs/apk/standard/release/app-standard-release.apk` + ## Screenshots Use the Android emulator and Maestro to take screenshots for the README and fastlane metadata. diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c46b0b4..5992c73 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -14,8 +14,13 @@ android { applicationId = "no.naiv.tilfluktsrom" minSdk = 26 targetSdk = 35 - versionCode = 11 - versionName = "1.7.0" + versionCode = 12 + versionName = "1.8.0" + + // Deep link domain — single source of truth for manifest + Kotlin code + val deepLinkDomain = "tilfluktsrom.naiv.no" + buildConfigField("String", "DEEP_LINK_DOMAIN", "\"$deepLinkDomain\"") + manifestPlaceholders["deepLinkHost"] = deepLinkDomain } dependenciesInfo { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 58bf2ed..e522483 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -29,13 +29,14 @@ - + + android:scheme="https" + android:host="${deepLinkHost}" + android:pathPrefix="/shelter/" /> diff --git a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt index e1fd8e0..5f80847 100644 --- a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt +++ b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt @@ -143,12 +143,14 @@ class MainActivity : AppCompatActivity(), SensorEventListener { } /** - * Handle tilfluktsrom://shelter/{lokalId} deep link. + * Handle https://{domain}/shelter/{lokalId} deep link. * If shelters are already loaded, select immediately; otherwise store as pending. */ private fun handleDeepLinkIntent(intent: Intent?) { val uri = intent?.data ?: return - if (uri.scheme != "tilfluktsrom" || uri.host != "shelter") return + if (uri.scheme != "https" || + uri.host != BuildConfig.DEEP_LINK_DOMAIN || + uri.path?.startsWith("/shelter/") != true) return val lokalId = uri.lastPathSegment ?: return // Clear intent data so config changes don't re-trigger @@ -669,8 +671,8 @@ class MainActivity : AppCompatActivity(), SensorEventListener { /** * Share the currently selected shelter via ACTION_SEND. - * Includes address, capacity, geo: URI (for non-app recipients), - * and a tilfluktsrom:// deep link (for app users). + * Includes address, capacity, geo: URI, and an HTTPS deep link + * that opens the app (if installed) or the PWA (in browser). */ private fun shareShelter() { val selected = selectedShelter @@ -680,12 +682,14 @@ class MainActivity : AppCompatActivity(), SensorEventListener { } val shelter = selected.shelter + val deepLink = "https://${BuildConfig.DEEP_LINK_DOMAIN}/shelter/${shelter.lokalId}" val body = getString( R.string.share_body, shelter.adresse, shelter.plasser, shelter.latitude, - shelter.longitude + shelter.longitude, + deepLink ) val shareIntent = Intent(Intent.ACTION_SEND).apply { diff --git a/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt b/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt index b5afd3b..048a93d 100644 --- a/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt +++ b/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt @@ -46,7 +46,7 @@ class ShelterRepository(private val context: Context) { .readTimeout(60, TimeUnit.SECONDS) .addInterceptor(Interceptor { chain -> chain.proceed(chain.request().newBuilder() - .header("User-Agent", "Tilfluktsrom/1.7.0") + .header("User-Agent", "Tilfluktsrom/1.8.0") .build()) }) .build() diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 74c464b..8f0f2d3 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -60,7 +60,7 @@ Tilfluktsrom - Tilfluktsrom: %1$s\n%2$d plasser\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f + Tilfluktsrom: %1$s\n%2$d plasser\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s Ingen tilfluktsrom valgt diff --git a/app/src/main/res/values-nn/strings.xml b/app/src/main/res/values-nn/strings.xml index f3077e5..088398a 100644 --- a/app/src/main/res/values-nn/strings.xml +++ b/app/src/main/res/values-nn/strings.xml @@ -60,7 +60,7 @@ Tilfluktsrom - Tilfluktsrom: %1$s\n%2$d plassar\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f + Tilfluktsrom: %1$s\n%2$d plassar\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s Ingen tilfluktsrom valt diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 38d09b2..34afc98 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -60,7 +60,7 @@ Emergency shelter - Shelter: %1$s\n%2$d places\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f + Shelter: %1$s\n%2$d places\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s No shelter selected diff --git a/pwa/.gitignore b/pwa/.gitignore index b947077..35ca4c8 100644 --- a/pwa/.gitignore +++ b/pwa/.gitignore @@ -1,2 +1,3 @@ node_modules/ dist/ +public/data/shelters.json diff --git a/pwa/index.html b/pwa/index.html index 876bde3..7440b65 100644 --- a/pwa/index.html +++ b/pwa/index.html @@ -6,14 +6,11 @@ + content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://*.tile.openstreetmap.org; connect-src 'self' https://*.tile.openstreetmap.org; font-src 'self'; worker-src 'self'" /> Tilfluktsrom - - - - + + +
@@ -66,6 +63,6 @@
- + diff --git a/pwa/public/.well-known/assetlinks.json b/pwa/public/.well-known/assetlinks.json new file mode 100644 index 0000000..b95a5f1 --- /dev/null +++ b/pwa/public/.well-known/assetlinks.json @@ -0,0 +1,12 @@ +[ + { + "relation": ["delegate_permission/common.handle_all_urls"], + "target": { + "namespace": "android_app", + "package_name": "no.naiv.tilfluktsrom", + "sha256_cert_fingerprints": [ + "43:05:79:6F:EA:3E:F4:50:45:D3:8A:EF:EA:58:B6:65:49:D2:D2:C3:4B:4C:61:11:EE:74:48:B0:C7:70:E4:5B" + ] + } + } +] diff --git a/pwa/public/data/shelters.json b/pwa/public/data/shelters.json deleted file mode 100644 index 239a144..0000000 --- a/pwa/public/data/shelters.json +++ /dev/null @@ -1,4450 +0,0 @@ -[ - { - "lokalId": "87853d43-4dda-4964-96e5-96dffc1cf7f3", - "romnr": 776, - "plasser": 400, - "adresse": "Trimv. 09 - Borre Idrettspark (off)", - "latitude": 59.404915, - "longitude": 10.462107 - }, - { - "lokalId": "630ff427-3bfe-4766-b67c-89258e4d7055", - "romnr": 777, - "plasser": 390, - "adresse": "Torget 6", - "latitude": 59.417183, - "longitude": 10.483879 - }, - { - "lokalId": "c46fa6c9-5963-42f3-a034-830e1e0b5678", - "romnr": 785, - "plasser": 370, - "adresse": "Vestre Braarudgt. 6b - Åsheim", - "latitude": 59.4177, - "longitude": 10.479063 - }, - { - "lokalId": "fa659eb8-49cf-4c1e-8f12-e3cf3e75d28d", - "romnr": 786, - "plasser": 215, - "adresse": "Vognmannsgt. 1 - Trygdegården", - "latitude": 59.415724, - "longitude": 10.483809 - }, - { - "lokalId": "13486699-ae0a-443f-8fda-e48aa24a5d87", - "romnr": 787, - "plasser": 800, - "adresse": "Langgt. 14", - "latitude": 59.489427, - "longitude": 10.315461 - }, - { - "lokalId": "9245e9ca-3425-462d-b913-57ddaac9cd6a", - "romnr": 788, - "plasser": 159, - "adresse": "Badeparken 7 - Bøkeskogen eldresenter", - "latitude": 59.057097, - "longitude": 10.029484 - }, - { - "lokalId": "2ed1eaf2-3cb7-47c0-bf56-e2536b036815", - "romnr": 789, - "plasser": 265, - "adresse": "Byskogv. 5 - Byskogen Bo- og aktivitetssenter", - "latitude": 59.053505, - "longitude": 10.036693 - }, - { - "lokalId": "ed81c068-a806-40fe-9720-da17282d8624", - "romnr": 791, - "plasser": 128, - "adresse": "Øvre Dr. Holms vei 44 - KUF-huset", - "latitude": 59.056225, - "longitude": 10.047809 - }, - { - "lokalId": "3c482130-3752-4480-9446-ecb164ece9ba", - "romnr": 793, - "plasser": 220, - "adresse": "Nordbyveien 27 - Hagatun grendehus", - "latitude": 59.077853, - "longitude": 10.049947 - }, - { - "lokalId": "264c5903-71df-47c1-bdb4-05a582e645b1", - "romnr": 794, - "plasser": 220, - "adresse": "Rosendalsgt. 17 - Langestrand skole", - "latitude": 59.048978, - "longitude": 10.011399 - }, - { - "lokalId": "e7a139a6-6582-4986-9da2-d8d13f17eacc", - "romnr": 795, - "plasser": 850, - "adresse": "Ahlefeldtsgt. 1 - Mesterfjellet", - "latitude": 59.049386, - "longitude": 10.041182 - }, - { - "lokalId": "fcf81be7-c342-4214-a08d-218d065da7ed", - "romnr": 796, - "plasser": 425, - "adresse": "Skallestadv. 38 - Hårkollhallen", - "latitude": 59.200725, - "longitude": 10.442214 - }, - { - "lokalId": "ca9264db-5a82-4904-9944-f6dbd1f3313e", - "romnr": 797, - "plasser": 42, - "adresse": "Tinghaugv. 14 - Nøtterøy kulturhus, nedre rom", - "latitude": 59.225079, - "longitude": 10.409499 - }, - { - "lokalId": "1c8c9782-1a18-475c-9d3a-a7880c61a7ed", - "romnr": 798, - "plasser": 225, - "adresse": "Tinghaugv. 14 - Nøtterøy kulturhus, øvre rom", - "latitude": 59.225024, - "longitude": 10.409453 - }, - { - "lokalId": "0bf67a70-c797-4b99-9516-6ef9f2edb7fa", - "romnr": 799, - "plasser": 415, - "adresse": "Harpunv. 3 - Optura A/S (off.)", - "latitude": 59.262825, - "longitude": 10.390622 - }, - { - "lokalId": "dfeff471-85d2-4f2f-a119-b9b4c7d173a7", - "romnr": 802, - "plasser": 195, - "adresse": "Sportsv. 31 - Off. Bugården u-skole", - "latitude": 59.134069, - "longitude": 10.187642 - }, - { - "lokalId": "d9be3b5e-b011-4732-b46c-db393892eae2", - "romnr": 803, - "plasser": 1170, - "adresse": "Dronningensgt. 24 - Off. Forsmannssenteret", - "latitude": 59.132868, - "longitude": 10.21984 - }, - { - "lokalId": "eb68ddcf-0464-4e34-831e-1efd59a180cc", - "romnr": 804, - "plasser": 293, - "adresse": "Lyhmannsv. 2 - Off. Framnes Eldresenter", - "latitude": 59.118233, - "longitude": 10.234024 - }, - { - "lokalId": "34674a45-67ed-4ccf-951e-ba69a63e6207", - "romnr": 805, - "plasser": 1233, - "adresse": "Maurveien 14 - Off. Gjekstad (garasjeanlegg)", - "latitude": 59.131677, - "longitude": 10.264337 - }, - { - "lokalId": "5ce1823a-3eec-40b7-955f-b09677a2069e", - "romnr": 806, - "plasser": 400, - "adresse": "Gokstadv. 5 - Off.", - "latitude": 59.134373, - "longitude": 10.229432 - }, - { - "lokalId": "096655bc-6260-46ef-ae0f-b85747c75635", - "romnr": 807, - "plasser": 600, - "adresse": "Høstsgt. 3 - Off.", - "latitude": 59.129605, - "longitude": 10.214538 - }, - { - "lokalId": "712a4c9c-fd0f-4779-ab52-177d2cc9e47b", - "romnr": 808, - "plasser": 200, - "adresse": "Hystadv. 167 - Off. Jotun A/S", - "latitude": 59.111364, - "longitude": 10.222859 - }, - { - "lokalId": "9139f600-e7cf-46f0-877f-3df577e4091d", - "romnr": 809, - "plasser": 300, - "adresse": "Rødslia 28 - I krysset ved Fagerstadveien", - "latitude": 59.115648, - "longitude": 10.240034 - }, - { - "lokalId": "1071e773-5a36-477d-87d9-a00ce5d35baf", - "romnr": 810, - "plasser": 400, - "adresse": "Sandefjordsv. 3 - Off. Sandefjord Rådhus", - "latitude": 59.128743, - "longitude": 10.219716 - }, - { - "lokalId": "ea2c071c-139a-42fd-a241-2fa45a02f601", - "romnr": 813, - "plasser": 1500, - "adresse": "Haugar", - "latitude": 59.268637, - "longitude": 10.410234 - }, - { - "lokalId": "3db39a05-3227-47e4-86fe-f3726f0eae21", - "romnr": 814, - "plasser": 150, - "adresse": "Larvev. 31 - Hogsnes Grendehus, rom 1 (off)", - "latitude": 59.26682, - "longitude": 10.356823 - }, - { - "lokalId": "94a80dc3-3c75-4883-a2d4-f22036e62233", - "romnr": 815, - "plasser": 150, - "adresse": "Larvev. 31 - Hogsnes Grendehus, rom 2 (off)", - "latitude": 59.26682, - "longitude": 10.356823 - }, - { - "lokalId": "99ccff09-c015-47a0-ba6d-865b17824def", - "romnr": 816, - "plasser": 962, - "adresse": "Slottsfjelltunnelen (off)", - "latitude": 59.270745, - "longitude": 10.401937 - }, - { - "lokalId": "b16aa85d-9318-460d-bb86-432f66ed7a71", - "romnr": 817, - "plasser": 215, - "adresse": "Trimveien 14 - ved Slagenhallen", - "latitude": 59.269527, - "longitude": 10.462225 - }, - { - "lokalId": "7e320f2d-4de5-438a-b451-0ab115ba5cb1", - "romnr": 831, - "plasser": 800, - "adresse": "Dronningensgate 52", - "latitude": 68.437973, - "longitude": 17.429275 - }, - { - "lokalId": "2e1fd4f8-f4f5-4208-840b-7811da72b777", - "romnr": 917, - "plasser": 215, - "adresse": "Torget 6", - "latitude": 58.451713, - "longitude": 6.001131 - }, - { - "lokalId": "f5dc9a2e-a4d7-4005-afdd-fcce77fe0ac3", - "romnr": 933, - "plasser": 240, - "adresse": "Jernbaneveien 22", - "latitude": 58.455565, - "longitude": 6.002466 - }, - { - "lokalId": "071349d7-e899-4718-85af-6dfbd4299bc7", - "romnr": 934, - "plasser": 88, - "adresse": "Sokndalsveien 26", - "latitude": 58.447808, - "longitude": 6.006581 - }, - { - "lokalId": "a839751e-51bf-4697-8ec9-aa659eaf64b0", - "romnr": 1220, - "plasser": 270, - "adresse": "Røyrvika 10", - "latitude": 58.736629, - "longitude": 5.655472 - }, - { - "lokalId": "b3150f2e-1589-4f1c-a0b6-1643ea849f68", - "romnr": 1255, - "plasser": 60, - "adresse": "Bedriftsvegen 6", - "latitude": 58.785422, - "longitude": 5.697514 - }, - { - "lokalId": "b692f1ac-e55c-436e-8a01-bdef8b810a8f", - "romnr": 1286, - "plasser": 180, - "adresse": "Kleppevarden 2", - "latitude": 58.774921, - "longitude": 5.627087 - }, - { - "lokalId": "c3df37b1-1adc-4fcd-90ba-8f194c0232af", - "romnr": 1423, - "plasser": 30, - "adresse": "Horghallvegen 25, HORGHALLEN", - "latitude": 63.15113, - "longitude": 10.283676 - }, - { - "lokalId": "baffc78f-6c35-4d46-be4c-eec0049ba024", - "romnr": 1434, - "plasser": 50, - "adresse": "Tømmesdalsvegen 70, HOVIN SKOLE/SAMF.HUS", - "latitude": 63.106671, - "longitude": 10.226629 - }, - { - "lokalId": "443aac13-ea31-41fd-a3f6-7a553f256862", - "romnr": 1435, - "plasser": 60, - "adresse": "Per Bortens veg 21, MELHUS SKYSSTASJON", - "latitude": 63.28477, - "longitude": 10.276954 - }, - { - "lokalId": "2da7587c-44f0-4c20-9914-6484370d6d2f", - "romnr": 1515, - "plasser": 200, - "adresse": "STATENS HUS ORKANGER", - "latitude": 63.297739, - "longitude": 9.847558 - }, - { - "lokalId": "9763b9a2-e781-46b6-925f-82207c6cc206", - "romnr": 1516, - "plasser": 33, - "adresse": "TORGSENTERET, ORKANGER", - "latitude": 63.305067, - "longitude": 9.849685 - }, - { - "lokalId": "c5259e37-3e49-413a-8f34-c6aca0468ca3", - "romnr": 1517, - "plasser": 40, - "adresse": "Orkdalsveien 82", - "latitude": 63.301909, - "longitude": 9.848431 - }, - { - "lokalId": "7b56309c-8595-4f67-9b1c-b72c4ef69293", - "romnr": 1563, - "plasser": 16, - "adresse": "Sollihagaen 17, RØROS KJØLESERVICE", - "latitude": 62.571786, - "longitude": 11.369025 - }, - { - "lokalId": "f2362ae1-bb9a-4018-b1ce-e94651dd91f2", - "romnr": 1568, - "plasser": 20, - "adresse": "Lorentz Lossius gata 45, RØROSMUSEET", - "latitude": 62.577088, - "longitude": 11.391251 - }, - { - "lokalId": "a9a1b57f-b1bc-4016-9b50-c113ea290893", - "romnr": 1628, - "plasser": 170, - "adresse": "Teletunet, Opphaug, Offentlig", - "latitude": 63.725351, - "longitude": 9.687023 - }, - { - "lokalId": "7fcaa9f0-fc08-46a7-b6fb-1a2d83500d7d", - "romnr": 1681, - "plasser": 315, - "adresse": "Kaigaten 8 OFF T-ROM hotellet", - "latitude": 70.37253, - "longitude": 31.103902 - }, - { - "lokalId": "bd92c299-14bc-4e46-bf49-8144058702f8", - "romnr": 1688, - "plasser": 136, - "adresse": "BANEHEIVEIEN", - "latitude": 58.149152, - "longitude": 7.982371 - }, - { - "lokalId": "4fae9780-f765-4fc0-99a0-1e38c11f465e", - "romnr": 1707, - "plasser": 195, - "adresse": "BYDALSVEIEN 19", - "latitude": 58.148045, - "longitude": 7.922027 - }, - { - "lokalId": "271b4f52-2053-4bbd-bf72-dfdf99435a7f", - "romnr": 1740, - "plasser": 65, - "adresse": "FREDRIK FRANSSONSVEI 4", - "latitude": 58.182995, - "longitude": 8.083974 - }, - { - "lokalId": "b22c8975-2250-436a-ac57-6ca4e70a5188", - "romnr": 1755, - "plasser": 235, - "adresse": "GROSTØLVEIEN 4 E", - "latitude": 58.200181, - "longitude": 8.03204 - }, - { - "lokalId": "8cdb7ae6-39a7-478d-ac53-5ba35e7a8980", - "romnr": 1756, - "plasser": 500, - "adresse": "GRÅGÅSVEIEN 43", - "latitude": 58.121466, - "longitude": 7.936556 - }, - { - "lokalId": "52c634f3-32e0-4d27-895e-3f9e8a51f03e", - "romnr": 1776, - "plasser": 170, - "adresse": "RAVNEDALSVEIEN 34", - "latitude": 58.155102, - "longitude": 7.972959 - }, - { - "lokalId": "d390adf0-b68f-4ed1-bc44-2146cbe203ab", - "romnr": 1795, - "plasser": 50, - "adresse": "HÅNESVEIEN 61", - "latitude": 58.181109, - "longitude": 8.08888 - }, - { - "lokalId": "741fe60c-0401-47d1-8559-6503245da9aa", - "romnr": 1799, - "plasser": 390, - "adresse": "INDUSTRIGATA 6", - "latitude": 58.151396, - "longitude": 8.025719 - }, - { - "lokalId": "2896f65b-8106-4a2c-9c0f-ccc7b4d65c72", - "romnr": 1818, - "plasser": 170, - "adresse": "JORDBÆRVEIEN 2", - "latitude": 58.175809, - "longitude": 8.09532 - }, - { - "lokalId": "eb74ad26-64b8-4be3-8805-5605c759c9fd", - "romnr": 1822, - "plasser": 184, - "adresse": "KARUSSVEIEN 7", - "latitude": 58.129267, - "longitude": 7.946368 - }, - { - "lokalId": "6e8126e5-d179-4d8c-b8f6-d9cff8cca8c8", - "romnr": 1832, - "plasser": 465, - "adresse": "KIRSTEN FLAGSTADSVEI 30", - "latitude": 58.12539, - "longitude": 7.953968 - }, - { - "lokalId": "00631cd5-e0bc-4b72-a827-a388dea3f008", - "romnr": 1857, - "plasser": 243, - "adresse": "KONGENSGATE 2", - "latitude": 58.142947, - "longitude": 7.99551 - }, - { - "lokalId": "99c2e1ad-8b17-46d7-87dd-037117fc4f75", - "romnr": 1874, - "plasser": 191, - "adresse": "KRISTIAN 4. DES GATE 35-37", - "latitude": 58.148304, - "longitude": 7.991811 - }, - { - "lokalId": "a7cd6fa4-50d7-4e46-b8fc-0599b7c0684f", - "romnr": 1890, - "plasser": 120, - "adresse": "LINDEBØSKOGEN", - "latitude": 58.08907, - "longitude": 7.999181 - }, - { - "lokalId": "322932aa-f80d-4e72-a83a-ce259a89a397", - "romnr": 1895, - "plasser": 95, - "adresse": "MAGNUS BARFOTSVEI 7", - "latitude": 58.177356, - "longitude": 8.043248 - }, - { - "lokalId": "bf826545-0846-44f3-84fc-814eec51c5f0", - "romnr": 1897, - "plasser": 360, - "adresse": "MALMVEIEN 4", - "latitude": 58.14858, - "longitude": 7.955773 - }, - { - "lokalId": "532a6aae-032a-4dd3-9540-ed3eaf7b2d44", - "romnr": 1908, - "plasser": 330, - "adresse": "MARKENSGATE 42", - "latitude": 58.147248, - "longitude": 7.990485 - }, - { - "lokalId": "5ff2b3ed-e6e0-44ab-83ab-13008e7c08e2", - "romnr": 1919, - "plasser": 200, - "adresse": "MÆBØ", - "latitude": 58.07591, - "longitude": 8.00126 - }, - { - "lokalId": "492f0ddc-fdff-4b0f-aff2-42a975d8fdf7", - "romnr": 1922, - "plasser": 300, - "adresse": "MØLLEVANNSVEIEN 50", - "latitude": 58.148601, - "longitude": 7.970139 - }, - { - "lokalId": "8c063d0a-8a57-484d-b3c5-6285fa0efc8c", - "romnr": 1931, - "plasser": 220, - "adresse": "ODDERHEI 1", - "latitude": 58.13434, - "longitude": 8.076467 - }, - { - "lokalId": "67da452e-4a66-40b8-a13e-d9244d63197e", - "romnr": 1938, - "plasser": 230, - "adresse": "PRESTHEIA 10", - "latitude": 58.166579, - "longitude": 8.010932 - }, - { - "lokalId": "d6095314-c5eb-4066-b20e-aa617f6ad2e8", - "romnr": 1951, - "plasser": 170, - "adresse": "RØDSTRUPEVEIEN 17", - "latitude": 58.133828, - "longitude": 7.960984 - }, - { - "lokalId": "da484bb2-229e-422c-8343-8752f72768b5", - "romnr": 1971, - "plasser": 170, - "adresse": "SKIBÅSEN 2", - "latitude": 58.173421, - "longitude": 8.126058 - }, - { - "lokalId": "9338937c-5210-4195-aea9-2789f6f91241", - "romnr": 1998, - "plasser": 70, - "adresse": "SLETTHEIVEIEN 63 B", - "latitude": 58.13564, - "longitude": 7.935866 - }, - { - "lokalId": "c03754b0-168e-45ae-af1d-b5466c8b811b", - "romnr": 2014, - "plasser": 234, - "adresse": "STRØMMEVEIEN 85-87", - "latitude": 58.15468, - "longitude": 8.081448 - }, - { - "lokalId": "7db195b7-25cb-4f84-a0a5-c3e54a44327b", - "romnr": 2057, - "plasser": 130, - "adresse": "VARDÅSVEIEN 115/117", - "latitude": 58.145409, - "longitude": 8.059191 - }, - { - "lokalId": "f0e4671e-497b-47ec-b237-afdae17d1e95", - "romnr": 2082, - "plasser": 150, - "adresse": "VIGVOLLÅSEN 16", - "latitude": 58.171563, - "longitude": 8.088489 - }, - { - "lokalId": "20dfa406-488e-4efa-98cb-ca51e83088de", - "romnr": 2083, - "plasser": 150, - "adresse": "VOIE RINGVEI 108", - "latitude": 58.101744, - "longitude": 7.947829 - }, - { - "lokalId": "6eb44464-e192-4a2c-8647-cdb83df46912", - "romnr": 2091, - "plasser": 120, - "adresse": "ØSTERVEIEN 30 B", - "latitude": 58.152844, - "longitude": 8.009103 - }, - { - "lokalId": "d1a161a1-7d18-466b-ae1d-b1c3b9ab2b19", - "romnr": 2094, - "plasser": 220, - "adresse": "ØSTERØYA 8", - "latitude": 58.077045, - "longitude": 8.001411 - }, - { - "lokalId": "5f373b9c-5b99-4a5a-8005-bb32b11f1e60", - "romnr": 2098, - "plasser": 190, - "adresse": "ØSTRE RINGVEI 8", - "latitude": 58.148571, - "longitude": 8.021041 - }, - { - "lokalId": "7e9704ce-7521-4856-b88b-b8102309fad0", - "romnr": 2104, - "plasser": 100, - "adresse": "ØSTRE STRANDGATE 67", - "latitude": 58.14818, - "longitude": 8.006068 - }, - { - "lokalId": "2e3a4c51-7250-47c9-a05f-37e41c33f61e", - "romnr": 2108, - "plasser": 360, - "adresse": "ØVRE BRATTBAKKEN 1", - "latitude": 58.178745, - "longitude": 8.091319 - }, - { - "lokalId": "b4d4e635-6e81-497c-b57c-15ec289d7977", - "romnr": 2127, - "plasser": 235, - "adresse": "TANGVALL", - "latitude": 58.096339, - "longitude": 7.814256 - }, - { - "lokalId": "84870d27-4956-425a-8579-50af0887c129", - "romnr": 2128, - "plasser": 133, - "adresse": "TANGVALL", - "latitude": 58.096339, - "longitude": 7.814256 - }, - { - "lokalId": "2f61f1be-c1f8-49df-b310-adccb913b228", - "romnr": 2180, - "plasser": 235, - "adresse": "SKOLEVEGEN 9", - "latitude": 58.275797, - "longitude": 7.9773 - }, - { - "lokalId": "4566c24b-3815-4246-a4a4-53111e239b6b", - "romnr": 2183, - "plasser": 75, - "adresse": "Drivenesvegen 24", - "latitude": 58.257678, - "longitude": 7.964487 - }, - { - "lokalId": "6e916337-a9da-4549-ab0f-c2b948f24416", - "romnr": 2197, - "plasser": 100, - "adresse": "BURÅSVEIEN 59", - "latitude": 58.031973, - "longitude": 7.434499 - }, - { - "lokalId": "954002a0-01e0-4497-a6a5-e343bd3a3108", - "romnr": 2205, - "plasser": 150, - "adresse": "HOLBÆK ERIKSENSGATE 10", - "latitude": 58.029529, - "longitude": 7.460786 - }, - { - "lokalId": "7cc0bc51-b655-49a8-9766-f14526f994c1", - "romnr": 2224, - "plasser": 60, - "adresse": "SOMMERKROVEIEN 18", - "latitude": 58.025063, - "longitude": 7.472404 - }, - { - "lokalId": "950e1cff-2b5b-43a0-8c34-3cd98463e881", - "romnr": 2254, - "plasser": 400, - "adresse": "SELJEVEIEN 60", - "latitude": 58.030949, - "longitude": 7.490129 - }, - { - "lokalId": "7665fcb4-0b50-4df2-b4d6-374ec1dd6a0b", - "romnr": 2286, - "plasser": 30, - "adresse": "STÅLESEN BYGG AS-AUTOHALLEN Vanse", - "latitude": 58.093131, - "longitude": 6.69617 - }, - { - "lokalId": "cf44933f-c1e9-4071-99fa-5cfbcf1ec5c0", - "romnr": 2293, - "plasser": 100, - "adresse": "SVEGESKOGEN 17", - "latitude": 58.283261, - "longitude": 6.643839 - }, - { - "lokalId": "a9169e28-4828-44e0-b409-1b4ba4e990a8", - "romnr": 2306, - "plasser": 220, - "adresse": "Urgata 2", - "latitude": 58.296542, - "longitude": 6.665628 - }, - { - "lokalId": "415201ca-7e6a-4f32-8b30-be2f5987547d", - "romnr": 2310, - "plasser": 190, - "adresse": "RAULIVEIEN 2", - "latitude": 58.295212, - "longitude": 6.669011 - }, - { - "lokalId": "1c859126-a2df-4603-83da-be76ba1e160d", - "romnr": 2344, - "plasser": 35, - "adresse": "ROSFJORD", - "latitude": 58.12144, - "longitude": 7.058307 - }, - { - "lokalId": "2f023362-b3c7-4654-9e33-fdff01e03fa6", - "romnr": 2468, - "plasser": 160, - "adresse": "Myraveien 2 (Brannstasjonen)", - "latitude": 66.312793, - "longitude": 14.148941 - }, - { - "lokalId": "49a011ae-4543-4c6a-8f35-bc40a8b5a0e5", - "romnr": 2483, - "plasser": 230, - "adresse": "Kveldssolgata 99 (Hauknes skole - offentlig)", - "latitude": 66.285491, - "longitude": 14.054265 - }, - { - "lokalId": "19e029c6-95a8-4242-acab-a00c37d84356", - "romnr": 2502, - "plasser": 415, - "adresse": "Alstadveien 19, Alstad Ungdomsskole", - "latitude": 67.275052, - "longitude": 14.486811 - }, - { - "lokalId": "fdabca67-bd03-4934-a950-0ad808126aba", - "romnr": 2506, - "plasser": 160, - "adresse": "Salten gummiservice A/S, Tømrerveien 8", - "latitude": 67.275244, - "longitude": 14.400001 - }, - { - "lokalId": "6a75dbe5-12d6-4758-82be-bbdd6a482434", - "romnr": 2519, - "plasser": 600, - "adresse": "Gråholten", - "latitude": 67.274848, - "longitude": 14.378414 - }, - { - "lokalId": "bed1bd5e-2f13-474a-a4c1-f45a47263210", - "romnr": 2521, - "plasser": 340, - "adresse": "Torvet, Sjøgaten, Bodø", - "latitude": 67.284683, - "longitude": 14.381687 - }, - { - "lokalId": "5b255d31-093a-4ff2-b686-5a9085ae1341", - "romnr": 2522, - "plasser": 520, - "adresse": "Holstbakken Alta", - "latitude": 69.973665, - "longitude": 23.301067 - }, - { - "lokalId": "66084972-7d02-4076-95c3-9c2384a3ce63", - "romnr": 2524, - "plasser": 1154, - "adresse": "Rensås Syd, Bodø", - "latitude": 67.283731, - "longitude": 14.40508 - }, - { - "lokalId": "a530f56d-cbce-493c-ada9-53294b01b9ac", - "romnr": 2525, - "plasser": 300, - "adresse": "Dreyfushammaren, Burøyveien, Bodø", - "latitude": 67.297966, - "longitude": 14.395184 - }, - { - "lokalId": "bfca52a9-e485-4a79-81d5-35b603cfd896", - "romnr": 2527, - "plasser": 500, - "adresse": "Rensås Nord, Parkveien, Bodø", - "latitude": 67.283004, - "longitude": 14.400086 - }, - { - "lokalId": "34fdefbc-3ae6-4b1d-8c9c-46e40cdecd5b", - "romnr": 2571, - "plasser": 450, - "adresse": "Gymnaset, Gymnasveien 5, Fauske", - "latitude": 67.262641, - "longitude": 15.375249 - }, - { - "lokalId": "869bc6c8-7c6a-4559-bfce-6963f3ce8a2f", - "romnr": 2625, - "plasser": 410, - "adresse": "Strandgata 20", - "latitude": 66.314566, - "longitude": 14.132171 - }, - { - "lokalId": "95c6d533-2997-4897-b08c-77817319bae6", - "romnr": 2645, - "plasser": 320, - "adresse": "Selfors Barneskole", - "latitude": 66.326036, - "longitude": 14.180946 - }, - { - "lokalId": "1e166204-285b-4e51-b0a1-342925bc8851", - "romnr": 2662, - "plasser": 240, - "adresse": "Ytteren Somatiske sykehjem - off.", - "latitude": 66.340782, - "longitude": 14.138547 - }, - { - "lokalId": "9c663030-0d50-4b2b-adac-68f4efdd4ca0", - "romnr": 3247, - "plasser": 600, - "adresse": "Flintergata 6", - "latitude": 58.852, - "longitude": 5.733833 - }, - { - "lokalId": "8860fab7-f876-43c3-bd76-072d886d0fb1", - "romnr": 3249, - "plasser": 420, - "adresse": "Roald Amundsens gate 28A", - "latitude": 58.861441, - "longitude": 5.743306 - }, - { - "lokalId": "62cc4598-9caf-42dd-b0ee-d2c5b4662063", - "romnr": 3255, - "plasser": 155, - "adresse": "Nikkelveien 13", - "latitude": 58.869807, - "longitude": 5.731038 - }, - { - "lokalId": "ae844a34-00e7-463c-af2b-232a37ab3024", - "romnr": 3289, - "plasser": 20, - "adresse": "Sjøveien 4", - "latitude": 58.884679, - "longitude": 5.745893 - }, - { - "lokalId": "11dad206-5544-461f-8e97-591c92d56e04", - "romnr": 3325, - "plasser": 80, - "adresse": "Iglemyrveien 3", - "latitude": 58.842988, - "longitude": 5.756187 - }, - { - "lokalId": "c2bd8ed7-1656-4e91-964c-4452714d2a8b", - "romnr": 3553, - "plasser": 138, - "adresse": "Moafjæra 1d", - "latitude": 63.739158, - "longitude": 11.28213 - }, - { - "lokalId": "9782250a-c7d5-4742-b770-883908b08f30", - "romnr": 3680, - "plasser": 110, - "adresse": "Wergelandsveien 27", - "latitude": 63.475072, - "longitude": 10.914986 - }, - { - "lokalId": "1918f122-3286-49b4-a812-c44ec3142ff9", - "romnr": 4005, - "plasser": 98, - "adresse": "Haugen 25", - "latitude": 58.825497, - "longitude": 5.726609 - }, - { - "lokalId": "293c692f-46d9-4499-a620-2dc535fb16c3", - "romnr": 4008, - "plasser": 225, - "adresse": "Somaveien 4", - "latitude": 58.872972, - "longitude": 5.725455 - }, - { - "lokalId": "a8c44d20-fc0d-4207-ac12-b072681c0c37", - "romnr": 4013, - "plasser": 570, - "adresse": "Olabakken 2", - "latitude": 58.825574, - "longitude": 5.713467 - }, - { - "lokalId": "68d1e0ad-6982-4165-b28a-e0b41e2e9839", - "romnr": 4026, - "plasser": 241, - "adresse": "Luramyrveien 61", - "latitude": 58.883893, - "longitude": 5.726643 - }, - { - "lokalId": "7870d7f3-4dd5-44cd-8c51-2d4430f72772", - "romnr": 4193, - "plasser": 230, - "adresse": "Samuel J. Sandveds vei 16", - "latitude": 58.841264, - "longitude": 5.72609 - }, - { - "lokalId": "f47bc94b-74be-48fa-bdfa-4a275ba195c2", - "romnr": 4194, - "plasser": 200, - "adresse": "Smørbukkveien 11", - "latitude": 58.884865, - "longitude": 5.734584 - }, - { - "lokalId": "bc723bec-c1b1-4a3d-accb-b4faedcf87af", - "romnr": 4241, - "plasser": 150, - "adresse": "Damsgårdsgaten 4A", - "latitude": 58.453424, - "longitude": 6.006291 - }, - { - "lokalId": "23c43b1b-f74a-4252-8c5a-3c90ebf7aa4b", - "romnr": 4291, - "plasser": 235, - "adresse": "Sam Eydesgt. 163, IINGOLFLAND SKOLE", - "latitude": 59.879548, - "longitude": 8.614609 - }, - { - "lokalId": "4b805b16-49fd-4688-8965-290cb14c5462", - "romnr": 4303, - "plasser": 200, - "adresse": "Kaiveien 23", - "latitude": 58.929458, - "longitude": 5.85136 - }, - { - "lokalId": "b68f5c59-30ba-4ea1-8263-64749ad93e58", - "romnr": 4305, - "plasser": 200, - "adresse": "Kaiveien 25", - "latitude": 58.93021, - "longitude": 5.851264 - }, - { - "lokalId": "020ca2ab-af00-43e3-8cc2-d7b9340ef717", - "romnr": 4695, - "plasser": 100, - "adresse": "Skansen kjøpesenter, T. Kveldulvsons gate 24", - "latitude": 66.022369, - "longitude": 12.635415 - }, - { - "lokalId": "f98f0b93-efa2-48b3-8ff2-0ca06d6f8b8b", - "romnr": 4703, - "plasser": 120, - "adresse": "Skole/Samfunnshus, Skolegata 1", - "latitude": 65.468137, - "longitude": 12.211094 - }, - { - "lokalId": "b703762b-dbd7-4eba-9555-65dd8ae97d0c", - "romnr": 4741, - "plasser": 736, - "adresse": "Mysenhallen/ Smedgata 19", - "latitude": 59.553801, - "longitude": 11.333741 - }, - { - "lokalId": "d7e76a10-635a-472f-89d6-d115536d9122", - "romnr": 4855, - "plasser": 300, - "adresse": "Karsches gate 3 \"Tilflukt\"", - "latitude": 59.668901, - "longitude": 9.651787 - }, - { - "lokalId": "58dc9f73-9d2e-463f-bf2f-b2cbf87a4ff8", - "romnr": 4908, - "plasser": 172, - "adresse": "Soknedalsveien 7", - "latitude": 60.169954, - "longitude": 10.243451 - }, - { - "lokalId": "ae3be434-c0db-4985-8440-eecb9ac6fa8e", - "romnr": 4963, - "plasser": 537, - "adresse": "Betzy Kjelsbergs vei 182", - "latitude": 59.757079, - "longitude": 10.131048 - }, - { - "lokalId": "abd7d06c-3cee-403a-bb4a-a051c14b109d", - "romnr": 4969, - "plasser": 1200, - "adresse": "Prins Oscarsgate / Brantenborg.", - "latitude": 59.74564, - "longitude": 10.221617 - }, - { - "lokalId": "41edbd5e-744d-4fd8-9ff8-604014e36945", - "romnr": 5463, - "plasser": 600, - "adresse": "Nedre Tverrgate 1 - Nedre Eiker Samfunnshus", - "latitude": 59.748786, - "longitude": 10.012376 - }, - { - "lokalId": "aa0c74f3-6a5b-4801-b4ab-154118afa078", - "romnr": 5617, - "plasser": 385, - "adresse": "Stasjonsgata 24", - "latitude": 59.770967, - "longitude": 9.908552 - }, - { - "lokalId": "185a05cb-c4f7-403d-bfad-eab4fc8e840e", - "romnr": 5630, - "plasser": 320, - "adresse": "Hellefoss veien 2", - "latitude": 59.773209, - "longitude": 9.908353 - }, - { - "lokalId": "77d3f950-9162-4456-8551-ff64806be211", - "romnr": 5647, - "plasser": 220, - "adresse": "Skotselvveien 29", - "latitude": 59.770037, - "longitude": 9.898972 - }, - { - "lokalId": "5a4154aa-678c-4e79-b1c3-9651aaf1d70a", - "romnr": 5652, - "plasser": 14, - "adresse": "Havnegt.16", - "latitude": 64.466916, - "longitude": 11.494325 - }, - { - "lokalId": "3f2b574d-d0f8-4fc5-8659-4570c33c0edb", - "romnr": 5653, - "plasser": 25, - "adresse": "Abel Meyers gate 3", - "latitude": 64.464827, - "longitude": 11.494884 - }, - { - "lokalId": "191f5c70-7f01-4457-ac9f-eef16da90c4f", - "romnr": 5655, - "plasser": 60, - "adresse": "Overh.vn.8", - "latitude": 64.469204, - "longitude": 11.50363 - }, - { - "lokalId": "ae27f566-5ac9-4763-982f-4e2baac9662d", - "romnr": 5656, - "plasser": 70, - "adresse": "Kirkegt.5", - "latitude": 64.466466, - "longitude": 11.49507 - }, - { - "lokalId": "240ca620-f28a-44e8-94aa-ac368ba1f469", - "romnr": 5657, - "plasser": 78, - "adresse": "Strandvn.7", - "latitude": 64.468497, - "longitude": 11.479279 - }, - { - "lokalId": "fb140d42-3b57-4a12-a1f9-f5d64e99cc9f", - "romnr": 5658, - "plasser": 15, - "adresse": "Abel Meyers gate 21", - "latitude": 64.467607, - "longitude": 11.497318 - }, - { - "lokalId": "1d3d72ef-7cd1-49c8-9e84-5f381828ebca", - "romnr": 5732, - "plasser": 2000, - "adresse": "Jarl Hildrums veg 6, Kleppen", - "latitude": 64.474148, - "longitude": 11.521925 - }, - { - "lokalId": "9b602ba9-0351-45e6-85c9-b6901c7bf2b3", - "romnr": 5815, - "plasser": 400, - "adresse": "Sundelinveien 72 (Sandnes Skole)", - "latitude": 69.668159, - "longitude": 29.952576 - }, - { - "lokalId": "30d5dd6f-4e44-4258-9d14-dd6268f965a0", - "romnr": 5832, - "plasser": 340, - "adresse": "Rådhuset, Sivert Nilsensgate 24", - "latitude": 65.467761, - "longitude": 12.205777 - }, - { - "lokalId": "4216edda-adcf-4e28-9cad-cb360eeb18cf", - "romnr": 5962, - "plasser": 230, - "adresse": "Gåsungen Barnehage - Gåsåsen 20", - "latitude": 58.459572, - "longitude": 8.747527 - }, - { - "lokalId": "c665543f-ff90-458b-a4cf-1f9d7d57c108", - "romnr": 6056, - "plasser": 35, - "adresse": "Birkenes kommunehus - Smedens Kjerr 30", - "latitude": 58.335013, - "longitude": 8.23294 - }, - { - "lokalId": "dc509365-2c71-47e7-9f21-c22dc2cda05c", - "romnr": 6074, - "plasser": 20, - "adresse": "Herefoss Skole - Torsbumoen 14", - "latitude": 58.519123, - "longitude": 8.353128 - }, - { - "lokalId": "d1baaff4-6b80-43ff-b55c-5c8fcc7e55b4", - "romnr": 6157, - "plasser": 240, - "adresse": "Risør Idrettshall - Caspersens vei 25", - "latitude": 58.714551, - "longitude": 9.215198 - }, - { - "lokalId": "af2660f5-e13b-4dcd-8acf-93b9e5b2b076", - "romnr": 6160, - "plasser": 470, - "adresse": "Risør videregående skole - Sirisveien 8 Blokk A", - "latitude": 58.720064, - "longitude": 9.216877 - }, - { - "lokalId": "b55d268f-6bed-478a-8500-c70d7513e4e7", - "romnr": 6206, - "plasser": 90, - "adresse": "Bjorbekktunet - Off - Bjorbekk - Johan Landmarksve", - "latitude": 58.440072, - "longitude": 8.706223 - }, - { - "lokalId": "9454d973-8531-420d-a170-d57cb7389823", - "romnr": 6207, - "plasser": 26, - "adresse": "Meny - Off - Stoa - Åsbieveien 2", - "latitude": 58.458411, - "longitude": 8.712128 - }, - { - "lokalId": "ea723bda-d386-44ea-ad71-207950af90d8", - "romnr": 6222, - "plasser": 90, - "adresse": "Idrettens Hus - Off - Kåre Eriksen A/S - Åsbievn 1", - "latitude": 58.458295, - "longitude": 8.720036 - }, - { - "lokalId": "5516bb9a-4d84-4ea1-b28a-483cf4be508f", - "romnr": 6342, - "plasser": 264, - "adresse": "Høvågheimen Bo og aktivitetsenter - Høvåg", - "latitude": 58.170947, - "longitude": 8.245037 - }, - { - "lokalId": "1c168707-1644-48ab-9864-4cca2dca14bf", - "romnr": 6356, - "plasser": 28, - "adresse": "Lillesand rådhus - Østregate 2", - "latitude": 58.249877, - "longitude": 8.378622 - }, - { - "lokalId": "93e3950b-4523-4147-8646-420a5388dce1", - "romnr": 6394, - "plasser": 1300, - "adresse": "Kulturhuset - Hestetorget,Storgaten 33", - "latitude": 58.342862, - "longitude": 8.590395 - }, - { - "lokalId": "f1f92f26-0bf8-4a9c-ba6a-96d311fb4a14", - "romnr": 6442, - "plasser": 228, - "adresse": "Eide Skole - Johan Markussens vei 90", - "latitude": 58.2689, - "longitude": 8.504972 - }, - { - "lokalId": "3e9b2e4e-307b-4793-8b73-de3d3c53865c", - "romnr": 6547, - "plasser": 50, - "adresse": "Oddensenteret (kjeller) - Vesterled 4", - "latitude": 58.337942, - "longitude": 8.592676 - }, - { - "lokalId": "0040b298-85a8-4ac3-9231-26d042ff50e2", - "romnr": 6720, - "plasser": 400, - "adresse": "Froland Idrettshall - Mjølhusmoen - Rislandsvn 10", - "latitude": 58.515114, - "longitude": 8.632786 - }, - { - "lokalId": "43ca8211-7024-40cf-b21c-d41cab8117bd", - "romnr": 6749, - "plasser": 106, - "adresse": "Dønnestadgården - Bibliotekveien 4", - "latitude": 58.626552, - "longitude": 8.928731 - }, - { - "lokalId": "6f8919e3-6a6b-40ce-a5ff-e6c3d45f6bb7", - "romnr": 6815, - "plasser": 2400, - "adresse": "Arendalstunnelen - Parkeringstunnell -Torvet/Barb", - "latitude": 58.4619, - "longitude": 8.766067 - }, - { - "lokalId": "0a5cbf36-68c3-459b-a68e-7adc42875cff", - "romnr": 6819, - "plasser": 1800, - "adresse": "Birkenlundhallen - Kirkefjell 11", - "latitude": 58.471025, - "longitude": 8.791073 - }, - { - "lokalId": "63687f3c-be87-4a69-8bfc-c65f4a18670b", - "romnr": 6870, - "plasser": 630, - "adresse": "Westermannsveita 4 Tidl. Nordre gate 1", - "latitude": 63.431029, - "longitude": 10.39903 - }, - { - "lokalId": "5a75f46d-a078-4666-b333-b33b0140b6e7", - "romnr": 6963, - "plasser": 265, - "adresse": "Dr.Randersgate 5, Askim", - "latitude": 59.583244, - "longitude": 11.160927 - }, - { - "lokalId": "15d72df6-7510-4d30-96ae-4bed5f112003", - "romnr": 6964, - "plasser": 260, - "adresse": "Dr. Randersgate 2, Askim", - "latitude": 59.582696, - "longitude": 11.161255 - }, - { - "lokalId": "799edf55-2bfc-4855-b34f-b91efafac1b6", - "romnr": 6966, - "plasser": 260, - "adresse": "Rom skole/ Gramveien 63A, Askim", - "latitude": 59.590274, - "longitude": 11.128584 - }, - { - "lokalId": "6626ae01-6a88-46bd-8468-690d9ee6d11b", - "romnr": 7021, - "plasser": 90, - "adresse": "endresens vei 4, Varangerbotn", - "latitude": 70.172568, - "longitude": 28.558419 - }, - { - "lokalId": "483bb2ca-ddf9-48f9-8981-03bbd7bd099c", - "romnr": 7098, - "plasser": 1079, - "adresse": "Melløs stadion, Nordahl Griegsgt 22", - "latitude": 59.420957, - "longitude": 10.670078 - }, - { - "lokalId": "226e3d7e-431a-41c1-905c-baa2e9eb2dca", - "romnr": 7103, - "plasser": 1000, - "adresse": "Blinken/ Jeløgata 3", - "latitude": 59.433847, - "longitude": 10.654783 - }, - { - "lokalId": "36730a9b-b40a-4013-8fc8-d675bb8a0b02", - "romnr": 7105, - "plasser": 400, - "adresse": "Malakoff vg. skole, Dyreveien 9", - "latitude": 59.427789, - "longitude": 10.668656 - }, - { - "lokalId": "cca467f7-d3a8-423f-88bd-5e46ebfb1830", - "romnr": 7106, - "plasser": 250, - "adresse": "Reier skole/Brageveien 9", - "latitude": 59.429391, - "longitude": 10.63015 - }, - { - "lokalId": "e049a7a3-46c0-49d8-83b3-0f2ac8b06f0e", - "romnr": 7107, - "plasser": 300, - "adresse": "Krapfoss skole /Anton Krogsveldsvei 4", - "latitude": 59.43334, - "longitude": 10.68175 - }, - { - "lokalId": "bdc85bd6-a3b6-47ef-8be4-4987bdb4c186", - "romnr": 7114, - "plasser": 450, - "adresse": "Parkeringshus Piasenteret/ Møllergata 1", - "latitude": 59.437466, - "longitude": 10.667859 - }, - { - "lokalId": "f8e069a3-b2a0-449d-b083-6d94cb7bc955", - "romnr": 7158, - "plasser": 168, - "adresse": "Wilh Bugges Veg 5", - "latitude": 61.221816, - "longitude": 6.075034 - }, - { - "lokalId": "bb7be8ae-e375-44bd-b3f8-6c2f2f37ca5b", - "romnr": 7254, - "plasser": 122, - "adresse": "Haugevegen 31", - "latitude": 59.420374, - "longitude": 5.263855 - }, - { - "lokalId": "7d4ffef2-7cec-4ffc-8b83-b5f67b5e26d6", - "romnr": 7270, - "plasser": 78, - "adresse": "Storbukt Skole Honningsvåg", - "latitude": 70.995711, - "longitude": 25.980348 - }, - { - "lokalId": "6fa14e4f-c7d5-421e-b6a4-2c992cd860c0", - "romnr": 7409, - "plasser": 448, - "adresse": "Baksalen Skole Hammerfest", - "latitude": 70.657017, - "longitude": 23.705373 - }, - { - "lokalId": "8d2f8e12-7b54-4406-b3c2-901d4d7ca1ff", - "romnr": 7411, - "plasser": 400, - "adresse": "Reindalen skole", - "latitude": 70.691759, - "longitude": 23.700527 - }, - { - "lokalId": "51b58414-4cd3-4366-a8f9-461e1de8f2cc", - "romnr": 7412, - "plasser": 228, - "adresse": "Bokollektivet Rypefjord", - "latitude": 70.637318, - "longitude": 23.677216 - }, - { - "lokalId": "f8afc4ca-cfb9-4311-8b45-57852ccf038b", - "romnr": 7413, - "plasser": 622, - "adresse": "Sivilforsvarets lager Nybakken 9 Hammerfest", - "latitude": 70.663789, - "longitude": 23.692815 - }, - { - "lokalId": "de6da9d8-07d6-4b77-9cb1-6da2a45e0e33", - "romnr": 7436, - "plasser": 211, - "adresse": "Porsanger Rådhus Lakselv", - "latitude": 70.052199, - "longitude": 24.956483 - }, - { - "lokalId": "e74a5f0f-2f8b-4573-bc00-86f76e58fc8b", - "romnr": 7438, - "plasser": 170, - "adresse": "Flerbrukshallen Lakselv", - "latitude": 70.048491, - "longitude": 24.967072 - }, - { - "lokalId": "b9c2ce15-8f3c-42f9-a82b-12a969dc7f9c", - "romnr": 7443, - "plasser": 280, - "adresse": "Helsetun Lakselv", - "latitude": 70.052063, - "longitude": 24.952458 - }, - { - "lokalId": "7af66c10-dded-4578-9fd7-1c1a995cd4af", - "romnr": 7464, - "plasser": 570, - "adresse": "Idrettsanlegg Honningsvåg", - "latitude": 70.976088, - "longitude": 25.97941 - }, - { - "lokalId": "29e7d3f9-024c-4be4-871d-b8a9c27639e8", - "romnr": 7574, - "plasser": 130, - "adresse": "Brubakken 2", - "latitude": 61.118083, - "longitude": 10.461766 - }, - { - "lokalId": "fed6eff0-1d85-4cf4-8e25-79db88c43193", - "romnr": 7856, - "plasser": 550, - "adresse": "Storgata 10", - "latitude": 60.794817, - "longitude": 10.69013 - }, - { - "lokalId": "77af968f-88ce-439e-88a9-61f105a70f48", - "romnr": 7956, - "plasser": 65, - "adresse": "Mattisrudsvingen 9", - "latitude": 60.783142, - "longitude": 10.648554 - }, - { - "lokalId": "bdf7f784-6c98-410e-b388-144da1e6b15c", - "romnr": 8044, - "plasser": 30, - "adresse": "Rosteinvegen 7", - "latitude": 60.833774, - "longitude": 10.055507 - }, - { - "lokalId": "03464253-44f2-4407-a1d5-150c0f0f49a2", - "romnr": 8050, - "plasser": 550, - "adresse": "Prøvenvegen 65", - "latitude": 60.715098, - "longitude": 10.605248 - }, - { - "lokalId": "81c435a1-b0aa-426e-aafc-504a2081072f", - "romnr": 8060, - "plasser": 50, - "adresse": "Jørstadmovegen 690", - "latitude": 61.155827, - "longitude": 10.391659 - }, - { - "lokalId": "e7d7298e-5a53-4aee-be80-d173feb1e209", - "romnr": 8061, - "plasser": 250, - "adresse": "Gudbrandsdalsvegen 190", - "latitude": 61.128144, - "longitude": 10.451822 - }, - { - "lokalId": "1ef9a75e-1d3b-432e-b5b1-ea27d531afa0", - "romnr": 8062, - "plasser": 150, - "adresse": "Nordsetervegen 45", - "latitude": 61.122977, - "longitude": 10.470935 - }, - { - "lokalId": "e35a768a-25a8-4492-908a-919cc5488673", - "romnr": 8063, - "plasser": 300, - "adresse": "Jul Pettersens gate 2", - "latitude": 61.117916, - "longitude": 10.462682 - }, - { - "lokalId": "ad26e0b2-7a30-408a-bdb8-175a2b426346", - "romnr": 8064, - "plasser": 616, - "adresse": "Kirkegata 74", - "latitude": 61.116166, - "longitude": 10.462264 - }, - { - "lokalId": "42542c87-f569-4a7c-bc6f-a1b79f59a59e", - "romnr": 8823, - "plasser": 650, - "adresse": "v/ Seimsdalstunnellen", - "latitude": 61.236154, - "longitude": 7.691842 - }, - { - "lokalId": "2978ebbb-6cdc-4bbc-9f75-2168e1692f4c", - "romnr": 8825, - "plasser": 550, - "adresse": "Storevegen 13 (Lykkja )", - "latitude": 61.311211, - "longitude": 7.80573 - }, - { - "lokalId": "948dd61c-c5f9-4da7-9ed9-8187e91d0e58", - "romnr": 9067, - "plasser": 30, - "adresse": "Petter Dassgt 15", - "latitude": 65.838383, - "longitude": 13.196375 - }, - { - "lokalId": "cb085b04-7a18-43a8-b434-49ed266d72c3", - "romnr": 9071, - "plasser": 40, - "adresse": "Strandgt. 31-33 (offentlig)", - "latitude": 65.836379, - "longitude": 13.190012 - }, - { - "lokalId": "e3d132d6-586f-4a7d-9c28-0930ed9e0615", - "romnr": 9092, - "plasser": 122, - "adresse": "Erling Skjalgssons gate 25", - "latitude": 59.420405, - "longitude": 5.265106 - }, - { - "lokalId": "5bae63ac-f45a-48bf-a5a0-0ac2653bbe65", - "romnr": 9093, - "plasser": 220, - "adresse": "Spannavegen 135", - "latitude": 59.398251, - "longitude": 5.303656 - }, - { - "lokalId": "071b67c6-d8a9-4061-b118-e2bdf578d28f", - "romnr": 9123, - "plasser": 200, - "adresse": "Kvalamarka 26", - "latitude": 59.436944, - "longitude": 5.257753 - }, - { - "lokalId": "3011fe06-fc9f-4b22-bcc7-6b6216277591", - "romnr": 9214, - "plasser": 265, - "adresse": "Skjoldavegen 318", - "latitude": 59.409627, - "longitude": 5.329626 - }, - { - "lokalId": "181e5379-4c7f-416c-b1a7-1efa60123ae5", - "romnr": 9357, - "plasser": 235, - "adresse": "Spannavegen 75", - "latitude": 59.404753, - "longitude": 5.298109 - }, - { - "lokalId": "fcda4c93-242a-47c3-9f9e-a5ecd49e9d58", - "romnr": 9398, - "plasser": 220, - "adresse": "Marker rådhus/ Storgata 60", - "latitude": 59.47952, - "longitude": 11.659117 - }, - { - "lokalId": "e8053161-2c4c-4f14-a6b9-85fd33f17c99", - "romnr": 9403, - "plasser": 2000, - "adresse": "Kulås/ Sandesundveien 10C", - "latitude": 59.280082, - "longitude": 11.107723 - }, - { - "lokalId": "65effa39-a999-4d99-b83b-ec6b2902d06e", - "romnr": 9404, - "plasser": 900, - "adresse": "Spikern/ Alvimveien 19", - "latitude": 59.27118, - "longitude": 11.089701 - }, - { - "lokalId": "0ad6bea2-809b-49fb-b727-d6aba741b399", - "romnr": 9405, - "plasser": 300, - "adresse": "Sagahuset/ Sandesundveien 1", - "latitude": 59.28341, - "longitude": 11.108994 - }, - { - "lokalId": "a8a2befb-6692-4b85-bdbe-2137e220e285", - "romnr": 9407, - "plasser": 477, - "adresse": "Skjeberg rådhus/ Rådhusveien 17", - "latitude": 59.266996, - "longitude": 11.169627 - }, - { - "lokalId": "c78ee9bb-0063-479e-8953-f954f09109ce", - "romnr": 9408, - "plasser": 89, - "adresse": "Dahles bilforretn/ Herbergveien 4", - "latitude": 59.288717, - "longitude": 11.087792 - }, - { - "lokalId": "486751a8-dbe5-4d1e-a0d2-9a44a1467000", - "romnr": 9410, - "plasser": 40, - "adresse": "Hafslundsøy skole/ Hagastuveien 60", - "latitude": 59.285791, - "longitude": 11.14699 - }, - { - "lokalId": "5e5cbfb4-1680-4e45-b144-c19f0f39e340", - "romnr": 9412, - "plasser": 100, - "adresse": "Borg bil/ Glomveien 5", - "latitude": 59.290141, - "longitude": 11.086135 - }, - { - "lokalId": "3f50f828-85b0-4649-9efb-9c166b013c6a", - "romnr": 9413, - "plasser": 183, - "adresse": "Tingvollheimen aldersheim/ Tuneveien 70", - "latitude": 59.294775, - "longitude": 11.074037 - }, - { - "lokalId": "83e303e1-11d1-4037-b8b1-3d07afe11272", - "romnr": 9474, - "plasser": 388, - "adresse": "Håreksgt. 13", - "latitude": 65.835442, - "longitude": 13.195049 - }, - { - "lokalId": "387a6bc7-4a9a-4085-8662-76b48b82c727", - "romnr": 9505, - "plasser": 25, - "adresse": "Strandgata 36 (offentlig)", - "latitude": 65.836672, - "longitude": 13.190495 - }, - { - "lokalId": "1b5fb39f-ddbe-4ea9-a178-8715f934434a", - "romnr": 9508, - "plasser": 15, - "adresse": "C.M. Havigsgt. 28 (offentlig)", - "latitude": 65.837097, - "longitude": 13.191516 - }, - { - "lokalId": "9333e182-b38c-45f1-822e-12938cdcf0c1", - "romnr": 9517, - "plasser": 310, - "adresse": "Fearnleysgt. 14 (Mosjøen viderg.skole- off.)", - "latitude": 65.837793, - "longitude": 13.193526 - }, - { - "lokalId": "b7b8a046-c0eb-47de-8065-1460a413c9d4", - "romnr": 9521, - "plasser": 220, - "adresse": "Stortingmannsv. 20 (Kulstad skole - Off.)", - "latitude": 65.866093, - "longitude": 13.19978 - }, - { - "lokalId": "db29b8b3-2944-4d84-8f03-095bb70b42f5", - "romnr": 9528, - "plasser": 172, - "adresse": "Olderskog skole - Skule Svendsv. 17", - "latitude": 65.821638, - "longitude": 13.217572 - }, - { - "lokalId": "1f3634c6-a68e-4c55-9a25-dff95e3b9d65", - "romnr": 9529, - "plasser": 100, - "adresse": "Skjervgata 43 - Rådhuset i Vefsn (off.)", - "latitude": 65.840847, - "longitude": 13.199839 - }, - { - "lokalId": "34a653bc-e887-441a-9b93-f6c89fabe02a", - "romnr": 9548, - "plasser": 222, - "adresse": "Torjus Gards veg 7", - "latitude": 59.428182, - "longitude": 5.267023 - }, - { - "lokalId": "346e80c1-1fb4-4e36-8ade-01875a4b0c5c", - "romnr": 9550, - "plasser": 220, - "adresse": "Tittelsnesvegen 332", - "latitude": 59.468892, - "longitude": 5.284654 - }, - { - "lokalId": "b3e6e4fc-b57d-47b9-a7a5-73bd20f87831", - "romnr": 9670, - "plasser": 500, - "adresse": "Florvågvegen 3, Løfjell, Kleppestø", - "latitude": 60.409259, - "longitude": 5.228322 - }, - { - "lokalId": "fff8c7dd-eb9e-48d1-8f74-8fc6d28e8369", - "romnr": 9806, - "plasser": 65, - "adresse": "Kvassnesv. 52 Pb. 157", - "latitude": 60.544934, - "longitude": 5.293043 - }, - { - "lokalId": "d87c6802-023b-4427-90f0-3c3a48a9cdeb", - "romnr": 9852, - "plasser": 100, - "adresse": "Bu og rehab. senter", - "latitude": 59.781823, - "longitude": 5.487313 - }, - { - "lokalId": "0b36e3c4-23cb-48b7-aecb-523bf296f706", - "romnr": 9915, - "plasser": 233, - "adresse": "Strandavegen 334", - "latitude": 60.658698, - "longitude": 6.434672 - }, - { - "lokalId": "871f4efd-fde7-4fc9-97a8-223dda6cd476", - "romnr": 9952, - "plasser": 698, - "adresse": "Miltzowsgt. 2", - "latitude": 60.62794, - "longitude": 6.419728 - }, - { - "lokalId": "bdc42977-f258-47e6-a633-c2af7878611b", - "romnr": 9983, - "plasser": 100, - "adresse": "Tjørnahaugane 60", - "latitude": 60.616448, - "longitude": 6.536621 - }, - { - "lokalId": "94ba0b4b-c0f2-4632-bbbb-187b38d8d57c", - "romnr": 10113, - "plasser": 360, - "adresse": "Elvavegen 2, Ytre Arna", - "latitude": 60.460226, - "longitude": 5.438147 - }, - { - "lokalId": "57d2c6a3-1d4b-4e5b-91c2-5c2d4f740445", - "romnr": 10212, - "plasser": 758, - "adresse": "Håkonsgaten 5", - "latitude": 60.391032, - "longitude": 5.317521 - }, - { - "lokalId": "9f18b131-7635-4bad-a9f3-4809a3a83701", - "romnr": 10387, - "plasser": 600, - "adresse": "Kalfarveien 76", - "latitude": 60.386629, - "longitude": 5.348519 - }, - { - "lokalId": "769fc494-b223-4947-8af2-32b56922225d", - "romnr": 10507, - "plasser": 500, - "adresse": "Nykirkealmenning ovenfor nr 19", - "latitude": 60.396579, - "longitude": 5.311762 - }, - { - "lokalId": "80e3c0ee-5e24-4729-97b8-938a9582ba94", - "romnr": 10508, - "plasser": 1400, - "adresse": "Holbergsalm. v/Strandgt 96", - "latitude": 60.395896, - "longitude": 5.316373 - }, - { - "lokalId": "88d0c98f-6dd0-4ede-bc0d-ef9b08d77050", - "romnr": 10511, - "plasser": 650, - "adresse": "Dokkeskjærskaien 1", - "latitude": 60.388199, - "longitude": 5.310968 - }, - { - "lokalId": "8f9df418-e25f-4898-a460-e0e4acc731b0", - "romnr": 10512, - "plasser": 3500, - "adresse": "Sydnestunnelen", - "latitude": 60.38943, - "longitude": 5.321949 - }, - { - "lokalId": "a137fbcb-b1a6-419d-91a1-664473af4228", - "romnr": 10516, - "plasser": 850, - "adresse": "Nordnes, v/ Haugeveien 32", - "latitude": 60.398272, - "longitude": 5.305496 - }, - { - "lokalId": "a41cc9dd-9069-4fb1-b45e-299ee1169810", - "romnr": 10788, - "plasser": 150, - "adresse": "Bønesberget 1", - "latitude": 60.332294, - "longitude": 5.30858 - }, - { - "lokalId": "8715ca46-6bd1-41ee-8ef5-83970b6a7e62", - "romnr": 11235, - "plasser": 150, - "adresse": "Søreidtunet 2", - "latitude": 60.314876, - "longitude": 5.271338 - }, - { - "lokalId": "8314551c-5b0b-4fec-9ff3-888f0ece65a0", - "romnr": 11236, - "plasser": 175, - "adresse": "Nordåsbrotet 2", - "latitude": 60.305625, - "longitude": 5.308297 - }, - { - "lokalId": "52d7fa87-2ed3-40b4-ad46-554cd04cde35", - "romnr": 11284, - "plasser": 2000, - "adresse": "Haukelandsveien 30", - "latitude": 60.371759, - "longitude": 5.360393 - }, - { - "lokalId": "ee8d87c3-8342-44c5-9886-8a0bb6d09e37", - "romnr": 11285, - "plasser": 2000, - "adresse": "Kronstadhøyden - vis a vis Møllendalsv nr 8", - "latitude": 60.379365, - "longitude": 5.338758 - }, - { - "lokalId": "92432e29-01d2-48e1-b071-2c2fa0dbe345", - "romnr": 11289, - "plasser": 422, - "adresse": "Vilhelm Bjerknes' vei 22", - "latitude": 60.353994, - "longitude": 5.360502 - }, - { - "lokalId": "7b4461f3-aaef-429c-91da-4e64d65ea349", - "romnr": 11343, - "plasser": 1300, - "adresse": "Fageråsveien, vis a vis Fageråsv 20", - "latitude": 60.359363, - "longitude": 5.354027 - }, - { - "lokalId": "bf26feb7-923f-4005-94a0-ccac32a5e42b", - "romnr": 11424, - "plasser": 240, - "adresse": "Kanalveien 54", - "latitude": 60.364797, - "longitude": 5.346087 - }, - { - "lokalId": "5d764578-4baa-4dce-a040-f3769920bfbd", - "romnr": 11663, - "plasser": 755, - "adresse": "Flaktveitsvingane 17", - "latitude": 60.464214, - "longitude": 5.359736 - }, - { - "lokalId": "0fc3c4f4-1897-48a8-9734-4a2eb385fd56", - "romnr": 11675, - "plasser": 750, - "adresse": "Florida-Nygårdsparken, Jahnebakken 5", - "latitude": 60.382697, - "longitude": 5.332261 - }, - { - "lokalId": "7816cd4d-3bfc-41ad-9714-4797ceaecc1e", - "romnr": 11677, - "plasser": 1800, - "adresse": "St. Jørgen - St. Jakob, Danckert Krohnsgt", - "latitude": 60.392466, - "longitude": 5.334108 - }, - { - "lokalId": "f0eede3f-8fb7-4e65-b041-80072dd0204e", - "romnr": 11681, - "plasser": 1050, - "adresse": "St. Markus, Damsgårdsveien 70", - "latitude": 60.379838, - "longitude": 5.323122 - }, - { - "lokalId": "d5557e8a-a3ca-46e1-ad37-f7d68fd64bd6", - "romnr": 11686, - "plasser": 1500, - "adresse": "Rothaugen, Nye Sandviksv v/ 69a", - "latitude": 60.403998, - "longitude": 5.321513 - }, - { - "lokalId": "c58cacd7-1520-4669-b0be-087af4941a8b", - "romnr": 11688, - "plasser": 230, - "adresse": "Hølbekken 1, Arnatveit", - "latitude": 60.408357, - "longitude": 5.47878 - }, - { - "lokalId": "8ae5f367-1913-49e8-83e5-e955fe3eb0ec", - "romnr": 11692, - "plasser": 455, - "adresse": "Olsvikåsen 49, Olsvik", - "latitude": 60.381112, - "longitude": 5.217063 - }, - { - "lokalId": "d819b930-74da-47a9-be1a-cfd230a950b0", - "romnr": 11741, - "plasser": 465, - "adresse": "Rådhusgata 4", - "latitude": 69.472222, - "longitude": 25.518868 - }, - { - "lokalId": "5f3ac9c4-f56c-4988-b914-33905efcf7cb", - "romnr": 11754, - "plasser": 2000, - "adresse": "Fossliåsen", - "latitude": 63.480034, - "longitude": 10.933616 - }, - { - "lokalId": "de36c8bc-90de-4897-9060-3baa98298d62", - "romnr": 11824, - "plasser": 350, - "adresse": "Lande skole/ Triangelveien 5", - "latitude": 59.290321, - "longitude": 11.104092 - }, - { - "lokalId": "082c2441-ce96-47c9-8543-27306959c841", - "romnr": 11848, - "plasser": 200, - "adresse": "Siriusveien 10", - "latitude": 63.394464, - "longitude": 10.415986 - }, - { - "lokalId": "38d2a1d0-7079-415b-84c3-964d8fca4df2", - "romnr": 12016, - "plasser": 200, - "adresse": "Torvet 4-6", - "latitude": 59.284283, - "longitude": 11.110528 - }, - { - "lokalId": "d2a5c489-2f89-4832-9898-aaac31687161", - "romnr": 12021, - "plasser": 42, - "adresse": "Finn Sørli/ Hundskinnveien 92", - "latitude": 59.285444, - "longitude": 11.079418 - }, - { - "lokalId": "4effbc5f-a0a3-49d2-89f9-0a84d6d789eb", - "romnr": 12025, - "plasser": 87, - "adresse": "Erikmarka 3", - "latitude": 62.44375, - "longitude": 6.214557 - }, - { - "lokalId": "927ef9c3-2338-4359-b64f-8cae9a22ed3c", - "romnr": 12072, - "plasser": 500, - "adresse": "Keiser Wilhelms gate 11", - "latitude": 62.470973, - "longitude": 6.153836 - }, - { - "lokalId": "784be7db-0817-4fe1-8d6c-432b0d9aad09", - "romnr": 12163, - "plasser": 123, - "adresse": "Blindheimsgeilane 1", - "latitude": 62.445808, - "longitude": 6.363423 - }, - { - "lokalId": "600e66df-d12c-4d71-8ef2-a1534901bfb6", - "romnr": 12196, - "plasser": 300, - "adresse": "Storgata 16", - "latitude": 62.473695, - "longitude": 6.158668 - }, - { - "lokalId": "df03582e-bd79-4598-a279-67424860b65a", - "romnr": 12245, - "plasser": 500, - "adresse": "Gangstøvikvegen 27", - "latitude": 62.474085, - "longitude": 6.227913 - }, - { - "lokalId": "21c6887e-6d07-4789-b3b1-c13fca7717cf", - "romnr": 12272, - "plasser": 383, - "adresse": "Fjellgata 45", - "latitude": 62.472098, - "longitude": 6.175156 - }, - { - "lokalId": "18365474-66d5-49ca-8721-ae66bbbf81ef", - "romnr": 12304, - "plasser": 315, - "adresse": "Torggata 52", - "latitude": 60.794365, - "longitude": 11.072283 - }, - { - "lokalId": "bb0bdd03-1776-40df-8a41-96c728d969b5", - "romnr": 12306, - "plasser": 216, - "adresse": "Parkgata 33", - "latitude": 60.793351, - "longitude": 11.079709 - }, - { - "lokalId": "9dee91f4-3688-4d50-99f4-1e63ea308b34", - "romnr": 12307, - "plasser": 270, - "adresse": "Morteruds gate 22 - 24", - "latitude": 60.795423, - "longitude": 11.066359 - }, - { - "lokalId": "61de7828-aba3-4d1b-b967-845c145cf61d", - "romnr": 12308, - "plasser": 320, - "adresse": "Storhamargata 23 B-C", - "latitude": 60.794926, - "longitude": 11.065353 - }, - { - "lokalId": "6f70750c-a65d-4fb6-8033-dae3a62593ae", - "romnr": 12309, - "plasser": 80, - "adresse": "Rollsløkkvegen 19", - "latitude": 60.800691, - "longitude": 11.084808 - }, - { - "lokalId": "e688cf83-a179-4792-b7f7-30934162edbf", - "romnr": 12311, - "plasser": 50, - "adresse": "Aslak Bolts gate 42", - "latitude": 60.797859, - "longitude": 11.048915 - }, - { - "lokalId": "d144dde7-e60d-4693-b22e-2168c1a27c25", - "romnr": 12312, - "plasser": 158, - "adresse": "Torggata 31", - "latitude": 60.793802, - "longitude": 11.073934 - }, - { - "lokalId": "2849b0de-b4ce-47b0-96c7-1e1805e023ec", - "romnr": 12313, - "plasser": 49, - "adresse": "Finsalvegen 3", - "latitude": 60.804176, - "longitude": 11.132714 - }, - { - "lokalId": "87f19be5-4dd5-4774-9151-acf467bbef24", - "romnr": 12314, - "plasser": 35, - "adresse": "Elvesletta 25", - "latitude": 60.842298, - "longitude": 11.094855 - }, - { - "lokalId": "376ba9ad-c19b-45dc-9eef-bf26cf51afea", - "romnr": 12315, - "plasser": 15, - "adresse": "Midtstranda 1", - "latitude": 60.797947, - "longitude": 11.107548 - }, - { - "lokalId": "d208f3e4-3de4-4990-9071-c69c2e458005", - "romnr": 12325, - "plasser": 200, - "adresse": "Øvre Flatåsveg 2 A", - "latitude": 63.372677, - "longitude": 10.345811 - }, - { - "lokalId": "66624647-ece8-497a-88e0-fe141de7a7d0", - "romnr": 12330, - "plasser": 45, - "adresse": "Øvre Flatåsveg 16", - "latitude": 63.373192, - "longitude": 10.333224 - }, - { - "lokalId": "83ed37dd-6fad-482a-9304-1dc437eacf4d", - "romnr": 12333, - "plasser": 280, - "adresse": "Gamle Jonsvannsveien 12", - "latitude": 63.411511, - "longitude": 10.452723 - }, - { - "lokalId": "29d86544-0a39-476a-88be-a0f71069b65e", - "romnr": 12438, - "plasser": 459, - "adresse": "Infanteriveien 11, Setermoen brannstasjon", - "latitude": 68.860116, - "longitude": 18.354632 - }, - { - "lokalId": "183603f8-b340-4fbd-9692-ff9e0ba9f66a", - "romnr": 12456, - "plasser": 225, - "adresse": "Gesellveien 5", - "latitude": 59.653414, - "longitude": 9.63991 - }, - { - "lokalId": "cd02331f-fe44-4a2c-87ad-bc9f7fcdf3c0", - "romnr": 12704, - "plasser": 1250, - "adresse": "Lykkeberg/ St.Croix gate 31", - "latitude": 59.211252, - "longitude": 10.941203 - }, - { - "lokalId": "cfa9f5e8-195e-4410-822a-c9d57baec9c1", - "romnr": 12705, - "plasser": 1345, - "adresse": "Damyr/ Sportsveien 18", - "latitude": 59.21285, - "longitude": 10.948606 - }, - { - "lokalId": "d22a0437-178c-4d18-ac00-7d5c0561814b", - "romnr": 12706, - "plasser": 5384, - "adresse": "St. hansfjellet/ Farmansgate 16", - "latitude": 59.214646, - "longitude": 10.934136 - }, - { - "lokalId": "c3587616-a180-4054-8214-bb9081b19d43", - "romnr": 12707, - "plasser": 716, - "adresse": "Kongstenhallen", - "latitude": 59.200707, - "longitude": 10.961142 - }, - { - "lokalId": "df620830-e4e4-442f-bb78-0f5083257be2", - "romnr": 12708, - "plasser": 750, - "adresse": "Smertu/ Løypeveien 18", - "latitude": 59.2042, - "longitude": 10.936221 - }, - { - "lokalId": "7851bf7f-832e-425e-a4e7-5efffb4ba071", - "romnr": 12709, - "plasser": 1200, - "adresse": "Gressvik/ Storveien 103A", - "latitude": 59.214315, - "longitude": 10.902453 - }, - { - "lokalId": "d9804de5-f0ed-452e-814b-4104b7c64aab", - "romnr": 12710, - "plasser": 97, - "adresse": "Aktivitetshuset/ Gressvik torg 13", - "latitude": 59.216214, - "longitude": 10.906206 - }, - { - "lokalId": "b25053a2-6132-458c-b783-abbb487cda22", - "romnr": 12711, - "plasser": 100, - "adresse": "Rolvsøyahallen", - "latitude": 59.267677, - "longitude": 10.991211 - }, - { - "lokalId": "c77c9b95-7e38-4a72-953b-075d32a46afa", - "romnr": 13266, - "plasser": 165, - "adresse": "Bleikerveien 64 (Asker Tennisklubb)", - "latitude": 59.827695, - "longitude": 10.447574 - }, - { - "lokalId": "d7079e62-d506-4a68-a91e-3c5c89b7c570", - "romnr": 13361, - "plasser": 756, - "adresse": "Kulturhuset", - "latitude": 69.231288, - "longitude": 17.98805 - }, - { - "lokalId": "1a609376-125e-4bfb-bd68-696225d8acef", - "romnr": 13469, - "plasser": 65, - "adresse": "Øvermarka 24", - "latitude": 60.8436, - "longitude": 11.043208 - }, - { - "lokalId": "ffd6ac5e-53c6-40ac-913b-241c2626815b", - "romnr": 13470, - "plasser": 55, - "adresse": "Nygata 9", - "latitude": 60.881794, - "longitude": 10.939832 - }, - { - "lokalId": "b2391e67-12ce-4c07-95b6-b9863689b046", - "romnr": 13471, - "plasser": 343, - "adresse": "Brugata 3", - "latitude": 60.885432, - "longitude": 10.939129 - }, - { - "lokalId": "06ec3426-428f-4357-a048-668ee514dcc7", - "romnr": 13472, - "plasser": 52, - "adresse": "Ljøstadvegen 15", - "latitude": 60.715074, - "longitude": 11.204224 - }, - { - "lokalId": "129f5a0f-9ad4-40bc-bdab-57b3dac6d5d9", - "romnr": 13479, - "plasser": 1372, - "adresse": "Strømsø torg 7", - "latitude": 59.740131, - "longitude": 10.200576 - }, - { - "lokalId": "110aa298-bb7d-45a5-bc0d-4cb00a58f000", - "romnr": 13510, - "plasser": 313, - "adresse": "Sørreisa Rådhus/Helsesenter", - "latitude": 69.147198, - "longitude": 18.1559 - }, - { - "lokalId": "eb43f667-dcb2-4a70-b31e-589948272d34", - "romnr": 13511, - "plasser": 173, - "adresse": "Øyjordneset", - "latitude": 69.154384, - "longitude": 18.156183 - }, - { - "lokalId": "5d466183-5e6b-4157-a76d-5b4ac9a7b497", - "romnr": 13513, - "plasser": 175, - "adresse": "Dyrøy sykehjem, Brøstabotn", - "latitude": 69.091034, - "longitude": 17.69045 - }, - { - "lokalId": "ec478664-a4f5-4c13-a125-f2b17ec1aa4c", - "romnr": 13637, - "plasser": 1200, - "adresse": "Bergstien 37", - "latitude": 59.748307, - "longitude": 10.203019 - }, - { - "lokalId": "deec4abb-09e7-4ff4-ab8f-d043f1a6620d", - "romnr": 13649, - "plasser": 465, - "adresse": "Oscars gate 4", - "latitude": 70.074609, - "longitude": 29.750277 - }, - { - "lokalId": "552f184d-c045-4f9c-a2e1-447da99d8fc1", - "romnr": 14233, - "plasser": 372, - "adresse": "Garderobehuset, Narvik stadion, Lillevikveien 9", - "latitude": 68.442373, - "longitude": 17.406735 - }, - { - "lokalId": "fcd7cba7-d097-4bef-bf0f-6c36e79830d4", - "romnr": 14249, - "plasser": 120, - "adresse": "Fotvegen 16", - "latitude": 59.290624, - "longitude": 5.288196 - }, - { - "lokalId": "53c612ca-f463-41f6-96b4-af6beca8437b", - "romnr": 14250, - "plasser": 445, - "adresse": "Ankenes Bo- og serviceservice Krobakken 5", - "latitude": 68.422775, - "longitude": 17.349114 - }, - { - "lokalId": "4f007bac-8c81-4cca-a25f-f82cbe6685ba", - "romnr": 14279, - "plasser": 63, - "adresse": "Neptunveien 3-5", - "latitude": 59.760513, - "longitude": 10.03575 - }, - { - "lokalId": "c7036287-c719-4a24-a64d-398e01f344d7", - "romnr": 14355, - "plasser": 18, - "adresse": "Austre Veaveg 217", - "latitude": 59.292976, - "longitude": 5.226173 - }, - { - "lokalId": "50e15ba1-c4a6-4741-8b49-7311f3868969", - "romnr": 14476, - "plasser": 400, - "adresse": "Hagebyen skole", - "latitude": 68.813691, - "longitude": 16.543533 - }, - { - "lokalId": "c3383e3d-c735-4250-8b0a-9205233f2eac", - "romnr": 14487, - "plasser": 400, - "adresse": "Rådhuset Harstad OFFENTLIG", - "latitude": 68.798741, - "longitude": 16.53915 - }, - { - "lokalId": "fe6d439c-8114-4e5a-8ebe-2b49639428fa", - "romnr": 14559, - "plasser": 281, - "adresse": "Stokkeveien 2", - "latitude": 59.791903, - "longitude": 10.258623 - }, - { - "lokalId": "bfe4fed1-4064-47cd-a878-52121f124c21", - "romnr": 14566, - "plasser": 850, - "adresse": "Kanebogen skole OFFENTLIG", - "latitude": 68.779884, - "longitude": 16.55882 - }, - { - "lokalId": "ac17fbb5-c7cd-4c37-9cf5-1c6255c18da8", - "romnr": 14854, - "plasser": 320, - "adresse": "Kong Øysteinhall, Rækøyveien 40. Kabelvåg", - "latitude": 68.207975, - "longitude": 14.46518 - }, - { - "lokalId": "eda2e4d1-8016-4720-9616-7d7cb011a471", - "romnr": 14855, - "plasser": 3300, - "adresse": "VåganHallen, Løkthaugveien 10. Svolvær", - "latitude": 68.237656, - "longitude": 14.567376 - }, - { - "lokalId": "159c38d2-dbba-4d2c-b6b6-b4c4486885f6", - "romnr": 14871, - "plasser": 83, - "adresse": "Vesterngata 18", - "latitude": 60.170464, - "longitude": 10.268181 - }, - { - "lokalId": "5c571011-5b0f-485d-937a-6c603fb9e7e3", - "romnr": 14905, - "plasser": 90, - "adresse": "Skulegata 29", - "latitude": 59.652094, - "longitude": 6.357013 - }, - { - "lokalId": "b9cfdd00-82f8-4e74-b9bf-45869dbbad24", - "romnr": 14908, - "plasser": 125, - "adresse": "Saudavegen 279", - "latitude": 59.645393, - "longitude": 6.31035 - }, - { - "lokalId": "00aba34c-24b4-4d88-bc00-ad8adbfb5655", - "romnr": 14911, - "plasser": 150, - "adresse": "Rustå 31", - "latitude": 59.657841, - "longitude": 6.380221 - }, - { - "lokalId": "0609ac19-3913-458a-babf-b8b90a004912", - "romnr": 14918, - "plasser": 85, - "adresse": "Åbødalsveien 79", - "latitude": 59.656027, - "longitude": 6.363345 - }, - { - "lokalId": "c351b9f4-7a9f-42ac-aa98-942bf4b27b26", - "romnr": 14959, - "plasser": 814, - "adresse": "Karl Rasmussens plass 1", - "latitude": 70.077958, - "longitude": 29.739806 - }, - { - "lokalId": "9df20d2c-d3ad-41d2-81c5-859e20f416da", - "romnr": 14979, - "plasser": 600, - "adresse": "Skulegata 23", - "latitude": 59.651065, - "longitude": 6.357565 - }, - { - "lokalId": "49495ccf-97e9-4806-abb1-608585bf7554", - "romnr": 14981, - "plasser": 78, - "adresse": "Sjøen 45", - "latitude": 59.640103, - "longitude": 6.30552 - }, - { - "lokalId": "3646208a-0a6e-4309-bb72-35fefec26e89", - "romnr": 14984, - "plasser": 40, - "adresse": "Åbødalsveien 77", - "latitude": 59.655203, - "longitude": 6.363862 - }, - { - "lokalId": "10390a33-a17c-4de3-99be-f1dc77ba1bad", - "romnr": 15004, - "plasser": 100, - "adresse": "Sortlandshallen", - "latitude": 68.696152, - "longitude": 15.407296 - }, - { - "lokalId": "59406cab-1952-4a73-811f-bf668f1f8de1", - "romnr": 15005, - "plasser": 300, - "adresse": "Torvmyrveien 4A", - "latitude": 59.000947, - "longitude": 5.619654 - }, - { - "lokalId": "0be3386f-7f4f-4232-8da7-13688b493071", - "romnr": 15006, - "plasser": 270, - "adresse": "Torvmyrveien 40", - "latitude": 59.00893, - "longitude": 5.650053 - }, - { - "lokalId": "cfc1ace9-76e9-4300-b623-4a2593bb1aad", - "romnr": 15059, - "plasser": 2000, - "adresse": "Storevardvegen", - "latitude": 58.940876, - "longitude": 5.578049 - }, - { - "lokalId": "b670476d-0c81-4ade-bd14-b98f0515b97c", - "romnr": 15232, - "plasser": 2080, - "adresse": "Kirkebakken 18", - "latitude": 58.96844, - "longitude": 5.737782 - }, - { - "lokalId": "1a71c377-8a40-4c5d-8fd5-f6b9f8312728", - "romnr": 15236, - "plasser": 200, - "adresse": "Morgedalsveien 60", - "latitude": 58.951392, - "longitude": 5.695868 - }, - { - "lokalId": "04fe19e2-9c2b-4d27-96b4-f52cc49bdb81", - "romnr": 15239, - "plasser": 220, - "adresse": "Jupiterveien 30C", - "latitude": 58.947102, - "longitude": 5.700146 - }, - { - "lokalId": "2c781068-a801-4786-b18f-017d16d3c6fc", - "romnr": 15240, - "plasser": 500, - "adresse": "Lagårdsveien 77", - "latitude": 58.958333, - "longitude": 5.739728 - }, - { - "lokalId": "a590197a-9eb7-4660-a3c9-e07a9a9244ac", - "romnr": 15243, - "plasser": 5000, - "adresse": "Nedre Storaberget 1", - "latitude": 58.896774, - "longitude": 5.722953 - }, - { - "lokalId": "379ec27f-5699-41d4-a8a3-e4afc11484e9", - "romnr": 15245, - "plasser": 4000, - "adresse": "Nedre Strandgate", - "latitude": 58.973005, - "longitude": 5.725783 - }, - { - "lokalId": "93fb5dd2-ee84-46a3-ac83-bbeb9f36d6e7", - "romnr": 15246, - "plasser": 380, - "adresse": "Olav Liljekransstien 20", - "latitude": 58.944657, - "longitude": 5.698082 - }, - { - "lokalId": "ffa50c4c-cb44-458c-83de-8948d4531652", - "romnr": 15247, - "plasser": 380, - "adresse": "Hallingstien 38", - "latitude": 58.946174, - "longitude": 5.697058 - }, - { - "lokalId": "e1d932bf-27b4-4f02-8301-fae2e301efe4", - "romnr": 15250, - "plasser": 3930, - "adresse": "Skagenkaien 29", - "latitude": 58.972125, - "longitude": 5.731114 - }, - { - "lokalId": "71d153cc-a683-47c5-8619-ae6d34572b3b", - "romnr": 15251, - "plasser": 3140, - "adresse": "Eskelandsveien 35", - "latitude": 58.986136, - "longitude": 5.67812 - }, - { - "lokalId": "9da896af-9d7b-47de-ba1e-16723bdb4394", - "romnr": 15255, - "plasser": 72, - "adresse": "Avaldsnesvegen 72", - "latitude": 59.291226, - "longitude": 5.303296 - }, - { - "lokalId": "50e3e29b-79a2-4a21-8617-ffa1c4b0cdf2", - "romnr": 15258, - "plasser": 66, - "adresse": "Austre Karmøyveg 120", - "latitude": 59.280605, - "longitude": 5.300107 - }, - { - "lokalId": "5d9c7d1a-d71d-4965-9834-6e77c0eb81f2", - "romnr": 15260, - "plasser": 608, - "adresse": "Lotheparkvegen", - "latitude": 59.421294, - "longitude": 5.270669 - }, - { - "lokalId": "783b92ee-fc7f-42ce-8318-2e0793475c4a", - "romnr": 15347, - "plasser": 150, - "adresse": "Turist og konferansesenteret, Børøya", - "latitude": 68.570795, - "longitude": 14.92446 - }, - { - "lokalId": "b4bab817-3cfc-48af-9fc9-196af69fdaf1", - "romnr": 15468, - "plasser": 420, - "adresse": "Søndre Torv 7 B", - "latitude": 60.165649, - "longitude": 10.254797 - }, - { - "lokalId": "9dc780ee-1e06-433f-a82a-e8603fae95aa", - "romnr": 15471, - "plasser": 417, - "adresse": "Valhallveien 15", - "latitude": 60.182025, - "longitude": 10.196138 - }, - { - "lokalId": "1fb030cc-d777-4263-81a7-d9cf2a48b74d", - "romnr": 15476, - "plasser": 170, - "adresse": "Ringeriksgata 13", - "latitude": 60.157429, - "longitude": 10.262372 - }, - { - "lokalId": "6ea7900f-78a6-48a3-b9dc-52ebc33790d8", - "romnr": 15481, - "plasser": 100, - "adresse": "Dronning Åstas gate 12", - "latitude": 60.153285, - "longitude": 10.252902 - }, - { - "lokalId": "72f51a02-eef7-4d55-8e62-2299a791398a", - "romnr": 15597, - "plasser": 385, - "adresse": "Krokenveien 19", - "latitude": 60.180368, - "longitude": 10.259675 - }, - { - "lokalId": "f1af3458-1971-4b77-8b60-3fe819a0ec52", - "romnr": 15611, - "plasser": 330, - "adresse": "Wergelands gate 9", - "latitude": 59.748398, - "longitude": 10.19372 - }, - { - "lokalId": "00665953-a9db-44c3-82ff-8b58d01e697f", - "romnr": 15714, - "plasser": 150, - "adresse": "Søfteland", - "latitude": 60.2363, - "longitude": 5.452183 - }, - { - "lokalId": "e1386977-fd37-41e7-b140-84445e4907e6", - "romnr": 15715, - "plasser": 550, - "adresse": "Rådhus. Idrett og Svømmehall", - "latitude": 69.314139, - "longitude": 16.118059 - }, - { - "lokalId": "f86ac2c2-7916-4c4f-8e93-64e55ad21a31", - "romnr": 15717, - "plasser": 136, - "adresse": "Askviknes Sykehjem", - "latitude": 60.175596, - "longitude": 5.38207 - }, - { - "lokalId": "b833ca4b-52d7-4218-8f6c-348561490856", - "romnr": 15730, - "plasser": 500, - "adresse": "Os", - "latitude": 60.188854, - "longitude": 5.469669 - }, - { - "lokalId": "8f0ae2fb-a6da-406b-9c2c-84dd5145da40", - "romnr": 15745, - "plasser": 150, - "adresse": "Betanien Hospital", - "latitude": 59.209066, - "longitude": 9.596141 - }, - { - "lokalId": "b2d09ab0-d33e-41fa-9212-345efac5118d", - "romnr": 15746, - "plasser": 390, - "adresse": "Gampedalen", - "latitude": 59.20229, - "longitude": 9.617147 - }, - { - "lokalId": "b1f54198-34c4-42ba-96c5-eb1f8f599457", - "romnr": 15748, - "plasser": 325, - "adresse": "Nedre Hjellegt 9", - "latitude": 59.206353, - "longitude": 9.606643 - }, - { - "lokalId": "4e73e1b9-2771-4bd8-9f30-d931d483bd1d", - "romnr": 15749, - "plasser": 498, - "adresse": "Schweigaards gate 11", - "latitude": 59.21216, - "longitude": 9.605392 - }, - { - "lokalId": "44e8d95c-c810-4499-92d6-cc5270319428", - "romnr": 15750, - "plasser": 400, - "adresse": "Tamburlunden Gråtenmoen Terrasse 16", - "latitude": 59.185667, - "longitude": 9.616471 - }, - { - "lokalId": "a7a7c665-e70a-460c-90f8-804ced8c151b", - "romnr": 15752, - "plasser": 500, - "adresse": "Bånnåsen 21", - "latitude": 59.136651, - "longitude": 9.660227 - }, - { - "lokalId": "06c97fed-31e3-4088-ae82-35177c2896ba", - "romnr": 15753, - "plasser": 1120, - "adresse": "Helleberget, Huken, Crøgerlia 21", - "latitude": 59.137459, - "longitude": 9.644708 - }, - { - "lokalId": "cdb937f2-fc60-424f-bad8-d58cf6e66742", - "romnr": 15754, - "plasser": 490, - "adresse": "Klevstrand", - "latitude": 59.115603, - "longitude": 9.653273 - }, - { - "lokalId": "d5f60040-8208-4ee8-be96-9b398004b187", - "romnr": 15755, - "plasser": 540, - "adresse": "Lysthusåsen, Kleiva 4", - "latitude": 59.142081, - "longitude": 9.644843 - }, - { - "lokalId": "2a199dad-b9f7-47e0-a4d5-e20cf0c604d4", - "romnr": 15756, - "plasser": 130, - "adresse": "Politihuset, Rådhusgt 5", - "latitude": 59.141775, - "longitude": 9.657483 - }, - { - "lokalId": "4d5cf968-d970-4177-b09d-681e84793899", - "romnr": 15757, - "plasser": 2000, - "adresse": "Sentrumstunellen/Porsgrunntunnelen", - "latitude": 59.135636, - "longitude": 9.660491 - }, - { - "lokalId": "021367f0-00f6-49de-8269-74f1aa792a85", - "romnr": 15758, - "plasser": 140, - "adresse": "Slottsbrugt 25", - "latitude": 59.14586, - "longitude": 9.664885 - }, - { - "lokalId": "e57fadb2-3a57-49bc-b732-129d40dc3d4e", - "romnr": 15759, - "plasser": 1040, - "adresse": "Trosvik, Brevik", - "latitude": 59.054237, - "longitude": 9.691015 - }, - { - "lokalId": "abebabd2-9bac-4f67-adfa-8f4c25fdccfa", - "romnr": 15760, - "plasser": 1000, - "adresse": "Renseanlegget, Ytre Strandvei 15", - "latitude": 58.873599, - "longitude": 9.414783 - }, - { - "lokalId": "3bf7f665-a23d-4c03-b0ea-c5df79537f91", - "romnr": 15761, - "plasser": 220, - "adresse": "Årø skole, Nøkkeldalen 4", - "latitude": 58.890679, - "longitude": 9.356233 - }, - { - "lokalId": "ce5b04a6-24d9-4dca-b988-82950c5b9cb5", - "romnr": 15762, - "plasser": 55, - "adresse": "Kalstad KBO, Kalstadveien 16E", - "latitude": 58.871025, - "longitude": 9.388295 - }, - { - "lokalId": "c08496d0-3ab5-428f-b814-ff2a02cde9f5", - "romnr": 15765, - "plasser": 728, - "adresse": "Potekjeller tomta, Bøenstomten 10", - "latitude": 59.879335, - "longitude": 8.591391 - }, - { - "lokalId": "c5ffe2c5-41cc-479e-8b85-5baf0b2de0ba", - "romnr": 15766, - "plasser": 200, - "adresse": "Rjukan politikammer, Sam Eydes gate 71", - "latitude": 59.878593, - "longitude": 8.589474 - }, - { - "lokalId": "6f37425c-7109-4fad-98f9-f7c4b3e6de23", - "romnr": 15767, - "plasser": 420, - "adresse": "Heddal u/skole, Rogneståvegen 6", - "latitude": 59.569637, - "longitude": 9.211249 - }, - { - "lokalId": "09d3c381-fe94-423c-a867-c58684aad60b", - "romnr": 15768, - "plasser": 1900, - "adresse": "Ravnsflog, Tinnesgata 18", - "latitude": 59.560759, - "longitude": 9.254196 - }, - { - "lokalId": "02b61699-0710-4e4e-ac73-c76ae85c5c6c", - "romnr": 15769, - "plasser": 700, - "adresse": "Storgt 59", - "latitude": 59.561301, - "longitude": 9.261607 - }, - { - "lokalId": "34e71c7b-d2ff-45e8-9d0c-c76d049d9600", - "romnr": 15770, - "plasser": 180, - "adresse": "Stathelle Service Senter", - "latitude": 59.042874, - "longitude": 9.692843 - }, - { - "lokalId": "85abf213-51b3-4c1f-8cfc-368f1f9fe059", - "romnr": 15771, - "plasser": 1138, - "adresse": "Kvæfjordhallen, Husebyveien 3", - "latitude": 68.772839, - "longitude": 16.179076 - }, - { - "lokalId": "a1644a4c-3376-4f0c-9639-d35782d9a8dc", - "romnr": 16127, - "plasser": 465, - "adresse": "Nils Leuchsvei 40", - "latitude": 59.946683, - "longitude": 10.619218 - }, - { - "lokalId": "89fba71a-d961-44d1-8652-e422d933761f", - "romnr": 16213, - "plasser": 1550, - "adresse": "Rødskiferveien 1 Kolsås Senter", - "latitude": 59.916573, - "longitude": 10.50076 - }, - { - "lokalId": "74a68b66-d7bf-4eea-8165-e8567953f486", - "romnr": 16352, - "plasser": 225, - "adresse": "Østerndalen 23 Grini næringspark", - "latitude": 59.947496, - "longitude": 10.601794 - }, - { - "lokalId": "bc28dfa9-41ef-4e29-9c17-88b95c254621", - "romnr": 16719, - "plasser": 1130, - "adresse": "St. Hanshaugen, Ullevålsveien", - "latitude": 59.925364, - "longitude": 10.738991 - }, - { - "lokalId": "ec8244e3-dcc8-4269-a09a-d6dce62966a0", - "romnr": 16951, - "plasser": 197, - "adresse": "Tareveien 7 Tennishallen", - "latitude": 67.258352, - "longitude": 15.352302 - }, - { - "lokalId": "3b8b00cf-c39a-4f8b-b6bf-a77550648db4", - "romnr": 16958, - "plasser": 255, - "adresse": "Tinkeliheia 1, (Finneid nærmiljøsenter)", - "latitude": 67.259782, - "longitude": 15.444636 - }, - { - "lokalId": "9b5d2b64-46e1-4051-97f2-af06016bcf20", - "romnr": 16973, - "plasser": 1750, - "adresse": "Tullinsgate 2", - "latitude": 59.918829, - "longitude": 10.734887 - }, - { - "lokalId": "9bf053fa-788c-4258-b721-6245e4033cd9", - "romnr": 17007, - "plasser": 214, - "adresse": "Løpsmark Skole Nonshaugen 87, 8015 Bodø", - "latitude": 67.310299, - "longitude": 14.447098 - }, - { - "lokalId": "4fdce490-e4f5-401a-9de2-647e43f67d36", - "romnr": 17014, - "plasser": 400, - "adresse": "Bjørndalsveien 14 (Mørkvedmarka skole)", - "latitude": 67.290673, - "longitude": 14.588055 - }, - { - "lokalId": "15e3a9d8-87ff-4e93-b539-424b61be22ce", - "romnr": 17356, - "plasser": 80, - "adresse": "Peter Bondes veg 78", - "latitude": 60.624576, - "longitude": 6.388827 - }, - { - "lokalId": "2c87f1ba-0371-4c69-b12f-a51a2d23d14d", - "romnr": 17526, - "plasser": 320, - "adresse": "Risilveien 71, Vestbyhallen", - "latitude": 59.597822, - "longitude": 10.709967 - }, - { - "lokalId": "7e999c54-b386-4690-b2ca-8ebbeeb75c45", - "romnr": 17609, - "plasser": 590, - "adresse": "Frognhallen, Belsjøveien 2", - "latitude": 59.66884, - "longitude": 10.634824 - }, - { - "lokalId": "b23f45b7-7ef4-4ea2-8f30-e618e274e2b1", - "romnr": 17676, - "plasser": 100, - "adresse": "Tjørnahaugane 60", - "latitude": 60.616448, - "longitude": 6.536621 - }, - { - "lokalId": "33613aa6-caa9-40a6-a5aa-15a83c30cedd", - "romnr": 17701, - "plasser": 240, - "adresse": "Moerveien 1- Skoleveien 1 Ås Rådhus", - "latitude": 59.664228, - "longitude": 10.790869 - }, - { - "lokalId": "21d3e8f2-f0b6-4932-a434-4bea860f9458", - "romnr": 17829, - "plasser": 258, - "adresse": "Allbrukshus Langhus, Galmle Vevelstadvei 34", - "latitude": 59.758799, - "longitude": 10.841281 - }, - { - "lokalId": "ac9d6b55-c600-43a7-94b7-432ebeaa002f", - "romnr": 18081, - "plasser": 240, - "adresse": "Rektor Oldens gate 2", - "latitude": 58.955198, - "longitude": 5.692018 - }, - { - "lokalId": "f09d6171-8177-4459-bae6-dc18bd497c5a", - "romnr": 18533, - "plasser": 300, - "adresse": "Fred Olsensgt 11", - "latitude": 59.910517, - "longitude": 10.748667 - }, - { - "lokalId": "f87aa2ba-ed34-4d46-a1ba-4e252f3da671", - "romnr": 18616, - "plasser": 7060, - "adresse": "Holmlia bad, Holmlia sentervei 34", - "latitude": 59.834469, - "longitude": 10.792393 - }, - { - "lokalId": "513daacc-01a0-41a6-959d-0a4b08799a8c", - "romnr": 20209, - "plasser": 250, - "adresse": "Bentsegt 21-25", - "latitude": 59.937644, - "longitude": 10.759794 - }, - { - "lokalId": "927a95b8-be35-4f76-bcde-32f911d541e4", - "romnr": 20242, - "plasser": 230, - "adresse": "Grav Gårdsvei 5", - "latitude": 59.93033, - "longitude": 10.606651 - }, - { - "lokalId": "7f799fd7-e3c9-4243-ae98-45891f5402dd", - "romnr": 21027, - "plasser": 40, - "adresse": "K.O. Bjerklis veg 9", - "latitude": 60.807854, - "longitude": 11.03274 - }, - { - "lokalId": "e7e88a06-c5da-43a7-82c6-0824aca1ee4a", - "romnr": 20243, - "plasser": 233, - "adresse": "Peter Lorangesvei 1, Stabekk Bosenter", - "latitude": 59.904457, - "longitude": 10.586712 - }, - { - "lokalId": "953a32f7-d8ff-43a4-8377-3965f5c6cb80", - "romnr": 20244, - "plasser": 553, - "adresse": "Skollerudveien 7, Helset hallen", - "latitude": 59.942985, - "longitude": 10.50811 - }, - { - "lokalId": "5bc4785d-c8d1-40ed-a73d-7fafdf08ff1a", - "romnr": 20245, - "plasser": 5500, - "adresse": "Vogellund 7, Holmenhallen", - "latitude": 59.853057, - "longitude": 10.484845 - }, - { - "lokalId": "211131f2-add4-40ae-b119-16f31546dd16", - "romnr": 20246, - "plasser": 250, - "adresse": "Veståsen 18, Katolsk kapell", - "latitude": 59.935334, - "longitude": 10.60407 - }, - { - "lokalId": "adb8b934-7f7f-4e2e-90c9-a4e68e6c0cd1", - "romnr": 20247, - "plasser": 1336, - "adresse": "Gml Ringeriksvei 44", - "latitude": 59.918199, - "longitude": 10.584346 - }, - { - "lokalId": "1974f202-ec50-4c0c-82a1-8ffe50db83e6", - "romnr": 20248, - "plasser": 260, - "adresse": "Bjerkelundsveien 18 A", - "latitude": 59.929936, - "longitude": 10.614801 - }, - { - "lokalId": "5e3a1c9b-ccaf-4f83-933d-71d7e8fa120b", - "romnr": 20249, - "plasser": 233, - "adresse": "Nedre Toppenhaug 56", - "latitude": 59.940538, - "longitude": 10.507814 - }, - { - "lokalId": "c921185b-add1-4acb-ac5b-5669b1536436", - "romnr": 20250, - "plasser": 4200, - "adresse": "Hamangskråningen, Brynsveien 2 Sandvika", - "latitude": 59.894621, - "longitude": 10.512613 - }, - { - "lokalId": "0a20e1a1-3320-494b-a218-e16614f2bf08", - "romnr": 20251, - "plasser": 243, - "adresse": "Sleiverudåsen 3", - "latitude": 59.945117, - "longitude": 10.504182 - }, - { - "lokalId": "8c93f8c3-a6d6-4fc0-9064-54f597fb9022", - "romnr": 20253, - "plasser": 2800, - "adresse": "T-banen - Valkyrien stasjon", - "latitude": 59.928429, - "longitude": 10.717619 - }, - { - "lokalId": "b16f5ed2-5715-4158-9801-401e0739f339", - "romnr": 20254, - "plasser": 5600, - "adresse": "Klemetsrud, Lofsrudveien 6", - "latitude": 59.848756, - "longitude": 10.829616 - }, - { - "lokalId": "0969e8cc-0196-42ca-99ae-6ad4d2908d58", - "romnr": 20255, - "plasser": 404, - "adresse": "Jordalsgt 11", - "latitude": 59.908953, - "longitude": 10.785588 - }, - { - "lokalId": "8b553950-90aa-4790-9d5b-7aa7af16d0ea", - "romnr": 20256, - "plasser": 555, - "adresse": "Majorstuveien 38", - "latitude": 59.928313, - "longitude": 10.714875 - }, - { - "lokalId": "0363ba51-a591-435b-96d8-daa87601bd2e", - "romnr": 20257, - "plasser": 4300, - "adresse": "Maridalsveien 14", - "latitude": 59.92252, - "longitude": 10.750318 - }, - { - "lokalId": "a2832514-ef82-47cc-8fd0-a83eca60643c", - "romnr": 20258, - "plasser": 472, - "adresse": "Olav Schousvei 2-8 plan A", - "latitude": 59.930605, - "longitude": 10.781977 - }, - { - "lokalId": "7d52ca22-2975-4e74-be7b-aed5010a8ca4", - "romnr": 20259, - "plasser": 385, - "adresse": "Nobelsgt 30", - "latitude": 59.921882, - "longitude": 10.700768 - }, - { - "lokalId": "de1ea4fc-1183-4602-abcb-3ddb68a7caba", - "romnr": 20261, - "plasser": 486, - "adresse": "Vøyensvingen 4", - "latitude": 59.929862, - "longitude": 10.752136 - }, - { - "lokalId": "95625b93-ad68-4dc9-afd4-bb29f9792b58", - "romnr": 20262, - "plasser": 260, - "adresse": "Kingosgt 17", - "latitude": 59.930057, - "longitude": 10.751484 - }, - { - "lokalId": "82263184-bc90-4aba-bf6b-df5648691e05", - "romnr": 20263, - "plasser": 2000, - "adresse": "T-banen - Jernbanetorget, nedgang Hotell clarion", - "latitude": 59.912508, - "longitude": 10.751295 - }, - { - "lokalId": "21acd61f-abf7-4e71-ab04-a5bcf6833cbc", - "romnr": 20264, - "plasser": 570, - "adresse": "Akersgata 41", - "latitude": 59.913579, - "longitude": 10.741865 - }, - { - "lokalId": "46943f13-2874-4e21-bfd7-87841b6d967d", - "romnr": 20265, - "plasser": 3000, - "adresse": "Akershus festning - Akershusstranda", - "latitude": 59.908679, - "longitude": 10.734938 - }, - { - "lokalId": "ad71d7da-fb1d-449a-ae81-f12c769d4d5b", - "romnr": 20266, - "plasser": 250, - "adresse": "Fredrik Stangsgt 37", - "latitude": 59.917852, - "longitude": 10.70926 - }, - { - "lokalId": "cb90db04-9382-4175-b0c3-705a9992d171", - "romnr": 20268, - "plasser": 160, - "adresse": "Bogstadveien 30", - "latitude": 59.926167, - "longitude": 10.720795 - }, - { - "lokalId": "6f70b1c4-40a8-4bce-86bf-880db4d2b02f", - "romnr": 20270, - "plasser": 2500, - "adresse": "T-banen - Carl Berners plass", - "latitude": 59.925835, - "longitude": 10.777908 - }, - { - "lokalId": "002cf5ce-3d09-4025-baa2-3a17eef88974", - "romnr": 20272, - "plasser": 3100, - "adresse": "T-banen - Enerhaugen - Åkebergveien", - "latitude": 59.913667, - "longitude": 10.769125 - }, - { - "lokalId": "1f03ff26-3174-4c15-a484-1120450f6ddb", - "romnr": 20275, - "plasser": 330, - "adresse": "Fagerheimgt 22", - "latitude": 59.931105, - "longitude": 10.770913 - }, - { - "lokalId": "a39ad6e5-ba19-4406-9c9c-c438e6d66e80", - "romnr": 20277, - "plasser": 460, - "adresse": "Filipstadveien 15", - "latitude": 59.907938, - "longitude": 10.713782 - }, - { - "lokalId": "cc2bb1a6-db8b-47b4-960e-5ad1ca3b333d", - "romnr": 20280, - "plasser": 2000, - "adresse": "T-banen - Grønland stasjon", - "latitude": 59.913539, - "longitude": 10.758469 - }, - { - "lokalId": "65c7d9a6-70e4-4212-b992-a94a587115db", - "romnr": 20282, - "plasser": 700, - "adresse": "Hegdehaugsveien 36", - "latitude": 59.923521, - "longitude": 10.7254 - }, - { - "lokalId": "6c415fe8-e7bf-492e-9564-090a03d73e86", - "romnr": 20283, - "plasser": 3000, - "adresse": "T-banen - Nationalteater stasjon", - "latitude": 59.915064, - "longitude": 10.733025 - }, - { - "lokalId": "7babca14-1734-42ae-83ab-2a91c983c56e", - "romnr": 20284, - "plasser": 750, - "adresse": "Tollbugata 40 / Nedre Vollgate 11", - "latitude": 59.911594, - "longitude": 10.738037 - }, - { - "lokalId": "2368bf86-a924-4527-8e18-2ca5419e57e7", - "romnr": 20285, - "plasser": 400, - "adresse": "T-banen - Oscarsgate 19", - "latitude": 59.922607, - "longitude": 10.726896 - }, - { - "lokalId": "18302b31-4288-4698-8179-98259df4629d", - "romnr": 20286, - "plasser": 1000, - "adresse": "Schwensensgt 3/5", - "latitude": 59.923207, - "longitude": 10.737924 - }, - { - "lokalId": "62d70710-2f9b-4d61-8cbe-c50b03e32b8b", - "romnr": 20287, - "plasser": 7000, - "adresse": "T-banen - Stortinget stasjon", - "latitude": 59.912796, - "longitude": 10.741858 - }, - { - "lokalId": "ff3edd06-7880-4411-9d3d-19e443ce7e1e", - "romnr": 20288, - "plasser": 760, - "adresse": "Thorvald Meyersgate 7", - "latitude": 59.929734, - "longitude": 10.758476 - }, - { - "lokalId": "78ecd274-838e-44a1-92cb-9effd833e1a9", - "romnr": 20289, - "plasser": 520, - "adresse": "Trondheimsveien 80", - "latitude": 59.924023, - "longitude": 10.77298 - }, - { - "lokalId": "6dd39d41-2fc1-476a-80d1-f50b88d9d883", - "romnr": 20290, - "plasser": 3340, - "adresse": "Torvet 6, Lillestrøm", - "latitude": 59.956095, - "longitude": 11.04845 - }, - { - "lokalId": "4f7ded7a-e781-4349-92d5-f1ebe0912705", - "romnr": 20292, - "plasser": 4600, - "adresse": "Tæruddalen 85, Tærudhallen", - "latitude": 60.013707, - "longitude": 11.016283 - }, - { - "lokalId": "395e3d35-c128-405d-9322-f477af3c4d8c", - "romnr": 20293, - "plasser": 4000, - "adresse": "Nordlifaret 50, Skårerhallen", - "latitude": 59.923349, - "longitude": 10.967033 - }, - { - "lokalId": "d92142c8-af77-4f22-b119-073e1cd84782", - "romnr": 20296, - "plasser": 70, - "adresse": "Storgata 11 - Offentlig", - "latitude": 60.141733, - "longitude": 11.173662 - }, - { - "lokalId": "c025a30b-5e53-4818-a429-80406140e890", - "romnr": 20300, - "plasser": 580, - "adresse": "Vigernesgt, Vigernes skole", - "latitude": 59.955269, - "longitude": 11.071618 - }, - { - "lokalId": "9fe34f8a-c589-41e4-afc7-76c2ac653619", - "romnr": 20301, - "plasser": 100, - "adresse": "Engaveien 6 - Vitåsen (Garderåsen)", - "latitude": 59.942091, - "longitude": 11.13152 - }, - { - "lokalId": "42e8885b-6373-4945-ac4b-505ccc07d5bc", - "romnr": 20302, - "plasser": 300, - "adresse": "Strømsveien 74, Gamle rådhus", - "latitude": 59.948457, - "longitude": 11.01185 - }, - { - "lokalId": "839713ba-c119-42c7-9785-2b0d94001329", - "romnr": 20665, - "plasser": 500, - "adresse": "Sveavegen 1-25 - Jessheimtunet - Offentlig", - "latitude": 60.140963, - "longitude": 11.178132 - }, - { - "lokalId": "57b4df40-a6c3-4950-aaa7-60a4deda5833", - "romnr": 20777, - "plasser": 444, - "adresse": "Bøstad skole, Vikingveien 459. Vestvågøy", - "latitude": 68.239238, - "longitude": 13.751838 - }, - { - "lokalId": "ac3f2f62-e9f5-4561-8056-1b51fd2cf344", - "romnr": 20798, - "plasser": 650, - "adresse": "Kjøpmannsgata 34", - "latitude": 63.432078, - "longitude": 10.402294 - }, - { - "lokalId": "6bff1538-2303-4604-9df7-3ac0a4d39dfb", - "romnr": 20806, - "plasser": 357, - "adresse": "Hyttegata 2 \"Bjørneparken\"", - "latitude": 59.666213, - "longitude": 9.648765 - }, - { - "lokalId": "b56e7cfa-eccc-46ba-91e2-dfeed5a41d6f", - "romnr": 20837, - "plasser": 95, - "adresse": "Eidesbråtet 1", - "latitude": 60.056192, - "longitude": 6.546907 - }, - { - "lokalId": "c0cbc75d-7dd9-40bf-9b6c-fa81393e2711", - "romnr": 20853, - "plasser": 2400, - "adresse": "Flåtestadveien 5a Fjellhallen", - "latitude": 59.773247, - "longitude": 10.803393 - }, - { - "lokalId": "066845c7-c663-449e-860c-119ec8acc03b", - "romnr": 20860, - "plasser": 2000, - "adresse": "Komsa Fjellanlegg Alta Kommune", - "latitude": 69.975548, - "longitude": 23.272672 - }, - { - "lokalId": "c55e0f8e-ba19-44e5-91fd-b3ed168e3322", - "romnr": 20901, - "plasser": 300, - "adresse": "Statlandvegen 13, Nord Statland", - "latitude": 64.4965, - "longitude": 11.142948 - }, - { - "lokalId": "b2b727e1-6292-4240-991c-717457213149", - "romnr": 21023, - "plasser": 35, - "adresse": "Jon Sunds veg 18", - "latitude": 60.888038, - "longitude": 11.521303 - }, - { - "lokalId": "928ce163-777e-4c45-be14-aea4d911c83d", - "romnr": 21024, - "plasser": 73, - "adresse": "Munkedamsvegen 5", - "latitude": 60.878592, - "longitude": 11.576904 - }, - { - "lokalId": "0fb2120a-ec91-4b12-8b8e-4e48d9e33026", - "romnr": 21025, - "plasser": 1540, - "adresse": "Torggata 1", - "latitude": 60.886425, - "longitude": 11.560943 - }, - { - "lokalId": "1d834e1b-8197-473f-8386-b059649bb76d", - "romnr": 21097, - "plasser": 100, - "adresse": "Industrivegen 17", - "latitude": 63.110504, - "longitude": 7.779923 - }, - { - "lokalId": "f6df8442-b1a3-47fc-b599-c644b0696e88", - "romnr": 21148, - "plasser": 66, - "adresse": "Håkon den godes gate 30", - "latitude": 63.745956, - "longitude": 11.299777 - }, - { - "lokalId": "af7faecc-9f35-4dc1-b01a-c850b2646071", - "romnr": 21163, - "plasser": 80, - "adresse": "Trekanten 2, Levanger", - "latitude": 63.749125, - "longitude": 11.309466 - }, - { - "lokalId": "dc369401-4996-43dc-b343-4dfeb8ebe2f3", - "romnr": 21224, - "plasser": 388, - "adresse": "Romsdalsvegen 2", - "latitude": 62.674615, - "longitude": 8.561964 - }, - { - "lokalId": "a8fe6d3f-6a6a-467f-a0e3-9df58b5e29f7", - "romnr": 21225, - "plasser": 91, - "adresse": "Ringvegen 13", - "latitude": 62.672764, - "longitude": 8.57242 - }, - { - "lokalId": "9e3c45f0-e2a6-4a7b-90bb-8a0cb568c269", - "romnr": 21257, - "plasser": 400, - "adresse": "Strandveien 6 Lysaker", - "latitude": 59.912408, - "longitude": 10.639089 - }, - { - "lokalId": "e74d4611-0fef-420f-9b70-232be3414f03", - "romnr": 21271, - "plasser": 700, - "adresse": "Tangen. Havnegata", - "latitude": 59.729705, - "longitude": 10.231377 - }, - { - "lokalId": "d2ab12bc-c3f9-4e64-b234-645d0bdba829", - "romnr": 21280, - "plasser": 450, - "adresse": "Strøket 15A (Trekanten)", - "latitude": 59.835985, - "longitude": 10.432986 - }, - { - "lokalId": "cad89e8b-bb4e-4f03-814b-883f8f52a919", - "romnr": 25512, - "plasser": 300, - "adresse": "Tangen verft, Gamle Kragerøvei 12", - "latitude": 58.875152, - "longitude": 9.416357 - }, - { - "lokalId": "5f92e392-0bc3-4b8c-99d9-ab5d03a550da", - "romnr": 30651, - "plasser": 55, - "adresse": "Ulvahaugen 2", - "latitude": 61.23349, - "longitude": 7.093615 - }, - { - "lokalId": "041fdfa4-11f8-425b-b5a9-1c1c823dba1a", - "romnr": 30653, - "plasser": 80, - "adresse": "industrivegen 24", - "latitude": 61.590674, - "longitude": 5.001506 - }, - { - "lokalId": "dd81a619-3c2b-44ff-803b-59287511ac41", - "romnr": 30654, - "plasser": 120, - "adresse": "Gate 1 110", - "latitude": 61.93475, - "longitude": 5.113378 - }, - { - "lokalId": "cb93f4f9-4fed-48ac-8263-db2a23f2038c", - "romnr": 30655, - "plasser": 197, - "adresse": "Gate 1 129", - "latitude": 61.936271, - "longitude": 5.114131 - }, - { - "lokalId": "42c2201f-93d0-4216-98e6-8129f8431a60", - "romnr": 30656, - "plasser": 155, - "adresse": "Slettevollsholten 11", - "latitude": 61.601988, - "longitude": 5.132493 - }, - { - "lokalId": "cfd9ed14-261c-4ecd-87c4-b79bb3ed4329", - "romnr": 30657, - "plasser": 111, - "adresse": "Strangata 52", - "latitude": 61.600052, - "longitude": 5.035 - }, - { - "lokalId": "f6a03a38-7b9b-4f60-8ab4-59d416fedcc4", - "romnr": 30658, - "plasser": 160, - "adresse": "Rennekleiva 2", - "latitude": 61.455152, - "longitude": 5.902546 - }, - { - "lokalId": "49987aa8-66f1-4a8a-bfe2-1512ace0a6fe", - "romnr": 30659, - "plasser": 795, - "adresse": "Liavegen 35", - "latitude": 61.449697, - "longitude": 5.836535 - }, - { - "lokalId": "32932953-f5b0-48f4-9967-946dc3ce0931", - "romnr": 30660, - "plasser": 40, - "adresse": "Flåmsdalsvegen16", - "latitude": 60.85617, - "longitude": 7.110099 - }, - { - "lokalId": "bed27b4e-9eee-44d5-8097-934670720009", - "romnr": 30667, - "plasser": 220, - "adresse": "Olav Tryggvasons gate 28", - "latitude": 63.433433, - "longitude": 10.396615 - }, - { - "lokalId": "87cf8d80-3d1a-444b-b108-e5c9f1f44015", - "romnr": 30668, - "plasser": 700, - "adresse": "Otto Svedrups plass 4 - tidl. Øvre Torv 1", - "latitude": 59.892038, - "longitude": 10.526027 - }, - { - "lokalId": "a79ee693-981f-426a-a914-76ed9e592457", - "romnr": 30671, - "plasser": 800, - "adresse": "Nedre Bakklandet 11 - 41", - "latitude": 63.428649, - "longitude": 10.403588 - }, - { - "lokalId": "33c0c24d-de5f-4706-9118-afb1b5292674", - "romnr": 30672, - "plasser": 1740, - "adresse": "Strømsveien 9 Vassøyholtet", - "latitude": 59.941052, - "longitude": 11.002169 - }, - { - "lokalId": "5025d167-cb9f-4126-8ae5-5ba10cee25f4", - "romnr": 30673, - "plasser": 500, - "adresse": "Olav Kyrres gate 6 -Revmatismebygget - St. Olavs H", - "latitude": 63.421146, - "longitude": 10.392047 - }, - { - "lokalId": "61589d1b-11c6-44a1-9eaf-ff392d6779d0", - "romnr": 30677, - "plasser": 780, - "adresse": "Østre Rosten 39 - Rostenhallen", - "latitude": 63.359645, - "longitude": 10.380829 - }, - { - "lokalId": "259b29bb-77ba-42ea-9df6-5405f232b941", - "romnr": 30678, - "plasser": 513, - "adresse": "Hasselbakken 5A og 5 C", - "latitude": 63.436822, - "longitude": 10.495529 - }, - { - "lokalId": "dc2ed73e-4802-43e9-819d-250c420845ae", - "romnr": 30679, - "plasser": 330, - "adresse": "Oppdal Helsesenter", - "latitude": 62.598982, - "longitude": 9.692609 - }, - { - "lokalId": "adbad10f-2a59-4e2d-a5bd-eeb886f6cdf5", - "romnr": 31679, - "plasser": 200, - "adresse": "T - Senteret, Offentlig T-rom", - "latitude": 63.687737, - "longitude": 9.665849 - }, - { - "lokalId": "21d80bec-acc5-48c9-bbf8-5bf913d19502", - "romnr": 31749, - "plasser": 820, - "adresse": "Paradisveien 22", - "latitude": 58.962346, - "longitude": 5.74174 - }, - { - "lokalId": "42c44dfc-20bd-4432-a134-4f9d15272a56", - "romnr": 32760, - "plasser": 1210, - "adresse": "Olav Schousvei 2-8 plan B", - "latitude": 59.930605, - "longitude": 10.781977 - }, - { - "lokalId": "5203bf2a-ff96-4ea6-842d-0f6770521dd5", - "romnr": 36834, - "plasser": 1000, - "adresse": "Skippergata/ Johan Stangsplass 1", - "latitude": 59.118183, - "longitude": 11.390087 - }, - { - "lokalId": "32c9e3e8-b9c6-466a-9eb4-b0c3bc0b51a1", - "romnr": 36835, - "plasser": 760, - "adresse": "Rødsfjellet/ Peder Ankersgt 7B", - "latitude": 59.122614, - "longitude": 11.378465 - }, - { - "lokalId": "93a0a02b-1971-4f15-988a-0b9a51e8f570", - "romnr": 36836, - "plasser": 1000, - "adresse": "Oskleiva 18", - "latitude": 59.127712, - "longitude": 11.394312 - }, - { - "lokalId": "d05a7428-3170-4da2-b2c8-e7f5893e9896", - "romnr": 36837, - "plasser": 75, - "adresse": "Marker U. skole/ Skolegata 21,Ørje", - "latitude": 59.478394, - "longitude": 11.657639 - }, - { - "lokalId": "5748270c-6c2e-478d-86ef-6fdd7cbce281", - "romnr": 36838, - "plasser": 114, - "adresse": "Nordmyrveien 4/ Spydeberg", - "latitude": 59.615456, - "longitude": 11.077031 - }, - { - "lokalId": "06499b33-6731-4e7e-8b8c-21cafbd84810", - "romnr": 36839, - "plasser": 200, - "adresse": "Allaktivitetshuset Spydeberg/ Stasjonsgata 33", - "latitude": 59.619931, - "longitude": 11.081442 - }, - { - "lokalId": "7e59664b-b94d-4a10-9d8f-f57cc3de2f96", - "romnr": 36840, - "plasser": 118, - "adresse": "Grendehusveien 2J/ Saltnes", - "latitude": 59.295256, - "longitude": 10.762224 - }, - { - "lokalId": "16985b7e-4a7c-4ba3-bdac-e7f95d43c4e9", - "romnr": 36841, - "plasser": 32, - "adresse": "Råde Herredshus/ Skråtorpveien 2A", - "latitude": 59.351645, - "longitude": 10.871347 - }, - { - "lokalId": "489dd901-54f9-45f5-b950-090519c2bd78", - "romnr": 36842, - "plasser": 2000, - "adresse": "Øreåsen/Årvollskogen 97", - "latitude": 59.419264, - "longitude": 10.696867 - }, - { - "lokalId": "13527cb7-868c-4360-8169-08f3d9472051", - "romnr": 36843, - "plasser": 50, - "adresse": "Helse og sosialsenter", - "latitude": 59.488821, - "longitude": 10.871204 - }, - { - "lokalId": "9adcfe8d-9eef-42a6-a49c-56eb647dc24a", - "romnr": 36844, - "plasser": 90, - "adresse": "Citadel/ Jernbanegata 4, Mysen", - "latitude": 59.553859, - "longitude": 11.324296 - }, - { - "lokalId": "986d43df-ad16-4236-97c2-74788aa01225", - "romnr": 36845, - "plasser": 114, - "adresse": "Opsahlveien 1, Mysen", - "latitude": 59.553145, - "longitude": 11.338877 - }, - { - "lokalId": "0df92ef5-2c1b-4aab-ac0e-272292721cee", - "romnr": 36846, - "plasser": 124, - "adresse": "Rakkestad og Degernes brannkas/ Storgt 13", - "latitude": 59.426576, - "longitude": 11.342833 - }, - { - "lokalId": "da71bbf6-ffda-4122-ae4a-6bfd29fdfa10", - "romnr": 37868, - "plasser": 100, - "adresse": "Hunstadsenteret Hunstad Øst, offentlig", - "latitude": 67.282152, - "longitude": 14.541747 - }, - { - "lokalId": "f06e4620-fe8e-4b55-bc41-a5d0b218491d", - "romnr": 37869, - "plasser": 100, - "adresse": "Jernbanevegen 7", - "latitude": 60.986082, - "longitude": 9.237485 - }, - { - "lokalId": "9177fe37-d3fd-43b6-8335-a343357c6a52", - "romnr": 37870, - "plasser": 252, - "adresse": "Hammersengvegen 62", - "latitude": 61.132025, - "longitude": 10.462942 - }, - { - "lokalId": "e077a983-2a58-4f13-ac97-17f7d8c34ec6", - "romnr": 37879, - "plasser": 120, - "adresse": "Gullfakse Barnehage - Nordbødalen 12", - "latitude": 58.473322, - "longitude": 8.78905 - }, - { - "lokalId": "82fc7ba2-b7dc-4acd-8387-776610241c24", - "romnr": 37891, - "plasser": 40, - "adresse": "Rådhuset, Leknes", - "latitude": 68.148173, - "longitude": 13.611536 - }, - { - "lokalId": "04b738d5-d442-4f93-ba21-baf6d3d92519", - "romnr": 37914, - "plasser": 288, - "adresse": "Skogbrukets hus, fagerlidal 18", - "latitude": 69.068362, - "longitude": 18.524782 - }, - { - "lokalId": "687c93b6-7df5-47cb-a046-5db4b0e4aaeb", - "romnr": 37918, - "plasser": 185, - "adresse": "Hestmyrvegen 10", - "latitude": 59.381326, - "longitude": 5.318194 - }, - { - "lokalId": "a07d59c9-b800-4213-b798-e03aedf50dd9", - "romnr": 38930, - "plasser": 856, - "adresse": "Fannestrandvegen 49 b", - "latitude": 62.739478, - "longitude": 7.182817 - }, - { - "lokalId": "4b9804e7-bd95-4334-b006-9757446c3405", - "romnr": 38931, - "plasser": 2000, - "adresse": "Kirkebakken 4A", - "latitude": 62.739064, - "longitude": 7.160301 - }, - { - "lokalId": "9950b52e-0a32-4494-a65e-88fadbeb5f67", - "romnr": 38932, - "plasser": 1000, - "adresse": "Keiser Wilhelms gate 25", - "latitude": 62.471598, - "longitude": 6.157965 - }, - { - "lokalId": "3206d3f9-9aae-42df-9126-5c1a5fe13dd6", - "romnr": 38933, - "plasser": 70, - "adresse": "Kometvegen 5", - "latitude": 62.742701, - "longitude": 7.229242 - }, - { - "lokalId": "edd5b3fd-2a57-48be-96c6-6e1ceed48ff4", - "romnr": 38934, - "plasser": 100, - "adresse": "Årøsetervegen 17", - "latitude": 62.77184, - "longitude": 7.287248 - }, - { - "lokalId": "54ffc195-6f01-4cf0-b844-59d5aa1d3b41", - "romnr": 38937, - "plasser": 150, - "adresse": "Høglivegen 8", - "latitude": 62.786868, - "longitude": 7.530679 - }, - { - "lokalId": "a93df078-e2c5-4d2e-8db6-27d39d3f8e99", - "romnr": 38938, - "plasser": 80, - "adresse": "Baklivegen 4", - "latitude": 62.787671, - "longitude": 7.537625 - }, - { - "lokalId": "7af88e63-9a81-4cd8-bbcd-5a3dd360b567", - "romnr": 38939, - "plasser": 95, - "adresse": "Hospitalgata 6 \"gamle sykehus\"", - "latitude": 70.37379, - "longitude": 31.096688 - }, - { - "lokalId": "60afe513-12f6-4538-8289-6982d3fe75cb", - "romnr": 38945, - "plasser": 70, - "adresse": "Skorgeneset 31 / Møre og Romsdal Kornsilo", - "latitude": 62.576562, - "longitude": 7.120192 - }, - { - "lokalId": "b6cf560d-7e89-4a6e-a075-da5d88f1f4c6", - "romnr": 38947, - "plasser": 48, - "adresse": "Tresfjordvegen 215", - "latitude": 62.558244, - "longitude": 7.131404 - }, - { - "lokalId": "568b397e-5d67-4a80-bbb1-cb3bc1c3b6fa", - "romnr": 38950, - "plasser": 40, - "adresse": "Skulevegen 4", - "latitude": 62.616826, - "longitude": 7.089993 - }, - { - "lokalId": "f43fd6f5-6655-45e0-9b71-5bf821b931aa", - "romnr": 38952, - "plasser": 100, - "adresse": "Brugata 10", - "latitude": 62.621344, - "longitude": 7.089782 - }, - { - "lokalId": "55f831c9-5dec-4bcc-9446-9f6613ef8bf1", - "romnr": 38954, - "plasser": 65, - "adresse": "Nybøvegen 2", - "latitude": 62.601077, - "longitude": 6.931241 - }, - { - "lokalId": "09ba909c-c20a-4ef1-8a65-6a0c77111dd0", - "romnr": 38956, - "plasser": 60, - "adresse": "Skulebakken 1", - "latitude": 62.521179, - "longitude": 7.126651 - }, - { - "lokalId": "ac5149a3-d229-4ba8-b920-c68d2bdf7132", - "romnr": 38958, - "plasser": 75, - "adresse": "Neremsvegen 4", - "latitude": 62.522356, - "longitude": 7.126866 - }, - { - "lokalId": "cf2a7b37-0768-42be-a0e2-f90790be41fc", - "romnr": 38960, - "plasser": 35, - "adresse": "Remmemsvegen 85", - "latitude": 62.610433, - "longitude": 7.098366 - }, - { - "lokalId": "5093f892-126e-4f30-ba59-7dcc6ca113b4", - "romnr": 38963, - "plasser": 50, - "adresse": "Vollan 1", - "latitude": 62.568252, - "longitude": 7.688251 - }, - { - "lokalId": "2e3d29a8-eb7e-463b-8078-b01389700251", - "romnr": 38964, - "plasser": 40, - "adresse": "Sørsidevegen 747", - "latitude": 62.501345, - "longitude": 7.565888 - }, - { - "lokalId": "61328730-f5e9-4b31-826e-216a7812df57", - "romnr": 38966, - "plasser": 481, - "adresse": "Vollan 8A", - "latitude": 62.568237, - "longitude": 7.686241 - }, - { - "lokalId": "31a3030e-6d3d-4c76-906e-392e6609c8f5", - "romnr": 38967, - "plasser": 20, - "adresse": "Prestgardsvegen 140", - "latitude": 62.906298, - "longitude": 6.920707 - }, - { - "lokalId": "6fb90bc2-0cf0-47ec-a198-b0430c91f8a4", - "romnr": 38969, - "plasser": 90, - "adresse": "Lundhaugvegen 34", - "latitude": 62.905197, - "longitude": 6.915688 - }, - { - "lokalId": "04777990-c63b-41cd-a636-e026e9f5041e", - "romnr": 38971, - "plasser": 90, - "adresse": "Torget 13A", - "latitude": 62.854445, - "longitude": 7.163943 - }, - { - "lokalId": "b087468f-1504-4b1b-a179-2bc73f672064", - "romnr": 38973, - "plasser": 55, - "adresse": "Torget 14", - "latitude": 62.854089, - "longitude": 7.164355 - }, - { - "lokalId": "478edb97-bbc5-466e-b2c2-19bda7788398", - "romnr": 38975, - "plasser": 20, - "adresse": "Malmefjordvegen 18", - "latitude": 62.83544, - "longitude": 7.235397 - }, - { - "lokalId": "b30254aa-b072-4875-b304-4f1ef6c1390c", - "romnr": 38976, - "plasser": 22, - "adresse": "Myrbostadvegen 72", - "latitude": 62.855366, - "longitude": 7.188842 - }, - { - "lokalId": "fb7be88f-773e-4fc7-b8aa-da4c9c7c7fc7", - "romnr": 38977, - "plasser": 578, - "adresse": "Brendhaugen 7", - "latitude": 62.336748, - "longitude": 5.876821 - }, - { - "lokalId": "466d2898-ec2f-426d-b97f-df3503096690", - "romnr": 38981, - "plasser": 60, - "adresse": "Stemsvegen 13", - "latitude": 62.97589, - "longitude": 7.163689 - }, - { - "lokalId": "39977567-ee17-45a5-895f-72902d0d2fb9", - "romnr": 39987, - "plasser": 210, - "adresse": "Engasveien 27 (Rørvik samfunnshus )", - "latitude": 64.863633, - "longitude": 11.242084 - }, - { - "lokalId": "d7a61629-990e-4ec4-b2c9-e228828b1ef2", - "romnr": 39990, - "plasser": 75, - "adresse": "Valderøyvegen 1129", - "latitude": 62.526601, - "longitude": 6.12256 - }, - { - "lokalId": "340fbd10-b35f-4e25-b087-d6cdd7f2db8e", - "romnr": 39993, - "plasser": 143, - "adresse": "Sloghaugvegen 3", - "latitude": 62.440436, - "longitude": 6.190999 - }, - { - "lokalId": "b9bd9144-abe9-45ea-b590-b39643c3df13", - "romnr": 39995, - "plasser": 167, - "adresse": "Molværsvegen 74", - "latitude": 62.437853, - "longitude": 6.183652 - }, - { - "lokalId": "cde9c3b8-6c04-4173-8d7a-3807e5d1645b", - "romnr": 39997, - "plasser": 83, - "adresse": "Solavågseidet 76", - "latitude": 62.427553, - "longitude": 6.315725 - }, - { - "lokalId": "21d54e53-a487-4484-88a7-79f18bae9f1b", - "romnr": 40000, - "plasser": 181, - "adresse": "Langmyra 2", - "latitude": 62.180762, - "longitude": 6.083092 - }, - { - "lokalId": "2cdb86e3-2f27-47e5-bb6e-6b2bd6dd35a9", - "romnr": 40001, - "plasser": 100, - "adresse": "Torvmyrane 5", - "latitude": 62.182863, - "longitude": 6.084963 - }, - { - "lokalId": "6c0d6313-1b3c-42b0-9f4a-175589f71ec2", - "romnr": 40002, - "plasser": 257, - "adresse": "Vikegata 17", - "latitude": 62.200506, - "longitude": 6.124657 - }, - { - "lokalId": "7233c2f2-d3ef-47ec-94b7-cdaa5ed3567b", - "romnr": 41007, - "plasser": 333, - "adresse": "Aurdalslia 30, Aurdalslia skole", - "latitude": 60.30723, - "longitude": 5.2816 - }, - { - "lokalId": "2b46db25-af44-4d29-a315-c086259018d7", - "romnr": 44298, - "plasser": 300, - "adresse": "Enggata 37", - "latitude": 60.730839, - "longitude": 10.60403 - }, - { - "lokalId": "beeee155-6084-4ccc-9c1a-3bcf0c60b352", - "romnr": 46455, - "plasser": 200, - "adresse": "Peder Hiorts gate 18 B, RØROS SKOLE", - "latitude": 62.57574, - "longitude": 11.375244 - }, - { - "lokalId": "e8c9c459-861e-4ac3-a1d7-8450384627a0", - "romnr": 46465, - "plasser": 222, - "adresse": "Jærveien 107", - "latitude": 58.840201, - "longitude": 5.723395 - }, - { - "lokalId": "d2e62169-a1e2-4c8c-8720-bd44a199b9fd", - "romnr": 48494, - "plasser": 450, - "adresse": "Mellomveien 5", - "latitude": 63.437722, - "longitude": 10.430205 - }, - { - "lokalId": "2337e2f4-2589-4901-8b0f-797519393f97", - "romnr": 48512, - "plasser": 9, - "adresse": "Melkeveien 1", - "latitude": 63.783681, - "longitude": 11.455099 - }, - { - "lokalId": "f9d58eda-ccfe-4c29-a67f-46314ad6bead", - "romnr": 48513, - "plasser": 42, - "adresse": "Magnus den godes vei 9", - "latitude": 63.78636, - "longitude": 11.469815 - }, - { - "lokalId": "4d160e7a-ae2f-42fc-af31-00e9d109bb6b", - "romnr": 48514, - "plasser": 49, - "adresse": "Hellbakkvegen 6", - "latitude": 63.774763, - "longitude": 11.746377 - }, - { - "lokalId": "da4f909e-5dd0-4225-a406-781150e8fa52", - "romnr": 48515, - "plasser": 109, - "adresse": "Gamle fergeveg 2", - "latitude": 63.790091, - "longitude": 11.469551 - }, - { - "lokalId": "44f4226d-b0a2-46b1-870b-129c8d015b41", - "romnr": 48516, - "plasser": 42, - "adresse": "Kirkegata 29", - "latitude": 63.745747, - "longitude": 11.296883 - }, - { - "lokalId": "88a06fe3-9478-469d-bb56-64b8e72622ef", - "romnr": 48518, - "plasser": 75, - "adresse": "Håkon den godes gate 17/19", - "latitude": 63.745562, - "longitude": 11.298084 - }, - { - "lokalId": "480d14e6-4166-4aa6-b055-16a283d4499a", - "romnr": 48527, - "plasser": 120, - "adresse": "Nedregårdsvegen 1", - "latitude": 62.464238, - "longitude": 6.363682 - }, - { - "lokalId": "706720c6-71c5-4567-b20a-fc265ba614c2", - "romnr": 48535, - "plasser": 30, - "adresse": "Tingvold Park hotell, Gamle Kongeveg 47", - "latitude": 64.023746, - "longitude": 11.491062 - }, - { - "lokalId": "0f331b8a-44c6-4898-9f9f-a21296b15d8e", - "romnr": 48536, - "plasser": 205, - "adresse": "Guldbergaunet, Svedjanvegen", - "latitude": 64.017505, - "longitude": 11.514335 - }, - { - "lokalId": "00de4af4-5f78-495a-b013-9fce3b9ff296", - "romnr": 48537, - "plasser": 150, - "adresse": "Nedre Sannan", - "latitude": 64.010981, - "longitude": 11.499408 - }, - { - "lokalId": "e9d71ef8-2f81-4d29-aaf2-5e6a6607309e", - "romnr": 48538, - "plasser": 70, - "adresse": "Skolegata 22", - "latitude": 64.013296, - "longitude": 11.499952 - }, - { - "lokalId": "d70a487e-b787-49ad-a996-2926394a1e99", - "romnr": 48561, - "plasser": 274, - "adresse": "Åkersgata 4/Ticogården", - "latitude": 62.67298, - "longitude": 8.565769 - }, - { - "lokalId": "cbf7edbc-f63f-4062-8c06-134b516be1f7", - "romnr": 48565, - "plasser": 108, - "adresse": "Kjøpmannsgata 15", - "latitude": 62.371386, - "longitude": 6.027618 - }, - { - "lokalId": "2cbd75a9-a131-4060-8b6c-2a2348ccb158", - "romnr": 48566, - "plasser": 58, - "adresse": "Strandgata 72-74", - "latitude": 62.370041, - "longitude": 6.028899 - }, - { - "lokalId": "4a167787-177e-4078-a27f-6dc8e341c5fe", - "romnr": 48570, - "plasser": 20, - "adresse": "Strandgata 106-114", - "latitude": 62.37351, - "longitude": 6.02943 - }, - { - "lokalId": "30dfd473-5d8e-45f2-961b-767586ee7226", - "romnr": 48571, - "plasser": 270, - "adresse": "Gymnasvegen 2", - "latitude": 62.146149, - "longitude": 6.068552 - }, - { - "lokalId": "b0bc19f5-625f-4878-936f-f6b6ace09ab5", - "romnr": 48572, - "plasser": 62, - "adresse": "Dalevegen 24", - "latitude": 62.199002, - "longitude": 6.134409 - }, - { - "lokalId": "b506c2d6-a2da-4298-b6cd-cfff216a9066", - "romnr": 48573, - "plasser": 448, - "adresse": "Sjøgata 3", - "latitude": 62.340599, - "longitude": 5.852225 - }, - { - "lokalId": "3b52a0e0-37b5-42cb-94e8-02829ead1d03", - "romnr": 48576, - "plasser": 22, - "adresse": "Spjelkavikvegen 130", - "latitude": 62.454662, - "longitude": 6.358058 - }, - { - "lokalId": "f80e14e3-5fe5-41a0-a94e-77670f8c61df", - "romnr": 48577, - "plasser": 40, - "adresse": "Skulevegen 16", - "latitude": 62.440022, - "longitude": 6.211076 - }, - { - "lokalId": "6964ab63-02db-48c8-8a21-528d707535a8", - "romnr": 48578, - "plasser": 81, - "adresse": "Valderhaug 4", - "latitude": 62.500695, - "longitude": 6.134682 - }, - { - "lokalId": "1f7ec0bc-1ef4-4e37-926b-bf2414dbaa1c", - "romnr": 48580, - "plasser": 50, - "adresse": "Morkafura 8", - "latitude": 62.171096, - "longitude": 6.038961 - }, - { - "lokalId": "51f05b0f-7065-4298-8fdb-b00543fdf871", - "romnr": 48604, - "plasser": 7000, - "adresse": "Fjellanlegg - Tromsø parkering", - "latitude": 69.650827, - "longitude": 18.954024 - }, - { - "lokalId": "f1bc391f-3be9-4323-bade-930cdaaefb65", - "romnr": 48632, - "plasser": 375, - "adresse": "Tømmeråsv. 3 - Svelvik Samfunnshus (off)", - "latitude": 59.606648, - "longitude": 10.405089 - }, - { - "lokalId": "f2ca9fd6-7c7e-483a-95ce-2e5ca480e41f", - "romnr": 48661, - "plasser": 0, - "adresse": "Mikkelsmyrveien 3B", - "latitude": 58.028221, - "longitude": 7.476917 - }, - { - "lokalId": "c3572f1d-8cd6-468c-afd7-a3bcb9a8d05f", - "romnr": 5826, - "plasser": 150, - "adresse": "Dr. Wessels gate 7", - "latitude": 69.727773, - "longitude": 30.041818 - } -] \ No newline at end of file diff --git a/pwa/public/manifest.webmanifest b/pwa/public/manifest.webmanifest index eff6a67..37b1419 100644 --- a/pwa/public/manifest.webmanifest +++ b/pwa/public/manifest.webmanifest @@ -2,20 +2,21 @@ "name": "Tilfluktsrom", "short_name": "Tilfluktsrom", "description": "Find the nearest public shelter in Norway", - "start_url": "/", + "start_url": ".", + "scope": ".", "display": "standalone", "orientation": "portrait", "theme_color": "#1A1A2E", "background_color": "#1A1A2E", "icons": [ { - "src": "/icons/icon-192.png", + "src": "icons/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any maskable" }, { - "src": "/icons/icon-512.png", + "src": "icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" diff --git a/pwa/src/app.ts b/pwa/src/app.ts index 6a2113e..ceceb58 100644 --- a/pwa/src/app.ts +++ b/pwa/src/app.ts @@ -9,7 +9,7 @@ import type { Shelter, ShelterWithDistance, LatLon } from './types'; import { t } from './i18n/i18n'; -import { formatDistance } from './util/distance-utils'; +import { formatDistance, distanceMeters, bearingDegrees } from './util/distance-utils'; import { findNearest } from './location/shelter-finder'; import * as repo from './data/shelter-repository'; import * as locationProvider from './location/location-provider'; @@ -20,7 +20,7 @@ import * as shelterList from './ui/shelter-list'; import * as statusBar from './ui/status-bar'; import * as loading from './ui/loading-overlay'; import * as mapCache from './cache/map-cache-manager'; -import * as aboutDialog from './ui/about-dialog'; +import * as civilDefenseDialog from './ui/civil-defense-dialog'; const NEAREST_COUNT = 3; @@ -43,14 +43,15 @@ export async function init(): Promise { setupShelterList(); setupButtons(); await loadData(); + handleDeepLink(); } /** Set localized aria-labels and wire the about button. */ function applyA11yLabels(): void { - document.getElementById('about-btn')?.setAttribute('aria-label', t('action_about')); + document.getElementById('about-btn')?.setAttribute('aria-label', t('action_civil_defense_info')); document.getElementById('about-btn')?.addEventListener('click', () => { navigator.vibrate?.(10); - aboutDialog.showAbout(); + civilDefenseDialog.showCivilDefenseInfo(); }); document.getElementById('map-container')?.setAttribute('aria-label', t('a11y_map')); document.getElementById('compass-container')?.setAttribute('aria-label', t('a11y_compass')); @@ -108,6 +109,7 @@ function setupButtons(): void { } mapContainer.style.display = 'none'; compassContainer.classList.add('active'); + compassView.resize(); toggleFab.textContent = '\uD83D\uDDFA\uFE0F'; // map emoji compassProvider.startCompass(onHeadingUpdate); } else { @@ -397,3 +399,67 @@ async function forceRefresh(): Promise { statusBar.setStatus(t('update_failed')); } } + +/** + * Handle /shelter/{lokalId} deep links. + * Called after loadData() so allShelters is populated. + */ +function handleDeepLink(): void { + const match = window.location.pathname.match(/^\/shelter\/(.+)$/); + if (!match) return; + + const lokalId = decodeURIComponent(match[1]); + + // Clean the URL so refresh doesn't re-trigger + window.history.replaceState({}, '', '/'); + + const shelter = allShelters.find((s) => s.lokalId === lokalId); + if (!shelter) { + statusBar.setStatus(t('error_shelter_not_found')); + return; + } + + selectShelterByData(shelter); +} + +/** + * Select a specific shelter, even if it's not in the current nearest-3 list. + * Used for deep link targets. + */ +function selectShelterByData(shelter: Shelter): void { + // Check if it's already in nearestShelters + const existingIdx = nearestShelters.findIndex( + (s) => s.shelter.lokalId === shelter.lokalId, + ); + + if (existingIdx >= 0) { + userSelectedShelter = true; + selectedShelterIndex = existingIdx; + } else { + // Compute distance/bearing if we have a location, otherwise use placeholder + let dist = NaN; + let bearing = 0; + if (currentLocation) { + dist = distanceMeters( + currentLocation.latitude, currentLocation.longitude, + shelter.latitude, shelter.longitude, + ); + bearing = bearingDegrees( + currentLocation.latitude, currentLocation.longitude, + shelter.latitude, shelter.longitude, + ); + } + + // Prepend to the list so it becomes the selected shelter + nearestShelters.unshift({ + shelter, + distanceMeters: dist, + bearingDegrees: bearing, + }); + userSelectedShelter = true; + selectedShelterIndex = 0; + shelterList.updateList(nearestShelters, selectedShelterIndex); + } + + updateSelectedShelter(true); +} diff --git a/pwa/src/config.ts b/pwa/src/config.ts new file mode 100644 index 0000000..a0ccb93 --- /dev/null +++ b/pwa/src/config.ts @@ -0,0 +1,2 @@ +/** Deep link domain — single source of truth for the PWA. */ +export const DEEP_LINK_DOMAIN = 'tilfluktsrom.naiv.no'; diff --git a/pwa/src/i18n/en.ts b/pwa/src/i18n/en.ts index 8120a8f..6a77154 100644 --- a/pwa/src/i18n/en.ts +++ b/pwa/src/i18n/en.ts @@ -46,6 +46,7 @@ export const en: Record = { 'No cached data available. Connect to the internet to download shelter data.', update_success: 'Shelter data updated', update_failed: 'Update failed \u2014 using cached data', + error_shelter_not_found: 'Shelter not found', // Accessibility direction_arrow_description: 'Direction to shelter, %s away', @@ -54,6 +55,21 @@ export const en: Record = { a11y_shelter_info: 'Shelter info', a11y_nearest_shelters: 'Nearest shelters', + // Civil defense + action_civil_defense_info: 'Civil defense information', + civil_defense_title: 'What to do if the alarm sounds', + civil_defense_step1_title: '1. Important message signal', + civil_defense_step1_body: 'Three series of short blasts with one minute of silence between each series. This means: seek information immediately. Turn on DAB radio, TV, or check official sources online.', + civil_defense_step2_title: '2. Air raid alarm', + civil_defense_step2_body: 'Short blasts lasting approximately one minute. This means immediate danger of attack — seek shelter now. Go to the nearest shelter, basement, or inner room immediately.', + civil_defense_step3_title: '3. Go indoors and find shelter', + civil_defense_step3_body: 'Get indoors. Close all windows, doors, and ventilation openings. Use this app to find the nearest public shelter. The compass and map work offline. If no shelter is nearby, go to a basement or an inner room away from windows.', + civil_defense_step4_title: '4. Listen to NRK on DAB radio', + civil_defense_step4_body: 'Tune in to NRK P1 on DAB radio for official updates and instructions from authorities. DAB radio works even when mobile networks and the internet are down.', + civil_defense_step5_title: '5. All clear', + civil_defense_step5_body: 'One continuous tone lasting approximately 30 seconds. The danger or attack is over. Continue to follow instructions from authorities.', + civil_defense_source: 'Source: DSB (Norwegian Directorate for Civil Protection)', + // About about_title: 'About Tilfluktsrom', about_description: @@ -71,4 +87,6 @@ export const en: Record = { about_open_source: 'Open source — kode.naiv.no/olemd/tilfluktsrom', action_about: 'About', action_close: 'Close', + action_clear_cache: 'Clear cached data', + cache_cleared: 'All cached data cleared', }; diff --git a/pwa/src/i18n/nb.ts b/pwa/src/i18n/nb.ts index 2cb9b40..8c285d8 100644 --- a/pwa/src/i18n/nb.ts +++ b/pwa/src/i18n/nb.ts @@ -41,6 +41,7 @@ export const nb: Record = { 'Ingen lagrede data tilgjengelig. Koble til internett for å laste ned tilfluktsromdata.', update_success: 'Tilfluktsromdata oppdatert', update_failed: 'Oppdatering mislyktes — bruker lagrede data', + error_shelter_not_found: 'Fant ikke tilfluktsrommet', // Tilgjengelighet direction_arrow_description: 'Retning til tilfluktsrom, %s unna', @@ -49,6 +50,21 @@ export const nb: Record = { a11y_shelter_info: 'Tilfluktsrominfo', a11y_nearest_shelters: 'Nærmeste tilfluktsrom', + // Sivilforsvar + action_civil_defense_info: 'Sivilforsvarsinformasjon', + civil_defense_title: 'Hva du skal gjøre hvis alarmen går', + civil_defense_step1_title: '1. Viktig melding-signalet', + civil_defense_step1_body: 'Tre serier med korte støt med ett minutts stillhet mellom hver serie. Dette betyr: søk informasjon umiddelbart. Slå på DAB-radio, TV, eller sjekk offisielle kilder på nett.', + civil_defense_step2_title: '2. Flyalarm', + civil_defense_step2_body: 'Korte støt som varer omtrent ett minutt. Dette betyr umiddelbar fare for angrep — søk dekning nå. Gå til nærmeste tilfluktsrom, kjeller eller innerrom umiddelbart.', + civil_defense_step3_title: '3. Gå innendørs og finn dekning', + civil_defense_step3_body: 'Kom deg innendørs. Lukk alle vinduer, dører og ventilasjonsåpninger. Bruk denne appen for å finne nærmeste offentlige tilfluktsrom. Kompasset og kartet fungerer uten internett. Hvis det ikke er noe tilfluktsrom i nærheten, gå til en kjeller eller et innerrom bort fra vinduer.', + civil_defense_step4_title: '4. Lytt til NRK på DAB-radio', + civil_defense_step4_body: 'Lytt til NRK P1 på DAB-radio for offisielle oppdateringer og instruksjoner fra myndighetene. DAB-radio fungerer selv når mobilnettet og internett er nede.', + civil_defense_step5_title: '5. Faren over', + civil_defense_step5_body: 'Én sammenhengende tone på omtrent 30 sekunder. Faren eller angrepet er over. Fortsett å følge instruksjoner fra myndighetene.', + civil_defense_source: 'Kilde: DSB (Direktoratet for samfunnssikkerhet og beredskap)', + // Om about_title: 'Om Tilfluktsrom', about_description: @@ -66,4 +82,6 @@ export const nb: Record = { about_open_source: 'Åpen kildekode — kode.naiv.no/olemd/tilfluktsrom', action_about: 'Om', action_close: 'Lukk', + action_clear_cache: 'Slett lagrede data', + cache_cleared: 'Alle lagrede data slettet', }; diff --git a/pwa/src/i18n/nn.ts b/pwa/src/i18n/nn.ts index b0cc328..eace6bd 100644 --- a/pwa/src/i18n/nn.ts +++ b/pwa/src/i18n/nn.ts @@ -41,6 +41,7 @@ export const nn: Record = { 'Ingen lagra data tilgjengeleg. Kopla til internett for å laste ned tilfluktsromdata.', update_success: 'Tilfluktsromdata oppdatert', update_failed: 'Oppdatering mislukkast — brukar lagra data', + error_shelter_not_found: 'Fann ikkje tilfluktsrommet', // Tilgjenge direction_arrow_description: 'Retning til tilfluktsrom, %s unna', @@ -49,6 +50,21 @@ export const nn: Record = { a11y_shelter_info: 'Tilfluktsrominfo', a11y_nearest_shelters: 'Nærmaste tilfluktsrom', + // Sivilforsvar + action_civil_defense_info: 'Sivilforsvarsinformasjon', + civil_defense_title: 'Kva du skal gjere om alarmen går', + civil_defense_step1_title: '1. Viktig melding-signalet', + civil_defense_step1_body: 'Tre seriar med korte støyt med eitt minutt stille mellom kvar serie. Dette tyder: søk informasjon med ein gong. Slå på DAB-radio, TV, eller sjekk offisielle kjelder på nett.', + civil_defense_step2_title: '2. Flyalarm', + civil_defense_step2_body: 'Korte støyt som varar omtrent eitt minutt. Dette tyder umiddelbar fare for åtak — søk dekning no. Gå til næraste tilfluktsrom, kjellar eller innerrom med ein gong.', + civil_defense_step3_title: '3. Gå innandørs og finn dekning', + civil_defense_step3_body: 'Kom deg innandørs. Lukk alle vindauge, dører og ventilasjonsopningar. Bruk denne appen for å finne næraste offentlege tilfluktsrom. Kompasset og kartet fungerer utan internett. Om det ikkje er noko tilfluktsrom i nærleiken, gå til ein kjellar eller eit innerrom bort frå vindauge.', + civil_defense_step4_title: '4. Lytt til NRK på DAB-radio', + civil_defense_step4_body: 'Lytt til NRK P1 på DAB-radio for offisielle oppdateringar og instruksjonar frå styresmaktene. DAB-radio fungerer sjølv når mobilnettet og internett er nede.', + civil_defense_step5_title: '5. Faren over', + civil_defense_step5_body: 'Éin samanhengande tone på omtrent 30 sekund. Faren eller åtaket er over. Hald fram med å følgje instruksjonar frå styresmaktene.', + civil_defense_source: 'Kjelde: DSB (Direktoratet for samfunnstryggleik og beredskap)', + // Om about_title: 'Om Tilfluktsrom', about_description: @@ -66,4 +82,6 @@ export const nn: Record = { about_open_source: 'Open kjeldekode — kode.naiv.no/olemd/tilfluktsrom', action_about: 'Om', action_close: 'Lukk', + action_clear_cache: 'Slett lagra data', + cache_cleared: 'Alle lagra data sletta', }; diff --git a/pwa/src/styles/main.css b/pwa/src/styles/main.css index 47d9768..a7e2dfb 100644 --- a/pwa/src/styles/main.css +++ b/pwa/src/styles/main.css @@ -458,6 +458,48 @@ html, body { margin-bottom: 2px; } +#civil-defense-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.85); + z-index: 2000; + display: flex; + align-items: center; + justify-content: center; + padding: 16px; +} + +.about-link-btn { + display: block; + margin: 16px 0 0; + padding: 0; + background: none; + border: none; + color: #FF6B35; + font-size: 14px; + cursor: pointer; + min-height: 48px; + line-height: 48px; +} + +.about-clear-btn { + display: block; + margin: 12px 0 0; + padding: 8px 16px; + background: transparent; + border: 1px solid #90A4AE; + border-radius: 6px; + color: #90A4AE; + font-size: 13px; + cursor: pointer; +} + +.about-clear-btn:disabled { + border-color: #4a6a5a; + color: #4a6a5a; + cursor: default; +} + .about-close-btn { display: block; margin: 16px auto 0; diff --git a/pwa/src/ui/about-dialog.ts b/pwa/src/ui/about-dialog.ts index 19c5d08..6788df3 100644 --- a/pwa/src/ui/about-dialog.ts +++ b/pwa/src/ui/about-dialog.ts @@ -1,5 +1,6 @@ /** * About dialog: app info, privacy statement, data sources, copyright. + * Includes a "Clear cached data" button that removes all local storage. * Opens as a modal overlay, same pattern as loading-overlay. */ @@ -35,6 +36,13 @@ export function showAbout(): void { content.appendChild(subheading(t('about_stored_title'))); content.appendChild(para(t('about_stored_body'))); + // Clear cache button + const clearBtn = document.createElement('button'); + clearBtn.className = 'about-clear-btn'; + clearBtn.textContent = t('action_clear_cache'); + clearBtn.addEventListener('click', () => clearAllData(clearBtn)); + content.appendChild(clearBtn); + const footer = document.createElement('div'); footer.className = 'about-footer'; footer.appendChild(small(t('about_copyright'))); @@ -63,6 +71,28 @@ export function hideAbout(): void { previousFocus = null; } +/** Clear all cached data: IndexedDB, localStorage, and service worker caches. */ +async function clearAllData(btn: HTMLButtonElement): Promise { + btn.disabled = true; + + // Clear localStorage (map cache metadata) + localStorage.clear(); + + // Clear IndexedDB (shelter database) + const dbs = await indexedDB.databases?.() ?? []; + for (const db of dbs) { + if (db.name) indexedDB.deleteDatabase(db.name); + } + + // Clear service worker caches (map tiles, precache) + const cacheNames = await caches.keys(); + for (const name of cacheNames) { + await caches.delete(name); + } + + btn.textContent = t('cache_cleared'); +} + function heading(text: string): HTMLElement { const el = document.createElement('h2'); el.textContent = text; diff --git a/pwa/src/ui/civil-defense-dialog.ts b/pwa/src/ui/civil-defense-dialog.ts new file mode 100644 index 0000000..d022422 --- /dev/null +++ b/pwa/src/ui/civil-defense-dialog.ts @@ -0,0 +1,96 @@ +/** + * Civil defense info dialog: what to do when the alarm sounds. + * Same content as the Android CivilDefenseInfoDialog. + * Links to the about dialog at the bottom. + */ + +import { t } from '../i18n/i18n'; +import { showAbout } from './about-dialog'; + +let overlay: HTMLDivElement | null = null; +let previousFocus: HTMLElement | null = null; + +/** Show the civil defense info dialog. */ +export function showCivilDefenseInfo(): void { + if (overlay) return; + + previousFocus = document.activeElement as HTMLElement | null; + + overlay = document.createElement('div'); + overlay.id = 'civil-defense-overlay'; + overlay.setAttribute('role', 'dialog'); + overlay.setAttribute('aria-modal', 'true'); + overlay.setAttribute('aria-label', t('civil_defense_title')); + + const content = document.createElement('div'); + content.className = 'about-content'; + + content.appendChild(heading(t('civil_defense_title'))); + + for (let i = 1; i <= 5; i++) { + content.appendChild(subheading(t(`civil_defense_step${i}_title`))); + content.appendChild(para(t(`civil_defense_step${i}_body`))); + } + + content.appendChild(small(t('civil_defense_source'))); + + // "About this app" link + const aboutLink = document.createElement('button'); + aboutLink.className = 'about-link-btn'; + aboutLink.textContent = t('action_about'); + aboutLink.addEventListener('click', () => { + hideCivilDefenseInfo(); + showAbout(); + }); + content.appendChild(aboutLink); + + const closeBtn = document.createElement('button'); + closeBtn.className = 'about-close-btn'; + closeBtn.textContent = t('action_close'); + closeBtn.addEventListener('click', hideCivilDefenseInfo); + content.appendChild(closeBtn); + + overlay.appendChild(content); + document.body.appendChild(overlay); + + closeBtn.focus(); +} + +/** Hide the dialog and restore focus. */ +export function hideCivilDefenseInfo(): void { + if (overlay) { + overlay.remove(); + overlay = null; + } + previousFocus?.focus(); + previousFocus = null; +} + +function heading(text: string): HTMLElement { + const el = document.createElement('h2'); + el.textContent = text; + el.className = 'about-heading'; + return el; +} + +function subheading(text: string): HTMLElement { + const el = document.createElement('h3'); + el.textContent = text; + el.className = 'about-subheading'; + return el; +} + +function para(text: string): HTMLElement { + const el = document.createElement('p'); + el.textContent = text; + el.className = 'about-para'; + return el; +} + +function small(text: string): HTMLElement { + const el = document.createElement('p'); + el.textContent = text; + el.className = 'about-small'; + el.style.fontStyle = 'italic'; + return el; +} diff --git a/pwa/src/ui/compass-view.ts b/pwa/src/ui/compass-view.ts index 5638dd9..e0945a1 100644 --- a/pwa/src/ui/compass-view.ts +++ b/pwa/src/ui/compass-view.ts @@ -135,6 +135,11 @@ function drawNorthIndicator( c.restore(); } +/** Resize the canvas (call when the compass container becomes visible). */ +export function resize(): void { + resizeCanvas(); +} + /** Clean up compass resources. */ export function destroyCompass(): void { window.removeEventListener('resize', resizeCanvas); diff --git a/pwa/src/ui/loading-overlay.ts b/pwa/src/ui/loading-overlay.ts index f6dc948..cafba89 100644 --- a/pwa/src/ui/loading-overlay.ts +++ b/pwa/src/ui/loading-overlay.ts @@ -6,6 +6,8 @@ * Focus is moved into the dialog when shown and restored when hidden. */ +import { t } from '../i18n/i18n'; + /** Element that had focus before the overlay opened. */ let previousFocus: HTMLElement | null = null; @@ -45,6 +47,9 @@ export function showCachePrompt( buttonRow.style.display = 'flex'; overlay.style.display = 'flex'; + okBtn.textContent = t('action_cache_ok'); + skipBtn.textContent = t('action_skip'); + okBtn.onclick = () => { hideLoading(); onOk(); diff --git a/pwa/src/ui/map-view.ts b/pwa/src/ui/map-view.ts index 52ee6ba..a7d99e1 100644 --- a/pwa/src/ui/map-view.ts +++ b/pwa/src/ui/map-view.ts @@ -6,16 +6,19 @@ */ import L from 'leaflet'; +import markerIcon from 'leaflet/dist/images/marker-icon.png'; +import markerIcon2x from 'leaflet/dist/images/marker-icon-2x.png'; +import markerShadow from 'leaflet/dist/images/marker-shadow.png'; import type { Shelter, ShelterWithDistance, LatLon } from '../types'; import { t } from '../i18n/i18n'; -// Fix Leaflet default icon paths (broken by bundlers) +// Fix Leaflet default icon paths (broken by bundlers) — use bundled assets // eslint-disable-next-line @typescript-eslint/no-explicit-any delete (L.Icon.Default.prototype as any)._getIconUrl; L.Icon.Default.mergeOptions({ - iconUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png', - iconRetinaUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png', - shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png', + iconUrl: markerIcon, + iconRetinaUrl: markerIcon2x, + shadowUrl: markerShadow, }); const DEFAULT_ZOOM = 14; diff --git a/pwa/vite.config.ts b/pwa/vite.config.ts index 6be5179..4df550a 100644 --- a/pwa/vite.config.ts +++ b/pwa/vite.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from 'vite'; import { VitePWA } from 'vite-plugin-pwa'; export default defineConfig({ + base: '/', define: { // Injected as a global — changes every build, breaking any stale cache __BUILD_REVISION__: JSON.stringify( @@ -21,7 +22,7 @@ export default defineConfig({ cleanupOutdatedCaches: true, // SPA: serve index.html for all navigation requests - navigateFallback: '/index.html', + navigateFallback: 'index.html', // Vite already hashes JS/CSS filenames — skip Workbox's // cache-bust query parameter for those