diff client/src/map/Maplayer.vue @ 942:912d016275ee

client: add arrow to drawn linesegment * Add styling function that will place an icon png image at the end of each drawn line segment, in the right rotation. Note that this does not look perfectly centered, see comment in the code.
author Bernhard Reiter <bernhard@intevation.de>
date Tue, 09 Oct 2018 18:39:01 +0200
parents fe923c8ef08f
children c2b03f4755b6
line wrap: on
line diff
--- a/client/src/map/Maplayer.vue	Tue Oct 09 17:00:49 2018 +0200
+++ b/client/src/map/Maplayer.vue	Tue Oct 09 18:39:01 2018 +0200
@@ -33,11 +33,12 @@
 import { WFS, GeoJSON } from "ol/format.js";
 // import GeometryType from "ol/geom/GeometryType.js";
 import LineString from "ol/geom/LineString.js";
+import Point from "ol/geom/Point.js";
 import Draw from "ol/interaction/Draw.js";
 import { Vector as VectorLayer } from "ol/layer.js";
 import { Vector as VectorSource } from "ol/source.js";
 import { getLength } from "ol/sphere.js";
-import { Stroke, Style, Fill } from "ol/style.js";
+import { Icon, Stroke, Style, Fill } from "ol/style.js";
 
 import distance from "@turf/distance";
 import {
@@ -83,9 +84,49 @@
     createVectorSource() {
       this.vectorSource = new VectorSource({ wrapX: false });
     },
+    drawStyleFunction(feature) {
+      // adapted from OpenLayer's LineString Arrow Example
+      var geometry = feature.getGeometry();
+      var styles = [
+        // linestring
+        new Style({
+          stroke: new Stroke({
+            color: "#369aca",
+            width: 2
+          })
+        })
+      ];
+
+      geometry.forEachSegment(function(start, end) {
+        var dx = end[0] - start[0];
+        var dy = end[1] - start[1];
+        var rotation = Math.atan2(dy, dx);
+        // arrows
+        styles.push(
+          new Style({
+            geometry: new Point(end),
+            image: new Icon({
+              // we need to make sure the image is loaded by Vue Loader
+              src: require("../application/assets/linestring_arrow.png"),
+              // fiddling with the anchor's y value does not help to
+              // position the image more centered on the line ending, as the
+              // default line style seems to be slightly uncentered in the
+              // anti-aliasing, but the image is not placed with subpixel
+              // precision
+              anchor: [0.75, 0.5],
+              rotateWithView: true,
+              rotation: -rotation
+            })
+          })
+        );
+      });
+
+      return styles;
+    },
     createVectorLayer() {
       this.vectorLayer = new VectorLayer({
-        source: this.vectorSource
+        source: this.vectorSource,
+        style: this.drawStyleFunction
       });
     },
     removeCurrentInteraction() {