6. Vyskakovací okna
Data, se kterými chceme pracovat máme přidána. Chybí ale podrobnější informace o svatebních místech a přesunech mezi nimi. Mapa postrádá jakoukoli interaktivitu.
Informace o obřadě jako například čas, souřadnice, fotka a pozvání svatebčanů a další informace mohou být součástí vyskakovacích oken. U ikonek obsah vyskakovacích oken definujeme dynamicky, protože budeme chtít v textu uvést číselné hodnoty souřadnic míst v systémech S-JTSK (EPSG:5514) i WGS84 (EPSG:4326). Souřadnice v S-JTSK budeme proto za běhu transformovat do WGS84. Obsah vyskakovacích oken u přesunových tras budeme definovat pouze na základě vlastností v GeoJSON souboru.
Vyskakovací okna u vektorových vrstev
Vyskakovací okno je HTML objektem. Je tedy nutné ho přidat i v rámci index.html souboru. Kvůli transformaci souřadnic ze systému EPSG:5514 do systému EPSG:4326 pro účely zobrazení přetransformovaných hodnot ve vyskakovacím okně je nutné dále připojit do index.html ještě JavaScript knihovnu proj4. To provedeme přidáním následujícího odkazu: https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/x-icon" href="https://openlayers.org/…ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Plánek svatba</title>
</head>
<body>
<div id="map"></div>
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content"></div>
</div>
<script type="module" src="./main.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>
</body>
</html>
Stylizaci popup okna definujeme v souboru style.css:
@import "node_modules/ol/ol.css";
html, body {
margin: 0;
height: 100%;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.ol-popup {
position: absolute;
background-color: white;
box-shadow: 0 1px 4px rgba(0,0,0,0.4);
padding: 20px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 15px;
left: -50px;
min-width: 280px;
}
.ol-popup:after, .ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}
V souboru main.js dále sestavíme obsah zprávy, která se má zobrazit v závislosti na typu vybraného prvku. Vytvoříme si dvě funkce transformGeometryToWGS84 a definePopupContent, které budou sloužit k dynamickému naplnění obsahu popup oken patřících k ikonkám. Poté napíšeme, co se má stát při události singleclick - na základě typu prvku zobraz požadované vyskakovací okno. To bude mít pokaždé podobnou strukturu. Pokud bychom chtěli okno jiné struktury, můžeme obsah HTML definovat rovnou do content.innerHTML vlastnosti.
// Add Krovak CRS as PROJ def in order to have the possibility to transform from SJTSK to WGS84
addProjection(sjtsk_projection);
proj4.defs('EPSG:5514','+proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 +alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +towgs84=589,76,480,0,0,0,0 +units=m +no_defs +type=crs');
register(proj4);
// Function for transforming S-JTSK coordinates to WGS-84
function transformGeometryToWGS84(geometrySJTSK) {
return toStringHDMS(transform(geometrySJTSK, 'EPSG:5514', 'EPSG:4326'));
}
// Function for preparing content of popup windows for two important places
// Popups have a similar style which include place description, picture, picture title and coordinates in both CRS systems
function definePopupContent(textHtml, pictureHtml, pictureTitleHtml, coordinatesSJTSK){
return textHtml + pictureHtml + pictureTitleHtml +
'WGS84: <code>' + transformGeometryToWGS84(coordinatesSJTSK) + '</code><p> S-JTSK: <code>' +
coordinatesSJTSK + '</code></p>';
}
// Take popup elements
const container = document.getElementById('popup');
const content = document.getElementById('popup-content');
const closer = document.getElementById('popup-closer');
// Create popup overlay layer
var popup = new Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
map.addOverlay(popup);
closer.onclick = function () {
popup.setPosition(undefined);
closer.blur();
return false;
};
// Show popup above Icon and Linestring on single click if feature exists
map.on('singleclick', function(event) {
if (map.hasFeatureAtPixel(event.pixel) === true) {
var coordinate = event.coordinate;
var features = map.getFeaturesAtPixel(event.pixel);
content.innerHTML = "undefined";
if (features[0].getGeometry().getType() == "Point" && features[0].getProperties().name != "text") {
// HTML content of point features
if (features[0].getProperties().name == "kostel") {
content.innerHTML = definePopupContent('<p>Zde si řekneme své ano.</p>',
'<img src="data/pictures/kostel.jpg" width="300" height="200">',
'<p>Kostel sv. Václava na Proseku</p>',
features[0].getGeometry().getFlatCoordinates());
}
if (features[0].getProperties().name == "restaurant") {
content.innerHTML = definePopupContent('<p>Zde náš významný den společně oslavíme.</p>',
'<img src="data/pictures/sv_dvur.jpg" width="370" height="227">',
'<p>Restaurace a hotel Svatojánský Dvůr</p>',
features[0].getGeometry().getFlatCoordinates());
}
} else if ((features[0].getGeometry().getType() == "LineString")) {
// HTML content of linestring features
content.innerHTML = features[0].getProperties().popupContent;
}
// Set position of overlazing popup
if (content.innerHTML != "undefined") {
popup.setPosition(coordinate);
} else {
popup.setPosition(undefined);
}
};
});
Znovu nezapomeneme na začátek souboru přidat importní deklarace:
import {addProjection} from 'ol/proj';
import {transform} from 'ol/proj';
import {register} from 'ol/proj/proj4';
import {toStringHDMS} from 'ol/coordinate';
import Overlay from 'ol/Overlay';

Vyskakovací okna u vektorových dlaždic
Podobně můžeme nechat zobrazit vyskakovací okna při kliku na parcelu jakožto prvek vektorové dlaždice (dlaždic). Znovu půjde o událost typu singleclick:
// Show popup above Icon on single click on the parcela if parcela exists
map.on('singleclick', function(event) {
vectorTiles.getFeatures(event.pixel).then(function (features) {
const feature = features[0];
if (!feature) {
return;
}
var coordinate = event.coordinate;
if (feature.get("ID_2") == 2238913101){
content.innerHTML = "Případné další info k obřadu:.. ";
popup.setPosition(coordinate);
}
if (feature.get("ID_2") == 2113941101){
content.innerHTML = "Případné další info k hostině:.. ";
popup.setPosition(coordinate);
}
});
});
Po kliknutí na ikonku příslušnou parcelu restaurace se nám zobrazí následující popup okno:
