changeset 1164:dc99decbf9e3

added input to enter cross cut coordinates manually currently the input field is placed in the cross profile view, so you need to make a first cut to access this field. There needs to be another field that is accesible immediately, without making a cross cut first. Duplicated code needs to be fixed/centralized. UI needs to be improved.
author Markus Kottlaender <markus@intevation.de>
date Wed, 14 Nov 2018 09:03:20 +0100
parents fb5c83d4ea1d
children a44ac5193b38
files client/src/drawtool/Drawtool.vue client/src/fairway/Fairwayprofile.vue
diffstat 2 files changed, 131 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/drawtool/Drawtool.vue	Wed Nov 14 07:29:51 2018 +0100
+++ b/client/src/drawtool/Drawtool.vue	Wed Nov 14 09:03:20 2018 +0100
@@ -190,10 +190,31 @@
         this.$store
           .dispatch("fairwayprofile/loadProfile", this.selectedSurvey)
           .then(() => {
-            var vectorSource = this.getLayerByName(
-              "Fairway Dimensions"
-            ).data.getSource();
-            this.calculateIntersection(vectorSource, profileLine);
+            this.getLayerByName("Fairway Dimensions")
+              .data.getSource()
+              .forEachFeatureIntersectingExtent(
+                // need to use EPSG:3857 which is the proj of vectorSource
+                profileLine
+                  .clone()
+                  .transform("EPSG:4326", "EPSG:3857")
+                  .getExtent(),
+                feature => {
+                  // transform back to prepare for usage
+                  var intersectingPolygon = feature
+                    .getGeometry()
+                    .clone()
+                    .transform("EPSG:3857", "EPSG:4326");
+                  const fairwayCoordinates = calculateFairwayCoordinates(
+                    profileLine,
+                    intersectingPolygon,
+                    DEMODATA
+                  );
+                  this.$store.commit(
+                    "fairwayprofile/setFairwayCoordinates",
+                    fairwayCoordinates
+                  );
+                }
+              );
           })
           .then(() => {
             this.$store.commit("application/showSplitscreen", true);
@@ -206,33 +227,6 @@
             });
           });
       }
-    },
-    calculateIntersection(vectorSource, profileLine) {
-      const transformedLine = profileLine
-        .clone()
-        .transform("EPSG:4326", "EPSG:3857")
-        .getExtent();
-      const featureCallback = feature => {
-        // transform back to prepare for usage
-        var intersectingPolygon = feature
-          .getGeometry()
-          .clone()
-          .transform("EPSG:3857", "EPSG:4326");
-        const fairwayCoordinates = calculateFairwayCoordinates(
-          profileLine,
-          intersectingPolygon,
-          DEMODATA
-        );
-        this.$store.commit(
-          "fairwayprofile/setFairwayCoordinates",
-          fairwayCoordinates
-        );
-      };
-      vectorSource.forEachFeatureIntersectingExtent(
-        // need to use EPSG:3857 which is the proj of vectorSource
-        transformedLine,
-        featureCallback
-      );
     }
   },
   mounted() {
--- a/client/src/fairway/Fairwayprofile.vue	Wed Nov 14 07:29:51 2018 +0100
+++ b/client/src/fairway/Fairwayprofile.vue	Wed Nov 14 09:03:20 2018 +0100
@@ -43,6 +43,12 @@
                                 v-clipboard:success="onCopyCoordinates"
                                 class="btn btn-outline-secondary btn-sm mt-2">
                           Copy coordinates
+                        </button><br>
+                        <br>
+                        Enter coordinates
+                        <input class="form-control mt-2" placeholder="Lat,Lon,Lat,Lon" v-model="coordinatesInput" /><br>
+                        <button class="btn btn-sm btn-outline-secondary" @click="applyCoordinates">
+                          Apply
                         </button>
                     </small>
                 </div>
@@ -116,10 +122,15 @@
  * Thomas Junk <thomas.junk@intevation.de>
  */
 import * as d3 from "d3";
-import { mapState } from "vuex";
+import { mapState, mapGetters } from "vuex";
 import { displayError, displayInfo } from "../application/lib/errors.js";
+import Feature from "ol/Feature";
+import LineString from "ol/geom/LineString";
+import { getLength } from "ol/sphere.js";
+import { calculateFairwayCoordinates } from "../application/lib/geo.js";
 
 const GROUND_COLOR = "#4A2F06";
+const DEMODATA = 2.5;
 
 export default {
   name: "fairwayprofile",
@@ -132,7 +143,14 @@
     "margin",
     "additionalSurveys"
   ],
+  data() {
+    return {
+      wait: false,
+      coordinatesInput: ""
+    };
+  },
   computed: {
+    ...mapGetters("map", ["getLayerByName"]),
     ...mapState("application", ["showSplitscreen"]),
     ...mapState("fairwayprofile", [
       "startPoint",
@@ -189,11 +207,6 @@
       );
     }
   },
-  data() {
-    return {
-      wait: false
-    };
-  },
   watch: {
     showSplitscreen() {
       this.drawDiagram();
@@ -465,6 +478,93 @@
         title: "Success",
         message: "Coordinates copied to clipboard!"
       });
+    },
+    applyCoordinates() {
+      if (this.coordinatesInput) {
+        const coordinates = this.coordinatesInput
+          .split(",")
+          .map(coord => parseFloat(coord.trim()));
+        if (coordinates.length === 4) {
+          // draw line on map
+          const cutLayer = this.getLayerByName("Cut Tool");
+          cutLayer.data.getSource().clear();
+          const cut = new Feature({
+            geometry: new LineString([
+              [coordinates[1], coordinates[0]],
+              [coordinates[3], coordinates[2]]
+            ]).transform("EPSG:4326", "EPSG:3857")
+          });
+          cutLayer.data.getSource().addFeature(cut);
+
+          // draw diagram
+          this.loadProfile(cut);
+        }
+      }
+    },
+    loadProfile(cut) {
+      // TODO: find central place for this logic, duplicated code from Drawtool.vue
+      const length = getLength(cut.getGeometry());
+      this.$store.commit("map/setCurrentMeasurement", {
+        quantity: "Length",
+        unitSymbol: "m",
+        value: Math.round(length * 10) / 10
+      });
+
+      // 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 (this.selectedSurvey) {
+        this.$store.commit("fairwayprofile/clearCurrentProfile");
+        console.log("requesting profile for", this.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))));
+        this.$store.commit("fairwayprofile/setStartPoint", start);
+        this.$store.commit("fairwayprofile/setEndPoint", end);
+        const profileLine = new LineString([start, end]);
+        this.$store
+          .dispatch("fairwayprofile/loadProfile", this.selectedSurvey)
+          .then(() => {
+            this.getLayerByName("Fairway Dimensions")
+              .data.getSource()
+              .forEachFeatureIntersectingExtent(
+                // need to use EPSG:3857 which is the proj of vectorSource
+                profileLine
+                  .clone()
+                  .transform("EPSG:4326", "EPSG:3857")
+                  .getExtent(),
+                feature => {
+                  // transform back to prepare for usage
+                  var intersectingPolygon = feature
+                    .getGeometry()
+                    .clone()
+                    .transform("EPSG:3857", "EPSG:4326");
+                  const fairwayCoordinates = calculateFairwayCoordinates(
+                    profileLine,
+                    intersectingPolygon,
+                    DEMODATA
+                  );
+                  this.$store.commit(
+                    "fairwayprofile/setFairwayCoordinates",
+                    fairwayCoordinates
+                  );
+                }
+              );
+          })
+          .then(() => {
+            this.$store.commit("application/showSplitscreen", true);
+          })
+          .catch(error => {
+            console.log(error);
+            const { status, data } = error.response;
+            displayError({
+              title: "Backend Error",
+              message: `${status}: ${data.message || data}`
+            });
+          });
+      }
     }
   },
   mounted() {