Leaflet Maps
Manuell eingebunden - ohne zusätzliche Contao-Extension.
Ausgehend von: Tipp von Franko im Contao-Forum
Weitere Quellen:
- Leaflet-Dokumentation
- Selfhtml - Einstieg in Leaflet
- https://kau-boys.de/4653/webentwicklung/verwende-marker-auf-deinem-eigenen-bild-mit-leaflet
Längengrad und Breitengrad herausfinden:
- Mit dem Koordinaten Picker - das geht direkt hier - einfach Doppelklick auf die Karte
Der Picker kann in der Datei files/js/leafletmap.js deaktiviert werden. - https://www.laengengrad-breitengrad.de/
- oder auch mit Geojson, das noch weitere Funktionen bietet.
Es werden verschiedene Kartenlayer definiert, die rechts oben mit dem Layer-Icon aktiviert werden:
- OSM Straßenkarte
- topographische Karte
- Satellit
und ein Fullscreen Plugin wird eingebaut.
Howto
Download Leaflet Library
Leaflet herunterladen und z.B. nach files/leaflet entpacken - Ordner veröffentlichen.
Für die Fullscreen Darstellung gibt es unter anderen z.B. dieses Plugin:
Download Fullscreen Plugin für Openstreetmap von Codeworld
Das Plugin herunterladen und nach files/leaflet/fullscreen entpacken.
Zunächst etwas CSS (SCSS)
- Leaflet und das Fullscreen Plugin bringen jeweils eigene CSS Dateien mit, die im weiter unten stehenden Template eingebunden werden.
- Da ich aber einige Selektoren ändern möchte, überschreibe ich diese in meinem eigenen CSS:
- Wichtig ist eine Höhenangabe im .leaflet-container, weil sonst die Karte nicht angezeigt wird.
Hinweis: Folgende CSS Anweisungen gelten speziell für diese Website. Darum nicht einfach kopieren sondern nur als Idee für das eigene CSS nutzen.
// _leaflet_map.scss
// osmblocker oveleon-cookiebar
.osmblocker {
width: calc(100% - 2*var(--marg));
margin: 0 auto;
}
.button.osm {
margin: 0 var(--marg);
}
// map
#map {
margin-bottom: var(--margin-bottom);
}
.leaflet-container {
z-index: var(--zindex-leaflet);
height: calc(90vh - 50px);
max-height: 700px;
width: calc(100% - var(--marg));
margin: 0 auto;
background: var(--white);
font-family: var(--font-default) !important;
font-size: 1.3rem !important;
@include respond-above(md) {
height: 80vh;
max-width: 1800px;
}
/* hr im Leaflet-popup */
hr {
margin: 5px 0;
}
}
.leaflet-control,
.leaflet-bottom,
.leaflet-top {
z-index: var(--zindex-leaflet);
}
.leaflet-top {
bottom: 3rem !important;
}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: var(--white);
width: auto;
}
.leaflet-popup-content {
p {margin: 0 !important;}
}
/* Stellt die Karten in Grautönen dar
.leaflet-tile-pane {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
*/
Zwei Javascript-Dateien anlegen
und in files/js speichern:
- files/js/osmblocker.js
für die Anbindung an die oveleon/contao-cookiebar - files/js/leafletmap.js
für die Darstellung der Karten
// files/js/osmblocker.js
document.addEventListener("DOMContentLoaded", function() {
cookiebar.addModule(6, initializeLeaflet, {
selector: '#map',
message: '<div class="osmblocker bg blue block"><p class="h3">Hier soll eine Karte gezeigt werden</p><p>Für die Kartendarstellungen nutzen wir fremde Dienste, die von externen Servern geladen werden. Dafür benötigen wir Ihre Zustimmung.<br>Sie können in den <a href="javascript:cookiebar.show(true);" title="Cookie-Settings" class="linkshield">Cookie Einstellungen</a> die Details einsehen und dort auch die Zustimmung jederzeit wieder ändern.</p></div>',
button: {
show: true,
text: 'Zustimmen und Karte ansehen.',
classes: 'button osm'
}
});
});
Anbindung an die Oveleon Cookiebar Extension
Auf die Oveleon Cookiebar gehe ich hier nicht näher ein, dafür gibt es bereits mehrere Threads im Contao-Forum.
Im Zusammenhang mit der OSM Karte ist wichtig, dass ganz oben in der files/js/osmblocker.js bei
cookiebar.addModule(6, initializeLeaflet, {...
die ID des entsprechenden Oveleon-Cookiebar-Eintrages steht. Hier in meinem Fall ist das die ID 6.
// files/js/leafletmap.js
function initializeLeaflet() {
// Layer definieren
var osm = L.tileLayer('https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', {
'attribution': 'Kartendaten © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
maxZoom: 19,
useCache: true
});
var opentopo = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
maxZoom: 17,
attribution: 'Kartendaten: © OpenStreetMap-Mitwirkende, SRTM | Kartendarstellung: © <a href="https://opentopomap.org/about">OpenTopoMap</a> (CC-BY-SA)'
});
var satellit = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
maxZoom: 18,
attribution: 'Map data © <a href="https://www.esri.com/">Esri</a>, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
});
var map = L.map('map', {
layers: osm,
tap: false,
fullscreenControl: true,
});
L.control.scale({imperial:false}).addTo(map); // imperial:false zeigt nur den metrischen Maßstab
var baseLayers = {
"OpenStreetMap": osm,
"OpenTopoMap": opentopo,
"Satellit": satellit
};
L.control.layers(baseLayers).addTo(map);
// Kartenausschnitt festlegen
var bounds = [ [47.50013976186046,9.732603475826199], [47.513192289950354,9.757662053958269] ];
map.fitBounds( bounds );
// Zentriert die Marker on resize
// map.on("resize", function(e){
// map.fitBounds( bounds );
// });
// Position von Markericon, etc. festlegen -->
var customIcon = L.Icon.extend({
options: {
shadowUrl: 'files/leaflet/images/marker-shadow.png',
iconSize: [25, 45],
iconAnchor: [12, 45],
popupAnchor: [1, -43],
tooltipAnchor: [16, -28],
shadowSize: [41, 45]
}
})
// eigene Marker Icons festlegen
var blackIcon = new customIcon({ iconUrl: 'files/theme/design/marker/marker-black.png', iconRetinaUrl: 'files/theme/design/marker/marker-black-2x.png' })
var blueIcon = new customIcon({ iconUrl: 'files/theme/design/marker/marker-blue.png', iconRetinaUrl: 'files/theme/design/marker/marker-blue-2x.png' })
var redIcon = new customIcon({ iconUrl: 'files/theme/design/marker/marker-red.png', iconRetinaUrl: 'files/theme/design/marker/marker-red-2x.png' })
var orangeIcon = new customIcon({ iconUrl: 'files/theme/design/marker/marker-orange.png', iconRetinaUrl: 'files/theme/design/marker/marker-orange-2x.png' })
// mehrere Marker mit Popup in Karte einfügen -->
// wenn die Marker eine url haben, steht der Link im Popup
// wenn die Marker kein spezielles Icon zugewiesen haben, wird das StandardIcon(blau) angezeigt
var myMarker = [
{
'name': 'Seebühne Bregenz',
'latlng': [47.50572190274721, 9.738092422485353],
'url': 'https://bregenzerfestspiele.com',
'icon': redIcon,
},
{
'name': 'Hafen Bregenz',
'latlng': [47.506782927165574, 9.747180506246696],
},
{
'name': 'Vorarlberger Landestheater',
'latlng': [47.5046782514231, 9.747147560119629],
'url': 'https://landestheater.org',
'icon': orangeIcon,
},
];
myMarker.map( mrk => {
let marker = L.marker( mrk.latlng, { title: mrk.name } );
if ( mrk.icon && mrk.icon !== '' ) {
marker = L.marker( mrk.latlng, { title: mrk.name,icon: mrk.icon } );
}
if ( mrk.url !== undefined ) {
marker.bindPopup(mrk.name+'<br><a class="linkextern" target="_blank" href="'+mrk.url+'">'+mrk.url+'</a>');
} else {
marker.bindPopup(mrk);
}
marker.addTo( map );
} );
// Koordinaten Picker
// zum Deaktivieren einfach auskommentieren
var popup = L.popup();
map.on("dblclick", function(e) {
popup
.setLatLng(e.latlng)
.setContent('<p class="h5">Koordinaten Picker</p><hr><p>'+e.latlng.lat+', '+e.latlng.lng+'<hr>Kann in leafletmap.js deaktiviert werden!</p>')
.openOn(map);
});
}
Twig-Template erstellen
Nachfolgenden Code als openstreetmap.html.twig im Ordner templates/content_element/html/ speichern.
In diesem Template werden alle Dateien zusammengeführt.
Wichtig dabei:
- anders lautende Template-Namen müssen in der config/config.yaml der Cookiebar unter der Rubik iframe_types mitgeteilt werden (nur den Namen - ohne Suffix - eintragen). Siehe das Beispiel weiter unten.
- Evtl. auch die Pfade zu den css und js - Dateien anpassen,
ebenso die Pfade zum Fullscreen Plugin Control.FullScreen.css und Control.FullScreen.js
templates/content_element/html/openstreetmap.html.twig
{# templates/content_element/html/openstreetmap.html.twig #}
{% extends "@Contao/content_element/html.html.twig" %}
{#
** Add changes to the base template here. **
Hint: Try adjusting blocks and attributes instead of
overwriting the whole template. This way your version
can remain compatible with future changes to the base
template as well as adjustments made by extensions.
Currently available blocks:
"editor_view", "html"
#}
{% block html %}
{{ parent() }}
{# OSM Blocker einbinden #}
<script src="files/js/osmblocker.js"></script>
{# Leaflet einbinden #}
<link rel="stylesheet" href="files/leaflet/leaflet.css">
<script src="files/leaflet/leaflet.js"></script>
{# Fullscreen einbinden #}
<link rel="stylesheet" href="files/leaflet/fullscreen/Control.FullScreen.css" />
<script src="files/leaflet/fullscreen/Control.FullScreen.js"></script>
{# eigene Karte einbinden #}
<script src="files/js/leafletmap.js"></script>
{% endblock %}
config/config.yaml
// config/config.yaml
contao_cookiebar:
iframe_types:
openstreetmap:
- andererTemplatename
Karte in Contao ausgeben
Ein HTML-Element mit folgendem Inhalt anlegen und für die Ausgabe das angelegte openstreetmap-Template zuweisen:
<div id="map"></div>