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)