felix@6878: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde felix@6878: * Software engineering by Intevation GmbH felix@6878: * felix@6878: * This file is Free Software under the GNU AGPL (>=v3) felix@6878: * and comes with ABSOLUTELY NO WARRANTY! Check out the felix@6878: * documentation coming with Dive4Elements River for details. felix@6878: */ felix@6878: felix@6878: package org.dive4elements.river.exports.process; felix@6878: felix@6880: import java.util.ArrayList; felix@6880: import java.util.List; felix@6880: felix@6878: import org.apache.log4j.Logger; felix@6878: import org.jfree.data.xy.XYSeries; felix@6878: felix@6878: import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; felix@6878: import org.dive4elements.artifacts.CallContext; felix@6878: import org.dive4elements.river.artifacts.model.FacetTypes; felix@6878: import org.dive4elements.river.artifacts.model.WQKms; felix@6898: import org.dive4elements.river.exports.DischargeCurveGenerator; felix@6878: import org.dive4elements.river.exports.XYChartGenerator; felix@6880: import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation; felix@6880: import org.dive4elements.river.jfree.RiverAnnotation; felix@6922: import org.dive4elements.river.jfree.StickyAxisAnnotation; felix@6878: import org.dive4elements.river.jfree.StyledXYSeries; teichmann@6905: import org.dive4elements.river.themes.ThemeDocument; felix@6880: felix@6880: import org.jfree.chart.annotations.XYTextAnnotation; felix@6878: felix@6878: felix@6878: /** Helper for data handling in discharge diagrams. */ felix@6878: public class DischargeProcessor aheinecke@7059: extends DefaultProcessor implements FacetTypes { felix@6878: felix@6878: private final static Logger logger = felix@6878: Logger.getLogger(DischargeProcessor.class); felix@6878: felix@6880: /** Station for which the diagram is shown. */ felix@6880: private double km; felix@6880: felix@6880: /** Tolerance for comparison of kilometers. */ felix@6880: public static final double KM_EPSILON = 0.001d; felix@6880: felix@6880: felix@6880: /** This processor needs to be constructed with a given km. */ felix@6880: private DischargeProcessor() { felix@6880: km = Double.NaN; felix@6880: } felix@6880: felix@6880: felix@6880: public DischargeProcessor(double km) { felix@6880: this.km = km; felix@6880: } felix@6880: felix@6878: felix@6878: /** Process data, add it to plot. */ felix@6878: @Override felix@6878: public void doOut( felix@6878: XYChartGenerator generator, felix@6878: ArtifactAndFacet aandf, teichmann@6905: ThemeDocument theme, felix@6878: boolean visible, felix@6914: int axisIndex felix@6878: ) { felix@6878: CallContext context = generator.getCallContext(); felix@6878: Object data = aandf.getData(context); felix@6898: if (false && data instanceof WQKms) { felix@6880: doWQKmsPointOut( felix@6914: generator, (WQKms) data, aandf, theme, visible, axisIndex); felix@6878: return; felix@6878: } felix@6898: else if (data instanceof RiverAnnotation) { felix@6914: doRiverAnnotationOut( felix@6914: generator, (RiverAnnotation) data, aandf, theme, visible); felix@6898: return; felix@6898: } felix@6922: else if (data instanceof double[][]) { felix@6922: doMarksOut( felix@6922: generator, (double[][]) data, aandf, theme, visible); felix@6922: return; felix@6922: } felix@6922: else { felix@6922: logger.error("Can't process " felix@6922: + data.getClass().getName() + " objects of facet " felix@6922: + aandf.getFacetName()); felix@6922: } felix@6878: } felix@6878: felix@6878: felix@6878: /** True if this processor knows how to deal with facetType. */ felix@6878: @Override felix@6878: public boolean canHandle(String facetType) { felix@6898: return /*STATIC_WQKMS_W.equals(facetType) felix@6898: ||*/ COMPUTED_DISCHARGE_MAINVALUES_Q.equals(facetType) felix@6898: || MAINVALUES_Q.equals(facetType) felix@6898: || COMPUTED_DISCHARGE_MAINVALUES_W.equals(facetType) felix@6922: || MAINVALUES_W.equals(facetType) felix@6922: || STATIC_W_INTERPOL.equals(facetType); felix@6878: } felix@6878: felix@6878: felix@6897: /** The station of the current calculation/view. */ felix@6897: protected double getKm() { felix@6897: return km; felix@6897: } felix@6897: felix@6897: felix@6880: /** Handle WQKms data by finding w/q values at given km. */ felix@6878: protected void doWQKmsPointOut(XYChartGenerator generator, felix@6880: WQKms wqkms, felix@6878: ArtifactAndFacet aandf, teichmann@6905: ThemeDocument theme, felix@6878: boolean visible, felix@6880: int axidx felix@6880: ) { felix@6914: logger.debug("doWQKmsPointOut"); felix@6880: String title = aandf.getFacetDescription(); felix@6880: XYSeries series = new StyledXYSeries( felix@6880: title, felix@6880: theme); felix@6878: felix@6880: double[] kms = wqkms.getKms(); felix@6878: felix@6880: for (int i = 0 ; i< kms.length; i++) { felix@6897: if (Math.abs(kms[i] - getKm()) <= KM_EPSILON) { felix@6880: series.add(wqkms.getQ(i), wqkms.getW(i)); felix@6880: generator.addAxisSeries(series, axidx, visible); teichmann@6905: if(visible && theme.parseShowPointLabel()) { felix@6880: List textAnnos = new ArrayList(); felix@6880: XYTextAnnotation anno = new CollisionFreeXYTextAnnotation( felix@6880: title, felix@6880: wqkms.getQ(i), felix@6880: // TODO add a percentage to the extend of W axis felix@6880: wqkms.getW(i)); felix@6880: textAnnos.add(anno); felix@6880: RiverAnnotation flysAnno = new RiverAnnotation(null, null, null, theme); felix@6880: flysAnno.setTextAnnotations(textAnnos); felix@6880: generator.addAnnotations(flysAnno); felix@6880: } felix@6880: return; felix@6880: } felix@6880: } felix@6897: felix@6897: logger.warn("No WQ found for km " + getKm()); felix@6878: } felix@6922: felix@6922: protected void doRiverAnnotationOut(XYChartGenerator generator, felix@6922: RiverAnnotation annotations, felix@6922: ArtifactAndFacet aandf, felix@6922: ThemeDocument theme, felix@6922: boolean visible felix@6922: ) { felix@6922: if (!(generator instanceof DischargeCurveGenerator)) { felix@6922: logger.error("DischargeProcessor can only be used in " + felix@6922: " in DischargeCurveGenerator-classes."); felix@6922: return; felix@6922: } felix@6922: logger.debug("doRiverAnnotationOut"); felix@6922: DischargeCurveGenerator dGenerator = felix@6922: (DischargeCurveGenerator) generator; felix@6922: felix@6922: dGenerator.translateRiverAnnotation(annotations); felix@6922: dGenerator.doAnnotations( felix@6922: annotations, felix@6922: aandf, theme, visible); felix@6922: } felix@6922: felix@6922: felix@6922: /** felix@6922: * Put Sticky Axis Markers to Y-axis for each value. felix@6922: * @param data [[-,y1],[-,y2],...] ('x'-coordinates ignored) felix@6922: */ felix@6922: protected void doMarksOut(XYChartGenerator generator, felix@6922: double[][] data, felix@6922: ArtifactAndFacet aandf, felix@6922: ThemeDocument theme, felix@6922: boolean visible felix@6922: ) { felix@6922: logger.debug("doMarksOut"); felix@6922: felix@6922: if (!visible) { felix@6922: return; felix@6922: } felix@6922: felix@6922: // TODO subtract gauge null point if at gauge. felix@6922: String title = aandf.getFacetDescription(); felix@6922: List yMarks = new ArrayList(); felix@6922: felix@6922: for (double yPos: data[1]) { felix@6922: yMarks.add(new StickyAxisAnnotation( felix@6922: title, felix@6922: (float) yPos, felix@6922: StickyAxisAnnotation.SimpleAxis.Y_AXIS)); felix@6922: } felix@6922: felix@6922: generator.doAnnotations(new RiverAnnotation(title, yMarks), felix@6922: aandf, theme, visible); felix@6922: } felix@6878: } felix@6878: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :