+
+ addPoint(lng, lat, style) {
+ let vectorSource = new VectorSource({
+ features: [new Feature({
+ geometry: new Point(fromLonLat([lng, lat]))
+ })]
+ });
+ this.#map.addLayer(new VectorLayer({
+ source: vectorSource,
+ style: style,
+ }));
+ }
+
+ addUrlLayer(url, format, style) {
+ let vectorSource;
+ if (format === 'GEOJSON') {
+ vectorSource = new VectorSource({ url: url, format: new GeoJSON() })
+ }
+ else if (format === 'GPX') {
+ vectorSource = new VectorSource({ url: url, format: new GPX() })
+ }
+ this.#map.addLayer(new VectorLayer({
+ source: vectorSource,
+ style: style,
+ }));
+ }
+
+ /* CALLBACKS */
+ enableFeatureSingleClick() {
+ // we cannot use 'this' in the function provided to OpenLayers
+ let mapPart = this;
+ this.#map.on('singleclick', function(e) {
+ let feature = null;
+ // we chose the first one
+ e.map.forEachFeatureAtPixel(e.pixel, function(f) {
+ feature = f;
+ return true;
+ });
+ if (feature !== null)
+ mapPart.callbacks['onFeatureSingleClick'](feature.get('path'));
+ });
+ }
+
+ enableFeatureSelected() {
+ // we cannot use 'this' in the function provided to OpenLayers
+ let mapPart = this;
+ var select = new Select();
+ this.#map.addInteraction(select);
+ select.on('select', function(e) {
+ if (e.selected.length > 0) {
+ let feature = e.selected[0];
+ mapPart.callbacks['onFeatureSelected'](feature.get('path'));
+ }
+ });
+ }
+
+ enableFeaturePopup() {
+ // we cannot use 'this' in the function provided to OpenLayers
+ let mapPart = this;
+ /**
+ * Elements that make up the popup.
+ */
+ const container = document.getElementById('popup');
+ const content = document.getElementById('popup-content');
+ const closer = document.getElementById('popup-closer');
+
+ /**
+ * Create an overlay to anchor the popup to the map.
+ */
+ const overlay = new Overlay({
+ element: container,
+ autoPan: false,
+ autoPanAnimation: {
+ duration: 250,
+ },
+ });
+ this.#map.addOverlay(overlay);
+
+ let selected = null;
+ this.#map.on('pointermove', function(e) {
+ if (selected !== null) {
+ selected.setStyle(undefined);
+ selected = null;
+ }
+
+ e.map.forEachFeatureAtPixel(e.pixel, function(f) {
+ selected = f;
+ return true;
+ });
+
+ if (selected == null) {
+ overlay.setPosition(undefined);
+ return;
+ }
+ const coordinate = e.coordinate;
+ const path = selected.get('path');
+ if (path === null)
+ return true;
+ const res = mapPart.callbacks['onFeaturePopup'](path);
+ if (res != null) {
+ content.innerHTML = res;
+ overlay.setPosition(coordinate);
+ } else {
+ overlay.setPosition(undefined);
+ }
+ });
+ }
+
+ //
+ // HTML
+ //
+ getMapDivCssClass() {
+ return 'map';
+ }
+
+ //
+ // STATIC FOR EXTENSION
+ //
+ static newStyle(args){
+ return new Style(args);
+ }
+
+ static newIcon(args){
+ return new Icon(args);
+ }
+
+