{
  "title": "Parcel Intelligence data dictionary",
  "delivery_contract": "parcel-intelligence-delivery/2.1",
  "tile": {
    "file": "lands/<code>_<name>/parcels.pmtiles",
    "contract": "parcel-intelligence-tiles/2.1",
    "layers": {
      "parcels_coverage": {
        "min_zoom": 0,
        "max_zoom": 9,
        "fields": []
      },
      "parcels": {
        "min_zoom": 10,
        "max_zoom": 14,
        "detail": 16
      }
    },
    "fields": [
      {
        "name": "parcel_key",
        "type": "String",
        "presence": "always",
        "product": "parcel_key"
      },
      {
        "name": "area_m2",
        "type": "Number",
        "presence": "when_valued",
        "product": "round(official_area_m2)"
      },
      {
        "name": "land_use",
        "type": "String",
        "presence": "when_valued",
        "product": "land_use_types as |a|b| (empty -> omitted)"
      },
      {
        "name": "building_count",
        "type": "Number",
        "presence": "always",
        "product": "building_count"
      },
      {
        "name": "planning_status",
        "type": "String",
        "presence": "always",
        "product": "planning_status"
      },
      {
        "name": "plan_grz",
        "type": "Number",
        "presence": "when_valued",
        "product": "plan_grz"
      },
      {
        "name": "plan_grz_share",
        "type": "Number",
        "presence": "when_valued",
        "product": "round(plan_grz_share, 2)"
      },
      {
        "name": "plan_grz_values",
        "type": "String",
        "presence": "when_valued",
        "product": "plan_grz_values as |0.4|0.6| (empty/NULL -> omitted)"
      },
      {
        "name": "grz_headroom",
        "type": "Number",
        "presence": "when_valued",
        "product": "round(grz_headroom, 2)"
      },
      {
        "name": "public_property",
        "type": "String",
        "presence": "when_valued",
        "product": "public_property_codes as |code| (empty/NULL -> omitted)"
      },
      {
        "name": "plan_name",
        "type": "String",
        "presence": "when_valued",
        "product": "selected_plan_name"
      },
      {
        "name": "plan_gr_m2",
        "type": "Number",
        "presence": "when_valued",
        "product": "round(plan_gr_m2)"
      },
      {
        "name": "plan_gr_basis",
        "type": "String",
        "presence": "when_valued",
        "product": "plan_gr_basis"
      },
      {
        "name": "additional_gr_m2",
        "type": "Number",
        "presence": "when_valued",
        "product": "round(estimated_additional_grf_m2)"
      },
      {
        "name": "potential_class",
        "type": "String",
        "presence": "when_valued",
        "product": "development_potential_class"
      }
    ],
    "admin_fields": "adm_<level>: String, one per level with a parcelAttribute",
    "planning_statuses": [
      "resolved",
      "conflicting_grz",
      "multiple_plans",
      "no_grz",
      "no_applicable_plan",
      "no_planning_area",
      "unresolved_plan_relation",
      "invalid_parcel_geometry",
      "no_source"
    ],
    "plan_gr_bases": [
      "baugebiet_grz",
      "baugebiet_grz_baufenster",
      "baufenster_grz"
    ],
    "potential_classes": [
      "high",
      "medium",
      "low",
      "none",
      "review",
      "no_grz",
      "no_plan"
    ]
  },
  "product": {
    "file": "GeoParquet in the Portolan catalog",
    "contract": "de.parcel_intelligence.parcels@1.1.0",
    "null_rules": [
      "NULL means 'unknown or not applicable'; 0, false and an empty list are real observations.",
      "planning_status = no_source: every plan_* field, grz_headroom, estimated_additional_grf_m2, planning_* fields and plan_count are NULL; plan_grz_values is NULL (not an empty list); development_potential_class is NULL.",
      "public_property_status = no_source: public_property_codes is NULL. NULL never means 'privately owned'.",
      "public_property_status = matched: codes list the accepted classifications; no_match: the source covers the parcel but does not list it (codes = empty list). Public property only: no_match is NOT evidence of private ownership."
    ],
    "columns": [
      {
        "name": "parcel_id",
        "type": "string",
        "nullable": false,
        "meaning": "National product key: '<jurisdiction>:<ALKIS gml_id>', e.g. 'DE-BE:DEBE12YYJ0005c2g'. Unique in the file."
      },
      {
        "name": "state_code",
        "type": "string",
        "nullable": false,
        "meaning": "Two-digit AGS Land code of the delivering state, e.g. '02', '11'."
      },
      {
        "name": "source_parcel_id",
        "type": "string",
        "nullable": false,
        "meaning": "ALKIS gml_id (Objektidentifikator) as delivered."
      },
      {
        "name": "parcel_key",
        "type": "string",
        "nullable": true,
        "meaning": "Flurstückskennzeichen as delivered (20 characters, starts with the Land code). Unique in the file. NULL only if the source has none."
      },
      {
        "name": "official_area_m2",
        "type": "float64",
        "nullable": true,
        "meaning": "ALKIS amtlicheFlaeche (m²)."
      },
      {
        "name": "parcel_geometry_area_m2",
        "type": "float64",
        "nullable": false,
        "meaning": "ST_Area of the parcel geometry in the state CRS; denominator of every ratio below."
      },
      {
        "name": "alkis_gemeindekennzeichen",
        "type": "string",
        "nullable": true,
        "meaning": "ALKIS Gemeindezugehörigkeit as delivered (land || regierungsbezirk || kreis || gemeinde, 8 digits). The official AGS in Hamburg; Berlin puts the Bezirk number in the gemeinde part (11000001..11000012), so it is NOT an AGS there. Use adm_gemeinde for the official unit."
      },
      {
        "name": "adm_land",
        "type": "string",
        "nullable": false,
        "meaning": "Land unit id (2 digits)."
      },
      {
        "name": "adm_kreis",
        "type": "string",
        "nullable": true,
        "meaning": "Kreis unit id (5 digits), parent of the Gemeinde in BKG VG250."
      },
      {
        "name": "adm_gemeinde",
        "type": "string",
        "nullable": true,
        "meaning": "Official Gemeinde (8-digit AGS, BKG VG250). From the ALKIS Gemeindezugehörigkeit when it is a VG250 AGS, else the VG250 Gemeinde containing the parcel's point on surface (method in quality.json)."
      },
      {
        "name": "admin_unit_ids",
        "type": "string",
        "nullable": false,
        "meaning": "JSON object level -> unit id for every level assigned to the parcel, including local levels (e.g. Hamburg bezirk/stadtteil/statgebiet)."
      },
      {
        "name": "land_use_types",
        "type": "list<string>",
        "nullable": false,
        "meaning": "Distinct ALKIS tatsächliche-Nutzung classes (ax_...) overlapping the parcel (touching only does not count). Empty list = none."
      },
      {
        "name": "building_count",
        "type": "int32",
        "nullable": false,
        "meaning": "Distinct ALKIS buildings intersecting the parcel, touch-only pairs included. 0 = none."
      },
      {
        "name": "building_ids",
        "type": "list<string>",
        "nullable": false,
        "meaning": "gml_ids of those buildings, sorted. Empty list = none."
      },
      {
        "name": "has_buildings",
        "type": "bool",
        "nullable": false,
        "meaning": "At least one building overlaps the parcel with positive area."
      },
      {
        "name": "observed_building_footprint_area_m2",
        "type": "float64",
        "nullable": false,
        "meaning": "Area of the union of all building footprints within the parcel (no exclusions). Computed from ALKIS alone."
      },
      {
        "name": "observed_building_footprint_ratio",
        "type": "float64",
        "nullable": false,
        "meaning": "observed_building_footprint_area_m2 / parcel_geometry_area_m2. Diagnostic; not the GRZ utilisation."
      },
      {
        "name": "current_alkis_grz",
        "type": "float64",
        "nullable": true,
        "meaning": "Current ALKIS utilisation: sum(grundflaeche x 4-decimal footprint share) of GRZ-relevant buildings / parcel_geometry_area_m2, rounded to 4 decimals; garages, parking structures, garden houses excluded. Can exceed 1. NULL = not calculable (see status)."
      },
      {
        "name": "current_alkis_grz_status",
        "type": "string",
        "nullable": false,
        "meaning": "calculated | no_intersecting_buildings | no_grz_eligible_buildings | no_grundflaeche. no_grundflaeche: every counted building lacks ALKIS grundflaeche, as in the Berlin NAS."
      },
      {
        "name": "planning_status",
        "type": "string",
        "nullable": false,
        "meaning": "resolved | conflicting_grz | multiple_plans | no_grz | no_applicable_plan | no_planning_area | unresolved_plan_relation | invalid_parcel_geometry | no_source. no_source = no integrated planning source covers the parcel."
      },
      {
        "name": "planning_source",
        "type": "string",
        "nullable": true,
        "meaning": "Planning provider id (e.g. xplanung_oaf_snapshot). NULL when no_source."
      },
      {
        "name": "planning_snapshot_id",
        "type": "string",
        "nullable": true,
        "meaning": "Identifier of the planning snapshot used. NULL when no_source."
      },
      {
        "name": "planning_method_version",
        "type": "string",
        "nullable": true,
        "meaning": "grz-screening-v3 (area-weighted GRZ, slivers <= 1 m2 ignored). NULL when no_source."
      },
      {
        "name": "planning_legally_verified",
        "type": "bool",
        "nullable": true,
        "meaning": "Always false where a source exists (automated screening). NULL when no_source."
      },
      {
        "name": "plan_count",
        "type": "int32",
        "nullable": true,
        "meaning": "Number of applicable plans intersecting the parcel. NULL when no_source."
      },
      {
        "name": "selected_plan_id",
        "type": "string",
        "nullable": true,
        "meaning": "Plan id when exactly one applicable plan intersects the parcel."
      },
      {
        "name": "selected_plan_name",
        "type": "string",
        "nullable": true,
        "meaning": "Plan name when exactly one applicable plan intersects the parcel."
      },
      {
        "name": "plan_grz",
        "type": "float64",
        "nullable": true,
        "meaning": "Area-weighted mean of the GRZ (else GRZmax) values of the applicable plan areas intersecting the parcel (weight = parcel area under each value); buildable areas take precedence over development zones; intersections <= 1 m2 ignored; values above 1 withheld. Rounded to 4 decimals. Screening value, not legally verified."
      },
      {
        "name": "plan_grz_share",
        "type": "float64",
        "nullable": true,
        "meaning": "Share of the parcel geometry plan_grz applies to (0..1), BauNVO §19(3): the zones that gave the value; when it comes from buildable areas, every applicable zone on the parcel."
      },
      {
        "name": "plan_grz_values",
        "type": "list<float64>",
        "nullable": true,
        "meaning": "Every considered GRZ/GRZmax value of the parcel (intersections > 1 m2), ascending (withheld >1 values included). Empty list = source exists, no value; NULL = no_source."
      },
      {
        "name": "plan_gr_m2",
        "type": "float64",
        "nullable": true,
        "meaning": "zulässige Grundfläche GR (§19(2) BauNVO, m2), screening estimate: plan_grz x plan_grz_share x parcel area, capped by the buildable area (Baufenster) on the parcel when it has one (§23 BauNVO). Excludes the §19(4) allowance for garages, parking and ancillary structures. NULL when plan_grz is NULL."
      },
      {
        "name": "plan_gr_basis",
        "type": "string",
        "nullable": true,
        "meaning": "How plan_gr_m2 was derived (German XPlanung terms): baugebiet_grz = GRZ of the Baugebiet(steilfläche) x its part of the parcel; baugebiet_grz_baufenster = the same, limited by the überbaubare Grundstücksfläche (Baufenster) on the parcel; baufenster_grz = the GRZ is set on the überbaubare Grundstücksfläche itself. NULL when plan_grz is NULL."
      },
      {
        "name": "grz_headroom",
        "type": "float64",
        "nullable": true,
        "meaning": "plan_gr_m2 / parcel area - current utilisation, i.e. permitted minus current ground area per m2 of parcel (utilisation 0 without buildings or when buildings only touch the parcel). Equals plan_grz - utilisation for a fully covered parcel without a limiting Baufenster. NULL when plan_grz is NULL or utilisation is unknown."
      },
      {
        "name": "estimated_additional_grf_m2",
        "type": "float64",
        "nullable": true,
        "meaning": "plan_gr_m2 - current ground area (= grz_headroom x parcel_geometry_area_m2). Negative = above the plan value."
      },
      {
        "name": "development_potential_status",
        "type": "string",
        "nullable": false,
        "meaning": "calculated | no_current_grz | no_permitted_grz | planning_unresolved | no_planning_source (added: planning_status = no_source)."
      },
      {
        "name": "development_potential_class",
        "type": "string",
        "nullable": true,
        "meaning": "Map class of the potential: high | medium | low | none (from estimated_additional_grf_m2; thresholds config/pipeline.yml grz.potential_*, product assumptions: high >= 150 m2, medium >= 50 m2, low > 0, none <= 0) | review (plan value but not calculable: several plans, unresolved relation, unknown current ground area) | no_grz (plan in force without GRZ) | no_plan (no plan in force in the source; may be §34/§35 BauGB land, not 'no potential'). NULL when no_source."
      },
      {
        "name": "public_property_status",
        "type": "string",
        "nullable": false,
        "meaning": "no_source | no_match | matched. no_source: no public-property source covers the parcel (all states without an adapter); no_match: covered, not in the source; matched: in the source (Hamburg: LBV)."
      },
      {
        "name": "public_property_codes",
        "type": "list<string>",
        "nullable": true,
        "meaning": "Accepted classification codes (Hamburg LBV: Grundbesitzart-Grundbesitztyp, e.g. 081-2902, sorted). NULL when no_source, empty when no_match; never evidence of private ownership."
      },
      {
        "name": "run_id",
        "type": "string",
        "nullable": false,
        "meaning": "Pipeline run that produced this file; equals the PMTiles metadata pipeline_run_id of the same state release."
      },
      {
        "name": "source_version",
        "type": "string",
        "nullable": false,
        "meaning": "ALKIS data version of the state delivery (e.g. 2026-09-18 Berlin, 2026-07-09 Hamburg)."
      },
      {
        "name": "geometry",
        "type": "binary",
        "nullable": false,
        "meaning": "Parcel MultiPolygon, WKB, state CRS."
      }
    ]
  }
}
