Mercurial > gemma
view client/src/components/map/Map.vue @ 3212:f87fd173f750
client: waterlevel diagrams: fixed tooltip bug
Bug was caused by selecting elements by css class instead of id (when multiple diagrams are displayed).
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Thu, 09 May 2019 10:34:09 +0200 |
parents | 77fc44ad05e3 |
children | d7bc51fd50b0 |
line wrap: on
line source
<template> <div :id="'map-' + paneId" :class="['map', { nocursor: this.hasActiveInteractions }]" > <Zoom :map="map" /> </div> </template> <style lang="sass" scoped> .map width: 100% height: 100% background-color: #eee background-image: linear-gradient(45deg, #e8e8e8 25%, transparent 25%, transparent 75%, #e8e8e8 75%, #e8e8e8), linear-gradient(45deg, #e8e8e8 25%, transparent 25%, transparent 75%, #e8e8e8 75%, #e8e8e8) background-size: 20px 20px background-position: 0 0, 10px 10px &.nocursor cursor: none </style> <script> /* This is Free Software under GNU Affero General Public License v >= 3.0 * without warranty, see README.md and license for details. * * SPDX-License-Identifier: AGPL-3.0-or-later * License-Filename: LICENSES/AGPL-3.0.txt * * Copyright (C) 2018, 2019 by via donau * – Österreichische Wasserstraßen-Gesellschaft mbH * Software engineering by Intevation GmbH * * Author(s): * * Thomas Junk <thomas.junk@intevation.de> * * Bernhard E. Reiter <bernhard.reiter@intevation.de> */ import { HTTP } from "@/lib/http"; import { mapState } from "vuex"; import { Map, View } from "ol"; import { Stroke, Style, Fill } from "ol/style"; import { displayError } from "@/lib/errors"; import { pane } from "@/lib/mixins"; import layers from "@/components/map/layers"; import { Tile as TileLayer } from "ol/layer"; import "ol/ol.css"; import OSM from "ol/source/OSM"; /* for the sake of debugging */ /* eslint-disable no-console */ export default { mixins: [pane], components: { Zoom: () => import("@/components/map/Zoom") }, data() { return { map: null }; }, computed: { ...mapState("map", ["initialLoad", "extent", "syncedMaps", "syncedView"]), ...mapState("bottlenecks", ["selectedSurvey"]), ...mapState("fairwayprofile", ["additionalSurvey"]), ...mapState("application", ["paneSetup", "paneRotate"]), ...mapState("imports", ["selectedStretchId"]), layers() { return layers(); }, hasActiveInteractions() { return ( this.map && this.map .getInteractions() .getArray() .filter( i => ["linetool", "polygontool", "cuttool"].includes(i.get("id")) && i.getActive() ).length ); } }, watch: { paneSetup() { this.$nextTick(() => this.map.updateSize()); }, paneRotate() { this.$nextTick(() => this.map.updateSize()); }, syncedMaps(syncedMaps) { if (syncedMaps.includes(this.paneId) || this.paneId === "main") { this.map.setView(this.syncedView); } else { this.map.setView( new View({ center: [this.extent.lon, this.extent.lat], minZoom: 5, // restrict zooming out to ~size of Europe for width 1000px zoom: this.extent.zoom, projection: "EPSG:3857" }) ); } }, selectedSurvey(survey) { if (this.paneId === "main") { if (survey) { this.updateBottleneckFilter(survey.bottleneck_id, survey.date_info); } else { this.updateBottleneckFilter("does_not_exist", "1999-10-01"); } } }, additionalSurvey(survey) { if (this.paneId === "compare-survey") { if (survey) { this.updateBottleneckFilter(survey.bottleneck_id, survey.date_info); } else { this.updateBottleneckFilter("does_not_exist", "1999-10-01"); } } }, selectedStretchId(id) { this.layers .get("STRETCHES") .getSource() .getFeatures() .forEach(f => { f.set("highlighted", false); if (id === f.getId()) { f.set("highlighted", true); } }); } }, methods: { updateBottleneckFilter(bottleneck_id, datestr) { const exists = bottleneck_id != "does_not_exist"; if (exists) { this.layers .get("BOTTLENECKISOLINE") .getSource() .updateParams({ cql_filter: `date_info='${datestr}' AND bottleneck_id='${bottleneck_id}'` }); } this.layers.get("BOTTLENECKISOLINE").setVisible(exists); }, initMap() { if (!this.syncedView) { this.$store.commit( "map/syncedView", new View({ center: [this.extent.lon, this.extent.lat], minZoom: 5, // restrict zooming out to ~size of Europe for width 1000px zoom: this.extent.zoom, projection: "EPSG:3857" }) ); } // move to user specific default extent if map loads for the first time // checking initialLoad will be obsolete once we abandoned the separated admin context if (this.initialLoad) { this.$store.commit("map/initialLoad", false); var currentUser = this.$store.state.user.user; HTTP.get("/users/" + currentUser, { headers: { "X-Gemma-Auth": localStorage.getItem("token"), "Content-type": "text/xml; charset=UTF-8" } }) .then(response => { this.mountMap(); this.$store.dispatch("map/moveToBoundingBox", { boundingBox: [ response.data.extent.x1, response.data.extent.y1, response.data.extent.x2, response.data.extent.y2 ], zoom: 17, preventZoomOut: true, duration: 0 }); }) .catch(error => { const { status, data } = error.response; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }); } else { this.mountMap(); } }, mountMap() { this.map = new Map({ layers: this.layers.config, target: "map-" + this.paneId, controls: [], view: this.syncedMaps.includes(this.paneId) || this.paneId === "main" ? this.syncedView : new View({ center: [this.extent.lon, this.extent.lat], minZoom: 5, zoom: this.extent.zoom, projection: "EPSG:3857" }) }); this.map.getLayer = id => this.layers.get(id); // store map position on every move // will be obsolete once we abandoned the separated admin context this.map.on("moveend", event => { const center = event.map.getView().getCenter(); this.$store.commit("map/extent", { lat: center[1], lon: center[0], zoom: event.map.getView().getZoom() }); }); this.$store.dispatch("map/openLayersMap", this.map); this.$store.dispatch("map/initIdentifyTool", this.map); } }, mounted() { // ToDo set path to correct endpoint in order to retrieve an OSM URL HTTP.get("/system/config", { headers: { "X-Gemma-Auth": localStorage.getItem("token") } }) .then(response => { const url = response.data["osm-url"]; const config = {}; if (url) { config["url"] = url; } this.layers.config.unshift( new TileLayer({ id: "OPENSTREETMAP", label: "Open Streetmap", visible: true, source: new OSM(config) }) ); this.initMap(); if (this.selectedSurvey && this.paneId === "main") { this.updateBottleneckFilter( this.selectedSurvey.bottleneck_id, this.selectedSurvey.date_info ); } if (this.additionalSurvey && this.paneId === "compare-survey") { this.updateBottleneckFilter( this.additionalSurvey.bottleneck_id, this.additionalSurvey.date_info ); } // load configured bottleneck colors HTTP.get("/system/style/Bottlenecks/stroke", { headers: { "X-Gemma-Auth": localStorage.getItem("token") } }) .then(response => { let btlnStrokeC = response.data.code; HTTP.get("/system/style/Bottlenecks/fill", { headers: { "X-Gemma-Auth": localStorage.getItem("token") } }) .then(response => { let btlnFillC = response.data.code; var newStyle = new Style({ stroke: new Stroke({ color: btlnStrokeC, width: 4 }), fill: new Fill({ color: btlnFillC }) }); this.layers.get("BOTTLENECKS").setStyle(newStyle); }) .catch(error => { console.log(error); }); }) .catch(error => { console.log(error); }); }) .catch(error => { const { status, data } = error.response; displayError({ title: "Backend Error", message: `${status}: ${data.message || data}` }); }); }, destroyed() { this.$store.commit("map/removeOpenLayersMap", this.map); } }; </script>