view client/src/components/layers/LegendElement.vue @ 5629:84d01a536bec 729-node-js-newer-version

Transformed scss and sass styles into css
author Luisa Beerboom <lbeerboom@intevation.de>
date Thu, 11 May 2023 13:23:52 +0200
parents 453a33b0717d
children
line wrap: on
line source

<template>
  <div :id="id" class="legendelement">
    <div v-if="layer.get('id') === 'FAIRWAYMARKS'">
      <img
        v-if="!isVectorLayer"
        style="margin: 0 auto;display: flex;"
        src="@/assets/fm_legend.svg"
        :key="id"
      />
    </div>
    <div v-else="">
      <img
        v-if="!isVectorLayer"
        style="margin: 0 auto;display: flex;"
        :src="imgSrc"
        :key="id"
      />
    </div>
  </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):
 * Thomas Junk <thomas.junk@intevation.de>
 */
import { mapState } from "vuex";

import { Map, View } from "ol";
import Feature from "ol/Feature";
import { Vector as VectorLayer } from "ol/layer";
import { Vector as VectorSource } from "ol/source";
import Polygon from "ol/geom/Polygon";
import LineString from "ol/geom/LineString";
import Point from "ol/geom/Point";
import { HTTP } from "@/lib/http";
import { Stroke, Style, Fill } from "ol/style";

export default {
  props: ["layer"],
  data: function() {
    return {
      myMap: null,
      src: null,
      url: null
    };
  },
  computed: {
    ...mapState("map", ["layers", "ongoingRefresh"]),
    isVectorLayer() {
      return this.layer.getType() === "VECTOR";
    },
    imgSrc() {
      // if (this.layer.get("id") === "DISTANCEMARKSAXIS") {
      //   return require("@/assets/distancemarks-axis.png");
      // }
      return this.src;
    },
    id() {
      return (
        "legendelement-" +
        this.layer
          .get("label")
          .toLowerCase()
          .replace(/\s/g, "")
      );
    },
    mstyle() {
      if (this.layer && this.layer.getStyle) {
        return this.layer.getStyle();
      }
    }
  },
  watch: {
    ongoingRefresh() {
      if (this.ongoingRefresh) return;
      if (
        this.layer.get("id") === "OPENSTREETMAP" ||
        this.layer.get("id") === "INLANDECDIS" ||
        this.layer.get("id") === "BOTTLENECKISOLINE" ||
        this.layer.get("id") === "DIFFERENCES"
      ) {
        // TODO: Do something useful?
        return;
      }
      if (this.isVectorLayer) {
        this.recreateLayers();
      } else {
        this.loadImageSrc();
      }
    },
    mstyle(newStyle, oldStyle) {
      // only recreate if there already was a style before
      if (oldStyle) {
        this.recreateLayers();
      }
    }
  },
  mounted() {
    if (this.layer.getType() == "VECTOR") {
      this.initMap();
    } else {
      if (
        this.layer.get("id") === "OPENSTREETMAP" ||
        this.layer.get("id") === "INLANDECDIS" ||
        this.layer.get("id") === "BOTTLENECKISOLINE" ||
        this.layer.get("id") === "DIFFERENCES"
      ) {
        // TODO: Do something useful?
        return;
      }
      if (this.layer.get("id") !== "DISTANCEMARKSAXIS") {
        this.url =
          `/internal/wms?REQUEST=GetLegendGraphic&VERSION=1.0.0&FORMAT=image/png&WIDTH=20&HEIGHT=20&LAYER=` +
          this.layer.getSource().getParams().LAYERS +
          `&legend_options=columns:4%3BfontAntiAliasing:true`;
      } else {
        this.url =
          `/internal/wms?REQUEST=GetLegendGraphic&VERSION=1.0.0&SCALE=80000&FORMAT=image/png&WIDTH=20&HEIGHT=20&LAYER=` +
          this.layer.getSource().getParams().LAYERS +
          `&legend_options=columns:1%3BfontAntiAliasing:true%3BforceLabels:off`;
      }

      this.loadImageSrc();
    }
  },
  methods: {
    loadImageSrc() {
      HTTP.get(this.url, {
        headers: {
          "X-Gemma-Auth": localStorage.getItem("token")
        },
        responseType: "blob"
      }).then(response => {
        this.src = URL.createObjectURL(response.data);
      });
    },
    recreateLayers() {
      let vector = this.createVectorLayer();

      this.myMap.removeLayer(this.myMap.getLayers().getArray()[0]);

      this.myMap.addLayer(vector);
    },
    initMap() {
      let vector = this.createVectorLayer();

      this.myMap = new Map({
        layers: [vector],
        target: this.id,
        controls: [],
        interactions: [],
        view: new View({
          enableRotation: false,
          center: [0, 0],
          zoom: 3,
          projection: "EPSG:4326"
        })
      });
    },
    createVectorLayer() {
      let mapStyle = this.layer.getStyle();
      let feature;
      // show bottleneck legend as polygon
      if (this.layer.get("id") === "BOTTLENECKS") {
        feature = new Feature({
          geometry: new Polygon([
            [
              [-1.7, -1.2],
              [-1.7, 0.5],
              [1.7, 1.2],
              [1.7, -0.5]
            ]
          ])
        });
        if (typeof mapStyle === "function") {
          mapStyle = mapStyle();
        }
        mapStyle = new Style({
          stroke: new Stroke({
            color: mapStyle.getStroke().getColor(),
            // reduce the stroke width for better layout in map legend.
            width: 2
          }),
          fill: new Fill({
            color: mapStyle.getFill().getColor()
          })
        });
      } else {
        feature = new Feature({
          geometry: new LineString([
            [-1, -1],
            [0, 0],
            [1, 1]
          ])
        });
      }
      // special case if we need to call the style function with a special
      // parameter or to detect a point layer
      let legendStyle = this.layer.get("forLegendStyle");
      if (legendStyle) {
        if (legendStyle) {
          feature.setGeometry(new Point([0, 0]));
        }
        mapStyle = this.layer.getStyleFunction()(
          feature,
          legendStyle.resolution,
          true
        );
      }

      // we could add extra properties here, if they are needed for
      // the styling function in the future. An idea is to extend the
      // this.layer["forLegendStyle"] for it.
      // FIXME, this is a special case for the Fairway Dimensions style
      feature.set("level_of_service", "");
      return new VectorLayer({
        source: new VectorSource({
          features: [feature],
          wrapX: false
        }),
        style: mapStyle
      });
    }
  }
};
</script>

<style scoped>
.legendelement {
  max-height: 1.5rem;
  width: 2rem;
  overflow: hidden;
}
</style>