Skip to content

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)

Kartenstil & Theme fest einstellen (Frontend & Backend)

Die Stil-/Theme-Buttons in den Demo-Seiten sind nur eine Live-Vorschau im Browser und speichern nichts. Um z. B. dauerhaft Positron als Basisstil mit dem Theme dark zu verwenden, wird das an der jeweiligen Einbindungsstelle per Attribut bzw. Feld festgelegt:

KontextWie einstellen
<vectormap>-Tag (Frontend: Template, Modul, Artikel)map-style="positron" theme="dark" als HTML-Attribute direkt am Tag
Builder-Element „Vector Map"Im Element-Tab Karte die Felder Kartenstil und Theme je Slice auswählen
YForm-Feld vector_map_location4. und 5. Schema-Parameter: value|vector_map_location|name|label|positron|dark|1
Allgemeiner Geodaten-Picker (data-vector-picker)data-vector-picker-style="positron" data-vector-picker-theme="dark" bzw. PickerWidget::factory(...)->setMapStyle('positron')->setTheme('dark')

Frontend-Beispiel:

<vectormaplat="51.43" lng="6.77" zoom="13" map-style="positron" theme="dark" height="400px"></vectormap>

map-style bestimmt den Basis-Kartenstil (liberty, bright, positron, satellite oder ein eigener Theme-Name als Basisstil), theme legt zusätzlich eine Farbpalette (dark, redaxo, bright, warm, mono oder ein selbst im Theme-Editor angelegtes Theme) über diesem Basisstil fest. satellite ist ein Rasterbild und unterstützt daher kein Theme.


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 --><vectormaplat="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]);
?><vectormaplat="<?= $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:

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

Optional per PHP-Helper:

<?phpecho \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 --><vectormaplat="51.51" lng="-0.12" zoom="12"></vectormap><!-- Mit Markern und Popup --><vectormaplat="51.51" lng="-0.12" zoom="13"
markers='[{"lat":51.51,"lng":-0.12,"popup":"London"}]'></vectormap><!-- Vollbreite, 3D, Dark-Theme --><vectormaplat="48.85" lng="2.35" zoom="15"
height="500px" theme="dark" 3d></vectormap>

Alle Attribute

AttributStandardBeispielBeschreibung
lat51.505lat="51.51"Breitengrad des Kartenzentrums
lng7.0lng="-0.12"Längengrad des Kartenzentrums
centercenter="51.51,-0.12"Kartenmitte als lat,lng (Alternative zu lat+lng)
zoom6zoom="15"Anfangszoomstufe (0–22)
height400height="600px"CSS-Höhe des Karten-Containers
pitch0pitch="45"Kamerakippung in Grad (0–60)
bearing0bearing="45"Kartenausrichtung in Grad
map-stylelibertymap-style="satellite"OFM-Stilname: liberty, bright, positron, satellite (ESRI World Imagery) – oder Theme-Name
show-satellitefalseshow-satelliteToggle-Button zum Wechsel zwischen Vektor- und Satellitenbild (ESRI World Imagery, kein API-Key)
themetheme="dark"Farb-Theme: dark, warm, mono oder eigener Theme-Name
theme-transition350theme-transition="600"Einblend-Dauer in ms nach Theme-Load (0 = sofort, Standard: 350)
languagedelanguage="en"Sprachcode für Kartenbeschriftungen (ISO 639-1)
markersmarkers='[{"lat":51.51,"lng":-0.12}]'JSON-Array mit Marker-Objekten
fit-boundsautofit-bounds="false"Kartenausschnitt an alle Marker anpassen. Standard: aktiv bei mehreren Markern; mit fit-bounds="false" deaktivieren
clusterfalseclusterMarker bei hoher Dichte clustern
3dfalse3d3D-Gebäude aktivieren
interactivetrueinteractive="false"Karte scrollbar/zoombar (Standard: aktiv). Mit interactive="false" deaktivieren
locatefalselocateStandort-Button anzeigen
fullscreenfalsefullscreenFullscreen-Button anzeigen (Karte im Browser-Vollbild umschalten)
controls-positiontop-rightcontrols-position="top-left"Position der MapLibre-Navigation (top-left, top-right, bottom-left, bottom-right)
controls-clusterrightcontrols-cluster="left"Einfacher Shortcut für sinnvolle Defaults: clustert Navigation + Locate/Satellit gemeinsam (left, right, oder direkte Ecke wie bottom-left)
controls-stylecontrols-style="rail"Vorgefertigte UI-Stile für Navigation/Kompass/Fullscreen plus Locate/Satellit: soft, rail, minimal, bold
fullscreen-positionwie controls-positionfullscreen-position="bottom-right"Position des Fullscreen-Buttons
no-navigationfalseno-navigationZoom-/Kompass-Controls ausblenden
no-attributionfalseno-attributionAttributionszeile ausblenden
buttons-positionwie controls-positionbuttons-position="top-left"Basisposition für locate/show-satellite Buttons
locate-positionwie buttons-positionlocate-position="bottom-left"Individuelle Position des Locate-Buttons
satellite-positionwie buttons-positionsatellite-position="top-left"Individuelle Position des Satellit-Buttons
buttons-offset10buttons-offset="16"Außenabstand der Overlay-Buttons in px
buttons-gap38buttons-gap="44"Vertikaler Abstand zwischen Locate- und Satelliten-Button in derselben Ecke
popup-focus-modeautopopup-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-htmlinfo-html="<strong>Info</strong>"Globales Infofenster innerhalb der Karte (HTML erlaubt)
info-positiontop-leftinfo-position="bottom-right"Position des Infofensters (top-left, top-right, bottom-left, bottom-right)
info-offset12info-offset="20"Außenabstand des Infofensters in px
info-classinfo-class="my-info-box"Zusätzliche CSS-Klasse für eigenes Styling
info-visibletrueinfo-visible="false"Infofenster ein-/ausblenden
info-closablefalseinfo-closableSchließen-Button im Infofenster anzeigen
route-panel-positiontop-leftroute-panel-position="bottom-right"Position des Route-Panels
route-panel-offset12route-panel-offset="18"Außenabstand des Route-Panels in px
route-panel-styleroute-panel-style="glass"Vorgefertigte Panel-Skins: glass, contrast, brand
route-panel-layoutoverlayroute-panel-layout="side-right"Layout des Route-Panels: overlay (in der Karte), side-right, side-left
route-panel-width340route-panel-width="360"Breite der Seiten-Spalte bei side-right/side-left
fly-tofly-to="48.85,2.35"Kartenansicht nach dem Laden animiert zentrieren
min-zoom0min-zoom="5"Minimaler Zoom-Level
max-zoom22max-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):

<vectormapcenter="51.165691,10.451526"
zoom="6"
locateshow-satellitefullscreen></vectormap>

Einfach komplett nach links clustern:

<vectormapcenter="51.165691,10.451526"
zoom="6"
locateshow-satellitefullscreencontrols-cluster="left"></vectormap>

Manuell trennen (optional):

<vectormapcenter="51.165691,10.451526"
zoom="6"
locateshow-satellitecontrols-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

<vectormapcenter="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">

<vectormapcenter="51.43,6.77" zoom="12" height="380"><divclass="mapinfo" data-position="top-left" data-closabledata-class="my-info-box"><strong>Kontakt</strong><br>
Mo-Fr 08:00-18:00<br><ahref="/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)

<vectormapcenter="52.520008,13.404954"
zoom="12"
height="420"
locateshow-satellitefullscreencontrols-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)

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

3) Routing-Seite (Panel als echte Spalte)

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

Control-Design per CSS-Variablen

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

<vectormaplocateshow-satellitefullscreencontrols-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:010px26pxrgba(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:010px26pxrgba(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><vectormapclass="vm-skin-signature-editorial"
locateshow-satellitefullscreencontrols-position="top-left"
buttons-position="top-left"
route-panelroute-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:012px28pxrgba(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:012px28pxrgba(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><vectormapclass="vm-skin-signature-transit"
locateshow-satellitefullscreencontrols-position="top-right"
buttons-position="top-right"
route-panelroute-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 --><vectormaplat="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 --><vectormaplat="48.85" lng="2.35" zoom="6"
route-from="Eiffelturm, Paris"
route-to="Duisburg Hauptbahnhof"
route-mode="driving"></vectormap>

Routing-Attribute

AttributStandardBeispielBeschreibung
route-fromroute-from="51.43,6.77"Startpunkt: lat,lng oder Adresse als Text
route-toroute-to="51.45,6.76"Zielpunkt: lat,lng oder Adresse als Text
route-modedrivingroute-mode="walking"Routing-Profil: driving, walking, cycling
route-panelfalseroute-panelInteraktives Von/Nach-Panel auf der Karte einblenden
route-to-lockedfalseroute-to-lockedZieladresse im Panel fixieren – nicht editierbar, kein Autocomplete
route-to-popuproute-to-popup="Firmenname<br>firmenname.de"Eigener Popup-Inhalt (HTML) am Ziel-Marker, wenn nur route-to gesetzt ist
route-no-stepsfalseroute-no-stepsAbbiegehinweise (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:

<vectormaplat="51.43" lng="6.77" zoom="13"
height="500px" interactiveroute-panelroute-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:

<vectormaplat="51.4298" lng="6.7742" zoom="12"
height="450px"
interactiveroute-panelroute-to="Duisburg Hauptbahnhof"
route-to-lockedroute-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:

<vectormapheight="500px"
route-panelroute-to="Am Schürmannshütt 40g, 47441 Moers"
route-to-popup="<strong>KLXM Crossmedia GmbH</strong><br>klxm.de"
route-to-lockedroute-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 --><vectormaplat="48.858844" lng="2.294351" zoom="16" height="400px"
map-style="satellite"><markerlat="48.858844" lng="2.294351" popup="Eiffelturm"></marker></vectormap><!-- Vektor-Karte mit Toggle-Button für Satellitenansicht --><vectormaplat="52.520008" lng="13.404954" zoom="13" height="400px"
show-satellite><markerlat="52.520008" lng="13.404954" popup="Brandenburger Tor"></marker></vectormap>
StilBeschreibung
satelliteReines Satellitenbild (ESRI World Imagery)
show-satelliteToggle-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:

<vectormapcenter="52.52,13.405"
zoom="12"
height="420"
locateshow-satellitebuttons-position="top-left"
route-panelroute-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:

constel=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):

<vectormapcenter="51.43,6.77" zoom="12"><divclass="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 --><vectormaplat="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 --><vectormaplat="51.43" lng="6.77" zoom="13"
height="500px"
nearby="shop=supermarket|shop=discount"
nearby-locate></vectormap>

Nearby-Attribute

AttributStandardBeispielBeschreibung
nearbynearby="amenity=restaurant"Overpass-Filter (key=value), mehrere mit | trennen
nearby-radius1000nearby-radius="2000"Suchradius in Metern
nearby-labelOSM-Tagsnearby-label="Restaurant"Fallback-Label für Popups (wenn kein OSM-Name)
nearby-locatefalsenearby-locateNutzerstandort (Geolokalisierung) als Suchmittelpunkt verwenden

Häufige Overpass-Filter

FilterBeschreibung
amenity=charging_stationE-Ladestationen
amenity=fuelTankstellen
amenity=restaurantRestaurants
amenity=cafeCafés
amenity=pharmacyApotheken
amenity=hospitalKrankenhäuser
amenity=bankBanken
shop=supermarketSupermärkte
shop=supermarket|shop=discountSupermärkte und Discounter
leisure=parkParks
tourism=hotelHotels
tourism=museumMuseen

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>-Elementsconstel=document.getElementById('meine-karte');constmap=el._vmMap;// nach dem 'load'-Event verfügbar// GeoJSON-Source + Layer anlegenmap.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)lettimer;map.on('moveend',()=>{clearTimeout(timer);timer=setTimeout(async()=>{if(map.getZoom()<9)return;// erst ab Zoom 9 ladenconstb=map.getBounds();constq=`[out:json][timeout:10];`+`node["amenity"="charging_station"]`+`(${b.getSouth()},${b.getWest()},${b.getNorth()},${b.getEast()});`+`out 200;`;constdata=awaitfetch(vmProxyUrl('https://overpass-api.de/api/interpreter?data='+encodeURIComponent(q))).then(r=>r.json());constfeatures=(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-MeteoconstomUrl='https://api.open-meteo.com/v1/forecast'+'?latitude=52.52&longitude=13.405&current=temperature_2m,weather_code&timezone=auto';constomData=awaitfetch(vmProxyUrl(omUrl)).then(r=>r.json());console.log('Berlin:',omData.current.temperature_2m,'°C');// Aktuelles DWD-Wetter für Hamburg via Bright SkyconstbsUrl='https://api.brightsky.dev/current_weather?lat=53.55&lon=10.0';constbsData=awaitfetch(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:

ThemeAttributBeschreibung
Standard(leer)Helles Standardlayout (OpenFreeMap Liberty)
darktheme="dark"Dunkles Layout
redaxotheme="redaxo"REDAXO-Backend-Farben (Blau/Neutral)
brighttheme="bright"Leuchtendes, kontrastreiches Layout
warmtheme="warm"Warmes Orange-/Beigelayout
monotheme="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 --><vectormapmap-style="klxm" height="400px"></vectormap><!-- Langsam: 800 ms --><vectormapmap-style="klxm" theme-transition="800" height="400px"></vectormap><!-- Sofort (kein Fade): 0 ms --><vectormapmap-style="klxm" theme-transition="0" height="400px"></vectormap>

Marker-Format

Marker werden als JSON-Array übergeben:

<vectormaplat="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:

EigenschaftBeschreibung
lat, lngPosition (erforderlich)
popupPopup-Inhalt (HTML erlaubt)
colorMarker-Farbe für Standard-Pin (CSS-Farbwert, Standard: #2b7095)
iconURL zu einem Bild (PNG, SVG, WebP) → Custom-Pin als <img>
htmlBeliebiger 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)
anchorAnkerpunkt 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 --><vectormaplat="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 --><vectormaplat="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 --><vectormaplat="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) --><vectormaplat="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) --><vectormaplat="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) --><vectormaplat="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

AttributStandardBeispielBeschreibung
geojsongeojson="/data.geojson"Relative/absolute URL oder Inline-JSON-String
geojson-color#2b7095geojson-color="#e74c3c"Standardfarbe für Punkte, Linien und Flächen
geojson-opacity0.3geojson-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:

<vectormaplat="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):

PropertyBeispielBeschreibung
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(staticfunction(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

<divclass="form-group"><label>Koordinaten</label><inputtype="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

<vectormaplat="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:

DienstVerwendung
OpenFreeMapVektorkacheln (Karte)
Nominatim / OpenStreetMapAdresssuche (Geocoding)
OSRMRouting (Fahrt-, Fuß-, Radwege)
Overpass APIPOI-Suche & dynamisches Datennachladen
Open-MeteoWeltweite Wettervorhersage (kostenlos, kein API-Key)
Bright Sky / DWDDeutsche Wetterdaten (DWD Open Data, Server in DE)
Esri ArcGIS / World ImagerySatellitenbilder (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', staticfunction(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

<vectormaplat="51.4298"
lng="6.7742"
zoom="14"
height="500px"
theme="dark"
3dinteractivelocatemarkers='[ {"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

SeiteBeschreibung
DemoInteraktive Übersicht aller Features mit Live-Beispielen
ThemesTheme-Editor zum Erstellen und Anpassen benutzerdefinierter Themes (inkl. Routing-Linienfarbe)
EinstellungenFrontend-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

BefehlBeschreibung
npm run buildEigene Assets (assets/build/) minifizieren
npm run build:allVendor-Assets aus npm aktualisieren und eigene Assets minifizieren
npm run watchWatch-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


Lizenz

MIT License – siehe LICENSE.md

Entwickelt von KLXM Crossmedia

About

REDAXO AddOn Vector Maps :: MapLibre GL JS OpenFreeMap

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages