gernotbelger@9246: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde gernotbelger@9246: * Software engineering by Intevation GmbH gernotbelger@9246: * gernotbelger@9246: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@9246: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@9246: * documentation coming with Dive4Elements River for details. gernotbelger@9246: */ gernotbelger@9246: gernotbelger@9246: package org.dive4elements.river.artifacts.uinfo.salix; gernotbelger@9246: gernotbelger@9246: import java.util.HashMap; gernotbelger@9246: import java.util.Iterator; gernotbelger@9246: import java.util.List; gernotbelger@9246: import java.util.Map; gernotbelger@9246: import java.util.TreeMap; gernotbelger@9246: gernotbelger@9246: import org.dive4elements.artifacts.Artifact; gernotbelger@9246: import org.dive4elements.artifacts.CallContext; gernotbelger@9246: import org.dive4elements.artifacts.common.utils.XMLUtils.ElementCreator; gernotbelger@9246: import org.dive4elements.river.artifacts.resources.Resources; gernotbelger@9246: import org.dive4elements.river.artifacts.states.AddTableDataHelper; gernotbelger@9246: import org.dive4elements.river.artifacts.states.DistanceOnlySelect; gernotbelger@9246: import org.dive4elements.river.artifacts.uinfo.UINFOArtifact; gernotbelger@9246: import org.dive4elements.river.model.BedHeight; gernotbelger@9247: import org.dive4elements.river.model.River; gernotbelger@9247: import org.dive4elements.river.utils.Formatter; gernotbelger@9246: import org.w3c.dom.Element; gernotbelger@9246: gernotbelger@9246: public class DistanceOnlyPartHistoricalSelect extends DistanceOnlySelect { gernotbelger@9246: gernotbelger@9246: private static final long serialVersionUID = 1L; gernotbelger@9246: gernotbelger@9321: private List bhs = null; gernotbelger@9321: private Integer epoch = null; gernotbelger@9321: private Integer year = null; gernotbelger@9321: private Double lowerKm = null; gernotbelger@9321: private Double upperKm = null; gernotbelger@9321: private River river = null; gernotbelger@9246: gernotbelger@9246: @Override gernotbelger@9246: protected String getUIProvider() { gernotbelger@9246: return "distance_only_part_historical_panel"; gernotbelger@9246: } gernotbelger@9246: gernotbelger@9246: @Override gernotbelger@9246: protected String getTitle(final CallContext context) { gernotbelger@9246: // REMARK: that is how it should be: return Resources.getMsg(context.getMeta(), getID()); gernotbelger@9271: return Resources.getMsg(context.getMeta(), "state.title.salix.historical.distance_part_state"); gernotbelger@9246: } gernotbelger@9246: gernotbelger@9246: @Override gernotbelger@9246: protected void appendItems(final Artifact artifact, final ElementCreator creator, final String name, final CallContext context, final Element select) { gernotbelger@9246: final String datakey = "bedheights_for_part"; gernotbelger@9246: gernotbelger@9246: try { gernotbelger@9246: if (datakey.equals(name)) { gernotbelger@9321: makeDataSourceYearEpoch(creator, select, context, getBedheights(artifact)); // ist nur n test gernotbelger@9246: } else if (name.equals("ld_from_part")) { gernotbelger@9246: gernotbelger@9246: final SalixLineAccess access = new SalixLineAccess((UINFOArtifact) artifact); gernotbelger@9246: final double lowerSoundings = this.getLowerUpperKmRange(getBedheights(artifact))[0]; gernotbelger@9246: final double lowerKm = access.getLowerKm() > lowerSoundings ? access.getLowerKm() : lowerSoundings; gernotbelger@9246: gernotbelger@9246: creator.addAttr(select, "type", "options", true); gernotbelger@9246: gernotbelger@9246: final Element item = creator.create("item"); gernotbelger@9246: creator.addAttr(item, "label", "from_test", true); gernotbelger@9246: creator.addAttr(item, "value", String.valueOf(lowerKm), true); gernotbelger@9246: gernotbelger@9246: select.appendChild(item); gernotbelger@9246: } gernotbelger@9246: gernotbelger@9246: else if (name.equals("ld_to_part")) { gernotbelger@9246: final SalixLineAccess access = new SalixLineAccess((UINFOArtifact) artifact); gernotbelger@9246: final double upperSoundings = this.getLowerUpperKmRange(getBedheights(artifact))[1]; gernotbelger@9246: final double upperKm = access.getUpperKm() < upperSoundings ? access.getUpperKm() : upperSoundings; gernotbelger@9246: gernotbelger@9246: creator.addAttr(select, "type", "options", true); gernotbelger@9246: gernotbelger@9246: final Element item = creator.create("item"); gernotbelger@9246: creator.addAttr(item, "label", "to_test", true); gernotbelger@9246: creator.addAttr(item, "value", String.valueOf(upperKm), true); gernotbelger@9246: gernotbelger@9246: select.appendChild(item); gernotbelger@9246: gernotbelger@9246: } gernotbelger@9246: } gernotbelger@9246: catch ( gernotbelger@9246: gernotbelger@9321: final IllegalArgumentException iae) { gernotbelger@9246: iae.printStackTrace(); gernotbelger@9246: } gernotbelger@9246: } gernotbelger@9246: gernotbelger@9246: private List getBedheights(final Artifact artifact) { gernotbelger@9247: gernotbelger@9247: final SalixLineAccess access = new SalixLineAccess((UINFOArtifact) artifact); // improved lazy-loading gernotbelger@9247: final Integer year = access.getYear(); gernotbelger@9247: final Integer epoch = access.getEpoch(); gernotbelger@9247: final River river = access.getRiver(); // comparable? workflow does not allow return and change anyway... gernotbelger@9247: final Double lower = access.getLowerKm(); gernotbelger@9247: final Double upper = access.getUpperKm(); gernotbelger@9247: if (!(this.year == year && this.epoch == epoch && this.river == river && this.lowerKm == lower && this.upperKm == upper)) { gernotbelger@9247: this.bhs = null; gernotbelger@9247: } gernotbelger@9246: if (this.bhs == null) { gernotbelger@9246: final boolean isEpoch = epoch == null ? false : true; gernotbelger@9247: this.bhs = BedHeight.getBedHeightYearEpoch(isEpoch, isEpoch ? epoch : year, river, lower, upper); gernotbelger@9247: this.year = year; gernotbelger@9247: this.epoch = epoch; gernotbelger@9247: this.river = river; gernotbelger@9247: this.lowerKm = lower; gernotbelger@9247: this.upperKm = upper; gernotbelger@9246: } gernotbelger@9246: return this.bhs; gernotbelger@9246: gernotbelger@9246: } gernotbelger@9246: gernotbelger@9321: private static final void makeDataSourceYearEpoch(final ElementCreator creator, final Element select, final CallContext context, gernotbelger@9246: final List bedheights) { gernotbelger@9246: gernotbelger@9246: final AddTableDataHelper helper = new AddTableDataHelper(creator, select, "year", context.getMeta()); gernotbelger@9246: gernotbelger@9247: // TODO: probably aggregating results, no sound-row, output as single row gernotbelger@9247: gernotbelger@9247: int year = 0; // hässlich, aber kommt vermutlich eh bald weg gernotbelger@9247: if (bedheights != null && bedheights.size() > 0) gernotbelger@9247: year = bedheights.get(0).getYear(); // das jahr/epoche ist immer dasselbe gernotbelger@9247: gernotbelger@9247: helper.addColumn(0, "year", "60", "year", "INTEGER", "LEFT", null); gernotbelger@9247: helper.addColumn(1, "range", "130", "state.uinfo.salix.historical.km_range_part", "STRING", "LEFT", null); gernotbelger@9247: helper.addColumn(2, "description", "500", "uinfo.salix.sounding", "STRING", "LEFT", null); gernotbelger@9246: gernotbelger@9246: final TreeMap bedHeightSorted = new TreeMap<>(); gernotbelger@9246: final double min = Double.MAX_VALUE; gernotbelger@9246: final double max = -Double.MAX_VALUE; gernotbelger@9247: final java.text.NumberFormat formatter = Formatter.getCalculationKm(context.getMeta()); gernotbelger@9246: gernotbelger@9246: for (final BedHeight bh : bedheights) { gernotbelger@9246: final org.dive4elements.river.model.Range range = BedHeight.getRangeFromBedHeights(bh); gernotbelger@9246: final Double from = range.getA().doubleValue(); // NullPointer check?? gernotbelger@9246: final Double to = range.getB().doubleValue(); gernotbelger@9246: gernotbelger@9247: bedHeightSorted.put(bh.getDescription(), formatter.format(from) + " - " + formatter.format(to)); gernotbelger@9246: } gernotbelger@9246: final Iterator iterator = bedHeightSorted.keySet().iterator(); gernotbelger@9246: while (iterator.hasNext()) { gernotbelger@9246: final String descr = iterator.next(); gernotbelger@9246: final String fromTo = bedHeightSorted.get(descr); gernotbelger@9246: final Map row = new HashMap<>(); gernotbelger@9247: row.put("year", String.valueOf(year)); gernotbelger@9247: row.put("range", fromTo); gernotbelger@9246: row.put("description", descr); gernotbelger@9246: helper.addRow(row); gernotbelger@9246: } gernotbelger@9246: gernotbelger@9246: helper.submitMapToXml(); gernotbelger@9246: } gernotbelger@9246: gernotbelger@9246: private double[] getLowerUpperKmRange(final List bedheights) { gernotbelger@9246: double min = Double.MAX_VALUE; gernotbelger@9246: double max = -Double.MAX_VALUE; gernotbelger@9246: gernotbelger@9246: for (final BedHeight bh : bedheights) { gernotbelger@9246: final org.dive4elements.river.model.Range range = BedHeight.getRangeFromBedHeights(bh); gernotbelger@9246: try { gernotbelger@9246: final Double from = range.getA().doubleValue(); // NullPointer check?? -> try catch gernotbelger@9246: final Double to = range.getB().doubleValue(); gernotbelger@9246: gernotbelger@9246: final double upper = to > from ? to : from; gernotbelger@9246: final double lower = from < to ? from : to; gernotbelger@9246: if (upper > max) gernotbelger@9246: max = upper; gernotbelger@9246: gernotbelger@9246: if (lower < min) gernotbelger@9246: min = lower; gernotbelger@9246: } gernotbelger@9246: catch (final Exception e) { gernotbelger@9246: e.printStackTrace(); gernotbelger@9246: } gernotbelger@9246: gernotbelger@9246: } gernotbelger@9246: return new double[] { min, max }; gernotbelger@9246: } gernotbelger@9321: }