changeset 1247:c14353e2cdb9

repositioning of buttons (issue225)
author Markus Kottlaender <markus@intevation.de>
date Wed, 21 Nov 2018 08:15:28 +0100
parents a45fa8943254
children 9f37424f0cfa
files client/src/App.vue client/src/drawtool/Drawtool.vue client/src/identify/Identify.vue client/src/layers/Layers.vue client/src/morphtool/Morphtool.vue client/src/pdftool/Pdftool.vue client/src/store/map.js client/src/toolbar/Toolbar.vue client/src/toolbar/buttons/Cuttool.vue client/src/toolbar/buttons/Identify.vue client/src/toolbar/buttons/Layers.vue client/src/toolbar/buttons/Linetool.vue client/src/toolbar/buttons/Pdftool.vue client/src/toolbar/buttons/Polygontool.vue
diffstat 14 files changed, 427 insertions(+), 268 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/App.vue	Tue Nov 20 18:05:19 2018 +0100
+++ b/client/src/App.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -12,13 +12,13 @@
                 <div class="ml-auto d-flex">
                     <Layers v-if="routeName == 'mainview'"></Layers>
                     <Identify v-if="routeName == 'mainview'"></Identify>
+                    <Pdftool v-if="routeName == 'mainview'"></Pdftool>
+                    <Toolbar v-if="routeName == 'mainview'"></Toolbar>
                 </div>
             </div>
             <div class="flex-fill"></div>
             <div class="d-flex flex-row align-items-end">
                 <Morphtool v-if="routeName == 'mainview'"></Morphtool>
-                <Pdftool v-if="routeName == 'mainview'"></Pdftool>
-                <Drawtool v-if="routeName == 'mainview'"></Drawtool>
             </div>
             <Zoom v-if="routeName == 'mainview'"></Zoom>
         </div>
@@ -80,7 +80,6 @@
     }
   },
   components: {
-    Drawtool: () => import("./drawtool/Drawtool"),
     Morphtool: () => import("./morphtool/Morphtool"),
     Pdftool: () => import("./pdftool/Pdftool"),
     Zoom: () => import("./zoom/zoom"),
@@ -88,7 +87,8 @@
     Layers: () => import("./layers/Layers"),
     Sidebar: () => import("./application/Sidebar"),
     Search: () => import("./application/Search"),
-    Contextbox: () => import("./application/Contextbox")
+    Contextbox: () => import("./application/Contextbox"),
+    Toolbar: () => import("./toolbar/Toolbar")
   }
 };
 </script>
--- a/client/src/drawtool/Drawtool.vue	Tue Nov 20 18:05:19 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-<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
-            ? Math.round(areaSize / 1000) / 1000 // convert into 1 km² == 1000*1000 m² and round to 1000 m²
-            : 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>
--- a/client/src/identify/Identify.vue	Tue Nov 20 18:05:19 2018 +0100
+++ b/client/src/identify/Identify.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -1,20 +1,9 @@
 <template>
-    <div class="position-relative ml-3">
-        <div
-            @click="$store.commit('application/showIdentify', !showIdentify)"
-            class="d-flex flex-column ui-element minimizer mt-1"
-        >
-            <div :class="infoStyle">
-                <i class="fa fa-info"></i>
-            </div>
-        </div>
-        <div :class="identifyStyle">
-            <div v-if="showIdentify" class="card-body">
-                <div class="headline">
-                    <h4>Identified</h4>
-                </div>
-                <hr>
-                <div class="d-flex flex-column features">
+    <div class="position-relative mx-2">
+        <div :class="style">
+            <div v-if="showIdentify" class="p-3 d-flex flex-column">
+                <h4 class="pb-3 border-bottom">Identified</h4>
+                <div class="d-flex flex-column features flex-grow-1">
                     <small v-if="currentMeasurement">
                         <b>
                           {{ currentMeasurement.quantity }}
@@ -33,9 +22,12 @@
                             </small>
                         </div>
                     </div>
+                    <div v-if="!currentMeasurement && !identifiedFeatures.length" class="text-muted small text-center my-auto">
+                        No features identified.
+                    </div>
                 </div>
-                <div class="versioninfo">
-                    <hr>gemma
+                <div class="versioninfo border-top pt-1 mt-3">
+                    gemma
                     <a href="https://hg.intevation.de/gemma/file/tip">source-code</a>
                     {{ versionStr }}
                     <br>Some data ©
@@ -58,19 +50,13 @@
   opacity: $slight-transparent
 
 .identifycollapsed
-  min-height: $icon-height
-  width: $icon-width
+  min-height: 0
+  width: 0
   transition: $transition-fast
 
 .identifyexpanded
+  min-height: $identify-height
   width: $identify-width
-
-.minimizer
-  position: absolute
-  z-index: 2
-  right: 0
-  height: $icon-width
-  width: $icon-height
 </style>
 
 <script>
@@ -96,21 +82,14 @@
     ...mapGetters("application", ["versionStr"]),
     ...mapState("application", ["showIdentify"]),
     ...mapState("map", ["identifiedFeatures", "currentMeasurement"]),
-    identifyStyle() {
+    style() {
       return [
-        "ui-element rounded identify shadow bg-white text-left",
+        "ui-element rounded identify shadow bg-white text-left d-flex",
         {
           identifyexpanded: this.showIdentify,
           identifycollapsed: !this.showIdentify
         }
       ];
-    },
-    infoStyle() {
-      return {
-        info: true,
-        "text-info":
-          this.identifiedFeatures && this.identifiedFeatures.length > 0
-      };
     }
   },
   methods: {
--- a/client/src/layers/Layers.vue	Tue Nov 20 18:05:19 2018 +0100
+++ b/client/src/layers/Layers.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -1,18 +1,17 @@
 <template>
-    <div class="position-relative ml-auto">
-        <div @click="$store.commit('application/showLayers', !showLayers)" class="d-flex flex-column ui-element minimizer position-absolute mt-1">
-            <div>
-                <i class="fa fa-th-list"></i>
-            </div>
-        </div>
-        <div :class="layerSelectStyle">
-            <div v-if="showLayers" class="p-3 border-0 layers">
-                <div class="headline">
-                    <h4>Layers</h4>
-                </div>
-                <hr>
+    <div class="position-relative mx-2">
+        <div :class="style">
+            <div v-if="showLayers" class="p-3">
+                <h4 class="pb-3 border-bottom">Layers</h4>
                 <div class="d-flex flex-column">
-                    <Layerselect :layerindex="index" :layername="layer.name" v-for="(layer, index) in layersForLegend" :key="layer.name" :isVisible="layer.isVisible" @visibilityToggled="visibilityToggled"></Layerselect>
+                    <Layerselect
+                        v-for="(layer, index) in layersForLegend"
+                        :layerindex="index"
+                        :layername="layer.name"
+                        :key="layer.name"
+                        :isVisible="layer.isVisible"
+                        @visibilityToggled="visibilityToggled"
+                    ></Layerselect>
                 </div>
             </div>
         </div>
@@ -24,19 +23,13 @@
   opacity: $slight-transparent
 
 .layerselectioncollapsed
-  min-height: $icon-height
-  width: $icon-width
+  min-height: 0
+  width: 0
   transition: $transition-fast
 
 .layerselectionexpanded
   min-height: $layerselect-height
   width: $layerselect-width
-
-.minimizer
-  z-index: 2
-  right: 0
-  height: $icon-width
-  width: $icon-height
 </style>
 
 <script>
@@ -64,7 +57,7 @@
   computed: {
     ...mapGetters("map", ["layersForLegend"]),
     ...mapState("application", ["showLayers"]),
-    layerSelectStyle() {
+    style() {
       return [
         "ui-element rounded layerselection bg-white shadow",
         {
--- a/client/src/morphtool/Morphtool.vue	Tue Nov 20 18:05:19 2018 +0100
+++ b/client/src/morphtool/Morphtool.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -1,5 +1,5 @@
 <template>
-    <div class="mb-3 ml-auto rounded position-relative">
+    <div class="mb-3 mr-3 ml-auto rounded position-relative">
         <div v-if="selectedBottleneck && surveys && !selectedSurvey" class="ui-element bg-white rounded p-3 shadow">
             <h4 class="text-center mx-4">{{ selectedBottleneck }}</h4>
             <hr>
--- a/client/src/pdftool/Pdftool.vue	Tue Nov 20 18:05:19 2018 +0100
+++ b/client/src/pdftool/Pdftool.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -1,16 +1,9 @@
 <template>
-    <div class="pdftool position-absolute mr-3 mb-3" :style="selectedSurvey ? 'bottom: 140px' : ''">
-        <div @click="$store.commit('application/showPdfTool', !showPdfTool)" class="d-flex flex-column ui-element minimizer position-absolute mt-1">
-            <i :class="['fa', 'mt-1', {'fa-file-pdf-o': !showPdfTool}, {'fa-close': showPdfTool}]"></i>
-        </div>
+    <div class="position-relative mx-2">
         <div :class="style">
-            <div v-if="showPdfTool" class="card-body">
-                <div class="headline">
-                    <h4>Generate PDF</h4>
-                </div>
-                <hr>
+            <div v-if="showPdfTool" class="p-3 d-flex flex-column">
+                <h4 class="pb-3 border-bottom">Generate PDF</h4>
                 <b>Chose format:</b>
-                <br>
                 <select v-model="form.format" class="d-block w-100">
                     <option>landscape</option>
                     <option>portrait</option>
@@ -44,26 +37,16 @@
 
 <style lang="sass" scoped>
 .pdftool
-  bottom: 96px
-  right: 0
-
-.inner
   opacity: $slight-transparent
 
 .pdftoolcollapsed
-  min-height: $icon-height
-  width: $icon-width
+  min-height: 0
+  width: 0
   transition: $transition-fast
 
 .pdftoolexpanded
-  width: $identify-width
-
-.minimizer
-  z-index: 2
-  right: 0
-  top: 0
-  height: $icon-width
-  width: $icon-height
+  min-height: 204px
+  width: 16rem
 </style>
 
 <script>
@@ -99,7 +82,7 @@
     ...mapState("bottlenecks", ["selectedSurvey"]),
     style() {
       return [
-        "ui-element rounded inner ml-2 bg-white text-left shadow",
+        "ui-element rounded pdftool bg-white shadow",
         {
           pdftoolexpanded: this.showPdfTool,
           pdftoolcollapsed: !this.showPdfTool
--- a/client/src/store/map.js	Tue Nov 20 18:05:19 2018 +0100
+++ b/client/src/store/map.js	Wed Nov 21 08:15:28 2018 +0100
@@ -37,7 +37,7 @@
   state: {
     openLayersMap: null,
     identifiedFeatures: [], // map features identified by clicking on the map
-    currentMeasurement: null, // distance or area from drawTool
+    currentMeasurement: null, // distance or area from line-/polygon-/cutTool
     lineTool: null, // open layers interaction object (Draw)
     polygonTool: null, // open layers interaction object (Draw)
     cutTool: null, // open layers interaction object (Draw)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/toolbar/Toolbar.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -0,0 +1,77 @@
+<template>
+    <div class="ml-3">
+        <Identify></Identify>
+        <Layers></Layers>
+        <Linetool></Linetool>
+        <Polygontool></Polygontool>
+        <Cuttool></Cuttool>
+        <Pdftool></Pdftool>
+    </div>
+</template>
+
+<style lang="sass">
+// not scoped to affect nested components
+.toolbar-button
+  height: $icon-width
+  width: $icon-height
+  align-items: center
+  justify-content: center
+  display: flex
+  background: #fff
+  margin-bottom: $offset
+  border-radius: $border-radius
+  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15)
+  z-index: 2
+  pointer-events: auto
+  .inverted
+    color: #07f
+  .grey
+    color: #ddd
+</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):
+ * Markus Kottländer <markus.kottlaender@intevation.de>
+ */
+import { mapState, mapGetters } from "vuex";
+
+export default {
+  name: "toolbar",
+  components: {
+    Identify: () => import("./buttons/Identify.vue"),
+    Layers: () => import("./buttons/Layers.vue"),
+    Linetool: () => import("./buttons/Linetool.vue"),
+    Polygontool: () => import("./buttons/Polygontool.vue"),
+    Cuttool: () => import("./buttons/Cuttool.vue"),
+    Pdftool: () => import("./buttons/Pdftool.vue")
+  },
+  computed: {
+    ...mapGetters("map", ["getLayerByName"]),
+    ...mapState("map", ["lineTool", "polygonTool", "cutTool"])
+  },
+  mounted() {
+    window.addEventListener("keydown", e => {
+      // Escape
+      if (e.keyCode === 27) {
+        this.lineTool.setActive(false);
+        this.polygonTool.setActive(false);
+        this.cutTool.setActive(false);
+        this.$store.commit("map/setCurrentMeasurement", null);
+        this.getLayerByName("Draw Tool")
+          .data.getSource()
+          .clear();
+      }
+    });
+  }
+};
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/toolbar/buttons/Cuttool.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -0,0 +1,76 @@
+<template>
+  <div @click="toggleCutTool" class="toolbar-button">
+      <i :class="['fa fa-area-chart', { inverted: cutTool && cutTool.getActive(), grey: !selectedSurvey }]"></i>
+  </div>
+</template>
+
+<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):
+ * Markus Kottländer <markus.kottlaender@intevation.de>
+ */
+import { mapState, mapGetters } from "vuex";
+import Draw from "ol/interaction/Draw.js";
+import { Stroke, Style, Circle, Fill } from "ol/style.js";
+
+export default {
+  name: "cuttool",
+  computed: {
+    ...mapGetters("map", ["getLayerByName"]),
+    ...mapState("map", ["lineTool", "polygonTool", "cutTool", "openLayersMap"]),
+    ...mapState("bottlenecks", ["selectedSurvey"])
+  },
+  methods: {
+    toggleCutTool() {
+      console.log(this.selectedSurvey);
+      if (this.selectedSurvey) {
+        this.cutTool.setActive(!this.cutTool.getActive());
+        this.lineTool.setActive(false);
+        this.polygonTool.setActive(false);
+        this.$store.commit("map/setCurrentMeasurement", null);
+      }
+    },
+    cutEnd(event) {
+      this.$store.dispatch("fairwayprofile/cut", event.feature);
+    }
+  },
+  created() {
+    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);
+    }
+  }
+};
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/toolbar/buttons/Identify.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -0,0 +1,29 @@
+<template>
+    <div @click="$store.commit('application/showLayers', !showLayers)" class="toolbar-button">
+        <i :class="['fa fa-th-list', {inverted: showLayers}]"></i>
+    </div>
+</template>
+
+<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):
+ * Markus Kottländer <markus.kottlaender@intevation.de>
+ */
+import { mapState } from "vuex";
+
+export default {
+  name: "layers",
+  computed: {
+    ...mapState("application", ["showLayers"])
+  }
+};
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/toolbar/buttons/Layers.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -0,0 +1,29 @@
+<template>
+    <div @click="$store.commit('application/showIdentify', !showIdentify)" class="toolbar-button">
+        <i :class="['fa fa-info', {inverted: showIdentify}]"></i>
+    </div>
+</template>
+
+<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):
+ * Markus Kottländer <markus.kottlaender@intevation.de>
+ */
+import { mapState } from "vuex";
+
+export default {
+  name: "identify",
+  computed: {
+    ...mapState("application", ["showIdentify"])
+  }
+};
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/toolbar/buttons/Linetool.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -0,0 +1,70 @@
+<template>
+    <div @click="toggleLineTool" class="toolbar-button">
+        <i :class="['fa fa-pencil', {inverted: lineTool && lineTool.getActive()}]"></i>
+    </div>
+</template>
+
+<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):
+ * Markus Kottländer <markus.kottlaender@intevation.de>
+ */
+import { mapState, mapGetters } from "vuex";
+import { getLength } from "ol/sphere.js";
+import Draw from "ol/interaction/Draw.js";
+
+export default {
+  name: "linetool",
+  computed: {
+    ...mapGetters("map", ["getLayerByName"]),
+    ...mapState("map", ["lineTool", "polygonTool", "cutTool", "openLayersMap"])
+  },
+  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();
+    },
+    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);
+    }
+  },
+  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);
+    }
+  }
+};
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/toolbar/buttons/Pdftool.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -0,0 +1,29 @@
+<template>
+    <div @click="$store.commit('application/showPdfTool', !showPdfTool)" class="toolbar-button">
+        <i :class="['fa fa-file-pdf-o', {inverted: showPdfTool}]"></i>
+    </div>
+</template>
+
+<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):
+ * Markus Kottländer <markus.kottlaender@intevation.de>
+ */
+import { mapState } from "vuex";
+
+export default {
+  name: "pdftool",
+  computed: {
+    ...mapState("application", ["showPdfTool"])
+  }
+};
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/toolbar/buttons/Polygontool.vue	Wed Nov 21 08:15:28 2018 +0100
@@ -0,0 +1,73 @@
+<template>
+    <div @click="togglePolygonTool" class="toolbar-button">
+        <i :class="['fa fa-edit', {inverted: polygonTool && polygonTool.getActive()}]"></i>
+    </div>
+</template>
+
+<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):
+ * Markus Kottländer <markus.kottlaender@intevation.de>
+ */
+import { mapState, mapGetters } from "vuex";
+import { getArea } from "ol/sphere.js";
+import Draw from "ol/interaction/Draw.js";
+
+export default {
+  name: "polygontool",
+  computed: {
+    ...mapGetters("map", ["getLayerByName"]),
+    ...mapState("map", ["lineTool", "polygonTool", "cutTool", "openLayersMap"])
+  },
+  methods: {
+    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();
+    },
+    polygonEnd(event) {
+      const areaSize = getArea(event.feature.getGeometry());
+      this.$store.commit("map/setCurrentMeasurement", {
+        quantity: "Area",
+        unitSymbol: areaSize > 100000 ? "km²" : "m²",
+        value:
+          areaSize > 100000
+            ? Math.round(areaSize / 1000) / 1000 // convert into 1 km² == 1000*1000 m² and round to 1000 m²
+            : Math.round(areaSize)
+      });
+      this.$store.commit("application/showIdentify", true);
+    }
+  },
+  created() {
+    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);
+    }
+  }
+};
+</script>