view client/src/components/map/Map.vue @ 3685:8775bea8042a

client: layers: unset layer config on logout
author Markus Kottlaender <markus@intevation.de>
date Tue, 18 Jun 2019 14:39:36 +0200
parents f3102fa16a69
children 8acabf1f176f
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 "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"]),
    ...mapState("bottlenecks", ["selectedSurvey"]),
    ...mapState("fairwayprofile", ["additionalSurvey"]),
    ...mapState("application", ["paneSetup", "paneRotate"]),
    ...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: {
    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) {
      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 => {
        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
          );
        }
        // 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>