view client/src/store/map.js @ 1121:035dc35e1dfc store-refactoring

moved draw layer in map store's layers property and added a flag for layers to show in legend or not
author Markus Kottlaender <markus@intevation.de>
date Tue, 06 Nov 2018 10:00:13 +0100
parents 1b160eda22cf
children a4c74a95c177
line wrap: on
line source

/*
 * 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 { HTTP } from "../lib/http";

import TileWMS from "ol/source/TileWMS.js";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer.js";
import OSM from "ol/source/OSM";
import {
  Icon,
  Stroke,
  Style,
  Fill,
  Text,
  Circle as CircleStyle
} from "ol/style.js";
import VectorSource from "ol/source/Vector.js";
import Point from "ol/geom/Point.js";
import { bbox as bboxStrategy } from "ol/loadingstrategy";
import { HTTP } from "../application/lib/http";

export default {
  namespaced: true,
  state: {
    openLayersMap: null,
    identifiedFeatures: [],
    currentMeasurement: null,
    // there are three states of drawMode: null, "LineString", "Polygon"
    drawMode: null,
    layers: [
      {
        name: "Open Streetmap",
        data: new TileLayer({
          source: new OSM()
        }),
        isVisible: true,
        showInLegend: true
      },
      {
        name: "Inland ECDIS chart Danube",
        data: new TileLayer({
          source: new TileWMS({
            preload: 1,
            url: "https://demo.d4d-portal.info/wms",
            params: { LAYERS: "d4d", VERSION: "1.1.1", TILED: true }
          })
        }),
        isVisible: true,
        showInLegend: true
      },
      {
        name: "Fairway Dimensions",
        data: new VectorLayer({
          source: new VectorSource(),
          style: function(feature) {
            return [
              new Style({
                stroke: new Stroke({
                  color: "rgba(0, 0, 255, 1.0)",
                  width: 2
                })
              }),
              new Style({
                text: new Text({
                  font: 'bold 12px "Open Sans", "sans-serif"',
                  placement: "line",
                  fill: new Fill({
                    color: "black"
                  }),
                  text: "LOS: " + feature.get("level_of_service").toString()
                  //, zIndex: 10
                })
              })
            ];
          }
        }),
        isVisible: true,
        showInLegend: true
      },
      {
        name: "Waterway Area, named",
        data: new VectorLayer({
          source: new VectorSource({
            strategy: bboxStrategy
          }),
          style: new Style({
            stroke: new Stroke({
              color: "rgba(0, 132, 0, 1)",
              width: 2
            })
          })
        }),
        isVisible: false,
        showInLegend: true
      },
      {
        name: "Waterway Area",
        data: new VectorLayer({
          source: new VectorSource({
            strategy: bboxStrategy
          }),
          style: new Style({
            stroke: new Stroke({
              color: "rgba(0, 102, 0, 1)",
              width: 2
            })
          })
        }),
        isVisible: true,
        showInLegend: true
      },
      {
        name: "Waterway Axis",
        data: new VectorLayer({
          source: new VectorSource({
            strategy: bboxStrategy
          }),
          style: new Style({
            stroke: new Stroke({
              color: "rgba(0, 0, 255, .5)",
              lineDash: [5, 5],
              width: 2
            })
          })
        }),
        isVisible: true,
        showInLegend: true
      },
      {
        name: "Distance marks",
        forLegendStyle: { point: true, resolution: 8 },
        data: new VectorLayer({
          source: new VectorSource({
            strategy: bboxStrategy
          })
        }),
        isVisible: false,
        showInLegend: true
      },
      {
        name: "Bottlenecks",
        data: new VectorLayer({
          source: new VectorSource({
            strategy: bboxStrategy
          }),
          style: new Style({
            stroke: new Stroke({
              color: "rgba(230, 230, 10, .8)",
              width: 4
            }),
            fill: new Fill({
              color: "rgba(230, 230, 10, .3)"
            })
          })
        }),
        isVisible: true,
        showInLegend: true
      },
      {
        name: "Bottleneck isolines",
        data: new TileLayer({
          source: new TileWMS({
            preload: 0,
            projection: "EPSG:3857",
            url: window.location.origin + "/api/internal/wms",
            params: {
              LAYERS: "sounding_results_contour_lines_geoserver",
              VERSION: "1.1.1",
              TILED: true
            },
            tileLoadFunction: function(tile, src) {
              // console.log("calling for", tile, src);
              HTTP.get(src, {
                headers: {
                  "X-Gemma-Auth": localStorage.getItem("token")
                },
                responseType: "blob"
              }).then(response => {
                tile.getImage().src = URL.createObjectURL(response.data);
              });
            } // TODO  tile.setState(TileState.ERROR);
          })
        }),
        isVisible: false,
        showInLegend: true
      },
      {
        name: "Distance marks, Axis",
        forLegendStyle: { point: true, resolution: 8 },
        data: new VectorLayer({
          source: new VectorSource({
            strategy: bboxStrategy
          }),
          style: function(feature, resolution) {
            if (resolution < 10) {
              var s = new Style({
                image: new CircleStyle({
                  radius: 5,
                  fill: new Fill({ color: "rgba(255, 0, 0, 0.1)" }),
                  stroke: new Stroke({ color: "blue", width: 1 })
                })
              });
              if (resolution < 6) {
                s.setText(
                  new Text({
                    offsetY: 12,
                    font: '10px "Open Sans", "sans-serif"',
                    fill: new Fill({
                      color: "black"
                    }),
                    text: (feature.get("hectometre") / 10).toString()
                  })
                );
              }
              return s;
            } else {
              return [];
            }
          }
        }),
        isVisible: true,
        showInLegend: true
      },
      {
        name: "Draw Tool",
        data: new VectorLayer({
          source: new VectorSource({ wrapX: false }),
          style: function(feature) {
            // adapted from OpenLayer's LineString Arrow Example
            var geometry = feature.getGeometry();
            var styles = [
              // linestring
              new Style({
                stroke: new Stroke({
                  color: "#369aca",
                  width: 2
                })
              })
            ];

            if (geometry.getType() === "LineString") {
              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;
          }
        }),
        isVisible: true,
        showInLegend: false
      }
    ]
  },
  getters: {
    layers: state => {
      return state.layers;
    },
    layersForLegend: state => {
      return state.layers.filter(layer => layer.showInLegend);
    },
    getLayerByName: state => name => {
      return state.layers.find(layer => layer.name === name);
    }
  },
  mutations: {
    toggleVisibility: (state, layer) => {
      state.layers[layer].isVisible = !state.layers[layer].isVisible;
      state.layers[layer].data.setVisible(state.layers[layer].isVisible);
    },
    setOpenLayersMap: (state, map) => {
      state.openLayersMap = map;
    },
    setIdentifiedFeatures: (state, identifiedFeatures) => {
      state.identifiedFeatures = identifiedFeatures;
    },
    setCurrentMeasurement: (state, measurement) => {
      state.currentMeasurement = measurement;
    },
    toggleDrawModeLine: state => {
      if (state.drawMode) {
        state.drawMode = null;
      } else {
        state.drawMode = "LineString";
      }
    },
    activateDrawModePolygon: state => {
      state.drawMode = "Polygon";
    }
  }
};