Mercurial > gemma
view client/src/store/fairwayprofile.js @ 3430:6994602d2935
fairway availibilty: Implemented for streches and sections.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 23 May 2019 17:28:14 +0200 |
parents | ba7bc3740fb3 |
children | 30a47d9fc667 |
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"; import { generateFeatureRequest } from "@/lib/geo"; import { getLength } from "ol/sphere"; import { displayError } from "@/lib/errors"; import { featureToFairwayCoordinates } from "@/lib/geo"; // 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, differencesLoading: false }; }; 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]; }, setDifferencesLoading: (state, value) => { state.differencesLoading = value; }, 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.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: { clearCurrentProfile({ commit, rootState }) { commit("clearCurrentProfile"); commit("map/cutToolEnabled", false, { root: true }); rootState.map.openLayersMaps.forEach(m => { m.getLayer("CUTTOOL") .getSource() .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"); reject({ response: { status: null, data: "No intersection with sounding data." } }); } }) .catch(error => reject(error)); }); } }, cut({ commit, dispatch, state, 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 (state.additionalSurvey) { profileLoaders.push( dispatch("loadProfile", state.additionalSurvey) ); } commit("profileLoading", true); Promise.all(profileLoaders) .then(() => { commit("map/cutToolEnabled", false, { root: true }); const los3 = rootGetters["map/openLayersMap"]().getLayer( "FAIRWAYDIMENSIONSLOS3" ); los3.getSource().forEachFeatureIntersectingExtent( profileLine .clone() .transform("EPSG:4326", "EPSG:3857") .getExtent(), feature => { const fairwayCoordinates = featureToFairwayCoordinates( feature, profileLine ); let fairwayData = { coordinates: fairwayCoordinates, style: los3.getStyle() }; if (fairwayCoordinates.length > 0) { commit("addFairwayData", fairwayData); } } ); const los2 = rootGetters["map/openLayersMap"]().getLayer( "FAIRWAYDIMENSIONSLOS2" ); los2.getSource().forEachFeatureIntersectingExtent( profileLine .clone() .transform("EPSG:4326", "EPSG:3857") .getExtent(), feature => { let fairwayCoordinates = featureToFairwayCoordinates( feature, profileLine ); let fairwayData = { coordinates: fairwayCoordinates, style: los2.getStyle() }; if (fairwayCoordinates.length > 0) { commit("addFairwayData", fairwayData); } } ); const los1 = rootGetters["map/openLayersMap"]().getLayer( "FAIRWAYDIMENSIONSLOS1" ); los1.getSource().forEachFeatureIntersectingExtent( profileLine .clone() .transform("EPSG:4326", "EPSG:3857") .getExtent(), feature => { const fairwayCoordinates = featureToFairwayCoordinates( feature, profileLine ); let fairwayData = { coordinates: fairwayCoordinates, style: los1.getStyle() }; if (fairwayCoordinates.length > 0) { commit("addFairwayData", fairwayData); } } ); resolve(); }) .catch(error => { const { status, data } = error.response; displayError({ title: "Backend Error", message: `${status ? status + ":" : ""} ${data.message || data}` }); }) .finally(() => { commit("application/paneRotate", 1, { root: true }); if (state.additionalSurvey) { commit( "application/paneSetup", "COMPARESURVEYS_FAIRWAYPROFILE", { root: true } ); } else { commit("application/paneSetup", "FAIRWAYPROFILE", { root: true }); } 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)) ); } } };