Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions assets/js/borderPointsMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
const CONSENT_KEY = "borderPointsMapConsent";
const createMap = (container, points) => {
const map = L.map(container, {
scrollWheelZoom: false,
minZoom: 5,
});

const osmBase = new L.TileLayer(
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
{
attribution:
'<a href="https://www.openstreetmap.org/copyright">© OpenStreetMap contributors</a>',
maxZoom: 19,
},
).addTo(map);

const openrailwaymap = new L.TileLayer(
"https://tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png",
{
attribution:
'<a href="https://www.openstreetmap.org/copyright">© OpenStreetMap contributors</a>, Style: <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA 2.0</a> <a href="http://www.openrailwaymap.org/">OpenRailwayMap</a> and OpenStreetMap',
minZoom: 5,
maxZoom: 19,
tileSize: 256,
},
).addTo(map);

const bounds = [];
const markerIcon = L.divIcon({
className: "o-border-points-map__marker",
html: '<span class="a-icon" aria-hidden="true" style="--icon-url: url(\'/icons/material-symbols-rounded/location_on.svg\');"></span>',
iconSize: [24, 24],
iconAnchor: [12, 24],
popupAnchor: [0, -24],
});
points.forEach((point) => {
const marker = L.marker([point.lat, point.lng], { icon: markerIcon }).addTo(
map,
);
marker.bindPopup(point.name);
bounds.push([point.lat, point.lng]);
});

if (bounds.length) {
const pointsBounds = L.latLngBounds(bounds).pad(0.5);
map.fitBounds(pointsBounds, { padding: [20, 20] });
}

return map;
};

const loadLeafletAssets = () =>
new Promise((resolve, reject) => {
if (window.L) {
resolve();
return;
}

const existingCss = document.querySelector("link[data-leaflet]");
if (!existingCss) {
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css";
link.integrity = "sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=";
link.crossOrigin = "";
link.setAttribute("data-leaflet", "true");
document.head.appendChild(link);
}

const existingScript = document.querySelector("script[data-leaflet]");
if (existingScript) {
if (window.L) {
resolve();
} else {
existingScript.addEventListener("load", () => resolve());
}
return;
}

const script = document.createElement("script");
script.src = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js";
script.integrity = "sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=";
script.crossOrigin = "";
script.setAttribute("data-leaflet", "true");
script.onload = () => resolve();
script.onerror = () => reject();
document.body.appendChild(script);
});

const initBorderPointsMap = (wrapper) => {
const pointsData = wrapper.dataset.points;
if (!pointsData) {
return;
}

let points = [];
try {
points = JSON.parse(pointsData);
} catch (error) {
return;
}

const mapContainer = wrapper.querySelector(
"[data-border-points-map-container]",
);
const consentLayer = wrapper.querySelector(
"[data-border-points-map-consent]",
);
const acceptButton = wrapper.querySelector("[data-border-points-map-accept]");
const optOutButton = wrapper.querySelector("[data-border-points-map-optout]");

if (!mapContainer || !consentLayer || !acceptButton || !optOutButton) {
return;
}

const storedConsent = localStorage.getItem(CONSENT_KEY) === "true";
let mapInstance = null;
let resizeObserver = null;

const showMap = async () => {
consentLayer.hidden = true;
optOutButton.hidden = false;
if (!mapInstance) {
await loadLeafletAssets();
mapInstance = createMap(mapContainer, points);
resizeObserver = new ResizeObserver(() => {
mapInstance.invalidateSize();
});
resizeObserver.observe(mapContainer);
}
};

const showConsent = () => {
consentLayer.hidden = false;
optOutButton.hidden = true;
};

if (storedConsent) {
showMap();
} else {
showConsent();
}

acceptButton.addEventListener("click", async () => {
localStorage.setItem(CONSENT_KEY, "true");
await showMap();
});

optOutButton.addEventListener("click", () => {
localStorage.removeItem(CONSENT_KEY);
showConsent();
if (mapInstance) {
mapInstance.off();
mapInstance.remove();
mapInstance = null;
mapContainer.innerHTML = "";
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = null;
}
}
});
};

const initializeBorderPointsMaps = () => {
const wrappers = document.querySelectorAll("[data-border-points-map]");
wrappers.forEach((wrapper) => initBorderPointsMap(wrapper));
};

window.initializeBorderPointsMaps = initializeBorderPointsMaps;
13 changes: 13 additions & 0 deletions assets/js/expander.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,18 @@ function expandTargetedExpander() {
}
}

function initializeExpanderToggles() {
const expanders = document.querySelectorAll(".o-expander");
expanders.forEach((expander) => {
expander.addEventListener("toggle", (event) => {
const currentTarget = event.currentTarget;
if (currentTarget.open && window.initializeBorderPointsMaps) {
window.initializeBorderPointsMaps();
}
});
});
}

document.addEventListener("DOMContentLoaded", expandTargetedExpander);
document.addEventListener("DOMContentLoaded", initializeExpanderToggles);
window.addEventListener("hashchange", expandTargetedExpander);
1 change: 1 addition & 0 deletions assets/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ import "./expander.js";
import "./dialog.js";
import "./fipValidityComparison.js";
import "./search.js";
import "./borderPointsMap.js";
85 changes: 85 additions & 0 deletions assets/sass/borderPointsMap.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
.o-border-points-map {
margin: 1.5rem 0 2rem;

&__frame {
position: relative;
border-radius: var(--border-radius-m);
overflow: hidden;
box-shadow: var(--box-shadow);
}

&__map {
width: 100%;
min-height: 32rem;
background: linear-gradient(160deg, #111827 0%, #1f2937 55%, #0b1120 100%);
}

&__consent {
position: absolute;
inset: 0;
background: linear-gradient(
135deg,
rgba(16, 18, 24, 0.82),
rgba(7, 11, 24, 0.92)
);
color: #fff;
opacity: 1;
visibility: visible;
transition:
opacity 0.2s ease,
visibility 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
}

&__consent[hidden] {
opacity: 0;
visibility: hidden;
}

&__consent-content {
max-width: 42rem;
text-align: center;
display: grid;
gap: 1rem;
}

&__consent-title {
font-size: 1.8rem;
font-weight: 600;
margin: 0;
}

&__opt-out {
margin-top: 1rem;
}

.a-button {
background-color: rgba(255, 255, 255, 0.12);
color: #fff;
border: 0.1rem solid rgba(255, 255, 255, 0.4);
}

.a-button:hover,
.a-button:focus {
background-color: rgba(255, 255, 255, 0.2);
}

&__marker {
color: #b91c1c;
}

&__marker .a-icon {
width: 2.4rem;
height: 2.4rem;
display: block;
}

@media (max-width: 600px) {
&__map {
min-height: 24rem;
}
}
}
1 change: 1 addition & 0 deletions assets/sass/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
@import "button.scss";
@import "startpage.scss";
@import "interactiveMap.scss";
@import "borderPointsMap.scss";
@import "dropdown.scss";
@import "trainCategory.scss";
@import "tag.scss";
Expand Down
66 changes: 66 additions & 0 deletions content/country/switzerland/index.de.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,70 @@ params:
- Gondelbahn Grindelwald – Männlichen (GGM)
- Seilbahn Mürren – Allmendhubel (SMA)
- Luftseilbahn Stechelberg (Mürren – Schilthorn) (LSMS)
border_points_map:
- name: Basel Bad Bf
lat: 47.5674616
lng: 7.6073096
- name: Konstanz
lat: 47.6588689
lng: 9.1772175
- name: Schaffhausen
lat: 47.6981052
lng: 8.6326837
- name: Waldshut
lat: 47.6212145
lng: 8.2195188
- name: Buchs (SG)
lat: 47.1687116
lng: 9.4787656
- name: St. Margrethen
lat: 47.4531468
lng: 9.6382298
- name: Chiasso
lat: 45.8322299
lng: 9.0314153
- name: Domodossola
lat: 46.1154217
lng: 8.2964016
- name: Iselle di Trasquera [> Domodossola]
lat: 46.2070874
lng: 8.2070479
- name: Locarno [> Domodossola]
lat: 46.1723153
lng: 8.8013509
- name: Lugano [> Porto Ceresio]
lat: 46.0054989
lng: 8.9468486
- name: Pino transito
lat: 46.0986592
lng: 8.7370481
- name: Tirano
lat: 46.215738
lng: 10.1666093
- name: Basel SBB
lat: 47.5476225
lng: 7.5896417
- name: Delle
lat: 47.5055161
lng: 7.0099855
- name: Genève [> Bellegarde]
lat: 46.2102288
lng: 6.1426218
- name: Annemasse
lat: 46.1995889
lng: 6.2371108
- name: Le Châtelard-Frontière (fr)
lat: 46.0532873
lng: 6.9502321
- name: Le Locle-Col-des-Roches
lat: 47.0499315
lng: 6.7261101
- name: Pontarlier
lat: 46.9008879
lng: 6.35338
- name: Vallorbe
lat: 46.7122861
lng: 6.3706406
---

## FIP Nutzung
Expand All @@ -34,6 +98,8 @@ Die Schweiz verfügt über eines der dichtesten Bahnnetze der Welt. Trotz der to

{{% expander "Grenzpunkte" border %}}

{{< border-points-map >}}

| Land | Grenzpunkte |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| [Deutschland](/country/germany) ([DB AG](/operator/db)) | Basel Bad Bf, Konstanz, Schaffhausen, Waldshut |
Expand Down
Loading
Loading