Mercurial > gemma
changeset 5584:7ed9e32706d0 surveysperbottleneckid
Merged delault
author | Sascha Wilde <wilde@sha-bang.de> |
---|---|
date | Fri, 01 Apr 2022 16:47:53 +0200 |
parents | c1bd5f8eaf9a (diff) 41d7bbc9eac1 (current diff) |
children | 7e8830c808ba |
files | |
diffstat | 13 files changed, 147 insertions(+), 77 deletions(-) [+] |
line wrap: on
line diff
--- a/client/src/components/Bottlenecks.vue Thu Mar 10 17:25:44 2022 +0100 +++ b/client/src/components/Bottlenecks.vue Fri Apr 01 16:47:53 2022 +0200 @@ -138,7 +138,7 @@ this.$store .dispatch( "bottlenecks/setSelectedBottleneck", - bottleneck.properties.name + bottleneck.properties.bottleneck_id ) .then(() => { this.$store.commit("bottlenecks/selectedSurvey", survey); @@ -155,7 +155,7 @@ this.$store .dispatch( "bottlenecks/setSelectedBottleneck", - bottleneck.properties.name + bottleneck.properties.bottleneck_id ) .then(() => { this.$store.dispatch("map/moveToFeauture", { @@ -175,12 +175,16 @@ this.openBottleneckSurveys = null; } else { this.loading = bottleneck; - HTTP.get("/surveys/" + encodeURIComponent(bottleneck.properties.name), { - headers: { - "X-Gemma-Auth": localStorage.getItem("token"), - "Content-type": "text/xml; charset=UTF-8" + HTTP.get( + "/surveys?id=" + + encodeURIComponent(bottleneck.properties.bottleneck_id), + { + headers: { + "X-Gemma-Auth": localStorage.getItem("token"), + "Content-type": "text/xml; charset=UTF-8" + } } - }) + ) .then(response => { this.openBottleneckSurveys = response.data.surveys.sort((a, b) => { return a.date_info < b.date_info ? 1 : -1;
--- a/client/src/components/Pdftool.vue Thu Mar 10 17:25:44 2022 +0100 +++ b/client/src/components/Pdftool.vue Fri Apr 01 16:47:53 2022 +0200 @@ -826,7 +826,7 @@ this.pdf.doc.setTextColor(color); let textOptions = { baseline: "hanging" }; let str1_1 = this.$gettext("Bottleneck") + ": "; - let str1_2 = this.selectedBottleneck; + let str1_2 = this.bottleneckForPrint; let str2_1 = this.$gettext("Survey date") + ": "; let str2_2 = survey.date_info + " (" + SURVEYTYPES[survey["survey_type"]] + ")";
--- a/client/src/components/fairway/AvailableFairwayDepthDialogue.vue Thu Mar 10 17:25:44 2022 +0100 +++ b/client/src/components/fairway/AvailableFairwayDepthDialogue.vue Fri Apr 01 16:47:53 2022 +0200 @@ -74,6 +74,7 @@ :value="bn" > {{ bn.properties.name }} + <!-- name for display is okay --> </option> </optgroup> </select> @@ -440,8 +441,9 @@ if (this.type !== this.$options.BOTTLENECK) return true; if ( this.selectedEntry && - this.limitingFactorsPerBottleneck[this.selectedEntry.properties.name] == - this.$options.LIMITINGFACTORS.DEPTH + this.limitingFactorsPerBottleneck[ + this.selectedEntry.properties.bottleneck_id + ] == this.$options.LIMITINGFACTORS.DEPTH ) return true; return false; @@ -450,8 +452,9 @@ if (this.type !== this.$options.BOTTLENECK) return true; if ( this.selectedEntry && - this.limitingFactorsPerBottleneck[this.selectedEntry.properties.name] == - this.$options.LIMITINGFACTORS.WIDTH + this.limitingFactorsPerBottleneck[ + this.selectedEntry.properties.bottleneck_id + ] == this.$options.LIMITINGFACTORS.WIDTH ) return true; }, @@ -459,7 +462,7 @@ if (this.type !== this.$options.BOTTLENECK) return; if (this.selectedEntry) return this.limitingFactorsPerBottleneck[ - this.selectedEntry.properties.name + this.selectedEntry.properties.bottleneck_id ]; }, isComplete() { @@ -665,11 +668,11 @@ .setVisible(true); this.$store.dispatch( "bottlenecks/setSelectedBottleneck", - this.selectedFairwayAvailabilityFeature.properties.name + this.selectedFairwayAvailabilityFeature.properties.bottleneck_id ); this.$store.commit( "bottlenecks/setBottleneckForPrint", - this.selectedBottleneck + this.selectedFairwayAvailabilityFeature.properties.objnam // for printing objnam is okay ); } if (this.type === this.$options.STRETCH) { @@ -839,7 +842,7 @@ }, setSelectedBottleneck() { const bn = this.bottlenecksList.filter( - x => x.properties.name === this.selectedBottleneck + x => x.properties.bottleneck_id === this.selectedBottleneck )[0]; this.$store.commit( "fairwayavailability/setSelectedFairwayAvailability",
--- a/client/src/components/fairway/BottleneckDialogue.vue Thu Mar 10 17:25:44 2022 +0100 +++ b/client/src/components/fairway/BottleneckDialogue.vue Fri Apr 01 16:47:53 2022 +0200 @@ -29,9 +29,10 @@ <option v-for="bn in bottlenecksForCountry" :key="bn.properties.id" - :value="bn.properties.name" + :value="bn.properties.bottleneck_id" > {{ bn.properties.name }} + <!-- name for display is okay--> </option> </optgroup> </select> @@ -373,7 +374,7 @@ isAllowedToDelete() { const userCountryCode = this.userCountries[this.user]; const bottleneck = this.bottlenecksList.find( - bn => bn.properties.name === this.selectedBottleneck + bn => bn.properties.bottleneck_id === this.selectedBottleneck ); if (!bottleneck) return; if (this.isWaterwayAdmin || this.isSysAdmin) { @@ -421,8 +422,11 @@ get() { return this.$store.state.bottlenecks.selectedBottleneck; }, - set(name) { - this.$store.dispatch("bottlenecks/setSelectedBottleneck", name); + set(bottleneck_id) { + this.$store.dispatch( + "bottlenecks/setSelectedBottleneck", + bottleneck_id + ); } }, selectedWaterLevel: { @@ -517,15 +521,17 @@ .getLayer("BOTTLENECKS") .getSource() .getFeatures() - .find(f => f.get("objnam") === this.selectedBottleneck) + .find(f => f.get("bottleneck_id") === this.selectedBottleneck) : null; } }, watch: { selectedBottleneck() { this.$store.dispatch("fairwayprofile/previousCuts"); - this.cutLabel = - this.selectedBottleneck + " (" + new Date().toISOString() + ")"; + if (this.bottleneck) { + this.cutLabel = + this.bottleneck.get("objnam") + " (" + new Date().toISOString() + ")"; //objnam for Label is okay + } }, selectedSurvey(survey) { this.loadProfile(survey); @@ -726,7 +732,8 @@ JSON.parse(localStorage.getItem("previousCuts")) || []; const newEntry = { label: this.cutLabel, - bottleneckName: this.selectedBottleneck, + bottleneckName: this.bottleneck.get("objnam"), + bottleneckId: this.bottleneck.get("bottleneck_id"), coordinates: [...this.startPoint, ...this.endPoint], timestamp: new Date().getTime(), depth: this.depth, @@ -739,7 +746,6 @@ if (previousCuts.length > 100) previousCuts.shift(); localStorage.setItem("previousCuts", JSON.stringify(previousCuts)); this.$store.dispatch("fairwayprofile/previousCuts"); - this.showLabelInput = false; displayInfo({ title: this.$gettext("Profile saved!"), @@ -811,12 +817,12 @@ }, takeMeThere() { const bottleneck = this.bottlenecksList.find( - bn => bn.properties.name === this.selectedBottleneck + bn => bn.properties.bottleneck_id === this.selectedBottleneck ); if (!bottleneck) return; this.$store.commit( "bottlenecks/setBottleneckForPrint", - this.selectedBottleneck + bottleneck.properties.name ); this.$store.dispatch("map/moveToFeauture", { feature: bottleneck,
--- a/client/src/components/fairway/Fairwayprofile.vue Thu Mar 10 17:25:44 2022 +0100 +++ b/client/src/components/fairway/Fairwayprofile.vue Fri Apr 01 16:47:53 2022 +0200 @@ -239,9 +239,9 @@ this.waterlevelValid && this.refWaterlevelValid ? `${this.$options.filters.waterlevel(this.waterlevel)} m` : this.$gettext("No valid value available"); - return `${this.$gettext("Fairwayprofile")}: ${ - this.selectedBottleneck - } (${dates.join( + return `${this.$gettext("Fairwayprofile")}: ${this.bottleneck.get( + "objnam" //for title label objnam is okay + )} (${dates.join( ", " )}) WL: ${waterlevelLabel} ( ${waterlevelMeasurement} )`; }, @@ -266,7 +266,7 @@ .getLayer("BOTTLENECKS") .getSource() .getFeatures() - .find(f => f.get("objnam") === this.selectedBottleneck); + .find(f => f.get("bottleneck_id") === this.selectedBottleneck); }, waterlevel() { return this.selectedWaterLevel === "ref" @@ -286,7 +286,7 @@ fileName() { return this.downloadFilename( this.$gettext("Fairwayprofile"), - this.selectedBottleneck + this.bottleneck.get("objnam") //for filename objnam is okay ); } }, @@ -446,7 +446,10 @@ }, downloadPDF() { let fairwayInfo = - this.selectedBottleneck + " (" + this.selectedSurvey.date_info + ")"; + this.bottleneck.get("objnam") + //for Filename objnam is okay + " (" + + this.selectedSurvey.date_info + + ")"; this.generatePDF({ templateData: this.templateData, diagramTitle: fairwayInfo
--- a/client/src/components/importconfiguration/types/Soundingresults.vue Thu Mar 10 17:25:44 2022 +0100 +++ b/client/src/components/importconfiguration/types/Soundingresults.vue Fri Apr 01 16:47:53 2022 +0200 @@ -22,10 +22,11 @@ > <option v-for="bn in bottlenecksForCountry" - :key="bn.properties.objnam" + :key="bn.properties.bottleneck_id" :value="bn" > {{ bn.properties.objnam }} + <!-- objnam for label is okay --> </option> </optgroup> </select> @@ -303,7 +304,7 @@ const surveyType = response.data.meta["survey-type"]; this.negateZ = response.data.meta["negate-z"]; this.bottleneck = this.bottlenecks.find( - bn => bn.properties.objnam === bottleneck + bn => bn.properties.bottleneck_id === bottleneck ); this.depthReference = depthReference; this.importDate = new Date(date).toISOString().split("T")[0]; @@ -343,7 +344,7 @@ let formData = new FormData(); formData.append("token", this.token); if (this.bottleneck) - formData.append("bottleneck", this.bottleneck.properties.objnam); + formData.append("bottleneck", this.bottleneck.properties.bottleneck_id); if (this.importDate) formData.append("date", this.importDate.split("T")[0]); if (this.depthReference) @@ -362,7 +363,7 @@ title: this.$gettext("Import"), message: this.$gettext("Starting import for ") + - this.bottleneck.properties.objnam + this.bottleneck.properties.objnam //objnam for display is okay }); this.initialState(); }) @@ -464,7 +465,7 @@ encodeURIComponent( JSON.stringify({ "depth-reference": this.depthReference, - bottleneck: this.bottleneck.properties.objnam, + bottleneck: this.bottleneck.properties.bottleneck_id, date: this.importDate, "survey-type": this.beamType, epsg: Number(this.projection),
--- a/client/src/components/importoverview/BottleneckDetail.vue Thu Mar 10 17:25:44 2022 +0100 +++ b/client/src/components/importoverview/BottleneckDetail.vue Fri Apr 01 16:47:53 2022 +0200 @@ -20,6 +20,7 @@ </div> <a @click="moveToBottleneck(index)" href="#"> {{ bottleneck.properties.objnam }} + <!-- objnam for Text is okay--> </a> </div>
--- a/client/src/components/importoverview/SoundingResultDetail.vue Thu Mar 10 17:25:44 2022 +0100 +++ b/client/src/components/importoverview/SoundingResultDetail.vue Fri Apr 01 16:47:53 2022 +0200 @@ -31,6 +31,8 @@ * Thomas Junk <thomas.junk@intevation.de> */ import { mapState } from "vuex"; +import { HTTP } from "@/lib/http"; +import { displayError } from "@/lib/errors"; export default { name: "soundingresultdetails", @@ -55,10 +57,36 @@ zoom: 17, preventZoomOut: true }); - this.$store - .dispatch("bottlenecks/setSelectedBottleneck", bottleneck) - .then(() => { - this.$store.commit("bottlenecks/setSelectedSurveyByDate", date); + HTTP.get( + "/surveys?name=" + + encodeURIComponent(bottleneck) + + "&date=" + + encodeURIComponent(date), + { + headers: { + "X-Gemma-Auth": localStorage.getItem("token"), + "Content-type": "text/xml; charset=UTF-8" + } + } + ) + .then(response => { + const { bottleneck_id } = response.data.surveys[0]; + this.$store + .dispatch("bottlenecks/setSelectedBottleneck", bottleneck_id) + .then(() => { + this.$store.commit("bottlenecks/setSelectedSurveyByDate", date); + }); + }) + .catch(error => { + let message = "Backend not reachable"; + if (error.response) { + const { status, data } = error.response; + message = `${status}: ${data.message || data}`; + } + displayError({ + title: this.$gettext("Backend Error"), + message: message + }); }); } }
--- a/client/src/components/map/MapPopup.vue Thu Mar 10 17:25:44 2022 +0100 +++ b/client/src/components/map/MapPopup.vue Fri Apr 01 16:47:53 2022 +0200 @@ -180,7 +180,7 @@ this.$store.commit("application/showProfiles", true); this.$store.dispatch( "bottlenecks/setSelectedBottleneck", - bottleneck.get("objnam") + bottleneck.get("bottleneck_id") ); this.$store.dispatch("map/moveToBoundingBox", { boundingBox: bottleneck @@ -190,10 +190,10 @@ .getExtent(), zoom: 16 }); - this.$store.commit( - "bottlenecks/setBottleneckForPrint", - this.selectedBottleneck + const bn = this.bottlenecks.find( + b => b.get("bottleneck_id") == this.selectedBottleneck ); + this.$store.commit("bottlenecks/setBottleneckForPrint", bn.name); //name is okay. this.close(); }, openGauges(gauge) { @@ -209,7 +209,7 @@ this.$store.commit("fairwayavailability/type", TYPES.BOTTLENECK); this.$store.dispatch( "bottlenecks/setSelectedBottleneck", - bottleneck.get("objnam") + bottleneck.get("bottleneck_id") ); this.$store.dispatch("map/moveToBoundingBox", { boundingBox: bottleneck @@ -219,10 +219,10 @@ .getExtent(), zoom: 16 }); - this.$store.commit( - "bottlenecks/setBottleneckForPrint", - this.selectedBottleneck + const bn = this.bottlenecks.find( + b => b.bottleneck_id == this.selectedBottleneck ); + this.$store.commit("bottlenecks/setBottleneckForPrint", bn.name); //name is okay. this.openFairwayAvailability(); }, openFairwayAvailabilityForStretch(stretch) {
--- a/client/src/store/bottlenecks.js Thu Mar 10 17:25:44 2022 +0100 +++ b/client/src/store/bottlenecks.js Fri Apr 01 16:47:53 2022 +0200 @@ -14,8 +14,8 @@ */ import { HTTP } from "@/lib/http"; import { WFS } from "ol/format"; +import { compareAsc } from "date-fns"; import { displayError } from "@/lib/errors"; -import { compareAsc } from "date-fns"; // initial state const init = () => { return { @@ -38,7 +38,7 @@ limitingFactorsPerBottleneck: state => { if (state.bottlenecks.length === 0) return {}; return state.bottlenecks.reduce((o, n) => { - o[n.properties.objnam] = n.properties.limiting; + o[n.properties.bottleneck_id] = n.properties.limiting; return o; }, {}); }, @@ -77,8 +77,8 @@ setBottlenecksList: (state, bottlenecksList) => { state.bottlenecksList = bottlenecksList; }, - setSelectedBottleneck: (state, name) => { - state.selectedBottleneck = name; + setSelectedBottleneck: (state, value) => { + state.selectedBottleneck = value; }, setSurveys(state, surveys) { state.surveys = surveys; @@ -98,9 +98,9 @@ } }, actions: { - setSelectedBottleneck({ state, commit, rootState }, name) { + setSelectedBottleneck({ state, commit, rootState }, id) { return new Promise((resolve, reject) => { - if (name !== state.selectedBottleneck) { + if (id !== state.selectedBottleneck) { commit("selectedSurvey", null); commit("fairwayprofile/additionalSurvey", null, { root: true }); commit("fairwayprofile/clearCurrentProfile", null, { root: true }); @@ -111,10 +111,10 @@ .clear(); }); } - commit("setSelectedBottleneck", name); - if (name) { + commit("setSelectedBottleneck", id); + if (id) { commit("surveysLoading", true); - HTTP.get("/surveys/" + encodeURIComponent(name), { + HTTP.get("/surveys?id=" + encodeURIComponent(id), { headers: { "X-Gemma-Auth": localStorage.getItem("token"), "Content-type": "text/xml; charset=UTF-8" @@ -184,6 +184,7 @@ featureTypes: ["bottlenecks_geoserver"], outputFormat: "application/json", propertyNames: [ + "bottleneck_id", "objnam", "responsible_country", "limiting",
--- a/client/src/store/fairwayprofile.js Thu Mar 10 17:25:44 2022 +0100 +++ b/client/src/store/fairwayprofile.js Fri Apr 01 16:47:53 2022 +0200 @@ -1,3 +1,5 @@ +import { HTTP } from "@/lib/http"; +import LineString from "ol/geom/LineString"; /* This is Free Software under GNU Affero General Public License v >= 3.0 * without warranty, see README.md and license for details. * @@ -13,13 +15,11 @@ * 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 { displayError } from "@/lib/errors"; +import { featureToFairwayCoordinates } from "@/lib/geo"; import { generateFeatureRequest } from "@/lib/geo"; import { getLength } from "ol/sphere"; -import { displayError } from "@/lib/errors"; -import { featureToFairwayCoordinates } from "@/lib/geo"; +import { prepareProfile } from "@/lib/geo"; // initial state const init = () => { @@ -316,7 +316,7 @@ previousCuts .filter(cut => { return ( - cut.bottleneckName === rootState.bottlenecks.selectedBottleneck + cut.bottleneckId === rootState.bottlenecks.selectedBottleneck ); }) .sort((a, b) => (a.timestamp < b.timestamp ? 1 : -1))
--- a/pkg/controllers/routes.go Thu Mar 10 17:25:44 2022 +0100 +++ b/pkg/controllers/routes.go Fri Apr 01 16:47:53 2022 +0200 @@ -177,9 +177,13 @@ })).Methods(http.MethodGet) // Survey selection - api.Handle("/surveys/{bottleneck:.+}", any(&mw.JSONHandler{ + api.Handle("/surveys", any(&mw.JSONHandler{ Handle: listSurveys, - })).Methods(http.MethodGet) + })).Methods(http.MethodGet).Queries("id", "{id}") + + api.Handle("/surveys", any(&mw.JSONHandler{ + Handle: listSurveys, + })).Methods(http.MethodGet).Queries("name", "{name}", "date", "{date}") // difference calculation api.Handle("/diff", any(&mw.JSONHandler{
--- a/pkg/controllers/surveys.go Thu Mar 10 17:25:44 2022 +0100 +++ b/pkg/controllers/surveys.go Fri Apr 01 16:47:53 2022 +0200 @@ -19,15 +19,13 @@ "database/sql" "net/http" - "github.com/gorilla/mux" - "gemma.intevation.de/gemma/pkg/models" mw "gemma.intevation.de/gemma/pkg/middleware" ) const ( - listSurveysSQL = ` + listSurveysByIdSQL = ` SELECT DISTINCT s.bottleneck_id, s.date_info::text, @@ -42,23 +40,44 @@ LEFT JOIN waterway.gauges_reference_water_levels AS r ON s.depth_reference = r.depth_reference AND g.location = r.location AND g.validity = r.validity -WHERE b.objnam = $1` +WHERE b.bottleneck_id = $1` + + listSurveysByNameDateSQL = ` +SELECT DISTINCT + s.bottleneck_id, + s.date_info::text, + s.depth_reference, + COALESCE(g.objname, 'ERROR: MISSING GAUGE') AS gauge_objname, + r.value AS waterlevel_value, + COALESCE(s.surtyp, 'ERROR: MISSING SURVEY TYPE') AS surtype +FROM waterway.bottlenecks AS b + JOIN waterway.sounding_results AS s ON b.bottleneck_id = s.bottleneck_id + LEFT JOIN waterway.gauges AS g + ON b.gauge_location = g.location AND s.date_info::timestamptz <@ g.validity + LEFT JOIN waterway.gauges_reference_water_levels AS r + ON s.depth_reference = r.depth_reference + AND g.location = r.location AND g.validity = r.validity +WHERE b.objnam = $1 and s.date_info = $2` ) func listSurveys(req *http.Request) (jr mw.JSONResult, err error) { - bottleneckName := mux.Vars(req)["bottleneck"] - + v := req.URL.Query() + bottleneckName := v.Get("name") + date := v.Get("date") + id := v.Get("id") var rows *sql.Rows + surveys := []*models.Survey{} - rows, err = mw.JSONConn(req).QueryContext(req.Context(), listSurveysSQL, bottleneckName) + if date == "" && bottleneckName == "" && id != "" { + rows, err = mw.JSONConn(req).QueryContext(req.Context(), listSurveysByIdSQL, id) + } else if date != "" && bottleneckName != "" && id == "" { + rows, err = mw.JSONConn(req).QueryContext(req.Context(), listSurveysByNameDateSQL, bottleneckName, date) + } if err != nil { return } defer rows.Close() - - surveys := []*models.Survey{} - // as we do not use the values here, we could simply the code here // to work without an explicit mdels/surverys.go // (like done in controllers/search.go)