diff artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelFetcher.java @ 8881:6b93a2498e06

Slightly better abstraction for extraction waterlevels via datacage
author gernotbelger
date Fri, 09 Feb 2018 16:11:34 +0100
parents
children a536e1aacf0f
line wrap: on
line diff
--- /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<Segment> 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);
+    }
+}

http://dive4elements.wald.intevation.org