Skip to content

KLXM/vector_maps

Repository files navigation

Vector Maps – REDAXO AddOn

Interaktive Vektorkarten für REDAXO – datenschutzkonform, ohne API-Key, vollständig selbst


Features

  • Kein API-Key erforderlich – nutzt OpenFreeMap (freie Vektorkacheln)
  • DSGVO-konform – externer Datenverkehr wird vollständig über einen PHP-Proxy geleitet; Whitelist per Extension Point VECTOR_MAPS_PROXY_DOMAINS und Backend-Einstellungen erweiterbar
  • Web Component <vectormap> – direkt im Template oder Modul verwendbar, kein JavaScript nötig
  • Lazy-Init + Build-Queue – WebGL-Kontext wird sequentiell für jede Karte aufgebaut, erst wenn sie in den Viewport scrollt (verhindert Browserlimit von ~10 parallelen WebGL-Kontexten)
  • Backend-Koordinatenpicker – Koordinatenfelder in REDAXO-Modulen mit Karte und Adresssuche
  • Allgemeiner Geodaten-Picker – framework-unabhängiger Kartenpicker für normale Input-Felder, auch außerhalb von Modulen
  • YForm-Integration – eigenes Value-Feld vector_map_location mit Picker, Stil- und Theme-Vorgabe
  • Builder-Integration – eigener Feldtyp vector_map_picker und Element Vector Map für plain, bootstrap und uikit
  • Routing – Koordinaten oder Adressen, mit Auto-, Fuß- und Fahrradmodus (OSRM)
  • Interaktives Routenpanel – Von/Nach-Adressen direkt auf der Karte eingeben (Autocomplete); GPS-Locate-Button übernimmt den aktuellen Gerätestandort als Startpunkt
  • Umgebungssuche (nearby) – POI-Suche via Overpass API (z. B. Ladestationen, Restaurants)
  • Dynamisches Datennachladen – GeoJSON-Source per moveend aktualisieren (z. B. Ladestationen live aus OSM)
  • Freie Wetter-APIs – Open-Meteo und Bright Sky (DWD) via Proxy, kein API-Key, Badge-Marker mit Live-Daten
  • Standortsuche – optionale Geolokalisierung des Nutzers als Ausgangspunkt
  • Themesdark, warm, mono eingebaut, frei erweiterbar via Theme-Editor im Backend; Routing-Linienfarbe im Theme-Editor konfigurierbar; Themes werden per Fetch geladen und erst danach eingeblendet (kein Flash of Unstyled Map)
  • Theme-Fade-in – Karte blendet sich sanft ein sobald das Theme geladen ist; Dauer per theme-transition-Attribut (ms) steuerbar
  • 3D-Gebäude – aktivierbar per Attribut
  • Mehrsprachigkeit – Sprachcode per language-Attribut, steuert Kartenbeschriftungen von OpenFreeMap
  • Cluster – automatische Marker-Bündelung bei vielen Punkten
  • Satellitenbild – ESRI World Imagery als map-style="satellite" oder per show-satellite Toggle-Button, kein API-Key (Tiles laufen DSGVO-konform über den Proxy)
  • maxPitch 60° – Kamerakippung auf 60° begrenzt (verhindert extreme Perspektiven)

Installation

Über den REDAXO-Installer oder manuell:

  1. AddOn-Verzeichnis nach redaxo/src/addons/vector_maps/ kopieren
  2. Im REDAXO-Backend unter Installer > Eigene AddOns installieren und aktivieren

Keine weiteren Abhängigkeiten oder Node-Build-Schritte notwendig.


Frontend-Einbindung

Automatisch (Standard)

Nach der Installation lädt das AddOn alle benötigten Assets automatisch im Frontend — keine manuelle Einbindung notwendig. Die CSS- und JS-Dateien werden von REDAXO im <head> / vor </body> ausgegeben:

maplibre-gl.css        → MapLibre GL JS Kern-Styles
vectormaps.css         → Web Component Styles + Dark Mode
maplibre-gl.js         → MapLibre GL JS Kern-Script
vectormaps.js          → <vectormap> Custom Element

Danach kann <vectormap> direkt in jedem Template, Modul oder Artikel verwendet werden:

<!-- Karte einfach per Tag ausgeben – kein JS nötig -->
<vectormap lat="51.43" lng="6.77" zoom="13" height="400px"></vectormap>

Manuell (wenn Auto-Loading deaktiviert)

Über Vector Maps → Einstellungen kann das automatische Laden deaktiviert werden (load_frontend = false). In diesem Fall müssen die Assets im Template manuell eingebunden werden:

<?php
// In project/templates/template.php oder einem Fragment:
$vmAddon = rex_addon::get('vector_maps');
?>
<!DOCTYPE html>
<html>
<head>
    <!-- MapLibre GL JS Styles -->
    <link rel="stylesheet" href="<?= $vmAddon->getAssetsUrl('maplibre/maplibre-gl.css') ?>">
    <!-- Vector Maps Styles (Dark Mode, Custom Marker, Route-Panel …) -->
    <link rel="stylesheet" href="<?= $vmAddon->getAssetsUrl('build/vectormaps.css') ?>">
</head>
<body>

    <!-- Karten-Tags hier platzieren -->
    <vectormap lat="51.43" lng="6.77" zoom="13"></vectormap>

    <!-- MapLibre GL JS Core (defer empfohlen) -->
    <script defer src="<?= $vmAddon->getAssetsUrl('maplibre/maplibre-gl.js') ?>"></script>
    <!-- Vector Maps Web Component (defer empfohlen) -->
    <script defer src="<?= $vmAddon->getAssetsUrl('build/vectormaps.js') ?>"></script>
</body>
</html>

Hinweis: Die tatsächlichen Asset-Pfade variieren je nach REDAXO-Installation. getAssetsUrl() liefert immer die korrekte absolute URL.

Einbindung über REDAXO-Modul

Im Modul-Output kann die Karte direkt mit REX_VALUE-Platzhaltern ausgegeben werden:

<?php
// Module output
$lat = rex_escape(REX_VALUE[1]);
$lng = rex_escape(REX_VALUE[2]);
$zoom = rex_escape(REX_VALUE[3] ?: '14');
$popup = rex_escape(REX_VALUE[4]);
?>
<vectormap
    lat="<?= $lat ?>"
    lng="<?= $lng ?>"
    zoom="<?= $zoom ?>"
    height="400px"
    markers='[{"lat":<?= $lat ?>,"lng":<?= $lng ?>,"popup":"<?= $popup ?>"}]'>
</vectormap>

Allgemeiner Koordinaten-Picker für Input-Felder

Ein normales Input-Feld kann framework-unabhängig durch den Vector-Maps-Picker erweitert werden.

HTML:

<input
    type="text"
    name="location"
    value="52.520008,13.404954"
    data-vector-picker="1"
    data-vector-picker-style="bright">

Optional per PHP-Helper:

<?php
echo \KLXM\VectorMaps\Picker\PickerWidget::factory('location')
    ->setValue('52.520008,13.404954')
    ->setMapStyle('bright')
    ->setTheme('warm')
    ->parse();

Das Input-Feld wird automatisch mit einem Picker-Button erweitert. Im Modal können Koordinaten per Klick, Drag oder Adresssuche gesetzt werden.

Hinweis: Bei data-vector-picker-style="satellite" wird die Theme-Auswahl bewusst deaktiviert, da Themes nur auf Vektorstile wirken.

Für einen schnellen Funktionstest gibt es im Backend die Seite Demo → Geocoding mit Beispielen für Picker, YForm und Builder.

YForm-Feld: vector_map_location

Für YForm steht ein eigenes Value-Feld zur Verfügung, das Koordinaten als lat,lng speichert und den Vector-Maps-Picker direkt im Formular rendert.

Beispiel:

value|vector_map_location|location|Standort|liberty|warm|1

Schema:

value|vector_map_location|name|label|[map_style]|[theme]|[required]

Beispiel mit Notice:

value|vector_map_location|location|Standort|bright|redaxo|1|Bitte Position auf der Karte wählen

Das Feld eignet sich besonders für Kontakt-, Filial- oder Event-Datensätze, weil Redakteure die Position nicht manuell als Zahlenpaar pflegen müssen.

Builder-Element: Vector Map

Das AddOn registriert ein eigenes Builder-Element Vector Map und einen eigenen Builder-Feldtyp für den Koordinaten-Picker.

Merkmale:

  • Theme-Auswahl direkt im Element
  • Basis-Kartenstil wählbar (liberty, bright, positron, satellite)
  • Marker + Popup
  • optionales globales Infofenster
  • Controls, Locate, Satellit und Fullscreen
  • optionaler Routenplaner mit Start/Ziel, Modus, fixiertem Ziel und Panel-Layout
  • Templates für uikit, bootstrap und plain

Der Koordinatenwert wird im Builder über den gleichen Picker gesetzt wie bei normalen Input-Feldern.

Für typische Kontaktseiten kann das Element jetzt ohne Sondercode als Anfahrtskarte genutzt werden:

  • route_panel blendet das interaktive Von/Nach-Panel ein
  • route_to setzt ein festes Ziel als Adresse oder lat,lng
  • route_to_locked fixiert dieses Ziel für Redakteure und Besucher
  • route_panel_layout erlaubt Overlay oder Seiten-Spalte links/rechts
  • route_panel_style übernimmt die vorhandenen Panel-Skins glass, contrast und brand

Damit eignet sich dasselbe Element sowohl für eine einfache Marker-Karte als auch für eine vollwertige Anfahrts- oder Routenkarte.

CSP-Hinweis (Content-Security-Policy)

Falls eine Content-Security-Policy aktiv ist, müssen folgende Direktiven ergänzt werden — nur für Seiten mit Karten:

worker-src blob:;

Alle Tile-Requests laufen über den REDAXO-Proxy (/?rex_api_vector_maps_proxy=1), daher sind keine externen connect-src-Einträge für OpenFreeMap, Nominatim oder OSRM notwendig.


<!-- Einfache Karte -->
<vectormap lat="51.51" lng="-0.12" zoom="12"></vectormap>

<!-- Mit Markern und Popup -->
<vectormap lat="51.51" lng="-0.12" zoom="13"
    markers='[{"lat":51.51,"lng":-0.12,"popup":"London"}]'>
</vectormap>

<!-- Vollbreite, 3D, Dark-Theme -->
<vectormap lat="48.85" lng="2.35" zoom="15"
    height="500px" theme="dark" 3d>
</vectormap>

Alle Attribute

Attribut Standard Beispiel Beschreibung
lat 51.505 lat="51.51" Breitengrad des Kartenzentrums
lng 7.0 lng="-0.12" Längengrad des Kartenzentrums
center center="51.51,-0.12" Kartenmitte als lat,lng (Alternative zu lat+lng)
zoom 6 zoom="15" Anfangszoomstufe (0–22)
height 400 height="600px" CSS-Höhe des Karten-Containers
pitch 0 pitch="45" Kamerakippung in Grad (0–60)
bearing 0 bearing="45" Kartenausrichtung in Grad
map-style liberty map-style="satellite" OFM-Stilname: liberty, bright, positron, satellite (ESRI World Imagery) – oder Theme-Name
show-satellite false show-satellite Toggle-Button zum Wechsel zwischen Vektor- und Satellitenbild (ESRI World Imagery, kein API-Key)
theme theme="dark" Farb-Theme: dark, warm, mono oder eigener Theme-Name
theme-transition 350 theme-transition="600" Einblend-Dauer in ms nach Theme-Load (0 = sofort, Standard: 350)
language de language="en" Sprachcode für Kartenbeschriftungen (ISO 639-1)
markers markers='[{"lat":51.51,"lng":-0.12}]' JSON-Array mit Marker-Objekten
fit-bounds auto fit-bounds="false" Kartenausschnitt an alle Marker anpassen. Standard: aktiv bei mehreren Markern; mit fit-bounds="false" deaktivieren
cluster false cluster Marker bei hoher Dichte clustern
3d false 3d 3D-Gebäude aktivieren
interactive true interactive="false" Karte scrollbar/zoombar (Standard: aktiv). Mit interactive="false" deaktivieren
locate false locate Standort-Button anzeigen
fullscreen false fullscreen Fullscreen-Button anzeigen (Karte im Browser-Vollbild umschalten)
controls-position top-right controls-position="top-left" Position der MapLibre-Navigation (top-left, top-right, bottom-left, bottom-right)
controls-cluster right controls-cluster="left" Einfacher Shortcut für sinnvolle Defaults: clustert Navigation + Locate/Satellit gemeinsam (left, right, oder direkte Ecke wie bottom-left)
controls-style controls-style="rail" Vorgefertigte UI-Stile für Navigation/Kompass/Fullscreen plus Locate/Satellit: soft, rail, minimal, bold
fullscreen-position wie controls-position fullscreen-position="bottom-right" Position des Fullscreen-Buttons
no-navigation false no-navigation Zoom-/Kompass-Controls ausblenden
no-attribution false no-attribution Attributionszeile ausblenden
buttons-position wie controls-position buttons-position="top-left" Basisposition für locate/show-satellite Buttons
locate-position wie buttons-position locate-position="bottom-left" Individuelle Position des Locate-Buttons
satellite-position wie buttons-position satellite-position="top-left" Individuelle Position des Satellit-Buttons
buttons-offset 10 buttons-offset="16" Außenabstand der Overlay-Buttons in px
buttons-gap 38 buttons-gap="44" Vertikaler Abstand zwischen Locate- und Satelliten-Button in derselben Ecke
popup-focus-mode auto popup-focus-mode="restore" Fokusverhalten beim Schließen von Popups: restore (zurück zum Auslöser), canvas (zur Karte), none (kein Fokuswechsel). Standard: Marker-Popups restore, Layer-Popups canvas
info-html info-html="<strong>Info</strong>" Globales Infofenster innerhalb der Karte (HTML erlaubt)
info-position top-left info-position="bottom-right" Position des Infofensters (top-left, top-right, bottom-left, bottom-right)
info-offset 12 info-offset="20" Außenabstand des Infofensters in px
info-class info-class="my-info-box" Zusätzliche CSS-Klasse für eigenes Styling
info-visible true info-visible="false" Infofenster ein-/ausblenden
info-closable false info-closable Schließen-Button im Infofenster anzeigen
route-panel-position top-left route-panel-position="bottom-right" Position des Route-Panels
route-panel-offset 12 route-panel-offset="18" Außenabstand des Route-Panels in px
route-panel-style route-panel-style="glass" Vorgefertigte Panel-Skins: glass, contrast, brand
route-panel-layout overlay route-panel-layout="side-right" Layout des Route-Panels: overlay (in der Karte), side-right, side-left
route-panel-width 340 route-panel-width="360" Breite der Seiten-Spalte bei side-right/side-left
fly-to fly-to="48.85,2.35" Kartenansicht nach dem Laden animiert zentrieren
min-zoom 0 min-zoom="5" Minimaler Zoom-Level
max-zoom 22 max-zoom="18" Maximaler Zoom-Level

Buttons Positionieren (Einfach + Manuell)

Reihenfolge der Positionslogik:

  1. Wenn gesetzt, gilt locate-position bzw. satellite-position (pro Button).
  2. Sonst gilt buttons-position (gemeinsame Basis für beide Buttons).
  3. Sonst folgt buttons-position automatisch der Control-Ecke aus controls-position.
  4. Wenn controls-position fehlt, greift controls-cluster (right = oben rechts, left = oben links).

Standard ohne zusätzliche Attribute (alles gemeinsam in einer Ecke):

<vectormap
    center="51.165691,10.451526"
    zoom="6"
    locate
    show-satellite
    fullscreen>
</vectormap>

Einfach komplett nach links clustern:

<vectormap
    center="51.165691,10.451526"
    zoom="6"
    locate
    show-satellite
    fullscreen
    controls-cluster="left">
</vectormap>

Manuell trennen (optional):

<vectormap
    center="51.165691,10.451526"
    zoom="6"
    locate
    show-satellite
    controls-position="top-left"
    buttons-position="top-left"
    locate-position="bottom-left"
    satellite-position="top-right">
</vectormap>

Info-Kästen Erstellen

Variante A: per Attribut info-html

<vectormap
    center="51.43,6.77"
    zoom="12"
    height="380"
    info-position="top-left"
    info-html="<strong>Service</strong><br>Mo-Fr 08:00-18:00"
    info-closable>
</vectormap>

Variante B: Inline als Child <div class="mapinfo">

<vectormap center="51.43,6.77" zoom="12" height="380">
    <div class="mapinfo" data-position="top-left" data-closable data-class="my-info-box">
        <strong>Kontakt</strong><br>
        Mo-Fr 08:00-18:00<br>
        <a href="/kontakt">Zur Kontaktseite</a>
    </div>
</vectormap>

Unterstützte mapinfo-Optionen:

  • data-position="top-left|top-right|bottom-left|bottom-right"
  • data-class="deine-klasse"
  • data-closable

Quick Recipes

Drei kurze Copy-Paste-Vorlagen fuer typische Einsaetze.

1) Corporate Karte (ruhige Controls, klare Info)

<vectormap
    center="52.520008,13.404954"
    zoom="12"
    height="420"
    locate
    show-satellite
    fullscreen
    controls-cluster="left"
    controls-style="soft"
    info-position="top-right"
    info-html="<strong>Standort Berlin</strong><br>Mo-Fr 08:00-18:00"
    info-closable>
</vectormap>

2) Kontaktseite (festes Ziel, Besucher gibt nur Start ein)

<vectormap
    center="51.4298,6.7742"
    zoom="12"
    height="480"
    route-panel
    route-to="Am Schuermannshuett 40g, 47441 Moers"
    route-to-popup="<strong>KLXM Crossmedia GmbH</strong><br>klxm.de"
    route-to-locked
    route-mode="driving"
    controls-cluster="left"
    controls-style="minimal">
</vectormap>

3) Routing-Seite (Panel als echte Spalte)

<vectormap
    center="51.165691,10.451526"
    zoom="6"
    height="520"
    route-panel
    route-panel-layout="side-right"
    route-panel-width="360"
    route-panel-style="brand"
    route-from="Berlin HBF"
    route-to="Leipzig Hauptbahnhof"
    controls-cluster="left"
    locate
    show-satellite>
</vectormap>

Control-Design per CSS-Variablen

Die MapLibre-Buttons (+, , Kompass, Fullscreen) können gemeinsam mit Locate/Satellit eingefärbt werden:

<vectormap
    locate
    show-satellite
    fullscreen
    controls-style="rail"
    controls-position="top-right"
    buttons-position="top-right"
    style="
        --vm-nav-bg: rgba(12, 20, 32, .82);
        --vm-nav-color: #dbeafe;
        --vm-nav-hover-bg: rgba(30, 64, 175, .75);
        --vm-nav-active-bg: #38bdf8;
        --vm-nav-active-color: #0c1b2d;
        --vm-tool-bg: rgba(12, 20, 32, .82);
        --vm-tool-color: #dbeafe;
    ">
</vectormap>

Wichtige Variablen: --vm-nav-bg, --vm-nav-color, --vm-nav-hover-bg, --vm-nav-active-bg, --vm-nav-active-color, --vm-nav-border, --vm-nav-shadow, --vm-nav-size, --vm-tool-*.

Sinnvolle Defaults (ohne Zusatzaufwand)

  • Navigation + Locate + Satellit werden standardmäßig als gemeinsamer Control-Cluster positioniert.
  • buttons-position folgt automatisch der Control-Ecke (via controls-position oder controls-cluster).
  • Für individuelle Layouts können controls-position, buttons-position, locate-position, satellite-position weiterhin optional separat gesetzt werden.

Automatische Kollisionsvermeidung

  • Der Abstand für Locate/Satellit wird nicht über fixe Schätzwerte, sondern über die reale Höhe der gerenderten MapLibre-Control-Ecke berechnet.
  • Dadurch werden Überlagerungen mit +/-, Kompass und Fullscreen in unterschiedlichen Themes/Styles zuverlässig vermieden.

Signature Styles (Nicht-Standard-Look)

Zwei kuratierte Richtungen, wenn die Karte bewusst nicht nach klassischer Standard-Map aussehen soll.

1) Editorial Warm

<style>
vectormap.vm-skin-signature-editorial {
    --vm-nav-size: 34px;
    --vm-nav-radius: 14px;
    --vm-nav-bg: #f7f3ea;
    --vm-nav-color: #2f2a24;
    --vm-nav-border: 1px solid rgba(87, 76, 61, .22);
    --vm-nav-shadow: 0 10px 26px rgba(67, 56, 42, .22);
    --vm-nav-hover-bg: #efe7d8;
    --vm-nav-hover-color: #111827;
    --vm-nav-active-bg: #c67b4e;
    --vm-nav-active-color: #fffaf4;
    --vm-tool-bg: #f7f3ea;
    --vm-tool-color: #2f2a24;
    --vm-tool-border: 1px solid rgba(87, 76, 61, .22);
    --vm-tool-shadow: 0 10px 26px rgba(67, 56, 42, .22);
    --vm-tool-hover-bg: #efe7d8;
    --vm-tool-hover-color: #111827;
    --vm-tool-active-bg: #c67b4e;
    --vm-tool-active-color: #fffaf4;
}
</style>

<vectormap
    class="vm-skin-signature-editorial"
    locate
    show-satellite
    fullscreen
    controls-position="top-left"
    buttons-position="top-left"
    route-panel
    route-panel-style="brand"
    route-panel-position="bottom-left">
</vectormap>

2) Transit Tech

<style>
vectormap.vm-skin-signature-transit {
    --vm-nav-size: 35px;
    --vm-nav-radius: 8px;
    --vm-nav-bg: rgba(20, 26, 38, .9);
    --vm-nav-color: #d9e7ff;
    --vm-nav-border: 1px solid rgba(99, 120, 160, .38);
    --vm-nav-shadow: 0 12px 28px rgba(3, 8, 17, .45);
    --vm-nav-hover-bg: rgba(37, 54, 92, .92);
    --vm-nav-hover-color: #f0f6ff;
    --vm-nav-active-bg: #00c2a8;
    --vm-nav-active-color: #06211d;
    --vm-nav-icon-filter: invert(1) brightness(1.15);
    --vm-tool-bg: rgba(20, 26, 38, .9);
    --vm-tool-color: #d9e7ff;
    --vm-tool-border: 1px solid rgba(99, 120, 160, .38);
    --vm-tool-shadow: 0 12px 28px rgba(3, 8, 17, .45);
    --vm-tool-hover-bg: rgba(37, 54, 92, .92);
    --vm-tool-hover-color: #f0f6ff;
    --vm-tool-active-bg: #00c2a8;
    --vm-tool-active-color: #06211d;
}
</style>

<vectormap
    class="vm-skin-signature-transit"
    locate
    show-satellite
    fullscreen
    controls-position="top-right"
    buttons-position="top-right"
    route-panel
    route-panel-style="glass"
    route-panel-position="bottom-left">
</vectormap>

Routing

Routen zwischen zwei Punkten berechnen – sowohl mit Koordinaten als auch mit Adressen. Alle Routing-Anfragen laufen über OSRM und werden DSGVO-konform über den PHP-Proxy geleitet.

<!-- Routing mit Koordinaten -->
<vectormap lat="51.43" lng="6.77" zoom="13"
    route-from="51.4298,6.7742"
    route-to="51.4539,6.7658"
    route-mode="walking">
</vectormap>

<!-- Routing mit Adressen -->
<vectormap lat="48.85" lng="2.35" zoom="6"
    route-from="Eiffelturm, Paris"
    route-to="Duisburg Hauptbahnhof"
    route-mode="driving">
</vectormap>

Routing-Attribute

Attribut Standard Beispiel Beschreibung
route-from route-from="51.43,6.77" Startpunkt: lat,lng oder Adresse als Text
route-to route-to="51.45,6.76" Zielpunkt: lat,lng oder Adresse als Text
route-mode driving route-mode="walking" Routing-Profil: driving, walking, cycling
route-panel false route-panel Interaktives Von/Nach-Panel auf der Karte einblenden
route-to-locked false route-to-locked Zieladresse im Panel fixieren – nicht editierbar, kein Autocomplete
route-to-popup route-to-popup="Firmenname<br>firmenname.de" Eigener Popup-Inhalt (HTML) am Ziel-Marker, wenn nur route-to gesetzt ist
route-no-steps false route-no-steps Abbiegehinweise (Turn-by-Turn) im Panel ausblenden

Interaktives Routenpanel (route-panel)

Das Routenpanel wird als schwebende Seitenleiste auf der Karte angezeigt und ermöglicht es, Start- und Zielpunkt direkt per Texteingabe (mit Autocomplete) sowie das Profil per Klick zu wählen:

<vectormap lat="51.43" lng="6.77" zoom="13"
    height="500px" interactive route-panel
    route-from="Duisburg Hauptbahnhof"
    route-to="Duisburg Innenstadt">
</vectormap>

Das Routenpanel zeigt SVG-Icons für die drei Modi Auto, Zu Fuß und Fahrrad. Es überschreibt route-from/route-to-Attribute nicht, sondern verwendet sie als Startwerte.

Fixiertes Ziel (route-to-locked)

Wenn das Ziel fest vorgegeben ist (z.B. ein Firmenstandort), kann das Zielfeld eingesperrt werden. Der Nutzer gibt nur seine Startadresse ein — das Ziel ist nicht editierbar und hat kein Autocomplete:

<vectormap lat="51.4298" lng="6.7742" zoom="12"
    height="450px"
    interactive
    route-panel
    route-to="Duisburg Hauptbahnhof"
    route-to-locked
    route-no-steps>
</vectormap>

Mit route-no-steps wird nur der berechnete Weg auf der Karte angezeigt — ohne Schritt-für-Schritt-Abbiegehinweise darunter. Ideal für Anfahrtskarten auf Kontaktseiten.

Anfahrtskarte mit Firmen-Marker (route-to-popup)

Wenn nur route-to gesetzt ist (kein route-from), wird das Ziel automatisch geocodiert, ein Marker gesetzt und die Karte zentriert. Mit route-to-popup kann der Popup-Inhalt des Markers frei definiert werden:

<vectormap
    height="500px"
    route-panel
    route-to="Am Schürmannshütt 40g, 47441 Moers"
    route-to-popup="<strong>KLXM Crossmedia GmbH</strong><br>klxm.de"
    route-to-locked
    route-mode="driving">
</vectormap>

Der Nutzer sieht sofort den Ziel-Marker mit Popup. Sobald er seine Startadresse eingibt, wird die Route berechnet.


Satellitenbild

Zwei Möglichkeiten, ESRI World Imagery (kostenlos, kein API-Key) zu nutzen:

<!-- Reines Satellitenbild -->
<vectormap lat="48.858844" lng="2.294351" zoom="16" height="400px"
    map-style="satellite">
    <marker lat="48.858844" lng="2.294351" popup="Eiffelturm"></marker>
</vectormap>

<!-- Vektor-Karte mit Toggle-Button für Satellitenansicht -->
<vectormap lat="52.520008" lng="13.404954" zoom="13" height="400px"
    show-satellite>
    <marker lat="52.520008" lng="13.404954" popup="Brandenburger Tor"></marker>
</vectormap>
Stil Beschreibung
satellite Reines Satellitenbild (ESRI World Imagery)
show-satellite Toggle-Button zum Wechsel zwischen aktuellem Vektorstil und Satellitenbild

Der show-satellite Toggle-Button erscheint in der aktiven Button-/Control-Ecke (Default: gemeinsam oben rechts). Marker bleiben beim Wechsel erhalten, GeoJSON-Layer werden nach Rückkehr zur Vektorkarte automatisch neu geladen.

Hinweis: ESRI World Imagery und das Referenz-Overlay sind frei nutzbar (Lizenz: Esri Master License Agreement). Attribution wird automatisch gesetzt. Für gewerbliche Hochlast-Szenarien empfiehlt sich ein eigener Tile-Server.


Accessibility: Popup-Fokus

Für saubere Tastatur-Navigation (Tab-Reihenfolge) kann das Fokusverhalten nach dem Schließen eines Popups pro Karte gesteuert werden:

<!-- Fokus springt zurück zum auslösenden Marker -->
<vectormap ... popup-focus-mode="restore"></vectormap>

<!-- Fokus geht zurück auf die Kartenfläche -->
<vectormap ... popup-focus-mode="canvas"></vectormap>

<!-- Kein automatischer Fokuswechsel nach dem Schließen -->
<vectormap ... popup-focus-mode="none"></vectormap>

Standardverhalten ohne Attribut:

  • Marker-Popup: Fokus zurück zum Marker (restore)
  • Layer-/Feature-Popup ohne Marker-Trigger: Fokus auf Karte (canvas)

Custom UI (CSS-Variablen + JS API)

Die Overlay-UI ist pro Karte vollständig per CSS-Variablen anpassbar:

<vectormap
        center="52.52,13.405"
        zoom="12"
        height="420"
        locate
        show-satellite
        buttons-position="top-left"
        route-panel
        route-panel-style="glass"
        info-html="<strong>Service</strong><br>Mo-Fr 08:00-18:00"
        style="
            --vm-widget-size: 34px;
            --vm-widget-radius: 10px;
            --vm-widget-bg: #0f172a;
            --vm-widget-color: #e2e8f0;
            --vm-info-bg: rgba(15,23,42,.88);
            --vm-info-color: #e2e8f0;
            --vm-rp-accent: #5eead4;
        ">
</vectormap>

Infofenster lässt sich zusätzlich per JS steuern:

const el = document.getElementById('my-map');
el.setInfoHtml('<strong>Live-Update</strong><br>Stand: 12:30');
el.setInfoPosition('bottom-right');
el.showInfoWindow();
el.hideInfoWindow();

Alternative ohne Attribut (Inline-Markup als Child):

<vectormap center="51.43,6.77" zoom="12">
    <div class="mapinfo" data-position="top-left" data-closable>
        <strong>Kontakt</strong><br>
        Mo-Fr 08:00-18:00
    </div>
</vectormap>

Optional für .mapinfo:

  • data-position="top-left|top-right|bottom-left|bottom-right"
  • data-class="deine-klasse"
  • data-closable

Umgebungssuche (nearby)

Mit dem nearby-Attribut können Points of Interest (POI) aus OpenStreetMap rund um den Kartenmittelpunkt oder den Gerätestandort des Nutzers geladen werden. Die Abfragen laufen über die Overpass API und werden DSGVO-konform über den PHP-Proxy geleitet.

<!-- E-Ladestationen im Umkreis von 2 km um Duisburg HBF -->
<vectormap lat="51.4298" lng="6.7742" zoom="13"
    height="500px"
    nearby="amenity=charging_station"
    nearby-radius="2000"
    nearby-label="Ladestation">
</vectormap>

<!-- Supermärkte und Discounter in der Nähe des Nutzers -->
<vectormap lat="51.43" lng="6.77" zoom="13"
    height="500px"
    nearby="shop=supermarket|shop=discount"
    nearby-locate>
</vectormap>

Nearby-Attribute

Attribut Standard Beispiel Beschreibung
nearby nearby="amenity=restaurant" Overpass-Filter (key=value), mehrere mit | trennen
nearby-radius 1000 nearby-radius="2000" Suchradius in Metern
nearby-label OSM-Tags nearby-label="Restaurant" Fallback-Label für Popups (wenn kein OSM-Name)
nearby-locate false nearby-locate Nutzerstandort (Geolokalisierung) als Suchmittelpunkt verwenden

Häufige Overpass-Filter

Filter Beschreibung
amenity=charging_station E-Ladestationen
amenity=fuel Tankstellen
amenity=restaurant Restaurants
amenity=cafe Cafés
amenity=pharmacy Apotheken
amenity=hospital Krankenhäuser
amenity=bank Banken
shop=supermarket Supermärkte
shop=supermarket|shop=discount Supermärkte und Discounter
leisure=park Parks
tourism=hotel Hotels
tourism=museum Museen

Hinweis: Bei nearby-locate fragt die Karte den Browser nach dem Gerätestandort. Fällt die Geolokalisierung fehl, wird automatisch auf den Kartenmittelpunkt zurückgegriffen.


Dynamisches Datennachladen

Über die globale Hilfsfunktion vmProxyUrl() können externe APIs auch client-seitig per JavaScript angesprochen werden – DSGVO-konform über den REDAXO-Proxy, ohne CORS-Probleme.

Ladestationen live nachladen (Overpass API)

Das folgende Muster lädt E-Ladesäulen dynamisch für den aktuellen Kartenausschnitt, sobald die Karte bewegt wird:

// Zugriff auf die MapLibre-Instanz eines <vectormap>-Elements
const el  = document.getElementById('meine-karte');
const map = el._vmMap; // nach dem 'load'-Event verfügbar

// GeoJSON-Source + Layer anlegen
map.addSource('stationen', {
  type: 'geojson',
  data: { type: 'FeatureCollection', features: [] }
});
map.addLayer({
  id: 'stationen-punkte', type: 'circle', source: 'stationen',
  paint: { 'circle-color': '#27ae60', 'circle-stroke-color': '#fff', 'circle-stroke-width': 2 }
});

// Bei Kartenbewegung Daten nachladen (debounced)
let timer;
map.on('moveend', () => {
  clearTimeout(timer);
  timer = setTimeout(async () => {
    if (map.getZoom() < 9) return; // erst ab Zoom 9 laden
    const b = map.getBounds();
    const q = `[out:json][timeout:10];`
      + `node["amenity"="charging_station"]`
      + `(${b.getSouth()},${b.getWest()},${b.getNorth()},${b.getEast()});`
      + `out 200;`;
    const data = await fetch(vmProxyUrl(
      'https://overpass-api.de/api/interpreter?data=' + encodeURIComponent(q)
    )).then(r => r.json());
    const features = (data.elements || []).map(n => ({
      type: 'Feature',
      geometry: { type: 'Point', coordinates: [n.lon, n.lat] },
      properties: n.tags
    }));
    map.getSource('stationen').setData({ type: 'FeatureCollection', features });
  }, 600);
});

Hinweis: vmProxyUrl ist nach dem Laden von vectormaps.js global verfügbar. overpass-api.de ist bereits in der Proxy-Whitelist (lib/Proxy.php) eingetragen.

Wetter-Daten via Open-Meteo / Bright Sky (DWD)

// Aktuelles Wetter für Berlin via Open-Meteo
const omUrl = 'https://api.open-meteo.com/v1/forecast'
    + '?latitude=52.52&longitude=13.405&current=temperature_2m,weather_code&timezone=auto';
const omData = await fetch(vmProxyUrl(omUrl)).then(r => r.json());
console.log('Berlin:', omData.current.temperature_2m, '°C');

// Aktuelles DWD-Wetter für Hamburg via Bright Sky
const bsUrl = 'https://api.brightsky.dev/current_weather?lat=53.55&lon=10.0';
const bsData = await fetch(vmProxyUrl(bsUrl)).then(r => r.json());
console.log('Hamburg:', bsData.weather.temperature, '°C', bsData.weather.condition);

Beide Dienste sind bereits in der Proxy-Whitelist eingetragen (api.open-meteo.com, api.brightsky.dev).


Themes

Fünf eingebaute Themes stehen sofort zur Verfügung:

Theme Attribut Beschreibung
Standard (leer) Helles Standardlayout (OpenFreeMap Liberty)
dark theme="dark" Dunkles Layout
redaxo theme="redaxo" REDAXO-Backend-Farben (Blau/Neutral)
bright theme="bright" Leuchtendes, kontrastreiches Layout
warm theme="warm" Warmes Orange-/Beigelayout
mono theme="mono" Graustufen-Layout

Eigene Themes können im Backend unter Vector Maps → Themes angelegt und live per Theme-Editor konfiguriert werden. Die Routing-Linienfarbe (route_line) lässt sich ebenfalls pro Theme einstellen.

Theme-Fade-in

Bei Karten mit einem Theme (theme="..." oder map-style="<eigener-name>") bleibt die Karte zunächst unsichtbar und blendet sich sanft ein, sobald das Theme vollständig geladen und angewendet wurde. Das verhindert das kurze Aufblitzen des ungestylten Grundstils ("Flash of Unstyled Map").

Die Einblend-Dauer ist per Attribut steuerbar:

<!-- Standard: 350 ms -->
<vectormap map-style="klxm" height="400px"></vectormap>

<!-- Langsam: 800 ms -->
<vectormap map-style="klxm" theme-transition="800" height="400px"></vectormap>

<!-- Sofort (kein Fade): 0 ms -->
<vectormap map-style="klxm" theme-transition="0" height="400px"></vectormap>

Marker-Format

Marker werden als JSON-Array übergeben:

<vectormap lat="51.43" lng="6.77" zoom="12"
    markers='[
        {"lat":51.4298,"lng":6.7742,"popup":"<strong>Duisburg HBF</strong>"},
        {"lat":51.4539,"lng":6.7658,"popup":"Duisburg Zoo","color":"#e74c3c"}
    ]'>
</vectormap>

Unterstützte Marker-Eigenschaften:

Eigenschaft Beschreibung
lat, lng Position (erforderlich)
popup Popup-Inhalt (HTML erlaubt)
color Marker-Farbe für Standard-Pin (CSS-Farbwert, Standard: #2b7095)
icon URL zu einem Bild (PNG, SVG, WebP) → Custom-Pin als <img>
html Beliebiger HTML-String, Emoji oder SVG → Custom-Pin als HTML-Element
size [breite, höhe] in px für icon-Marker, z. B. [40, 48] (Standard: 32×32)
anchor Ankerpunkt des Custom-Pins: bottom (Standard), center, top, left, right

Custom Pins / Individuelle Marker

Jeder Marker kann als individueller Pin gestaltet werden – per Emoji, SVG, HTML-Div oder externem Bild:

<!-- Emoji-Pins -->
<vectormap lat="51.43" lng="6.77" zoom="13"
    markers='[
        {"lat":51.4298,"lng":6.7742,"html":"🚉","anchor":"center","popup":"Bahnhof"},
        {"lat":51.4339,"lng":6.7621,"html":"🏛️","anchor":"center","popup":"Museum"},
        {"lat":51.4218,"lng":6.7660,"html":"🏬","anchor":"center","popup":"Einkauf"}
    ]'>
</vectormap>

<!-- HTML-Div-Pins mit eigenem CSS -->
<vectormap lat="51.43" lng="6.77" zoom="13"
    markers='[
        {"lat":51.4298,"lng":6.7742,
         "html":"<div class=\"mein-pin mein-pin--rot\">A</div>",
         "popup":"Punkt A"}
    ]'>
</vectormap>

<!-- Icon-URL (SVG/PNG) mit benutzerdefinierter Größe -->
<vectormap lat="51.43" lng="6.77" zoom="13"
    markers='[
        {"lat":51.4298,"lng":6.7742,
         "icon":"/assets/custom/pin.svg",
         "size":[40,48],
         "anchor":"bottom",
         "popup":"Unser Standort"}
    ]'>
</vectormap>

Custom-Marker (icon / html) nutzen intern MapLibres element-Option und sind vollständig per CSS gestaltbar. Im Cluster-Modus werden sie als Standard-GeoJSON-Punkte dargestellt.


Externes GeoJSON

Mit dem geojson-Attribut können externe oder inline GeoJSON-Daten direkt auf der Karte angezeigt werden. Unterstützt werden Punkte, Linien und Flächen (auch gemischt in einer FeatureCollection).

<!-- Relative URL (wird direkt geladen) -->
<vectormap lat="51.43" lng="6.77" zoom="10"
    geojson="/assets/karte-data.geojson"
    geojson-color="#27ae60"
    geojson-popup="name">
</vectormap>

<!-- Externe URL (wird automatisch über den REDAXO-Proxy geleitet) -->
<vectormap lat="51.43" lng="6.77" zoom="6"
    geojson="https://example.com/data.geojson"
    geojson-color="#e74c3c"
    geojson-opacity="0.4"
    geojson-popup="description">
</vectormap>

<!-- Inline-JSON (kein Server-Request) -->
<vectormap lat="51.434" lng="6.763" zoom="14"
    geojson='{"type":"FeatureCollection","features":[
        {"type":"Feature","properties":{"name":"Innenhafen"},"geometry":{"type":"Polygon","coordinates":[...]}},
        {"type":"Feature","properties":{"name":"Museum"},"geometry":{"type":"Point","coordinates":[6.762,51.434]}}
    ]}'
    geojson-color="#2980b9"
    geojson-opacity="0.25">
</vectormap>

GeoJSON-Attribute

Attribut Standard Beispiel Beschreibung
geojson geojson="/data.geojson" Relative/absolute URL oder Inline-JSON-String
geojson-color #2b7095 geojson-color="#e74c3c" Standardfarbe für Punkte, Linien und Flächen
geojson-opacity 0.3 geojson-opacity="0.5" Transparenz der Flächen-Füllung (0–1)
geojson-popup (alle) geojson-popup="name" Property-Name für Klick-Popup; leer = automatische Tabelle aller Properties

geojson und markers lassen sich kombinieren — GeoJSON-Layer und individuelle Marker erscheinen gleichzeitig auf der Karte.

Individuelle Marker-Pins via GeoJSON (Simplestyle)

Punkte können pro Feature individuell gestaltet werden — direkt über GeoJSON-Properties ohne zusätzliche Attribute:

<vectormap lat="51.434" lng="6.763" zoom="13"
    geojson='{
        "type": "FeatureCollection",
        "features": [
            {
                "type": "Feature",
                "properties": {
                    "name": "Ladestation",
                    "Betreiber": "Stadtwerke",
                    "marker-color": "#27ae60",
                    "marker-symbol": "⚡"
                },
                "geometry": { "type": "Point", "coordinates": [6.763, 51.434] }
            },
            {
                "type": "Feature",
                "properties": {
                    "name": "Museum",
                    "marker-color": "#8e44ad",
                    "marker-symbol": "🏛"
                },
                "geometry": { "type": "Point", "coordinates": [6.770, 51.430] }
            },
            {
                "type": "Feature",
                "properties": { "name": "Stadtpark" },
                "geometry": {
                    "type": "Polygon",
                    "coordinates": [[[6.760, 51.435],[6.780, 51.435],[6.780, 51.425],[6.760, 51.425],[6.760, 51.435]]]
                }
            }
        ]
    }'
    geojson-color="#2980b9"
    geojson-opacity="0.25"
    geojson-popup="name">
</vectormap>

Simplestyle-Properties (pro GeoJSON-Feature, nur für Punkte):

Property Beispiel Beschreibung
marker-color "#e74c3c" Pin-Farbe — überschreibt geojson-color für diesen Punkt
marker-symbol "⚡" "🏥" "A" Emoji oder Text-Zeichen im Pin. Ohne Angabe: Standard-Farb-Pin

Flächen und Linien nutzen weiterhin geojson-color und geojson-opacity global.

In PHP lässt sich das komfortabel mit json_encode() aufbauen:

$locations = [
    ['name' => 'Rathaus',    'lat' => 51.434, 'lng' => 6.762, 'symbol' => '🏛', 'color' => '#8e44ad'],
    ['name' => 'Ladestation','lat' => 51.437, 'lng' => 6.770, 'symbol' => '', 'color' => '#27ae60'],
    ['name' => 'Parkplatz',  'lat' => 51.431, 'lng' => 6.758, 'symbol' => '🅿', 'color' => '#2980b9'],
];

$features = array_map(static function(array $loc): array {
    return [
        'type'       => 'Feature',
        'properties' => [
            'name'          => $loc['name'],
            'marker-color'  => $loc['color'],
            'marker-symbol' => $loc['symbol'],
        ],
        'geometry' => [
            'type'        => 'Point',
            'coordinates' => [$loc['lng'], $loc['lat']],
        ],
    ];
}, $locations);

$geoJson = json_encode(['type' => 'FeatureCollection', 'features' => $features]);

echo '<vectormap lat="51.434" lng="6.763" zoom="13"'
   . ' geojson=\'' . rex_escape($geoJson) . '\''
   . ' geojson-popup="name">'
   . '</vectormap>';

Backend-Koordinatenpicker

Für REDAXO-Module kann ein Koordinatenpicker aktiviert werden, der ein einfaches Eingabefeld mit Kartenpicker-Button ausstattet.

Im Modul-Input

<div class="form-group">
    <label>Koordinaten</label>
    <input type="text"
        name="REX_INPUT_VALUE[1]"
        value="REX_VALUE[1]"
        class="form-control"
        data-vector-picker="1"
        placeholder="lat,lng">
</div>

Durch data-vector-picker="1" erscheint neben dem Feld ein Karten-Button. Beim Klick öffnet sich ein Modal mit einer Vollbild-Karte, Adresssuche (Autocomplete via Nominatim) und Koordinatenübernahme per Klick oder Suche.

Im Modul-Output

<vectormap lat="REX_VALUE[1]" lng="REX_VALUE[2]" zoom="14"
    markers='[{"lat":REX_VALUE[1],"lng":REX_VALUE[2],"popup":"Unser Standort"}]'>
</vectormap>

Alternativ: lat,lng aus einem einzelnen Feld parsen:

<?php
$coords = explode(',', 'REX_VALUE[1]');
$lat = trim($coords[0] ?? '51.5');
$lng = trim($coords[1] ?? '7.0');
?>
<vectormap lat="<?= $lat ?>" lng="<?= $lng ?>" zoom="14"></vectormap>

Proxy-Architektur (DSGVO)

Alle externen Dienste werden über den internen PHP-Proxy geleitet, sodass keine IP-Adressen der Websitebesucher an Dritte übertragen werden:

Dienst Verwendung
OpenFreeMap Vektorkacheln (Karte)
Nominatim / OpenStreetMap Adresssuche (Geocoding)
OSRM Routing (Fahrt-, Fuß-, Radwege)
Overpass API POI-Suche & dynamisches Datennachladen
Open-Meteo Weltweite Wettervorhersage (kostenlos, kein API-Key)
Bright Sky / DWD Deutsche Wetterdaten (DWD Open Data, Server in DE)
Esri ArcGIS / World Imagery Satellitenbilder (Raster-Tiles)

Der Proxy unter lib/Proxy.php validiert alle Anfragen gegen eine Whitelist und leitet nur Anfragen an erlaubte Domains weiter. SSRF-Attacks werden durch strikte Domain-Prüfung verhindert.

Whitelist erweitern

Per Extension Point (andere AddOns):

rex_extension::register('VECTOR_MAPS_PROXY_DOMAINS', static function(rex_extension_point $ep): array {
    $list = $ep->getSubject();
    $list[] = 'https://my-tiles.example.com/';
    return $list;
});

Per Backend-Einstellungen (manuell): Unter Vector Maps → Einstellungen → Proxy: Zusätzliche erlaubte Domains können URL-Präfixe (eine pro Zeile) hinterlegt werden.


Vollständiges Beispiel

<vectormap
    lat="51.4298"
    lng="6.7742"
    zoom="14"
    height="500px"
    theme="dark"
    3d
    interactive
    locate
    markers='[
        {"lat":51.4298,"lng":6.7742,"popup":"<strong>Duisburg Hauptbahnhof</strong><br>Bahnhofsvorplatz, 47119 Duisburg","color":"#3498db"}
    ]'
    route-from="51.4298,6.7742"
    route-to="51.4539,6.7658"
    route-mode="walking">
</vectormap>

Backend-Seiten

Seite Beschreibung
Demo Interaktive Übersicht aller Features mit Live-Beispielen
Themes Theme-Editor zum Erstellen und Anpassen benutzerdefinierter Themes (inkl. Routing-Linienfarbe)
Einstellungen Frontend-Einbindung, Proxy-Whitelist (manuelle Domains), Tile-Cache verwalten

Voraussetzungen

  • REDAXO >= 5.14
  • PHP >= 8.1
  • PHP-Extensions: curl, json

Build-System (Entwicklung)

Der build/-Ordner enthält das Build-Tooling für Entwickler. Für den normalen Einsatz des AddOns wird kein Build-Schritt benötigt — alle kompilierten Assets liegen bereits fertig im Repository.

Ordnerstruktur

vector_maps/
├── assets/
│   ├── build/                   # Eigene Assets (Quelle + kompiliert)
│   │   ├── vectormaps.js        # Quelle: <vectormap> Web Component + Picker
│   │   ├── vectormaps.min.js    # Minifiziert (vom Build generiert)
│   │   ├── vectormaps_i18n.js   # Quelle: Frontend-Übersetzungen
│   │   ├── vectormaps_i18n.min.js
│   │   ├── theme-editor.js      # Quelle: Backend Theme-Editor
│   │   ├── theme-editor.min.js
│   │   ├── vectormaps.css       # Quelle: Styles
│   │   └── vectormaps.min.css   # Minifiziert (vom Build generiert)
│   └── maplibre/                # Vendor-Assets (von npm kopiert)
│       ├── maplibre-gl.js       # MapLibre GL JS
│       ├── maplibre-gl.css      # MapLibre GL JS Styles
│       └── pmtiles.js           # PMTiles-Decoder
├── build/                       # Build-Tooling (nicht im Release-ZIP)
│   ├── package.json             # npm-Abhängigkeiten (esbuild, maplibre-gl, pmtiles)
│   └── build.mjs                # Build-Script
└── .github/
    └── workflows/
        └── release.yml          # GitHub Actions: Release-ZIP auf Tag-Push

build/node_modules/ und *.map-Dateien sind per .gitignore ausgeschlossen und landen nicht im Release-ZIP.

Voraussetzungen

  • Node.js >= 18
  • npm

Setup

cd vector_maps/build
npm install

Befehle

Befehl Beschreibung
npm run build Eigene Assets (assets/build/) minifizieren
npm run build:all Vendor-Assets aus npm aktualisieren und eigene Assets minifizieren
npm run watch Watch-Modus: automatisch neu bauen bei Dateiänderungen (+ Source Maps)

Eigene Assets minifizieren

cd build
npm run build

Erzeugt *.min.js / *.min.css aus den Quelldateien in assets/build/.

Vendor-Assets aktualisieren (z. B. neues MapLibre-Release)

cd build
npm install                 # package.json aktualisieren falls nötig
npm run build:all

Kopiert die Distributionsdateien aus node_modules/maplibre-gl/dist/ und node_modules/pmtiles/dist/ nach assets/maplibre/ und baut anschließend alle eigenen Assets.

Watch-Modus (Entwicklung)

cd build
npm run watch

Überwacht alle Quelldateien in assets/build/ und kompiliert auf Änderungen sofort neu. Im Watch-Modus werden zusätzlich Source Maps (.map) generiert — sie sind per .gitignore ausgeschlossen und landen nicht im Repository.

Release

Releases werden automatisch per GitHub Actions erstellt, wenn ein Tag (v*.*.*) gepusht wird:

git tag v1.1.0
git push origin v1.1.0

Der Workflow (release.yml) installiert npm-Abhängigkeiten, baut alle Assets (npm run build:all) und erstellt ein Release-ZIP ohne den build/-Ordner, node_modules, .map-Dateien und andere Dev-Artefakte.


Credits

  • MapLibre GL JS – Open-Source-Kartenbibliothek (BSD-2-Clause)
  • OpenFreeMap – Kostenlose Vektorkacheln ohne API-Key
  • Nominatim / OSM – Adress-Geocoding (ODbL)
  • OSRM – Open Source Routing Machine (BSD-2-Clause)
  • Overpass API – OSM-Datenbankabfragen (AGPL)
  • Open-Meteo – Kostenlose Wetter-API, kein API-Key (CC BY 4.0)
  • Bright Sky – DWD-Wetterdaten für Deutschland (CC BY 4.0)

Lizenz

MIT License – siehe LICENSE.md

Entwickelt von KLXM Crossmedia

About

REDAXO AddOn Vector Maps :: MapLibre GL JS OpenFreeMap

Resources

License

Stars

4 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors