<template> <div id="weatherContainer"> <Legend id="legend" @stationUpdate="stationupdate" @layerVisibility="layerVisibility" :mapProperties="mapProperties"></Legend> <div ref="weathermap" id="weathermap" /> <div ref="popup" class="ol-popup"> <a href="#" ref="popup-closer" class="ol-popup-closer"></a> <div ref="popup-content"> </div> <StationChartPopup ref="StationChartPopup"/> </div> </div> </template> <style scoped> #weatherContainer{ width:100%; height:100%; position:relative; } #legend{ width:20%; height:100%; position:relative; float:right; } #weathermap{ width:80%; height:100%; position:relative; float:right; } .ol-popup { position: absolute; background-color: white; box-shadow: 0 1px 4px rgba(0,0,0,0.2); padding: 15px; border-radius: 10px; border: 1px solid #cccccc; bottom: 12px; 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: "✖"; } </style> <script lang="ts"> import {Vue, Ref, Component, Watch } from 'vue-property-decorator'; import View from 'ol/View'; import Map from 'ol/Map'; import OSM from 'ol/source/OSM'; import Overlay from 'ol/Overlay'; import TileLayer from 'ol/layer/Tile'; import { fromLonLat} from 'ol/proj'; import 'ol/ol.css'; import StationLayer from './StationLayer'; import MapProperties from './MapProperties'; import StationChartPopup from './StationChartPopup.vue'; import Legend from './Legend.vue'; @Component({components:{Legend, StationChartPopup}}) export default class WeatherMap extends Vue{ @Ref('weathermap') readonly targetElement!: HTMLElement; private map!: Map; private projection: string = 'EPSG:3857'; //4236 private mapProperties: MapProperties = new MapProperties(null, ""); private stationLayer: StationLayer; @Ref('StationChartPopup') stationChartPopup: StationChartPopup; @Ref('popup') container: HTMLElement; @Ref('popup-content') content: HTMLElement; @Ref('popup-closer') closer: HTMLElement; private overlay:Overlay; public mounted(): void{ this.overlay = new Overlay({ element: this.container, autoPan: true, autoPanAnimation: { duration: 250, }, }); this.map = new Map({ target: this.targetElement, layers: [ new TileLayer({ source: new OSM() }) ], view: new View({ zoom: 6.49, center: fromLonLat([4.0, 51.3]), constrainResolution: true, projection: this.projection }), overlays: [this.overlay], }); this.mapProperties = new MapProperties(this.map, this.projection); this.appendStationLayer(); this.map.on('click', (evt) => { const coordinate = evt.coordinate; var openPopup: boolean = false; this.map.forEachFeatureAtPixel(evt.pixel, (feature, layer)=> { if(layer.getClassName()===StationLayer.layerName){ this.stationChartPopup.renderGraph(this.stationLayer.getTemperatureSeriesFromFeature(feature)); openPopup = true; this.content.innerHTML = '<p>Station: ' + feature.get("id") + '</p>'; }else{ } }); if(openPopup){ this.overlay.setPosition(coordinate); }else{ this.closePopUp(); } }); this.closer.onclick = () => { this.closePopUp(); }; } private closePopUp():void{ this.overlay.setPosition(undefined); this.closer.blur(); } private appendStationLayer(){ this.stationLayer = new StationLayer(this.mapProperties); this.map.addLayer(this.stationLayer.getLayer()); } public stationupdate(event){ this.stationLayer.newYear(event); } protected layerVisibility(isVisible: boolean, layer:string):void{ //this.stationLayer.getLayer().setVisible(this.visibleLayers.has(StationLayer.layerName)); if(layer=='stationLayer'){ this.stationLayer.getLayer().setVisible(isVisible); } } }; </script>