HWHeat Waves
    DashboardUtforsk
    Analyse
    Data Kilder
        • Category Codes
        • Filter Axes
        • Regions
        • Building Types
        • SSB Tables
        • API Examples
      • Catalog
      • Pipeline
      • Entrypoints
    • Design Rationale
    • Doc Map
    DocsSettings
    DashboardAtlasUtforsk
    Analyse
    Data Kilder
    1. Documentation
    2. Ingestion
    3. Adapter Mappings
    4. Filter axes — native to filter id

    Loading documentation...

    Filter axes — native to filter id

    ETL contract for fire_type, building_type, building_age, and region native_value ↔ filters rows.

    Filter Mapping Table (Normalized)

    This file is the canonical filter map used across adapters.

    Rules

    • «Alle» / all values on an axis is the unfiltered request, stored as a NULL fact FK — never a filter row. The upstream "select nothing" request (empty BRASK form field, empty BRIS *.ids array, SSB Bygningsbranner dataset) produces a fact with NULL on that axis column. There is no ALL / ALL_BUILDINGS filter standard_code; total slices are read with an omitted get_fire_data axis param (→ <axis>_code IS NULL). The dimension-total category (cross-tab ALL_BUILDINGS / ALL_AGES on categories.standard_code, dim 5/6) is a separate concept — see category-native-to-cat-code.md.
    • Standard filter codes are used cross-source wherever comparison is possible:
      • Fire Type: CONFINED / DEVELOPED
      • Building Type: RESIDENTIAL (the only cross-source building_type filter code; "all buildings" is NULL, not a code)
      • Building Age: 0-5 / 6-10 / 11-20 / 21-30 / 31-50 / 51+ / UNKNOWN — BRASK only, no cross-source equivalent
      • Region: no unified standard — geographic systems differ per source (see §4)
    • BRASK filters are submitted as ASP.NET multiselect list box fields in a form POST to https://brask.finansnorge.no/. An empty string value means "Alle" (all values selected). Specific selections pass the numeric option id.
    • BRIS filter availability depends on the endpoint:
      • /aggregate ("Alle branner og ulykker") — supports Fire Type, Building Type, Region.
      • /restrictedaggregation ("Hvordan bygningsbranner starter") — supports Fire Type and Region only. Building Type is not available.
    • SSB has no request-level filter parameters like BRASK/BRIS. Building type is dataset choice (Boligbranner vs Bygningsbranner). Geography on table 12058 is the PxWeb KOKkommuneregion0000 dimension (national EAK or kommune codes) — see §4. SSB has no Fire Type or Building Age.

    Read-time (get_fire_data) vs ingest-time requests

    Charts: Passing standard_code strings such as RESIDENTIAL or CONFINED into get_fire_data resolves to all matching filters.id rows on that axis for the requested source(s) (postgres-contract-rls-and-keys.md). Passing multiple tokens in the same axis argument (e.g. two native_code values or both a standard_code and a leaf code) resolves to the union of matching ids (OR within that axis). Omitted filter-axis arguments mean only facts where that axis FK is NULL (upstream unfiltered slice). Different axes are combined with AND.

    ETL: Adapter POST bodies use upstream-native identifiers (form ids, Matrikkel codes, BRIS mission-type ids, etc.). On ingest, adapters resolve each applied native to filters.id and write that integer onto fact FK columns — never the native string. filters.native_code and standard_code live on the catalog row only.

    ETL rule — one native per slice: Each ingest slice resolves to exactly one filters.id per applied axis; the adapter POST body uses that row's native_code (Matrikkel leaf id, BRIS mission-type id, kommune code, etc.), not a rollup standard_code. When the UI selects a parent standard_code (e.g. RESIDENTIAL, COMMERCIAL), resolveFilterAxisTokens expands it to all matching leaf filters.id values before ingest; the BRIS adapter then passes buildingTypeIdsOverride: [native] with one Matrikkel leaf per slice (policeAggregateBuildingParams in lib/data-model/adapters/bris.ts). Fire type and region follow the same rule (toMissionTypeIds, counties.ids). Building age is BRASK-only (filterNativeCode on the form field). BRIS does not expose building age.

    Catalog labels: filters.name is a shortened per-leaf UI label (typically the text before the first comma in native_name). filters.standard_name labels standard_code rollups in the UI (e.g. Bolig for RESIDENTIAL). Neither field is an ingest axis token.

    BRIS precision: Examples below sometimes show several mission-type ids in one JSON body (e.g. all CONFINED natives). The HeatWaves BRIS adapter ingests one native mission type id per slice and stamps the matching filters.id into fire_type_code — not the BRIS numeric id itself.

    BRIS Endpoint Filter Capabilities

    Filter/aggregate/restrictedaggregationRequest body field
    Fire Type✓✓revisedMissionTypes.ids
    Building Type✓✗buildingTypes.ids
    Region (county)✓✓counties.ids
    Region (municipality)✓✗municipalities.ids
    Building Age✗✗—

    1) Fire Type (Branntype)

    standard_codes: CONFINED | DEVELOPED

    Supported by: BRASK, BRIS (all sub-sources). Not supported by SSB.

    Definition: CONFINED — fire contained to the object/item of origin (Begrenset branntilløp). DEVELOPED — fire spread beyond it (Utviklet brann).

    namesourcenative_paramnative_valuenative_namestandard_code
    Alle branntyper—(empty request)——NULL FK (no filter row)
    BegrensetBRASKctl00$Innhold$lbType2KaldCONFINED
    UtvikletBRASKctl00$Innhold$lbType1VarmDEVELOPED
    Begrenset (komfyr)BRIS — Police Sub-ArevisedMissionTypes.ids10086Branntilløp komfyrCONFINED
    Begrenset (bygg annet)BRIS — Police Sub-ArevisedMissionTypes.ids10212Branntilløp i bygg annetCONFINED
    Begrenset (skorstein)BRIS — Police Sub-ArevisedMissionTypes.ids10175Brann i skorsteinCONFINED
    UtvikletBRIS — Police Sub-ArevisedMissionTypes.ids10026Brann i bygningDEVELOPED
    Begrenset (komfyr)BRIS — Police Sub-BrevisedMissionTypes.ids10086Branntilløp komfyrCONFINED
    Begrenset (bygg annet)BRIS — Police Sub-BrevisedMissionTypes.ids10212Branntilløp i bygg annetCONFINED
    UtvikletBRIS — Police Sub-BrevisedMissionTypes.ids10026Brann i bygningDEVELOPED
    Begrenset (komfyr)BRIS — Fire BrigaderevisedMissionTypes.ids10086Branntilløp komfyrCONFINED
    Begrenset (bygg annet)BRIS — Fire BrigaderevisedMissionTypes.ids10212Branntilløp i bygg annetCONFINED
    UtvikletBRIS — Fire BrigaderevisedMissionTypes.ids10026Brann i bygningDEVELOPED
    Begrenset (komfyr)BRIS — DSBrevisedMissionTypes.ids10086Branntilløp komfyrCONFINED
    Begrenset (bygg annet)BRIS — DSBrevisedMissionTypes.ids10212Branntilløp i bygg annetCONFINED
    UtvikletBRIS — DSBrevisedMissionTypes.ids10026Brann i bygningDEVELOPED

    Brann i skorstein (10175) exists only in the "Alle branner og ulykker" dataset (Police Sub-A). It does not appear in "Hvordan bygningsbranner starter". It is a CONFINED-class chimney fire unique to that dataset.

    How Fire Type is applied in the API

    BRASK — ASP.NET form POST field. One fetch per fire type:

    # CONFINED (Kald)
    ctl00$Innhold$lbType = 2
    
    # DEVELOPED (Varm)
    ctl00$Innhold$lbType = 1
    
    # All fire types (empty = Alle)
    ctl00$Innhold$lbType =
    

    BRIS /aggregate — revisedMissionTypes.ids array in the JSON body. Fetch one slice per Oppdragstype value, then standardize at ingest:

    // DEVELOPED only { "revisedMissionTypes": { "ids": [10026], "isMissingValue": false } } // CONFINED only (Police Sub-A — all three confined types) { "revisedMissionTypes": { "ids": [10086, 10212, 10175], "isMissingValue": false } } // CONFINED only (Police Sub-B, Brigade, DSB — no skorstein) { "revisedMissionTypes": { "ids": [10086, 10212], "isMissingValue": false } }

    BRIS /restrictedaggregation — same revisedMissionTypes.ids field, restricted body:

    { "revisedMissionTypes": { "ids": [10026], "isMissingValue": false }, "counties": { "ids": [], "isMissingValue": false }, "hundredAndTenCentrals": { "ids": [], "isMissingValue": false }, "includePoliceCauseWithNoMission": false, "aggregationQuery": { ... } }

    Ingest iterates all relevant Oppdragstype values, tags each row with the standardized fire type code, and aggregates the slices.


    2) Building Type (Bygningstype)

    standard_codes: RESIDENTIAL ("all buildings" is the unfiltered slice — NULL building_type FK, not a code)

    Supported by: SSB (dataset selection only), BRASK (næring), BRIS /aggregate only. Not supported by BRIS /restrictedaggregation.

    namesourcenative_paramnative_valuenative_namestandard_code
    BoligSSBdatasetBoligbrannerBoligbrannerRESIDENTIAL
    Alle byggSSBdatasetBygningsbranner—NULL FK (no filter row)
    BoligBRASKctl00$Innhold$lbNæring0BeboelseRESIDENTIAL
    Alle byggBRASKctl00$Innhold$lbNæring(empty)—NULL FK (no filter row)
    Bolig (rollup)BRIS /aggregatebuildingTypes.ids30 Matrikkel leaf-IDs (one per ingest slice)—RESIDENTIAL (expands to all 1xx leaves)
    Bolig (leaf)BRIS /aggregatebuildingTypes.idsone 3-digit leaf ide.g. Enebolig (111)RESIDENTIAL
    Non-residential (leaf)BRIS /aggregatebuildingTypes.idsone 3-digit leaf ide.g. Fabrikkbygning (211)INDUSTRY / COMMERCIAL / OTHER / …
    Alle byggBRIS /aggregatebuildingTypes.ids(empty array)—NULL FK (no filter row)
    —BRIS /restrictedaggregation——Not supported—

    How Building Type is applied in the API

    SSB — no filter parameter. Two separate datasets are queried depending on the desired scope:

    • Boligbranner = RESIDENTIAL
    • Bygningsbranner = all building fires (including residential) → stored with building_type_code NULL (the unfiltered total), not a filter row

    BRASK — ASP.NET form POST field using the næring (industry) dimension. Only the Beboelse value is used for the building type split:

    # RESIDENTIAL (Beboelse)
    ctl00$Innhold$lbNæring = 0
    
    # All buildings (empty = Alle næringer) → stored as NULL building_type FK
    ctl00$Innhold$lbNæring =
    

    Note: næring has 22 industry sector values in total. For the Building Type filter, only 0 (Beboelse) and empty (all) are relevant. The full næring taxonomy is not used as a cross-source filter — it is a BRASK-specific analytical dimension.

    BRIS /aggregate — buildingTypes.ids array of Matrikkel leaf-level 3-digit string codes. Only leaf-level IDs work; parent IDs (e.g. "1" or "11") return zero results.

    Explore / Utforsk ingest: When the user selects Bolig (or individual leaves), Explore expands to one ingest slice per leaf filters.id, each calling the API with that leaf's native_code only — not the 30-id Bolig list and not standard_code=RESIDENTIAL. The whole-Bolig JSON below is the upstream shape for a single parent rollup request (native_code 0 or non-leaf RESIDENTIAL parent), not what each leaf slice sends.

    // RESIDENTIAL (Bolig — 30 leaf IDs from category "1") { "buildingTypes": { "ids": [ "111","112","113","121","122","123","124","131","133","135","136", "141","142","143","144","145","146","151","152","159","161","162", "163","171","172","181","182","183","193","199" ], "isMissingValue": false } } // All buildings (no filter) → stored as NULL building_type FK { "buildingTypes": { "ids": [], "isMissingValue": false } }

    Records without building type data are excluded when a filter is applied. To also include records with missing building type, set isMissingValue: true.

    BRIS Bolig leaf-code map (native_value -> native_name)

    Source of truth: scripts/dsb_detailed_site_map.md ("Bolig Leaf IDs").

    native_valuenative_name
    111Enebolig
    112Enebolig med hybelleilighet, sokkelleilighet o.l.
    113Våningshus
    121Tomannsbolig, vertikaldelt
    122Tomannsbolig, horisontaldelt
    123Våningshus, tomannsbolig, vertikaldelt
    124Våningshus, tomannsbolig, horisontaldelt
    131Rekkehus
    133Kjedehus inkl. atriumhus
    135Terrassehus
    136Andre småhus med 3 boliger eller flere
    141Store frittliggende boligbygg på 2 etasjer
    142Store frittliggende boligbygg på 3 og 4 etasjer
    143Store frittliggende boligbygg på 5 etasjer eller over
    144Store sammenbygde boligbygg på 2 etasjer
    145Store sammenbygde boligbygg på 3 og 4 etasjer
    146Store sammenbygde boligbygg på 5 etasjer og over
    151Bo- og servicesenter
    152Studenthjem/studentboliger
    159Annen bygning for bofellesskap
    161Fritidsbygning (hytter, sommerhus o.l.)
    162Helårsbolig benyttet som fritidsbolig
    163Våningshus benyttet som fritidsbolig
    171Seterhus, sel, rorbu o.l.
    172Koie, gamme
    181Garasje, uthus, anneks til bolig
    182Boligbrakke
    183Naust, båthus, sjøbu
    193Bolig med forretning, kontor e.l.
    199Annen boligbygning (uklassifisert)

    Ikke bolig (client-only comparison)

    Not a filter row or filters.name. «Ikke bolig» is a UI/analytics shorthand: compare the all-buildings total (building_type_code IS NULL) against RESIDENTIAL, or sum non-residential leaf facts (COMMERCIAL, INDUSTRY, OTHER, PUBLIC, UNKNOWN). See building-type-semantics.ts.

    BRIS non-RESIDENTIAL Matrikkel leaves (native_value → native_name)

    Upstream enumeration reference: NON_RESIDENTIAL_MATRIKKEL_LEAF_IDS in _brisUpstream.constants.ts (derived from https://brannstatistikk.no/api/v1/buildinginfo/types). Each leaf is a separate filters row with its own standard_code bucket — ingest uses one row per slice, never the full list in one POST.

    211: Fabrikkbygning 212: Verkstedbygning 214: Bygning for renseanlegg 216: Bygning for vannforsyning, bl.a. pumpestasjon 219: Annen industribygning 221: Kraftstasjon (>15 000 kVA) 223: Transformatorstasjon (>10 000 kVA) 229: Annen energiforsyningsbygning 231: Lagerhall 232: Kjøle- og fryselager 233: Silobygning 239: Annen lagerbygning 241: Hus for dyr, fôrlager, strølager, frukt- og grønnsakslager, landbrukssilo, høy-/korntørke 243: Veksthus 244: Driftsbygning for fiske og fangst, inkl. oppdrettsanlegg 245: Naust/redskapshus for fiske 248: Annen fiskeri- og fangstbygning 249: Annen landbruksbygning 311: Kontor- og administrasjonsbygning, rådhus 312: Bankbygning, posthus 313: Mediebygning 319: Annen kontorbygning 321: Kjøpesenter, varehus 322: Butikkbygning 323: Bensinstasjon 329: Annen forretningsbygning 330: Messe- og kongressbygning 411: Ekspedisjonsbygning, flyterminal, kontrolltårn 412: Jernbane- og T-banestasjon 415: Godsterminal 416: Postterminal 419: Annen ekspedisjons- og terminalbygning 429: Telekommunikasjonsbygning 431: Parkeringshus 439: Annen garasje- hangarbygning 441: Trafikktilsynsbygning 449: Annen veg- og trafikktilsynsbygning 511: Hotellbygning 512: Motellbygning 519: Annen hotellbygning 521: Hospits, pensjonat 522: Vandrerhjem, feriehjem/-koloni, turisthytte 523: Appartement 524: Campinghytte/utleiehytte 529: Annen bygning for overnatting 531: Restaurantbygning, kafébygning 532: Sentralkjøkken, kantinebygning 533: Gatekjøkken, kioskbygning 539: Annen restaurantbygning 611: Lekepark 612: Barnehage 613: Barneskole 614: Ungdomsskole 615: Kombinert barne- og ungdomsskole 616: Videregående skole 619: Annen skolebygning 621: Universitets- og høgskolebygning med integrerte funksjoner, auditorium, lesesal o.a. 623: Laboratoriebygning 629: Annen universitets-, høgskole- og forskningsbygning 641: Museum, kunstgalleri 642: Bibliotek, mediatek 643: Zoologisk og botanisk hage 649: Annen museums- og bibliotekbygning 651: Idrettshall 652: Ishall 653: Svømmehall 654: Tribune og idrettsgarderobe 655: Helsestudio 659: Annen idrettsbygning 661: Kinobygning, teaterbygning, opera/konserthus 662: Samfunnshus, grendehus 663: Diskotek 669: Annet kulturhus 671: Kirke, kapell 672: Bedehus, menighetshus 673: Krematorium, gravkapell, bårehus 674: Synagoge, moské 675: Kloster 679: Annen bygning for religiøse aktiviteter 719: Sykehus 721: Sykehjem 722: Bo- og behandlingssenter, aldershjem 723: Rehabiliteringsinstitusjon, kurbad 729: Annet sykehjem 731: Klinikk, legekontor/-senter/-vakt 732: Helse- og sosialsenter, helsestasjon 739: Annen primærhelsebygning 819: Fengselsbygning 821: Politistasjon 822: Brannstasjon, ambulansestasjon 823: Fyrstasjon, losstasjon 824: Stasjon for radarovervåkning av fly- og/eller skipstrafikk 825: Tilfluktsrom/bunker 829: Annen beredskapsbygning 830: Monument 840: Offentlig toalett

    3) Building Age (Bygningsalder) — BRASK only

    standard_codes: 0-5 | 6-10 | 11-20 | 21-30 | 31-50 | 51+ | UNKNOWN

    Supported by: BRASK only. Not supported by SSB or BRIS.

    BRASK exposes 13 fine-grained age buckets. HeatWaves normalizes these into 6 coarser buckets for storage.

    namesourcenative_paramnative_valuenative_namenormalized_bucket
    Alle aldersgrupperBRASK—(empty)—NULL FK (no filter row)
    0–5 årBRASKctl00$Innhold$lbAldersgruppe1Ny0-5
    0–5 årBRASKctl00$Innhold$lbAldersgruppe21-50-5
    6–10 årBRASKctl00$Innhold$lbAldersgruppe36-106-10
    11–20 årBRASKctl00$Innhold$lbAldersgruppe411-1511-20
    11–20 årBRASKctl00$Innhold$lbAldersgruppe516-2011-20
    21–30 årBRASKctl00$Innhold$lbAldersgruppe621-2521-30
    21–30 årBRASKctl00$Innhold$lbAldersgruppe726-3021-30
    31–50 årBRASKctl00$Innhold$lbAldersgruppe831-4031-50
    31–50 årBRASKctl00$Innhold$lbAldersgruppe941-5031-50
    51+ årBRASKctl00$Innhold$lbAldersgruppe1051-7551+
    51+ årBRASKctl00$Innhold$lbAldersgruppe1176-10051+
    51+ årBRASKctl00$Innhold$lbAldersgruppe12Over 10051+
    UkjentBRASKctl00$Innhold$lbAldersgruppe99UkjentUNKNOWN

    How Building Age is applied in the API

    Building Age is a BRASK-specific dimension that can be used in two ways:

    1. As a filter — restrict the query to a single age bucket, then retrieve Kilde or Årsak data.
    2. As a row or column dimension — retrieve a breakdown of fire counts by age bucket.

    BRASK — ASP.NET form POST field:

    # Single age bucket (6-10 år)
    ctl00$Innhold$lbAldersgruppe = 3
    
    # Multiple buckets (select both 6-10 and 11-15)
    ctl00$Innhold$lbAldersgruppe = 3
    ctl00$Innhold$lbAldersgruppe = 4
    
    # All age groups (empty = Alle)
    ctl00$Innhold$lbAldersgruppe =
    

    Normalization note: two BRASK native values (Ny and 1-5) both map to the 0-5 normalized bucket. When querying by normalized bucket, the adapter must send both native ids to cover the full range.

    BRIS — not supported on any endpoint.

    SSB — not supported on this axis.


    4) Region

    No unified standard code — geographic systems are incompatible between sources.

    Supported by: BRASK (cresta-sone, pre-2020 counties), BRIS /aggregate and /restrictedaggregation (counties.ids and municipalities.ids), SSB table 12058 (KOKkommuneregion0000 — national EAK or per-municipality codes; see ssb-pxwebapi-tables.md and pipeline §4.3).

    SSB — table 12058 (KOKkommuneregion0000)

    • Alle regioner / national: PxWeb EAK → stored as region_code IS NULL (not a filters.id).
    • Filtered kommune: { "filter": "item", "values": ["<4-digit code>", …] } → region_code = resolved filters.id (same spine as BRIS municipality ids where codes align).

    BRASK — Cresta-sone (pre-2020 county boundaries)

    BRASK uses Cresta-sone ids on form field ctl00$Innhold$lbFylke (empty = Alle). Native values and Cresta → canonical 2024 county mapping: regions-and-cresta.md §1.

    Note: Cresta id 13 is absent in upstream numbering (see regions doc).

    BRIS — Counties and Municipalities

    BRIS uses current Norwegian administrative geographic units. County IDs and municipality IDs come from the national geographic registry (SSR/Kartverket). These do not correspond to BRASK's Cresta-sone ids.

    Examples:

    • Oslo = county id 3, municipality id 301
    • Viken = county id 30 (post-2020 merged county, contains old Akershus, Buskerud, Østfold)

    The full county and municipality ID lists are fetched from GET /api/v1/buildinginfo/nace (or via the Pinia store where-data-options) at runtime and are not hardcoded in HeatWaves.

    How Region is applied in the API

    BRASK — ASP.NET form POST field. Empty = all regions. Single or multiple values:

    # Oslo only
    ctl00$Innhold$lbFylke = 3
    
    # Oslo and Akershus
    ctl00$Innhold$lbFylke = 3
    ctl00$Innhold$lbFylke = 2
    
    # All regions (empty = Alle)
    ctl00$Innhold$lbFylke =
    

    BRIS /aggregate and /restrictedaggregation — counties.ids (coarse) or municipalities.ids (fine) array in the JSON body. Both endpoints accept this field. Empty array = all regions:

    // Single county (Oslo = 3) { "counties": { "ids": [3], "isMissingValue": false } } // Single municipality (Oslo = 301) { "municipalities": { "ids": [301], "isMissingValue": false } } // All regions { "counties": { "ids": [], "isMissingValue": false } }

    Cross-Source Comparability

    FilterCross-source comparable?Notes
    Fire TypeYesBoth BRASK and BRIS expose it natively. HeatWaves standardizes to CONFINED/DEVELOPED. The only gap is Brann i skorstein (Police Sub-A only) — it contributes to CONFINED totals but has no BRASK or restricted-dataset equivalent.
    Building TypePartialComparable between BRASK and BRIS /aggregate (Police Sub-A). Not available in BRIS /restrictedaggregation (Police Sub-B, Fire Brigade, DSB) — those sub-sources always include all building types.
    Building AgeNoBRASK-only. No equivalent in BRIS or SSB.
    RegionNoBRASK uses pre-2020 Cresta-sone county ids. BRIS uses current post-2020 administrative ids. Direct comparison requires a manual lookup table between the two systems, which HeatWaves does not currently implement.

    Maintenance

    When changing BRASK form fields or BRIS county/municipality filters, update this file and regions-and-cresta.md. Adapter code: lib/data-model/adapters/_registry.ts, _braskWebForms.constants.ts, bris.ts.