view client/src/store/gauges.js @ 5588:94ef43fac0eb surveysperbottleneckid

Make BN for overview distinguishable
author Thomas Junk <thomas.junk@intevation.de>
date Tue, 05 Apr 2022 10:15:37 +0200
parents de86a96d55c3
children
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):
 * Markus Kottländer <markus@intevation.de>
 */
import Vue from "vue";
import { HTTP } from "@/lib/http";
import { WFS } from "ol/format";
import {
  isPast,
  startOfDay,
  endOfDay,
  format,
  isBefore,
  addMinutes
} from "date-fns";

let dateFrom = new Date();
dateFrom.setDate(dateFrom.getDate() - 30);
let dateTo = new Date();
dateTo.setDate(dateTo.getDate() + 3);

const init = () => {
  return {
    gauges: [],
    selectedGaugeISRS: null,
    waterlevels: [],
    waterlevelsCSV: "",
    longtermWaterlevels: [],
    longtermInterval: [],
    yearWaterlevels: [],
    nashSutcliffe: null,
    nashSutcliffeCache: {},
    dateFrom: dateFrom,
    dateTo: dateTo,
    yearCompare: new Date().getFullYear()
  };
};

export default {
  init,
  namespaced: true,
  state: init(),
  getters: {
    selectedGauge: state => {
      return state.gauges.find(
        g => g.properties.isrs_code === state.selectedGaugeISRS
      );
    }
  },
  mutations: {
    addNSCtoCache: (state, entry) => {
      const { isrsCode, nsc, timestamp } = entry;
      Vue.set(state.nashSutcliffeCache, isrsCode, {
        nsc,
        timestamp
      });
    },
    gauges: (state, gauges) => {
      state.gauges = gauges;
    },
    selectedGaugeISRS: (state, isrs) => {
      state.selectedGaugeISRS = isrs;
    },
    waterlevels: (state, data) => {
      state.waterlevels = data;
    },
    waterlevelsCSV: (state, data) => {
      state.waterlevelsCSV = data;
    },
    longtermWaterlevels: (state, data) => {
      state.longtermWaterlevels = data;
    },
    longtermInterval: (state, interval) => {
      state.longtermInterval = interval;
    },
    yearWaterlevels: (state, data) => {
      state.yearWaterlevels = data;
    },
    nashSutcliffe: (state, data) => {
      state.nashSutcliffe = data;
    },
    deleteNashSutcliffeCache: state => {
      state.nashSutcliffeCache = {};
    },
    dateFrom: (state, dateFrom) => {
      state.dateFrom = dateFrom;
    },
    dateTo: (state, dateTo) => {
      state.dateTo = dateTo;
    },
    yearCompare: (state, year) => {
      state.yearCompare = year;
    }
  },
  actions: {
    getNashSutcliffeForISRS: ({ state, commit }, isrsCode) => {
      return new Promise((resolve, reject) => {
        const now = new Date();
        let nashSutcliffe = state.nashSutcliffeCache[isrsCode];
        if (nashSutcliffe) {
          const { timestamp, nsc } = nashSutcliffe;
          const isRecent = isBefore(now, addMinutes(timestamp, 15));
          if (isRecent) {
            resolve(nsc);
            return;
          }
        }
        HTTP.get(`/data/nash-sutcliffe/${isrsCode}`, {
          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
        })
          .then(response => {
            nashSutcliffe = response.data;
            commit("addNSCtoCache", {
              isrsCode,
              nsc: nashSutcliffe,
              timestamp: now
            });
            resolve(nashSutcliffe);
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    setSelectedGaugeISRS: ({ commit, state }, isrs) => {
      if (state.selectedGaugeISRS !== isrs) {
        commit("selectedGaugeISRS", isrs);
      }
    },
    selectedGaugeISRS: ({ commit, dispatch, state }, isrs) => {
      if (state.selectedGaugeISRS !== isrs) {
        commit("selectedGaugeISRS", isrs);
        commit("application/showGauges", true, { root: true });
        dispatch("loadWaterlevels");
        dispatch("loadLongtermWaterlevels");
        dispatch("loadYearWaterlevels");
        dispatch("loadNashSutcliffe");
      }
    },
    loadGauges: ({ commit }) => {
      return new Promise((resolve, reject) => {
        var gaugesFeatureCollectionRequest = new WFS().writeGetFeature({
          srsName: "EPSG:4326",
          featureNS: "gemma",
          featurePrefix: "gemma",
          featureTypes: ["gauges_geoserver"],
          outputFormat: "application/json"
        });
        HTTP.post(
          "/internal/wfs",
          new XMLSerializer().serializeToString(gaugesFeatureCollectionRequest),
          {
            headers: {
              "X-Gemma-Auth": localStorage.getItem("token"),
              "Content-type": "text/xml; charset=UTF-8"
            }
          }
        )
          .then(response => {
            commit("gauges", response.data.features);
            resolve(response);
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    loadWaterlevels({ state, commit }) {
      return new Promise((resolve, reject) => {
        HTTP.get(
          `/data/waterlevels/${
            state.selectedGaugeISRS
          }?from=${encodeURIComponent(
            format(startOfDay(state.dateFrom), "YYYY-MM-DDTHH:mm:ssZ")
          )}&to=${encodeURIComponent(
            format(endOfDay(state.dateTo), "YYYY-MM-DDTHH:mm:ssZ")
          )}`,
          {
            headers: { "X-Gemma-Auth": localStorage.getItem("token") }
          }
        )
          .then(response => {
            commit("waterlevelsCSV", response.data);
            let data = response.data
              .split("\n")
              // remove empty rows and rows starting with #
              .filter(wl => wl && wl[0] !== "#")
              .map(wl => {
                wl = wl.split(",");
                return {
                  date: new Date(wl[0]),
                  waterlevel: Number(wl[1]),
                  min: Number(wl[2]),
                  max: Number(wl[3]),
                  predicted: wl[4] === "f" ? false : true
                };
              })
              .filter(wl => !(wl.predicted && isPast(wl.date)));
            data = data.sort((a, b) => a.date - b.date);
            commit("waterlevels", data);
            resolve(data);
          })
          .catch(error => {
            commit("waterlevels", []);
            reject(error);
          });
      });
    },
    loadLongtermWaterlevels({ state, commit }) {
      return new Promise((resolve, reject) => {
        HTTP.get(`/data/longterm-waterlevels/${state.selectedGaugeISRS}`, {
          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
        })
          .then(response => {
            const now = new Date();
            let data = response.data.split("\n");
            // get result interval from first line
            let interval = data[0]
              .split(",")[0]
              .split(" ")[1]
              .split("-")
              .map(y => Number(y));
            if (interval[0] === interval[1]) interval = [interval[0]];
            commit("longtermInterval", interval);
            data = data
              // remove empty rows and rows starting with #
              .filter(wl => wl && wl[0] !== "#")
              .map(wl => {
                wl = wl.split(",");
                let dayAndMonth = wl[0].split("-").map(n => Number(n));
                let date = new Date(
                  now.getFullYear(),
                  dayAndMonth[1] - 1,
                  dayAndMonth[0]
                );
                return {
                  date: date,
                  min: Number(wl[1]),
                  max: Number(wl[2]),
                  mean: Number(wl[3]),
                  median: Number(wl[4]),
                  q25: Number(wl[5]),
                  q75: Number(wl[6])
                };
              });
            data = data.sort((a, b) => a.date - b.date);
            commit("longtermWaterlevels", data);
            resolve(data);
          })
          .catch(error => {
            commit("longtermWaterlevels", []);
            reject(error);
          });
      });
    },
    loadYearWaterlevels({ state, commit }) {
      return new Promise((resolve, reject) => {
        HTTP.get(
          `/data/year-waterlevels/${state.selectedGaugeISRS}/${state.yearCompare}`,
          {
            headers: { "X-Gemma-Auth": localStorage.getItem("token") }
          }
        )
          .then(response => {
            const now = new Date();
            let data = response.data
              .split("\n")
              // remove empty rows and rows starting with #
              .filter(wl => wl && wl[0] !== "#")
              .map(wl => {
                wl = wl.split(",");
                let dayAndMonth = wl[0].split("-").map(n => Number(n));
                let date = new Date(
                  now.getFullYear(),
                  dayAndMonth[1] - 1,
                  dayAndMonth[0]
                );
                return {
                  date: date,
                  mean: Number(wl[1])
                };
              });
            data = data.sort((a, b) => a.date - b.date);
            commit("yearWaterlevels", data);
            resolve(data);
          })
          .catch(error => {
            commit("yearWaterlevels", []);
            reject(error);
          });
      });
    },
    loadNashSutcliffe({ state, commit }) {
      return new Promise((resolve, reject) => {
        HTTP.get(`/data/nash-sutcliffe/${state.selectedGaugeISRS}`, {
          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
        })
          .then(response => {
            commit("nashSutcliffe", response.data);
            resolve(response.data);
          })
          .catch(error => {
            commit("nashSutcliffe", null);
            reject(error);
          });
      });
    },
    loadNashSutcliffeForOverview(context, isrsCode) {
      return new Promise((resolve, reject) => {
        HTTP.get(`/data/nash-sutcliffe/${isrsCode}`, {
          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
        })
          .then(response => {
            resolve(response.data);
          })
          .catch(error => {
            reject(error);
          });
      });
    }
  }
};