Mercurial > gemma
view client/src/components/map/Map.vue @ 4434:0ca5e6c4f195
Added tag v4-preview20190918 for changeset b5619087e3e9
author | Sascha Wilde <wilde@intevation.de> |
---|---|
date | Wed, 18 Sep 2019 18:04:39 +0200 |
parents | a769e14f4baf |
children | 69166db6ba8a |
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 { layerFactory } from "@/components/map/layers"; import { ImageWMS as ImageSource } from "ol/source"; import { styles } from "./styles"; import "ol/ol.css"; /* 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", "ongoingRefresh" ]), ...mapState("bottlenecks", ["selectedSurvey"]), ...mapState("fairwayprofile", ["additionalSurvey"]), ...mapState("application", ["paneSetup", "paneRotate", "config"]), ...mapState("imports", ["selectedStretchId", "selectedSectionId"]), layers() { return layerFactory(this.paneId); }, hasActiveInteractions() { return ( this.map && this.map .getInteractions() .getArray() .filter( i => ["linetool", "polygontool", "cuttool"].includes(i.get("id")) && i.getActive() ).length ); } }, watch: { ongoingRefresh() { if (this.ongoingRefresh) return; this.loadStyles(); }, 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); } }); }, selectedSectionId(id) { this.layers .get("SECTIONS") .getSource() .getFeatures() .forEach(f => { f.set("highlighted", false); if (id === f.getId()) { f.set("highlighted", true); } }); } }, methods: { updateBottleneckFilter(bottleneck_id, datestr) { if (!bottleneck_id) return; 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/" + encodeURIComponent(`${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 => { this.mountMap(); const { status, data } = error.response; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }); } else { this.mountMap(); } }, mountMap() { const source = new ImageSource({ preload: 1, url: this.config.ecdis_wms_url, crossOrigin: "anonymous", params: JSON.parse(this.config.ecdis_wms_params) }); this.layers.get("INLANDECDIS").setSource(source); 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); }, loadStyles() { // load configured bottleneck colors HTTP.get("/system/settings", { headers: { "X-Gemma-Auth": localStorage.getItem("token") } }) .then(response => { let btlnStrokeC = response.data.bottlenecks_stroke, btlnFillC = response.data.bottlenecks_fill, strFillC = response.data.stretches_fill, strStrokeC = response.data.stretches_stroke, secStrokeC = response.data.sections_stroke, secFillC = response.data.sections_fill, fwd1StrokeC = response.data.fairwaydimensionslos1_stroke, fwd1FillC = response.data.fairwaydimensionslos1_fill, fwd2StrokeC = response.data.fairwaydimensionslos2_stroke, fwd2FillC = response.data.fairwaydimensionslos2_fill, fwd3StrokeC = response.data.fairwaydimensionslos3_stroke, fwd3FillC = response.data.fairwaydimensionslos3_fill, wwpStokeC = response.data.waterwayprofiles_stroke; let btlnStyle = new Style({ stroke: new Stroke({ color: btlnStrokeC, width: 4 }), fill: new Fill({ color: btlnFillC }) }), strStyle = new Style({ stroke: new Stroke({ color: strStrokeC, width: 2 }), fill: new Fill({ color: strFillC }) }), secStyle = new Style({ stroke: new Stroke({ color: secStrokeC, width: 5 }), fill: new Fill({ color: secFillC }) }), fwd1Style = new Style({ stroke: new Stroke({ lineDash: [2, 4], lineCap: "round", color: fwd1StrokeC, width: 2 }), fill: new Fill({ color: fwd1FillC }) }), fwd2Style = new Style({ stroke: new Stroke({ lineDash: [3, 6], lineCap: "round", color: fwd2StrokeC, width: 2 }), fill: new Fill({ color: fwd2FillC }) }), fwd3Style = new Style({ stroke: new Stroke({ color: fwd3StrokeC, width: 2 }), fill: new Fill({ color: fwd3FillC }) }), wwpStyle = new Style({ stroke: new Stroke({ color: wwpStokeC, lineDash: [5, 5], width: 2 }) }); this.layers.get("WATERWAYPROFILES").setStyle(wwpStyle); this.layers .get("FAIRWAYDIMENSIONSLOS1") .setStyle(() => [fwd1Style, styles.textFW1]); this.layers .get("FAIRWAYDIMENSIONSLOS2") .setStyle(() => [fwd2Style, styles.textFW2]); this.layers .get("FAIRWAYDIMENSIONSLOS3") .setStyle(() => [fwd3Style, styles.textFW3]); this.layers.get("SECTIONS").setStyle(secStyle); this.layers.get("STRETCHES").setStyle(strStyle); this.layers.get("BOTTLENECKS").setStyle(btlnStyle); this.$store.commit("gauges/deleteNashSutcliffeCache"); this.$store.dispatch("map/refreshLayers"); }) .catch(error => { console.log(error); }); } }, 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 => { if (response.data["osm-url"]) { this.layers .get("OPENSTREETMAP") .getSource() .setUrl(response.data["osm-url"]); } 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 ); } this.loadStyles(); }) .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>