Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java @ 4221:480de0dbca8e
Extended location input helper.
The locationpicker has now an attribute whether the input is distance or
location to display one or two clickable columns.
Replaced the record click handler with cell click handler.
author | Raimund Renkert <rrenkert@intevation.de> |
---|---|
date | Tue, 23 Oct 2012 13:17:20 +0200 |
parents | b220287a171e |
children | 96ea983b5c45 |
line wrap: on
line source
package de.intevation.flys.artifacts.states; import java.util.ArrayList; import java.util.List; import java.util.Comparator; import java.util.Collections; import org.apache.log4j.Logger; import org.w3c.dom.Element; import de.intevation.artifacts.Artifact; import de.intevation.artifacts.CallContext; import de.intevation.artifactdatabase.ProtocolUtils; import de.intevation.artifactdatabase.data.StateData; import de.intevation.artifacts.common.utils.XMLUtils; import de.intevation.flys.model.Gauge; import de.intevation.flys.model.Range; import de.intevation.flys.model.River; import de.intevation.flys.model.Wst; import de.intevation.flys.artifacts.FLYSArtifact; import de.intevation.flys.artifacts.model.RangeWithValues; import de.intevation.flys.artifacts.model.WstFactory; import de.intevation.flys.utils.FLYSUtils; /** * State to input W/Q data. * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> */ public class WQAdapted extends DefaultState { /** The logger used in this state.*/ private static Logger logger = Logger.getLogger(WQAdapted.class); public static final String FIELD_WQ_MODE = "wq_isq"; public static final String FIELD_WQ_VALUES = "wq_values"; public static final class GaugeOrder implements Comparator<Gauge> { private int order; public GaugeOrder(boolean up) { order = up ? 1 : -1; } public int compare(Gauge a, Gauge b) { return order * a.getRange().getA().compareTo(b.getRange().getA()); } } // class GaugeOrder public static final GaugeOrder GAUGE_UP = new GaugeOrder(true); public static final GaugeOrder GAUGE_DOWN = new GaugeOrder(false); /** Trivial, empty constructor. */ public WQAdapted() { } /** * This method creates one element for each gauge of the selected river that * is intersected by the given kilometer range. Each element is a tuple of * (from;to) where <i>from</i> is the lower bounds of the gauge or the lower * kilometer range. <i>to</i> is the upper bounds of the gauge or the upper * kilometer range. * * @param cr The ElementCreator. * @param artifact The FLYS artifact. * @param name The name of the data item. * @param context The CallContext. * * @return a list of elements that consist of tuples of the intersected * gauges of the selected river. */ @Override protected Element[] createItems( XMLUtils.ElementCreator cr, Artifact artifact, String name, CallContext context) { logger.debug("WQAdapted.createItems"); if (name != null && name.equals(FIELD_WQ_MODE)) { return createModeItems(cr, artifact, name, context); } else if (name != null && name.equals(FIELD_WQ_VALUES)) { return createValueItems(cr, artifact, name, context); } else { logger.warn("Unknown data object: " + name); return null; } } /** Creates "Q" and "W" items. */ protected Element[] createModeItems( XMLUtils.ElementCreator cr, Artifact artifact, String name, CallContext context) { logger.debug("WQAdapted.createModeItems"); Element w = createItem(cr, new String[] { "w", "W" }); Element q = createItem(cr, new String[] { "q", "Q" }); return new Element[] { w, q }; } protected Element[] createValueItems( XMLUtils.ElementCreator cr, Artifact artifact, String name, CallContext context) { logger.debug("WQAdapted.createValueItems"); FLYSArtifact flysArtifact = (FLYSArtifact) artifact; double[] dist = FLYSUtils.getKmRange(flysArtifact); River river = FLYSUtils.getRiver(flysArtifact); Wst wst = WstFactory.getWst(river); List<Gauge> gauges = FLYSUtils.getGauges(flysArtifact); int num = gauges != null ? gauges.size() : 0; if (num == 0) { logger.warn("Selected distance matches no gauges."); return null; } List<Element> elements = new ArrayList<Element>(); double rangeFrom = dist[0]; double rangeTo = dist[1]; if (rangeFrom < rangeTo) { Collections.sort(gauges, GAUGE_UP); for (Gauge gauge: gauges) { Range range = gauge.getRange(); double lower = range.getA().doubleValue(); double upper = range.getB().doubleValue(); // If gauge out of range, skip it. if (upper <= rangeFrom || lower >= rangeTo) { continue; } double from = lower < rangeFrom ? rangeFrom : lower; double to = upper > rangeTo ? rangeTo : upper; double[] mmQ = determineMinMaxQ(gauge, wst); double[] mmW = gauge.determineMinMaxW(); elements.add(createItem( cr, new String[] { from + ";" + to, ""}, mmQ, mmW)); } } else { Collections.sort(gauges, GAUGE_DOWN); rangeFrom = dist[1]; rangeTo = dist[0]; for (Gauge gauge: gauges) { Range range = gauge.getRange(); double lower = range.getA().doubleValue(); double upper = range.getB().doubleValue(); double from = lower < rangeFrom ? rangeFrom : lower; double to = upper > rangeTo ? rangeTo : upper; // TODO probably need to continue out if oof range (see above). double[] mmQ = determineMinMaxQ(gauge, wst); double[] mmW = gauge.determineMinMaxW(); elements.add(createItem( cr, new String[] { to + ";" + from, ""}, mmQ, mmW)); } } Element[] els = new Element[elements.size()]; return elements.toArray(els); } protected Element createItem(XMLUtils.ElementCreator cr, Object obj) { return createItem(cr, obj, null, null); } protected Element createItem( XMLUtils.ElementCreator cr, Object obj, double[] q, double[] w) { Element item = ProtocolUtils.createArtNode(cr, "item", null, null); Element label = ProtocolUtils.createArtNode(cr, "label", null, null); Element value = ProtocolUtils.createArtNode(cr, "value", null, null); String[] arr = (String[]) obj; label.setTextContent(arr[0]); value.setTextContent(arr[1]); item.appendChild(label); item.appendChild(value); if (q != null) { Element qRange = createRangeElement(cr, q, "Q"); item.appendChild(qRange); } if (w != null) { Element wRange = createRangeElement(cr, w, "W"); item.appendChild(wRange); } return item; } protected Element createRangeElement( XMLUtils.ElementCreator cr, double[] mm, String type) { Element range = ProtocolUtils.createArtNode( cr, "range", new String[] {"type"}, new String[] {type}); Element min = ProtocolUtils.createArtNode(cr, "min", null, null); min.setTextContent(String.valueOf(mm[0])); Element max = ProtocolUtils.createArtNode(cr, "max", null, null); max.setTextContent(String.valueOf(mm[1])); range.appendChild(min); range.appendChild(max); return range; } /** * Determines the min and max Q value for the given gauge. If no min and * max values could be determined, this method will return * [Double.MIN_VALUE, Double.MAX_VALUE]. * * @param gauge * @param wst * * @return the min and max Q values for the given gauge. */ protected double[] determineMinMaxQ(Gauge gauge, Wst wst) { logger.debug("WQAdapted.determineMinMaxQ"); double[] minmaxQ = gauge != null ? wst.determineMinMaxQ(gauge.getRange()) : null; double minQ = minmaxQ != null ? minmaxQ[0] : Double.MIN_VALUE; double maxQ = minmaxQ != null ? minmaxQ[1] : Double.MAX_VALUE; return new double[] { minQ, maxQ }; } @Override protected String getUIProvider() { return "wq_panel_adapted"; } @Override public boolean validate(Artifact artifact) throws IllegalArgumentException { logger.debug("WQAdapted.validate"); FLYSArtifact flys = (FLYSArtifact) artifact; StateData data = getData(flys, FIELD_WQ_MODE); String mode = data != null ? (String) data.getValue() : null; boolean isQ = mode != null ? Boolean.valueOf(mode) : false; if (!isQ) { return validateW(artifact); } else if (isQ) { return validateQ(artifact); } else { throw new IllegalArgumentException("error_feed_no_wq_mode_selected"); } } protected boolean validateW(Artifact artifact) throws IllegalArgumentException { logger.debug("WQAdapted.validateW"); FLYSArtifact flys = (FLYSArtifact) artifact; RangeWithValues[] rwvs = extractInput(getData(flys, "wq_values")); if (rwvs == null) { throw new IllegalArgumentException("error_missing_wq_data"); } List<Gauge> gauges = FLYSUtils.getGauges((FLYSArtifact) artifact); for (Gauge gauge: gauges) { Range range = gauge.getRange(); double lower = range.getA().doubleValue(); double upper = range.getB().doubleValue(); for (RangeWithValues rwv: rwvs) { if (lower <= rwv.getStart() && upper >= rwv.getEnd()) { compareWsWithGauge(gauge, rwv.getValues()); } } } return true; } protected boolean validateQ(Artifact artifact) throws IllegalArgumentException { logger.debug("WQAdapted.validateQ"); FLYSArtifact flys = (FLYSArtifact) artifact; RangeWithValues[] rwvs = extractInput(getData(flys, "wq_values")); if (rwvs == null) { throw new IllegalArgumentException("error_missing_wq_data"); } List<Gauge> gauges = FLYSUtils.getGauges(flys); River river = FLYSUtils.getRiver(flys); Wst wst = WstFactory.getWst(river); for (Gauge gauge: gauges) { Range range = gauge.getRange(); double lower = range.getA().doubleValue(); double upper = range.getB().doubleValue(); for (RangeWithValues rwv: rwvs) { if (lower <= rwv.getStart() && upper >= rwv.getEnd()) { compareQsWithGauge(wst, gauge, rwv.getValues()); } } } return true; } protected boolean compareQsWithGauge(Wst wst, Gauge gauge, double[] qs) throws IllegalArgumentException { double[] minmax = gauge != null ? wst.determineMinMaxQ(gauge.getRange()) : null; if (minmax == null) { logger.warn("Could not determine min/max Q of gauge."); return true; } if (logger.isDebugEnabled()) { logger.debug("Validate Qs with:"); logger.debug("-- Gauge: " + gauge.getName()); logger.debug("-- Gauge min: " + minmax[0]); logger.debug("-- Gauge max: " + minmax[1]); } for (double q: qs) { if (q < minmax[0] || q > minmax[1]) { throw new IllegalArgumentException( "error_feed_q_values_invalid"); } } return true; } protected boolean compareWsWithGauge(Gauge gauge, double[] ws) throws IllegalArgumentException { double[] minmax = gauge != null ? gauge.determineMinMaxW() : null; if (minmax == null) { logger.warn("Could not determine min/max W of gauge."); return true; } if (logger.isDebugEnabled()) { logger.debug("Validate Ws with:"); logger.debug("-- Gauge: " + gauge.getName()); logger.debug("-- Gauge min: " + minmax[0]); logger.debug("-- Gauge max: " + minmax[1]); } for (double w: ws) { if (w < minmax[0] || w > minmax[1]) { throw new IllegalArgumentException( "error_feed_w_values_invalid"); } } return true; } protected RangeWithValues[] extractInput(StateData data) { if (data == null) { return null; } String dataString = (String) data.getValue(); String[] ranges = dataString.split(":"); List<RangeWithValues> rwv = new ArrayList<RangeWithValues>(); for (String range: ranges) { String[] parts = range.split(";"); double lower = Double.parseDouble(parts[0]); double upper = Double.parseDouble(parts[1]); String[] values = parts[2].split(","); int num = values.length; double[] res = new double[num]; for (int i = 0; i < num; i++) { try { res[i] = Double.parseDouble(values[i]); } catch (NumberFormatException nfe) { logger.warn(nfe, nfe); } } rwv.add(new RangeWithValues(lower, upper, res)); } return rwv.toArray(new RangeWithValues[rwv.size()]); } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :