view client/src/drawtool/Drawtool.vue @ 1237:74562dc29e10

refactored drawtool The map interactions (ol/interaction/Draw) were previously always removed and re-created. Now there are created and added to the map once and their active flag is used to toggle the tools. Results in cleaner code and easier separation of the buttons in the future.
author Markus Kottlaender <markus@intevation.de>
date Tue, 20 Nov 2018 13:03:24 +0100
parents ba8cd80d68b6
children 442399fc1b71
line wrap: on
line source

<template>
    <div class="d-flex flex-column">
        <div @click="toggleLineTool" class="ui-element d-flex shadow drawtool bg-white mx-3 mb-3 p-2 rounded">
            <i :class="['fa fa-pencil', {inverted: lineTool && lineTool.getActive()}]"></i>
        </div>
        <div @click="togglePolygonTool" class="ui-element d-flex shadow drawtool bg-white mx-3 mb-3 p-2 rounded">
            <i :class="['fa fa-edit', {inverted: polygonTool && polygonTool.getActive()}]"></i>
        </div>
        <div @click="toggleCutTool" class="ui-element d-flex shadow drawtool bg-white mx-3 mb-3 p-2 rounded" v-if="selectedSurvey">
            <i :class="['fa fa-area-chart', {inverted: cutTool && cutTool.getActive()}]"></i>
        </div>
    </div>
</template>

<style lang="sass" scoped>
.drawtool
  height: $icon-width
  width: $icon-height
  z-index: 2

.inverted
  color: #0077ff
</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 by via donau
 *   – Österreichische Wasserstraßen-Gesellschaft mbH
 * Software engineering by Intevation GmbH
 *
 * Author(s):
 * Thomas Junk <thomas.junk@intevation.de>
 * Markus Kottländer <markus.kottlaender@intevation.de>
 */
import { mapState, mapGetters } from "vuex";
import { getLength, getArea } from "ol/sphere.js";
import Draw from "ol/interaction/Draw.js";
import { Stroke, Style, Circle, Fill } from "ol/style.js";

export default {
  name: "drawtool",
  computed: {
    ...mapGetters("map", ["getLayerByName"]),
    ...mapState("map", [
      "lineTool",
      "polygonTool",
      "cutTool",
      "openLayersMap"
    ]),
    ...mapState("bottlenecks", ["selectedSurvey"])
  },
  methods: {
    toggleLineTool() {
      this.lineTool.setActive(!this.lineTool.getActive());
      this.polygonTool.setActive(false);
      this.cutTool.setActive(false);
      this.$store.commit("map/setCurrentMeasurement", null);
      this.getLayerByName("Draw Tool").data.getSource().clear();
    },
    togglePolygonTool() {
      this.polygonTool.setActive(!this.polygonTool.getActive());
      this.lineTool.setActive(false);
      this.cutTool.setActive(false);
      this.$store.commit("map/setCurrentMeasurement", null);
      this.getLayerByName("Draw Tool").data.getSource().clear();
    },
    toggleCutTool() {
      this.cutTool.setActive(!this.cutTool.getActive());
      this.lineTool.setActive(false);
      this.polygonTool.setActive(false);
      this.$store.commit("map/setCurrentMeasurement", null);
    },
    lineEnd(event) {
      const length = getLength(event.feature.getGeometry());
      this.$store.commit("map/setCurrentMeasurement", {
        quantity: "Length",
        unitSymbol: "m",
        value: Math.round(length * 10) / 10
      });
      this.$store.commit("application/showIdentify", true);
    },
    polygonEnd(event) {
      const areaSize = getArea(event.feature.getGeometry());
      this.$store.commit("map/setCurrentMeasurement", {
        quantity: "Area",
        unitSymbol: areaSize > 100000 ? "km²" : "m²",
        value:
          areaSize > 100000
            // convert into 1 km² == 1000*1000 m² and round to 1000 m²
            ? Math.round(areaSize / 1000) / 1000
            : Math.round(areaSize)
      });
      this.$store.commit("application/showIdentify", true);
    },
    cutEnd(event) {
      this.$store.dispatch("fairwayprofile/cut", event.feature);
    }
  },
  created() {
    if (!this.lineTool) {
      const drawVectorSrc = this.getLayerByName("Draw Tool").data.getSource();
      const lineTool = new Draw({
        source: drawVectorSrc,
        type: "LineString",
        maxPoints: 2
      });
      lineTool.setActive(false);
      lineTool.on("drawstart", () => {
        drawVectorSrc.clear();
        this.$store.commit("map/setCurrentMeasurement", null);
      });
      lineTool.on("drawend", this.lineEnd);
      this.$store.commit("map/lineTool", lineTool);
      this.openLayersMap.addInteraction(lineTool);
    }

    if (!this.polygonTool) {
      const drawVectorSrc = this.getLayerByName("Draw Tool").data.getSource();
      const polygonTool = new Draw({
        source: drawVectorSrc,
        type: "Polygon",
        maxPoints: 50
      });
      polygonTool.setActive(false);
      polygonTool.on("drawstart", () => {
        drawVectorSrc.clear();
        this.$store.commit("map/setCurrentMeasurement", null);
      });
      polygonTool.on("drawend", this.polygonEnd);
      this.$store.commit("map/polygonTool", polygonTool);
      this.openLayersMap.addInteraction(polygonTool);
    }

    if (!this.cutTool) {
      const cutVectorSrc = this.getLayerByName("Cut Tool").data.getSource();
      const cutTool = new Draw({
        source: cutVectorSrc,
        type: "LineString",
        maxPoints: 2,
        style: new Style({
          stroke: new Stroke({
            color: "#444",
            width: 2,
            lineDash: [7, 7]
          }),
          image: new Circle({
            fill: new Fill({ color: "#333" }),
            stroke: new Stroke({ color: "#fff", width: 1.5 }),
            radius: 6
          })
        })
      });
      cutTool.setActive(false);
      cutTool.on("drawstart", () => {
        cutVectorSrc.clear();
      });
      cutTool.on("drawend", this.cutEnd);
      this.$store.commit("map/cutTool", cutTool);
      this.openLayersMap.addInteraction(cutTool);
    }
  },
  mounted() {
    window.addEventListener("keydown", e => {
      // Escape
      if (e.keyCode === 27) {
        this.lineTool.setActive(false);
        this.polygonTool.setActive(false);
        this.cutTool.setActive(false);
        this.getLayerByName("Draw Tool").data.getSource().clear();
      }
    });
  }
};
</script>