changeset 9708:93389a05119e

zu Nachtrag - BezugsWST in intell. Datenkorb
author dnt_bjoernsen <d.tironi@bjoernsen.de>
date Fri, 22 Jan 2021 18:45:39 +0100
parents 23702537fb4f
children b74f817435fe
files artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculationResults.java artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstMainCalculationResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelFetcher.java
diffstat 3 files changed, 231 insertions(+), 160 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculationResults.java	Fri Jan 22 15:47:55 2021 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculationResults.java	Fri Jan 22 18:45:39 2021 +0100
@@ -18,7 +18,7 @@
  * @author Gernot Belger
  */
 
-final class BezugswstCalculationResults extends AbstractCalculationResults<AbstractCalculationExportableResult> {
+public final class BezugswstCalculationResults extends AbstractCalculationResults<AbstractCalculationExportableResult> {
 
     private static final long serialVersionUID = 1L;
 
@@ -33,5 +33,4 @@
     public boolean hasSounding() {
         return this.hasSounding;
     }
-
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstMainCalculationResult.java	Fri Jan 22 15:47:55 2021 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstMainCalculationResult.java	Fri Jan 22 18:45:39 2021 +0100
@@ -33,7 +33,7 @@
  *
  * @author Gernot Belger
  */
-final class BezugswstMainCalculationResult extends AbstractCalculationExportableResult {
+public final class BezugswstMainCalculationResult extends AbstractCalculationExportableResult {
 
     private static final long serialVersionUID = 1L;
 
@@ -75,8 +75,8 @@
 
     public String getWstLabel() {
         if (this.ud != null)
-            return Integer.toString(this.endYear) + "; UD=" + Integer.toString(this.ud); // FIXME per WaterlevelDescriptionBuilder o.ä. zentralisieren
-        return Integer.toString(this.endYear) + "; " + this.wst.getLabel();
+            return Integer.toString(this.getEndYear()) + "; UD=" + Integer.toString(this.ud); // FIXME per WaterlevelDescriptionBuilder o.ä. zentralisieren
+        return Integer.toString(this.getEndYear()) + "; " + this.wst.getLabel();
     }
 
     public String getBedHeightLabel() {
@@ -100,7 +100,7 @@
         // Reihenfolge in der LV anders; ich finde sie aber so sinnvoller
         exportContextCSV.writeCSVMetaEntry("bundu.export.bezugswst.csv.meta.function", this.function);
         exportContextCSV.writeCSVMetaEntry("bundu.export.bezugswst.csv.meta.preprocessing", exportContextCSV.msg(String.valueOf(this.preprocessing)));
-        exportContextCSV.writeCSVMetaEntry("bundu.export.bezugswst.csv.meta.q_period", String.valueOf(this.startYear), String.valueOf(this.endYear));
+        exportContextCSV.writeCSVMetaEntry("bundu.export.bezugswst.csv.meta.q_period", String.valueOf(this.startYear), String.valueOf(this.getEndYear()));
         if (this.ud != null)
             exportContextCSV.writeCSVMetaEntry("bundu.export.bezugswst.csv.meta.ud", this.ud);
         else if (this.qOfGauges != null)
@@ -196,4 +196,8 @@
 
         return new double[][] { x.toNativeArray(), y.toNativeArray() };
     }
+
+	public int getEndYear() {
+		return endYear;
+	}
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelFetcher.java	Fri Jan 22 15:47:55 2021 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelFetcher.java	Fri Jan 22 18:45:39 2021 +0100
@@ -16,12 +16,15 @@
 import org.apache.commons.lang.math.DoubleRange;
 import org.apache.log4j.Logger;
 import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.AbstractFixBunduArtifact;
 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.bundu.bezugswst.BezugswstCalculationResults;
+import org.dive4elements.river.artifacts.bundu.bezugswst.BezugswstMainCalculationResult;
+import org.dive4elements.river.artifacts.common.AbstractCalculationExportableResult;
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.CalculationResult;
 import org.dive4elements.river.artifacts.model.Segment;
@@ -36,167 +39,232 @@
 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,
+ * 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);
-
-    /**
-     * @param simulationRange
-     *            This range is used to check if the found waterlevel covers it. It is NOT used to reduce the fetched data,
-     *            because in case of waterlevels we always need to full set in order to determine the relevant gauge.
-     */
-    public WaterlevelData findWaterlevel(final CallContext context, final String mingle, final DoubleRange simulationRange, final Calculation problems) {
-
-        final String[] def = mingle.split(";");
-        final String uuid = def[0];
-        // final String factory = def[1];
-        final int idx = Integer.parseInt(def[2]);
-        final String name = def[3];
-        final D4EArtifact d4eArtifact = RiverUtils.getArtifact(uuid, context);
-        if (d4eArtifact == null)
-            return null;
-
-        final WaterlevelData data = fetchWaterlevelFromArtifact(context, d4eArtifact, idx, Double.NaN, Double.NaN);
-        if (data == null) {
-            problems.addProblem("waterlevelfetcher.missing", mingle);
-            return null;
-        }
-
-        if (!data.covers(simulationRange)) {
-            problems.addProblem("waterlevelfetcher.empty", data.getName());
-            return null;
-        }
-
-        return data.withName(name);
-    }
-
-    private WaterlevelData fetchWaterlevelFromArtifact(final CallContext context, final D4EArtifact d4eArtifact, final int idx, final double from,
-            final double to) {
-
-        if (d4eArtifact instanceof StaticWKmsArtifact)
-            return fetchStaticWKmsArtifactWaterlevel((StaticWKmsArtifact) d4eArtifact, 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: 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. However this will most certainly break existing
-    // artifact-serialization
-
-    private WaterlevelData fetchStaticWKmsArtifactWaterlevel(final StaticWKmsArtifact staticWKms, final double from, final double to) {
-
-        log.debug("WDifferencesState obtain data from StaticWKms");
-
-        final WKms wkms = staticWKms.getWKms(from, to);
-
-        if (wkms != null) {
-            final int year = fetchStaticWKmsYear(staticWKms);
-            return new WaterlevelData(wkms, year, false, false);
-        }
-
-        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);
+	private static Logger log = Logger.getLogger(WaterlevelFetcher.class);
 
-        if (wkms != null) {
-            final int year = fetchStaticWKmsYear(staticWKms);
-            return new WaterlevelData(wkms, year, false, false);
-        }
-
-        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;
-        }
-
-        // REAMRK: W_INFO results does not know any 'year'
-        final int year = -1;
-        return new WaterlevelData(wkms[idx], year, false, true).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();
+	/**
+	 * @param simulationRange
+	 *            This range is used to check if the found waterlevel covers it. It
+	 *            is NOT used to reduce the fetched data, because in case of
+	 *            waterlevels we always need to full set in order to determine the
+	 *            relevant gauge.
+	 */
+	public WaterlevelData findWaterlevel(final CallContext context, final String mingle,
+			final DoubleRange simulationRange, final Calculation problems) {
 
-        // 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());
-
-        /* ugly but necessary to keep this logic at least a bit inside the FixRealizing stuff */
-        final FixRealizingCalculationExtended calculation = new FixRealizingCalculationExtended(fixAccess);
-        final int year = calculation.determineMeanYear();
-
-        // REMARK: same logic as in WaterlevelExporter
-        final boolean showAllGauges = isFixRealize;
-
-        return new WaterlevelData(frR.getWQKms()[idx], year, showAllGauges, true).filterByRange(from, to);
-    }
+		final String[] def = mingle.split(";");
+		final String uuid = def[0];
+		// final String factory = def[1];
+		final int idx = Integer.parseInt(def[2]);
+		final String name = def[3];
+		final D4EArtifact d4eArtifact = RiverUtils.getArtifact(uuid, context);
+		if (d4eArtifact == null)
+			return null;
 
-    /**
-     * Fetches the 'year' for a staticXXX-artifact.
-     * REMARK: actually this should happen inside the staticWKms artifact and eventually in the WKmsFactory, but the code
-     * there is already awful and it will also break the old artifact-serialization...
-     */
-    private int fetchStaticWKmsYear(final D4EArtifact staticWKms) {
-
-        final int colPos = Integer.parseInt(staticWKms.getDataAsString("col_pos"));
-        final int wstId = Integer.parseInt(staticWKms.getDataAsString("wst_id"));
+		final WaterlevelData data = fetchWaterlevelFromArtifact(context, d4eArtifact, idx, Double.NaN, Double.NaN);
+		if (data == null) {
+			problems.addProblem("waterlevelfetcher.missing", mingle);
+			return null;
+		}
 
-        final WstColumn wstColumn = WstColumnFactory.getWstColumn(wstId, colPos);
-        final TimeInterval timeInterval = wstColumn.getTimeInterval();
-        if (timeInterval == null)
-            return -1;
-
-        final Date startTime = timeInterval.getStartTime();
-        if (startTime == null)
-            return -1;
+		if (!data.covers(simulationRange)) {
+			problems.addProblem("waterlevelfetcher.empty", data.getName());
+			return null;
+		}
 
-        // REMARK: the times are stored without timezone in the DB, so it is unclear what hibernate makes of it.
-        // We simply use the default timezone here and hope we never get problems...
-        // Actually we always have 12:00 as time in the db data, so a smal timeshift due to winter/sommertime or UTC/GMT+1 will
-        // no change anything regarding the year.
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(startTime);
-        return cal.get(Calendar.YEAR);
-    }
+		return data.withName(name);
+	}
+
+	private WaterlevelData fetchWaterlevelFromArtifact(final CallContext context, final D4EArtifact d4eArtifact,
+			final int idx, final double from, final double to) {
+
+		if (d4eArtifact instanceof StaticWKmsArtifact)
+			return fetchStaticWKmsArtifactWaterlevel((StaticWKmsArtifact) d4eArtifact, 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 AbstractFixBunduArtifact) //including BUNDUArtifact
+			return fetchFixationArtifactWaterlevel(context, (AbstractFixBunduArtifact) d4eArtifact, idx, from, to);
+
+		log.warn(String.format("Get Waterlevel from %s not implemented!", d4eArtifact.getClass().getSimpleName()));
+		return null;
+	}
+
+	// REMARK: 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. However this will most
+	// certainly break existing
+	// artifact-serialization
+
+	private WaterlevelData fetchStaticWKmsArtifactWaterlevel(final StaticWKmsArtifact staticWKms, final double from,
+			final double to) {
+
+		log.debug("WDifferencesState obtain data from StaticWKms");
+
+		final WKms wkms = staticWKms.getWKms(from, to);
+
+		if (wkms != null) {
+			final int year = fetchStaticWKmsYear(staticWKms);
+			return new WaterlevelData(wkms, year, false, false);
+		}
+
+		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) {
+			final int year = fetchStaticWKmsYear(staticWKms);
+			return new WaterlevelData(wkms, year, false, false);
+		}
+
+		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;
+		}
+
+		// REAMRK: W_INFO results does not know any 'year'
+		final int year = -1;
+		return new WaterlevelData(wkms[idx], year, false, true).filterByRange(from, to);
+	}
+
+	// private WaterlevelData fetchBUNDUArtifactWaterlevel(final CallContext
+	// context, final BUNDUArtifact flys,
+	// final int idx, final double from, final double to) {
+	// log.debug("Get WKms from BUNDUArtifact");
+	//
+	// 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;
+	// }
+	//
+	// // REAMRK: W_INFO results does not know any 'year'
+	// final int year = -1;
+	// return new WaterlevelData(wkms[idx], year, false, true).filterByRange(from,
+	// to);
+	// }
+
+	private WaterlevelData fetchFixationArtifactWaterlevel(final CallContext context,
+			final AbstractFixBunduArtifact artifact, final int idx, final double from, final double to) {
+
+		log.debug("Get WKms from FixationArtifact or BUNDUArtifact.bezugswst");
+
+		final Object r = artifact.compute(context, ComputeType.ADVANCE, false);
+		if (r instanceof CalculationResult) {
+			final Object frR = ((CalculationResult) r).getData();
+			
+			///For BezugsWST
+			if (frR instanceof BezugswstCalculationResults) {
+				List<AbstractCalculationExportableResult> results = ((BezugswstCalculationResults)frR).getResults();
+				BezugswstMainCalculationResult mainResult = this.getBezugsWstMainResultFromList(results);
+				if (mainResult!=null) {
+					//Taken FROM BezugswstCalculation
+				     // We have no wst year as the wst is created by a calculation; we do not need it though
+			        final int wspYear = -1;
+			        // Remark: showAllGauges true for Fixierungsanalyse, false for WInfo, so true here as well
+			        final boolean showAllGauges = true;
+					return new WaterlevelData( mainResult.getWQKms() , wspYear, showAllGauges, true)
+							.filterByRange(from, to);
+				}
+			}
+			
+			else if (frR instanceof FixRealizingResult) {
+				// Get W/Q input per gauge for this case.
+				final FixRealizingAccess fixAccess = new FixRealizingAccess(artifact);
+				final List<Segment> segments = fixAccess.getSegments();
+				final boolean isFixRealize = (segments != null && !segments.isEmpty());
+
+				/*
+				 * ugly but necessary to keep this logic at least a bit inside the FixRealizing
+				 * stuff
+				 */
+				final FixRealizingCalculationExtended calculation = new FixRealizingCalculationExtended(fixAccess);
+				final int year = calculation.determineMeanYear();
+
+				// REMARK: same logic as in WaterlevelExporter
+				final boolean showAllGauges = isFixRealize;
+
+				return new WaterlevelData(((FixRealizingResult) frR).getWQKms()[idx], year, showAllGauges, true)
+						.filterByRange(from, to);
+			}
+		}
+		return null;
+	}
+	
+	private BezugswstMainCalculationResult getBezugsWstMainResultFromList(List<AbstractCalculationExportableResult> results) {
+		for (	Object result : results)
+			if (result instanceof BezugswstMainCalculationResult)
+				return (BezugswstMainCalculationResult) result;
+		return null;
+	}
+ 
+	/**
+	 * Fetches the 'year' for a staticXXX-artifact. REMARK: actually this should
+	 * happen inside the staticWKms artifact and eventually in the WKmsFactory, but
+	 * the code there is already awful and it will also break the old
+	 * artifact-serialization...
+	 */
+	private int fetchStaticWKmsYear(final D4EArtifact staticWKms) {
+
+		final int colPos = Integer.parseInt(staticWKms.getDataAsString("col_pos"));
+		final int wstId = Integer.parseInt(staticWKms.getDataAsString("wst_id"));
+
+		final WstColumn wstColumn = WstColumnFactory.getWstColumn(wstId, colPos);
+		final TimeInterval timeInterval = wstColumn.getTimeInterval();
+		if (timeInterval == null)
+			return -1;
+
+		final Date startTime = timeInterval.getStartTime();
+		if (startTime == null)
+			return -1;
+
+		// REMARK: the times are stored without timezone in the DB, so it is unclear
+		// what hibernate makes of it.
+		// We simply use the default timezone here and hope we never get problems...
+		// Actually we always have 12:00 as time in the db data, so a smal timeshift due
+		// to winter/sommertime or UTC/GMT+1 will
+		// no change anything regarding the year.
+		final Calendar cal = Calendar.getInstance();
+		cal.setTime(startTime);
+		return cal.get(Calendar.YEAR);
+	}
 }
\ No newline at end of file

http://dive4elements.wald.intevation.org