Mercurial > gemma
view client/src/store/fairway.js @ 2542:fc7d828695c9
Schema: Added caching schema containing the sounding differences.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 07 Mar 2019 15:55:25 +0100 |
parents | 3c17d401fbd4 |
children | 9bf6b767a56a |
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> * Markus Kottländer <markuks.kottlaender@intevation.de> */ import Vue from "vue"; import { HTTP } from "../lib/http"; import { prepareProfile } from "../lib/geo"; import LineString from "ol/geom/LineString.js"; import { generateFeatureRequest } from "../lib/geo.js"; import { getLength } from "ol/sphere.js"; import { displayError } from "../lib/errors.js"; import { featureToFairwayCoordinates } from "../lib/geo.js"; import { LAYERS } from "@/store/map.js"; // initial state const init = () => { return { additionalSurvey: null, minAlt: 0, maxAlt: 0, currentProfile: {}, referenceWaterLevel: null, waterLevels: {}, selectedWaterLevel: "", fairwayData: [], startPoint: null, endPoint: null, previousCuts: [], profileLoading: false, selectedCut: null }; }; export default { init, namespaced: true, state: init(), getters: { totalLength: state => { const keys = Object.keys(state.currentProfile); return keys.length ? Math.max(...keys.map(x => state.currentProfile[x].length)) : 0; }, additionalSurvey: state => { return state.additionalSurvey; } }, mutations: { additionalSurvey: (state, additionalSurvey) => { state.additionalSurvey = additionalSurvey; }, setSelectedWaterLevel: (state, level) => { state.selectedWaterLevel = state.waterLevels[level]; }, profileLoaded: (state, answer) => { const { response, surveyDate } = answer; const { data } = response; const { waterlevel } = response.data.properties; const { value, when } = waterlevel; const coordinates = data.geometry.coordinates; if (!coordinates) return; const startPoint = state.startPoint; const endPoint = state.endPoint; const geoJSON = data; const result = prepareProfile({ geoJSON, startPoint, endPoint }); // Use Vue.set() to make new object properties rective // https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats const entry = { date: when, value: value }; state.waterLevels = { [when]: entry }; state.selectedWaterLevel = entry; Vue.set(state.currentProfile, surveyDate, { points: result.points, length: result.lengthPolyLine }); if (!state.minAlt || state.minAlt > result.minAlt) { state.minAlt = result.minAlt; } if (!state.maxAlt || state.maxAlt < result.maxAlt) { state.maxAlt = result.maxAlt; } }, setStartPoint: (state, start) => { state.startPoint = start; }, setEndPoint: (state, end) => { state.endPoint = end; }, addFairwayData: (state, coordinates) => { state.fairwayData.push(coordinates); }, clearFairwayData: state => { state.fairwayData = []; }, clearCurrentProfile: state => { state.additionalSurvey = null; state.currentProfile = {}; state.minAlt = null; state.maxAlt = null; state.totalLength = null; state.fairwayData = []; state.startPoint = null; state.endPoint = null; state.referenceWaterLevel = null; state.waterLevels = {}; state.selectedWaterLevel = ""; }, previousCuts: (state, previousCuts) => { state.previousCuts = previousCuts; }, profileLoading: (state, loading) => { state.profileLoading = loading; }, selectedCut: (state, cut) => { state.selectedCut = cut; } }, actions: { clearSelection({ commit, dispatch, rootGetters, rootState }) { dispatch("bottlenecks/setSelectedBottleneck", null, { root: true }); dispatch("map/enableIdentifyTool", null, { root: true }); commit("clearCurrentProfile"); commit("application/showSplitscreen", false, { root: true }); rootState.map.cutTool.setActive(false); rootGetters["map/getVSourceByName"](LAYERS.CUTTOOL).clear(); }, loadProfile({ commit, state }, survey) { if (state.startPoint && state.endPoint) { return new Promise((resolve, reject) => { const profileLine = new LineString([ state.startPoint, state.endPoint ]); const geoJSON = generateFeatureRequest( profileLine, survey.bottleneck_id, survey.date_info ); HTTP.post("/cross", geoJSON, { headers: { "X-Gemma-Auth": localStorage.getItem("token") } }) .then(response => { if (response.data.geometry.coordinates.length) { commit("profileLoaded", { response: response, surveyDate: survey.date_info }); resolve(response); } else { commit("clearCurrentProfile"); commit("application/showSplitscreen", false, { root: true }); reject({ response: { status: null, data: "No intersection with sounding data." } }); } }) .catch(error => reject(error)); }); } }, cut({ commit, dispatch, rootState, rootGetters }, cut) { return new Promise(resolve => { const length = getLength(cut.getGeometry()); commit( "map/setCurrentMeasurement", { quantity: "Length", unitSymbol: "m", value: Math.round(length * 10) / 10 }, { root: true } ); commit("clearFairwayData"); // if a survey has been selected, request a profile // TODO an improvement could be to check if the line intersects // with the bottleneck area's polygon before trying the server request if (rootState.bottlenecks.selectedSurvey) { const inputLineString = cut.getGeometry().clone(); inputLineString.transform("EPSG:3857", "EPSG:4326"); const [start, end] = inputLineString .getCoordinates() .map(coords => coords.map(coord => parseFloat(coord.toFixed(8)))); commit("setStartPoint", start); commit("setEndPoint", end); const profileLine = new LineString([start, end]); const profileLoaders = [ dispatch("loadProfile", rootState.bottlenecks.selectedSurvey) ]; if (rootState.fairwayprofile.additionalSurvey) { profileLoaders.push( dispatch("loadProfile", rootState.fairwayprofile.additionalSurvey) ); } commit("profileLoading", true); Promise.all(profileLoaders) .then(() => { rootState.map.cutTool.setActive(false); const los3 = rootGetters["map/getLayerByName"]( LAYERS.FAIRWAYDIMENSIONSLOS3 ); los3.data.getSource().forEachFeatureIntersectingExtent( profileLine .clone() .transform("EPSG:4326", "EPSG:3857") .getExtent(), feature => { const fairwayCoordinates = featureToFairwayCoordinates( feature, profileLine ); let fairwayData = { coordinates: fairwayCoordinates, style: los3.data.getStyle() }; if (fairwayCoordinates.length > 0) { commit("addFairwayData", fairwayData); commit("application/showSplitscreen", true, { root: true }); } } ); const los2 = rootGetters["map/getLayerByName"]( LAYERS.FAIRWAYDIMENSIONSLOS2 ); los2.data.getSource().forEachFeatureIntersectingExtent( profileLine .clone() .transform("EPSG:4326", "EPSG:3857") .getExtent(), feature => { let fairwayCoordinates = featureToFairwayCoordinates( feature, profileLine ); let fairwayData = { coordinates: fairwayCoordinates, style: los2.data.getStyle() }; if (fairwayCoordinates.length > 0) { commit("addFairwayData", fairwayData); commit("application/showSplitscreen", true, { root: true }); } } ); const los1 = rootGetters["map/getLayerByName"]( LAYERS.FAIRWAYDIMENSIONSLOS1 ); los1.data.getSource().forEachFeatureIntersectingExtent( profileLine .clone() .transform("EPSG:4326", "EPSG:3857") .getExtent(), feature => { const fairwayCoordinates = featureToFairwayCoordinates( feature, profileLine ); let fairwayData = { coordinates: fairwayCoordinates, style: los1.data.getStyle() }; if (fairwayCoordinates.length > 0) { commit("addFairwayData", fairwayData); commit("application/showSplitscreen", true, { root: true }); } } ); resolve(); }) .catch(error => { const { status, data } = error.response; displayError({ title: "Backend Error", message: `${status ? status + ":" : ""} ${data.message || data}` }); }) .finally(() => { commit("profileLoading", false); }); } }); }, previousCuts({ commit, rootState }) { const previousCuts = JSON.parse(localStorage.getItem("previousCuts")) || []; commit( "previousCuts", previousCuts .filter(cut => { return ( cut.bottleneckName === rootState.bottlenecks.selectedBottleneck ); }) .sort((a, b) => (a.timestamp < b.timestamp ? 1 : -1)) ); } } };