# HG changeset patch # User dnt_bjoernsen # Date 1611337539 -3600 # Node ID 93389a05119e2987178ca9c888a8472db28f1c15 # Parent 23702537fb4f70c04bc9f39ed96cb1632ae1193e zu Nachtrag - BezugsWST in intell. Datenkorb diff -r 23702537fb4f -r 93389a05119e artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculationResults.java --- 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 { +public final class BezugswstCalculationResults extends AbstractCalculationResults { private static final long serialVersionUID = 1L; @@ -33,5 +33,4 @@ public boolean hasSounding() { return this.hasSounding; } - } \ No newline at end of file diff -r 23702537fb4f -r 93389a05119e artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstMainCalculationResult.java --- 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 diff -r 23702537fb4f -r 93389a05119e artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelFetcher.java --- 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 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 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 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 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