Zum Inhalt springen
Höhenlinien überlagern

Höhenlinien überlagern

Ziel: Höhenlinien in passender Dichte über ein Luftbild legen, Indexlinien kräftiger zeichnen und mit der Höhe beschriften.

Voraussetzungen: ein Browser und ein statischer Webserver. Beschriftung braucht eine eigene Schriftquelle (Glyphen), siehe Basiskarte gestalten.

Das Tileset Höhenlinien hat einen Layer contour_l mit den Feldern ele (Höhe in m), index (1 = Indexlinie) und lvl (Generalisierungsstufe 10, 12, 14, 16). Es gibt Linien ab z10.

  1. Seite mit Hintergrund. Das Orthophoto als Basis, die Höhenlinien als Vektorquelle:

    <!doctype html>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css">
    <script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
    <style>html, body, #map { margin: 0; height: 100%; }</style>
    <div id="map"></div>
    <script>
      const TOKEN = "DEIN_TOKEN"; // öffentlicher Token mx_pk_…
      const quellen = {
        ortho: { type: "raster", url: "https://tiles.mapx.at/v1/tiles/orthophoto.json", tileSize: 512 },
        linien: { type: "vector", url: "https://tiles.mapx.at/v1/tiles/contours.json" }
      };
  2. Stufe wählen. Die Kacheln enthalten mehrere Stufen mit eigenem Linienabstand. Damit je Zoom nur die passende Stufe sichtbar ist, nach lvl filtern:

    ZoomlvlAbstandIndexlinie
    10–1110100 m500 m
    12–131250 m200 m
    14–151420 m100 m
    ab 161610 m50 m

    Eine Ebene je Stufe, mit minzoom und maxzoom begrenzt:

    const stufen = [
      { lvl: 10, min: 10, max: 12 },
      { lvl: 12, min: 12, max: 14 },
      { lvl: 14, min: 14, max: 16 },
      { lvl: 16, min: 16, max: 24 }
    ];
    const linienEbenen = stufen.flatMap(({ lvl, min, max }) => [
      { id: `linie-${lvl}`, type: "line", source: "linien", "source-layer": "contour_l",
        minzoom: min, maxzoom: max,
        filter: ["all", ["==", ["get", "lvl"], lvl], ["!=", ["get", "index"], 1]],
        paint: { "line-color": "#ffd9a0", "line-width": 0.6, "line-opacity": 0.8 } },
      { id: `index-${lvl}`, type: "line", source: "linien", "source-layer": "contour_l",
        minzoom: min, maxzoom: max,
        filter: ["all", ["==", ["get", "lvl"], lvl], ["==", ["get", "index"], 1]],
        paint: { "line-color": "#ffb347", "line-width": 1.4 } }
    ]);
  3. Höhenbeschriftung. Nur Indexlinien tragen eine Zahl. symbol-placement: "line" setzt den Text entlang der Linie:

    const beschriftung = {
      id: "hoehe-text", type: "symbol", source: "linien", "source-layer": "contour_l", minzoom: 12,
      filter: ["==", ["get", "index"], 1],
      layout: {
        "symbol-placement": "line",
        "text-field": ["concat", ["to-string", ["get", "ele"]], " m"],
        "text-font": ["Open Sans Semibold"],
        "text-size": 11
      },
      paint: { "text-color": "#fff", "text-halo-color": "#7a4a00", "text-halo-width": 1.5 }
    };

    text-font muss eine Schrift der Glyphenquelle sein. Ohne Beschriftung entfällt diese Ebene und glyphs.

  4. Karte starten.

      new maplibregl.Map({
        container: "map",
        center: [12.694, 47.074], zoom: 14,
        // Token an alle Anfragen an mapx.at hängen
        transformRequest: (url) => ({
          url: /^https:\/\/([\w-]+\.)?mapx\.at\//.test(url) ? url + (url.includes("?") ? "&" : "?") + "access_token=" + TOKEN : url,
        }),
        style: {
          version: 8,
          glyphs: "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",   // eigene Glyphenquelle
          sources: quellen,
          layers: [{ id: "ortho", type: "raster", source: "ortho" }, ...linienEbenen, beschriftung]
        }
      });
    </script>

Ergebnis

Über dem Luftbild liegen feine Höhenlinien, deren Abstand sich mit dem Zoom anpasst (100 m bis 10 m). Indexlinien sind kräftig und tragen die Höhe in Metern.

Für eine Karte statt Luftbild die Orthophoto-Ebene durch die Ebenen aus Basiskarte gestalten ersetzen; die Höhenlinien kommen danach darüber.

Ohne Filter nach lvl liegen beim Überzoomen mehrere Stufen übereinander. Die Linien enden unterhalb von z10; für kleinere Maßstäbe bleibt das Relief über Schummerung.

Nächste Schritte