# HG changeset patch
# User gernotbelger
# Date 1518189094 -3600
# Node ID 6b93a2498e06f598cf3fa52e1867a9744712fbd2
# Parent 64ca63f79f6fe5926f1fe7a5689a697c5c2531d5
Slightly better abstraction for extraction waterlevels via datacage
diff -r 64ca63f79f6f -r 6b93a2498e06 artifacts/src/main/java/org/dive4elements/river/artifacts/states/WDifferencesState.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WDifferencesState.java Fri Feb 09 13:27:10 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WDifferencesState.java Fri Feb 09 16:11:34 2018 +0100
@@ -111,6 +111,7 @@
* Access the data (wkms) of an artifact, coded in mingle.
*/
// FIXME: meanwhile used by several places outside this context; refactor into separate helper class to access waterlevels
+ // FIXME: use org.dive4elements.river.artifacts.states.WaterlevelFetcher instead
public WKms getWKms(
String mingle,
CallContext context,
@@ -160,6 +161,7 @@
getData();
if (wkms == null || wkms.length == 0) {
log.warn("no waterlevels in artifact");
+ // FIXME: fall through will lead to exception...
}
else if (wkms.length < idx+1) {
log.warn("Not enough waterlevels in artifact.");
diff -r 64ca63f79f6f -r 6b93a2498e06 artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelData.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelData.java Fri Feb 09 16:11:34 2018 +0100
@@ -0,0 +1,84 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.states;
+
+import org.dive4elements.river.artifacts.model.WKms;
+import org.dive4elements.river.model.Gauge;
+import org.dive4elements.river.model.River;
+
+/**
+ * Represents a waterlevel fetched with the {@link WaterlevelFetcher}.
+ *
+ * @author Gernot Belger
+ */
+public class WaterlevelData {
+ private final WKms wkms;
+
+ private final String name;
+
+ /** If true
, tabular export will show gauges for every station, else only for the first gauge */
+ private final boolean showAllGauges;
+
+ public WaterlevelData(final WKms wkms) {
+ this(wkms, false);
+ }
+
+ public WaterlevelData(final WKms wkms, final boolean showAllGauges) {
+ this(null, wkms, showAllGauges);
+ }
+
+ public WaterlevelData(final String name, final WKms wkms, final boolean showAllGauges) {
+ this.name = name;
+ this.wkms = wkms;
+ this.showAllGauges = showAllGauges;
+ }
+
+ public WaterlevelData filterByRange(final double from, final double to) {
+ if (Double.isNaN(from) || Double.isNaN(to)) {
+ return this;
+ }
+
+ final WKms filteredWkms = this.wkms.filteredKms(from, to);
+ return new WaterlevelData(filteredWkms);
+ }
+
+ public WaterlevelData withName(final String nameToSet) {
+ return new WaterlevelData(nameToSet, this.wkms, this.showAllGauges);
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public WKms getWkms() {
+ return this.wkms;
+ }
+
+ public boolean isShowAllGauges() {
+ return this.showAllGauges;
+ }
+
+ public Gauge findReferenceGauge(final River river) {
+ final double[] wstFromTo = findWstFromTo();
+ return river.determineRefGauge(wstFromTo, true);
+ }
+
+ private double[] findWstFromTo() {
+
+ final double from = this.wkms.getKm(0);
+ final double to = this.wkms.getKm(this.wkms.size() - 1);
+
+ final boolean waterIncreasing = this.wkms.guessWaterIncreasing();
+ if (waterIncreasing)
+ return new double[] { to, from };
+
+ return new double[] { from, to };
+ }
+}
diff -r 64ca63f79f6f -r 6b93a2498e06 artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelFetcher.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelFetcher.java Fri Feb 09 16:11:34 2018 +0100
@@ -0,0 +1,146 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.states;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.FixationArtifact;
+import org.dive4elements.river.artifacts.StaticWKmsArtifact;
+import org.dive4elements.river.artifacts.StaticWQKmsArtifact;
+import org.dive4elements.river.artifacts.WINFOArtifact;
+import org.dive4elements.river.artifacts.access.FixRealizingAccess;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.Segment;
+import org.dive4elements.river.artifacts.model.WKms;
+import org.dive4elements.river.artifacts.model.WQKms;
+import org.dive4elements.river.artifacts.model.fixings.FixRealizingResult;
+import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
+import org.dive4elements.river.utils.RiverUtils;
+
+/**
+ * Helper class that accesses existing waterlevels (in most cases) from the data-cage.
+ * This is mainly a refaktoring of org.dive4elements.river.artifacts.states.WDifferencesState.getWKms(String,
+ * CallContext, double, double), adding more infos to the fetched water levels.
+ *
+ * @author Gernot Belger
+ */
+public class WaterlevelFetcher {
+ private static Logger log = Logger.getLogger(WaterlevelFetcher.class);
+
+ public WaterlevelData findWaterlevel(final CallContext context, final String mingle, final double from,
+ final double to) {
+
+ final String[] def = mingle.split(";");
+ final String uuid = def[0];
+ final String name = def[1];
+ final int idx = Integer.parseInt(def[2]);
+ final D4EArtifact d4eArtifact = RiverUtils.getArtifact(uuid, context);
+
+ final WaterlevelData data = fetchWaterlevelFromArtifact(context, d4eArtifact, idx, from, to);
+ return data.withName(name);
+ }
+
+ private WaterlevelData fetchWaterlevelFromArtifact(final CallContext context, final D4EArtifact d4eArtifact,
+ final int idx, final double from, final double to) {
+ if (d4eArtifact == null) {
+ log.warn("One of the artifacts (1) for diff calculation " + "could not be loaded");
+ return null;
+ }
+
+ if (d4eArtifact instanceof StaticWKmsArtifact) {
+ return fetchStaticWKmsArtifactWaterlevel((StaticWKmsArtifact) d4eArtifact, idx, from, to);
+ }
+
+ if (d4eArtifact instanceof StaticWQKmsArtifact) {
+ return fetchStaticWQKmsArtifactWaterlevel((StaticWQKmsArtifact) d4eArtifact, from, to);
+ }
+
+ if (d4eArtifact instanceof WINFOArtifact)
+ return fetchWINFOArtifactWaterlevel(context, (WINFOArtifact) d4eArtifact, idx, from, to);
+
+ if (d4eArtifact instanceof FixationArtifact)
+ return fetchFixationArtifactWaterlevel(context, (FixationArtifact) d4eArtifact, idx, from, to);
+
+ log.warn(String.format("Get Waterlevel from %s not implemented! )", d4eArtifact.getClass().getSimpleName()));
+ return null;
+ }
+
+ // REMARK/TODO: instead of several helper methods here this would be a good place for abstraction, in order to push
+ // this logic back to the corresponding artifacts
+
+ private WaterlevelData fetchStaticWKmsArtifactWaterlevel(final StaticWKmsArtifact staticWKms, final int idx,
+ final double from, final double to) {
+
+ log.debug("WDifferencesState obtain data from StaticWKms");
+
+ final WKms wkms = staticWKms.getWKms(idx, from, to);
+
+ if (wkms != null)
+ return new WaterlevelData(wkms);
+
+ log.error("No WKms from Static artifact for this range.");
+ return null;
+ }
+
+ private WaterlevelData fetchStaticWQKmsArtifactWaterlevel(final StaticWQKmsArtifact staticWKms, final double from,
+ final double to) {
+
+ log.debug("WDifferencesState obtain data from StaticWQKms");
+
+ final WQKms wkms = staticWKms.getWQKms(from, to);
+
+ if (wkms != null)
+ return new WaterlevelData(wkms);
+
+ log.error("No WKms from Static artifact for this range.");
+ return null;
+ }
+
+ private WaterlevelData fetchWINFOArtifactWaterlevel(final CallContext context, final WINFOArtifact flys,
+ final int idx, final double from, final double to) {
+ log.debug("Get WKms from WINFOArtifact");
+
+ final WKms[] wkms = (WKms[]) flys.getWaterlevelData(context).getData();
+
+ if (wkms == null || wkms.length == 0) {
+ log.warn("no waterlevels in artifact");
+ return null;
+ }
+
+ if (wkms.length < idx + 1) {
+ log.warn("Not enough waterlevels in artifact.");
+ return null;
+ }
+
+ return new WaterlevelData(wkms[idx]).filterByRange(from, to);
+ }
+
+ private WaterlevelData fetchFixationArtifactWaterlevel(final CallContext context,
+ final FixationArtifact fixation, final int idx, final double from, final double to) {
+
+ log.debug("Get WKms from FixationArtifact.");
+
+ final CalculationResult r = (CalculationResult) fixation.compute(context, ComputeType.ADVANCE, false);
+ final FixRealizingResult frR = (FixRealizingResult) r.getData();
+
+ // Get W/Q input per gauge for this case.
+ final FixRealizingAccess fixAccess = new FixRealizingAccess(fixation);
+ final List segments = fixAccess.getSegments();
+ final boolean isFixRealize = (segments != null && !segments.isEmpty());
+
+ // REMARK: same logic as in WaterlevelExporter
+ final boolean showAllGauges = isFixRealize;
+
+ return new WaterlevelData(frR.getWQKms()[idx], showAllGauges).filterByRange(from, to);
+ }
+}