diff client/src/components/map/Map.vue @ 3011:fc8fbea24568

client: moved map component, layer factory and styles to own subdirectory
author Markus Kottlaender <markus@intevation.de>
date Thu, 11 Apr 2019 12:14:01 +0200
parents
children 083cd270bdfd
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/map/Map.vue	Thu Apr 11 12:14:01 2019 +0200
@@ -0,0 +1,225 @@
+<template>
+  <div
+    :id="'map-' + uuid"
+    :class="[
+      'map',
+      {
+        splitscreen: this.splitscreen,
+        nocursor: this.hasActiveInteractions
+      }
+    ]"
+  ></div>
+</template>
+
+<style lang="sass" scoped>
+.map
+  width: 100%
+  height: 100%
+
+  &.splitscreen
+    height: 50%
+
+  &.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 { uuid } from "@/lib/mixins";
+import layers from "@/components/map/layers";
+import "ol/ol.css";
+
+/* for the sake of debugging */
+/* eslint-disable no-console */
+export default {
+  mixins: [uuid],
+  data() {
+    return {
+      splitscreen: false
+    };
+  },
+  computed: {
+    ...mapState("map", [
+      "initialLoad",
+      "extent",
+      "openLayersMap",
+      "lineTool",
+      "polygonTool",
+      "cutTool"
+    ]),
+    ...mapState("bottlenecks", ["selectedSurvey"]),
+    ...mapState("application", ["showSplitscreen"]),
+    ...mapState("imports", ["selectedStretchId"]),
+    hasActiveInteractions() {
+      return (
+        (this.lineTool && this.lineTool.getActive()) ||
+        (this.polygonTool && this.polygonTool.getActive()) ||
+        (this.cutTool && this.cutTool.getActive())
+      );
+    }
+  },
+  methods: {
+    updateBottleneckFilter(bottleneck_id, datestr) {
+      const exists = bottleneck_id != "does_not_exist";
+
+      if (exists) {
+        layers
+          .get("BOTTLENECKISOLINE")
+          .getSource()
+          .updateParams({
+            cql_filter: `date_info='${datestr}' AND bottleneck_id='${bottleneck_id}'`
+          });
+      }
+      layers.get("BOTTLENECKISOLINE").setVisible(exists);
+    }
+  },
+  watch: {
+    showSplitscreen(show) {
+      if (show) {
+        setTimeout(() => {
+          this.splitscreen = true;
+        }, 350);
+      } else {
+        this.splitscreen = false;
+      }
+    },
+    splitscreen() {
+      const map = this.openLayersMap;
+      this.$nextTick(() => {
+        map && map.updateSize();
+      });
+    },
+    selectedSurvey(newSelectedSurvey) {
+      if (newSelectedSurvey) {
+        this.updateBottleneckFilter(
+          newSelectedSurvey.bottleneck_id,
+          newSelectedSurvey.date_info
+        );
+      } else {
+        this.updateBottleneckFilter("does_not_exist", "1999-10-01");
+      }
+    },
+    selectedStretchId(id) {
+      layers
+        .get("STRETCHES")
+        .getSource()
+        .getFeatures()
+        .forEach(f => {
+          f.set("highlighted", false);
+          if (id === f.getId()) {
+            f.set("highlighted", true);
+          }
+        });
+    }
+  },
+  mounted() {
+    const map = new Map({
+      layers: layers.config,
+      target: "map-" + this.uuid,
+      controls: [],
+      view: 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"
+      })
+    });
+    map.getLayer = id => layers.get(id);
+
+    // store map position on every move
+    // will be obsolete once we abandoned the separated admin context
+    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", map);
+
+    // move to user specific default extent if map loads for the first timeout
+    // 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.$store.commit("map/moveToBoundingBox", {
+            boundingBox: [
+              response.data.extent.x1,
+              response.data.extent.y1,
+              response.data.extent.x2,
+              response.data.extent.y2
+            ],
+            zoom: 17,
+            preventZoomOut: true
+          });
+        })
+        .catch(error => {
+          const { status, data } = error.response;
+          displayError({
+            title: this.$gettext("Backend Error"),
+            message: `${status}: ${data.message || data}`
+          });
+        });
+    }
+
+    // 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
+              })
+            });
+            layers.get("BOTTLENECKS").setStyle(newStyle);
+          })
+          .catch(error => {
+            console.log(error);
+          });
+      })
+      .catch(error => {
+        console.log(error);
+      });
+
+    this.$store.dispatch("map/disableIdentifyTool");
+    this.$store.dispatch("map/enableIdentifyTool");
+  }
+};
+</script>