Initial commit: JGA Prag 2026 - interaktiver Tourenplan

This commit is contained in:
Hermes AI Bot
2026-06-26 21:27:25 +00:00
commit dafd92d616
4 changed files with 662 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
.DS_Store
*.log
+48
View File
@@ -0,0 +1,48 @@
# 🥳 JGA-2026 Prag Tourenplan
Interaktiver Tourenplan für den Junggesellenabschied in Prag (25.26. Juli 2026).
## Inhalt
- **`tourenplan.html`** — Karte mit allen 11 Locations (Hotel + 10 Attraktionen)
- **`tourenplan-mit-tram.html`** — Erweiterte Version mit 13 Tram-Linien & 10 Haltestellen eingezeichnet
## So öffnest du die Karten
1. Datei herunterladen
2. Doppelklick → öffnet im Browser
3. Zoom + Pan wie bei Google Maps
4. Klick auf Marker → Popup mit Adresse, Preis & Website
## Die 11 Locations
| Emoji | Location | Adresse |
|-------|----------|---------|
| 🏨 | Hotel Uno Prague | Štěchovická 2296/2a, Praha 10 |
| 🔐 | Endorfin Escape Games | Petrohradská 216/3, Praha 10 |
| 🏎️ | KartPlanet Praha | Mezitraťová, Praha 9 |
| ⛳ | Level Prague Minigolf | Národní 63/26, Praha 1 |
| 🎳 | Bowling Ovčín | Záběhlická 82, Praha 10 |
| 👻 | Mysterium Geister-Tour | Pařížská 6, Praha 1 |
| 🎯 | Prague Ranger (Schießstand) | Lublaňská 1729/23, Praha 2 |
| ⛵ | Beer Boat Prague | Štefánikův most, Praha 1 |
| 🎨 | Paintball Game Praha | Pod Císařkou, Praha 5 |
| 🔫 | Mercuria Laser Game Pankrác | Budějovická 409/1a, Praha 4 |
| 🔍 | Enigma Outdoor Adventure | stadtweit |
## Tram-Linien
13 Tram-Linien als Polylines eingezeichnet (3, 4, 5, 6, 9, 10, 13, 14, 16, 17, 18, 22, 24, 26).
Wichtige Haltestellen markiert: Na Hroudě (Hotel), Strašnická, Muzeum, Staroměstská, Národní třída, Jiráskovo náměstí, Vyšehrad, Pražského povstání, Pankrác, Svatoplukova, Náměstí Míru.
## Hinweise
- **Prague Ranger:** Range-Position wird vom Anbieter geheim gehalten → der offizielle Shuttle-Pickup ist markiert. Nach Buchung die echte GPS anfragen.
- **Enigma:** stadtweites App-Spiel ohne festen Startpunkt → Altstädter Ring als Symbolpunkt.
- **Level Minigolf** ist tatsächlich Indoor (im Máj-Haus), nicht Outdoor.
## Datenquellen
- OpenStreetMap (via Overpass API) für Tram-Linien und Haltestellen
- Nominatim (OpenStreetMap) für Adress-Geocoding
- Leaflet für die Karten-Darstellung
File diff suppressed because one or more lines are too long
+255
View File
@@ -0,0 +1,255 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JGA Prag Tourenplan</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""/>
<style>
html, body { margin: 0; padding: 0; height: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #1a1a1a; color: #eee; }
#header { padding: 16px 20px; background: linear-gradient(135deg, #2d2d2d 0%, #1a1a1a 100%); border-bottom: 2px solid #444; }
#header h1 { margin: 0 0 4px 0; font-size: 22px; }
#header .sub { color: #aaa; font-size: 13px; }
#map { height: calc(100vh - 80px); width: 100%; }
.legend { background: rgba(30,30,30,0.95); padding: 10px 12px; border-radius: 8px; color: #eee; font-size: 13px; box-shadow: 0 2px 8px rgba(0,0,0,0.4); border: 1px solid #444; max-width: 240px; }
.legend h4 { margin: 0 0 8px 0; font-size: 14px; }
.legend .item { display: flex; align-items: center; gap: 8px; margin: 4px 0; }
.legend .emoji { font-size: 18px; }
.legend .dot { width: 14px; height: 14px; border-radius: 50%; border: 2px solid white; }
.popup-content { font-family: -apple-system, BlinkMacSystemFont, sans-serif; min-width: 220px; }
.popup-content .emoji-big { font-size: 28px; margin-right: 8px; }
.popup-content h3 { margin: 0 0 6px 0; font-size: 16px; color: #1a1a1a; }
.popup-content .meta { font-size: 12px; color: #555; margin: 4px 0; }
.popup-content .desc { font-size: 13px; color: #333; margin: 6px 0; }
.popup-content .price { display: inline-block; background: #ffeb3b; color: #1a1a1a; padding: 2px 8px; border-radius: 4px; font-weight: 600; font-size: 12px; margin-top: 4px; }
.popup-content a { display: inline-block; margin-top: 8px; padding: 5px 10px; background: #1976d2; color: white; text-decoration: none; border-radius: 4px; font-size: 12px; }
.popup-content a:hover { background: #1565c0; }
.leaflet-popup-content-wrapper { border-radius: 8px; }
.marker-label { background: rgba(30,30,30,0.9); color: white; padding: 3px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; white-space: nowrap; box-shadow: 0 1px 4px rgba(0,0,0,0.4); border: none; }
.marker-label::before { display: none; }
</style>
</head>
<body>
<div id="header">
<h1>🥳 JGA Prag Tourenplan</h1>
<div class="sub">25.26. Juli 2026 · 8 Personen · Hotel Uno Prague als Basis</div>
</div>
<div id="map"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""></script>
<script>
const locations = [
// Hotel - immer als erstes
{
name: "Hotel Uno Prague",
emoji: "🏨",
color: "#4fc3f7",
lat: 50.0717636, lon: 14.4999461,
address: "Štěchovická 2296/2a, Praha 10 Strašnice",
desc: "Unsere Unterkunft. Tram 'Na Hroudě' (Linien 4, 13, 26) in 3 Min Fußweg.",
price: null,
url: "https://www.unoprague.cz",
category: "hotel"
},
{
name: "Endorfin Escape Games",
emoji: "🔐",
color: "#e91e63",
lat: 50.0639594, lon: 14.4520475,
address: "Petrohradská 216/3, Praha 10 Vršovice",
desc: "Escape Rooms (Titanic, Saw, Freddy Krueger). Eingang vom Petrohradská-Hof. Max. 5 Pers/Raum → 2 Teams parallel.",
price: "ca. 20 € p.P. / 1h",
url: "https://endorfin.cz/en/escape-games/",
category: "action"
},
{
name: "KartPlanet Praha",
emoji: "🏎️",
color: "#ff9800",
lat: 50.0998466, lon: 14.5133693,
address: "Mezitraťová, Praha 9 Hrdlořezy",
desc: "Indoor Go-Kart. Schnellste Karts in Prag, ca. 10 Min Heizerlebnis.",
price: "ca. 15 € p.P. / 10 min",
url: "https://kartplanet.cz/en/",
category: "action"
},
{
name: "Level Prague Minigolf",
emoji: "⛳",
color: "#66bb6a",
lat: 50.0815, lon: 14.4248,
address: "Národní 63/26, Praha 1 Nové Město (im Máj House of Fun)",
desc: "Indoor Minigolf mit Neon-Beleuchtung. Themen-Bahnen mit Überraschungen. Auch Bowling & Escape Rooms im selben Komplex.",
price: "ca. 25 € p.P. / 1h",
url: "https://levelsprague.com/de/minigolf/",
category: "fun"
},
{
name: "Bowling Ovčín",
emoji: "🎳",
color: "#ab47bc",
lat: 50.0537395, lon: 14.4875385,
address: "Záběhlická 82/3, Praha 10 Záběhlice",
desc: "Bowling + Billard + Restaurant. Gemütliche Atmosphäre, ideal für Gruppen.",
price: "ca. 6 € p.P. / 2h",
url: "https://www.ovcin.cz/",
category: "fun"
},
{
name: "Mysterium Tours Geister-Tour",
emoji: "👻",
color: "#7e57c2",
lat: 50.0885363, lon: 14.4201683,
address: "Treffpunkt: Cartier-Geschäft, Ecke Pařížská / Altstädter Ring",
desc: "Abendliche Geister-Tour durch die Altstadt. Geschichten & Legenden. Startzeiten 19:45 / 20:00 / 20:15, Dauer ~1:45h.",
price: "ca. 20 € p.P. / 2h",
url: "https://www.mysteriumtours.com/de/prag/prager-geister-tour/",
category: "sight"
},
{
name: "Prague Ranger (Schießstand)",
emoji: "🎯",
color: "#5d4037",
lat: 50.0714571, lon: 14.4320070,
address: "Shuttle-Pickup: Lublaňská 1729/23, Praha 2 Vyšehrad",
desc: "Outdoor-Schießstand, ca. 45 Min vom Stadtzentrum. Shuttle im Preis inklusive. Großer Komplex (70.000 m², 25500 m Bahnen). Genaue Range-Adresse wird erst nach Buchung per Mail mitgeteilt.",
price: "ca. 100200 € p.P. / 34h",
url: "https://www.pragueranger.cz/de/",
category: "action"
},
{
name: "Beer Boat Prague",
emoji: "⛵",
color: "#ffb300",
lat: 50.0941774, lon: 14.4269959,
address: "Startpunkt: Štefánikův most (Dvořákovo nábřeží), Praha 1",
desc: "Tretboot-Biertour auf der Moldau. Privater Kapitän, unbegrenzt Bier. Büro: Týnská 639/4, Praha 1.",
price: "ca. 45 € p.P. / 1h",
url: "https://beerboatsprague.com/de/Prague-Beer-Boat-Tour",
category: "fun"
},
{
name: "Paintball Game Praha",
emoji: "🎨",
color: "#ef5350",
lat: 50.0748169, lon: 14.3713262,
address: "Pod Císařkou, Praha 5 Buďánka",
desc: "Paintball mit Reball (kein Schmerz, wiederverwendbare Bälle). Indoor + Outdoor Kombi.",
price: "ca. 24 € p.P. / 1h",
url: "https://www.paintballgame.cz/de/paintball-pakete/reball",
category: "action"
},
{
name: "Mercuria Laser Game Pankrác",
emoji: "🔫",
color: "#26c6da",
lat: 50.0501649, lon: 14.4432250,
address: "Budějovická 409/1a, Praha 4 Pankrác (unter Bauhaus, neben Penny)",
desc: "Lasertag Arena. Mehrere Etagen mit Hindernissen.",
price: "ca. 7 € p.P. / 20 min",
url: "https://mercurialaser.cz/en/pankrac/",
category: "action"
},
{
name: "Enigma Outdoor City Adventure",
emoji: "🔍",
color: "#ffa726",
lat: 50.0875, lon: 14.4213,
address: "Symbolischer Startpunkt: Altstädter Ring (Staroměstské náměstí)",
desc: "Stadtweites Mobile-App Mystery-Spiel. Per GPS durch ganz Prag, kein fester Treffpunkt. Anbieter: Swallnet.",
price: "ca. 5 € p.P. / 12h",
url: "https://enigma.swallnet.com/index.php/jak-hrat-en/",
category: "fun"
}
];
// Karte initialisieren - Start auf Hotel Uno, fitBounds überschreibt das gleich
const map = L.map('map').setView([50.0718, 14.4999], 11);
// Dark Mode Tile Layer (CartoDB Dark Matter)
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> &copy; <a href="https://carto.com/attributions">CARTO</a>',
subdomains: 'abcd',
maxZoom: 19
}).addTo(map);
// Custom Marker mit Emoji + Label
function createIcon(emoji, color, isHotel=false) {
const size = isHotel ? 44 : 38;
const html = `
<div style="
background: ${color};
width: ${size}px;
height: ${size}px;
border-radius: 50% 50% 50% 0;
transform: rotate(-45deg);
display: flex;
align-items: center;
justify-content: center;
border: 3px solid white;
box-shadow: 0 3px 8px rgba(0,0,0,0.5);
">
<span style="transform: rotate(45deg); font-size: ${isHotel ? 22 : 19}px;">${emoji}</span>
</div>
`;
return L.divIcon({
html: html,
className: 'custom-marker',
iconSize: [size, size],
iconAnchor: [size/2, size],
popupAnchor: [0, -size]
});
}
// Marker setzen
const bounds = [];
locations.forEach(loc => {
const isHotel = loc.category === 'hotel';
const marker = L.marker([loc.lat, loc.lon], {
icon: createIcon(loc.emoji, loc.color, isHotel)
}).addTo(map);
const popupContent = `
<div class="popup-content">
<h3><span class="emoji-big">${loc.emoji}</span>${loc.name}</h3>
<div class="meta">📍 ${loc.address}</div>
<div class="desc">${loc.desc}</div>
${loc.price ? `<div class="price">${loc.price}</div>` : ''}
<a href="${loc.url}" target="_blank" rel="noopener">🔗 Website öffnen</a>
</div>
`;
marker.bindPopup(popupContent, { maxWidth: 320 });
bounds.push([loc.lat, loc.lon]);
});
// Bounds an alle Marker anpassen (mit Padding, damit nichts am Rand klebt)
map.fitBounds(bounds, { padding: [80, 80] });
// Legende
const legend = L.control({ position: 'bottomright' });
legend.onAdd = function() {
const div = L.DomUtil.create('div', 'legend');
div.innerHTML = `
<h4>🥳 JGA Prag Tourenplan</h4>
<div class="item"><span class="dot" style="background:#4fc3f7"></span>🏨 Hotel (Basis)</div>
<div class="item"><span class="dot" style="background:#e91e63"></span>🔐 Escape Room</div>
<div class="item"><span class="dot" style="background:#ff9800"></span>🏎️ KartPlanet</div>
<div class="item"><span class="dot" style="background:#66bb6a"></span>⛳ Minigolf</div>
<div class="item"><span class="dot" style="background:#ab47bc"></span>🎳 Bowling</div>
<div class="item"><span class="dot" style="background:#7e57c2"></span>👻 Geister-Tour</div>
<div class="item"><span class="dot" style="background:#5d4037"></span>🎯 Schießstand</div>
<div class="item"><span class="dot" style="background:#ffb300"></span>⛵ Beer Boat</div>
<div class="item"><span class="dot" style="background:#ef5350"></span>🎨 Paintball</div>
<div class="item"><span class="dot" style="background:#26c6da"></span>🔫 Lasertag</div>
<div class="item"><span class="dot" style="background:#ffa726"></span>🔍 Enigma</div>
`;
return div;
};
legend.addTo(map);
</script>
</body>
</html>