Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java @ 3610:66f539df4e8b
Issue 716.
FixA: Spilt reference and analysis period themes into one theme for each event.
flys-artifacts/trunk@5239 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Raimund Renkert <raimund.renkert@intevation.de> |
---|---|
date | Thu, 23 Aug 2012 08:49:37 +0000 |
parents | 988ec06c400a |
children | a74bdd032cf7 |
line wrap: on
line source
package de.intevation.flys.exports.fixings; import de.intevation.artifactdatabase.state.ArtifactAndFacet; import de.intevation.artifacts.ArtifactNamespaceContext; import de.intevation.artifacts.CallContext; import de.intevation.artifacts.common.utils.XMLUtils; import de.intevation.flys.artifacts.FLYSArtifact; import de.intevation.flys.artifacts.access.FixAnalysisAccess; import de.intevation.flys.artifacts.model.DateRange; import de.intevation.flys.artifacts.model.FacetTypes; import de.intevation.flys.artifacts.model.QWDDateRange; import de.intevation.flys.artifacts.model.fixings.QWD; import de.intevation.flys.artifacts.resources.Resources; import de.intevation.flys.exports.TimeseriesChartGenerator; import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation; import de.intevation.flys.jfree.FLYSAnnotation; import de.intevation.flys.jfree.StyledDomainMarker; import de.intevation.flys.jfree.StyledTimeSeries; import de.intevation.flys.jfree.StyledValueMarker; import de.intevation.flys.utils.ThemeUtil; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.xpath.XPathConstants; import org.apache.log4j.Logger; import org.jfree.chart.annotations.XYTextAnnotation; import org.jfree.data.time.Day; import org.jfree.data.time.Month; import org.jfree.data.time.RegularTimePeriod; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Generator for Delta W(t) charts. * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a> */ public class FixDeltaWtGenerator extends TimeseriesChartGenerator implements FacetTypes { /** Private logger. */ private static Logger logger = Logger.getLogger(FixDeltaWtGenerator.class); public static final String XPATH_CHART_CURRENTKM = "/art:action/art:attributes/art:currentKm"; public static final String I18N_CHART_TITLE = "chart.fix.deltawt.title"; public static final String I18N_CHART_SUBTITLE = "chart.fix.deltawt.subtitle"; public static final String I18N_XAXIS_LABEL = "chart.fix.deltawt.xaxis.label"; public static final String I18N_YAXIS_LABEL = "chart.fix.deltawt.yaxis.label"; public static final String I18N_YAXIS_SECOND_LABEL = "chart.fix.deltawt.yaxis.second.label"; public static enum YAXIS { dW(0); protected int idx; private YAXIS(int c) { idx = c; } } private FLYSArtifact artifact = null; @Override protected YAxisWalker getYAxisWalker() { return new YAxisWalker() { @Override public int length() { return YAXIS.values().length; } @Override public String getId(int idx) { YAXIS[] yaxes = YAXIS.values(); return yaxes[idx].toString(); } }; } @Override protected String getDefaultChartTitle() { return msg(I18N_CHART_TITLE, I18N_CHART_TITLE); } @Override protected String getChartTitle() { return Resources.format( context.getMeta(), I18N_CHART_TITLE, "", getCurrentKmFromRequest().doubleValue()); } @Override protected String getDefaultChartSubtitle() { FixAnalysisAccess access = new FixAnalysisAccess(artifact); DateRange dateRange = access.getDateRange(); DateRange refRange = access.getReferencePeriod(); return Resources.format( context.getMeta(), I18N_CHART_SUBTITLE, "", access.getRiver(), dateRange.getFrom(), dateRange.getTo(), refRange.getFrom(), refRange.getTo()); } @Override protected String getDefaultXAxisLabel() { return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL); } @Override protected String getDefaultYAxisLabel(int pos) { if (pos == 0) { return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL); } else if (pos == 1) { return msg(I18N_YAXIS_SECOND_LABEL, I18N_YAXIS_SECOND_LABEL); } else { return "NO TITLE FOR Y AXIS: " + pos; } } @Override public void doOut( ArtifactAndFacet artifactFacet, Document theme, boolean visible ) { String name = artifactFacet.getFacetName(); logger.debug("FixDeltaWtGenerator.doOut: " + name); logger.debug("Theme description is: " + artifactFacet.getFacetDescription()); this.artifact = (FLYSArtifact)artifactFacet.getArtifact(); if (name.contains(FIX_SECTOR_AVERAGE_DWT)) { doSectorAverageOut( (FLYSArtifact) artifactFacet.getArtifact(), artifactFacet.getData(context), artifactFacet.getFacetDescription(), theme, visible); } else if (name.equals(FIX_REFERENCE_EVENTS_DWT)) { doReferenceEventsOut( (FLYSArtifact) artifactFacet.getArtifact(), artifactFacet.getData(context), artifactFacet.getFacetDescription(), theme, visible); } else if (name.equals(FIX_ANALYSIS_EVENTS_DWT)) { doAnalysisEventsOut( (FLYSArtifact) artifactFacet.getArtifact(), artifactFacet.getData(context), artifactFacet.getFacetDescription(), theme, visible); } else if (name.equals(FIX_DEVIATION_DWT)) { doDeviationOut( (FLYSArtifact) artifactFacet.getArtifact(), artifactFacet.getData(context), artifactFacet.getFacetDescription(), theme, visible); } else if (name.equals(FIX_ANALYSIS_PERIODS_DWT)) { doAnalysisPeriodsOut( (FLYSArtifact) artifactFacet.getArtifact(), artifactFacet.getData(context), artifactFacet.getFacetDescription(), theme, visible); } else { logger.warn("doOut(): unknown facet name: " + name); return; } } protected void doSectorAverageOut( FLYSArtifact artifact, Object data, String desc, Document theme, boolean visible) { logger.debug("doSectorAverageOut(): description = " + desc); QWDDateRange qwd = (QWDDateRange) data; TimeSeriesCollection tsc = new TimeSeriesCollection(); TimeSeries series = new StyledTimeSeries(desc, theme); if (qwd == null || qwd.qwd == null || qwd.dateRange == null) { return; } RegularTimePeriod rtp = new Day(qwd.qwd.getDate()); double value = qwd.qwd.getDeltaW(); /* // Draw a line spanning the analysis time. series.add(rtp, value); rtp = new Day(qwd.dateRange.getFrom()); series.add(rtp, value); rtp = new Day(qwd.dateRange.getTo()); series.add(rtp, value); */ tsc.addSeries(series); addAxisDataset(tsc, 0, visible); addAttribute(desc, "outline"); Map<Integer, int[]> annoIdxMap = new HashMap<Integer, int[]>(); annoIdxMap.put (0, new int[]{0,0}); doQWDTextAnnotations(annoIdxMap, tsc, qwd.qwd, theme, visible); } protected void doAnalysisEventsOut( FLYSArtifact artifact, Object data, String desc, Document theme, boolean visible ) { logger.debug("doAnalysisEventsOut: desc = " + desc); QWD qwd = (QWD) data; doQWDEventsOut(qwd, desc, theme, visible); } protected void doQWDEventsOut(QWD qwd, String desc, Document theme, boolean visible) { TimeSeriesCollection tsc = new TimeSeriesCollection(); TimeSeries series = new StyledTimeSeries(desc, theme); TimeSeries interpol = new StyledTimeSeries(desc + "interpol", theme); if (qwd == null) { logger.debug("doQWDEventsOut: qwd == null"); return; } Map<Integer, int[]> annoIdxMap = new HashMap<Integer, int[]>(); int idxInterpol = 0; int idxRegular = 0; RegularTimePeriod rtp = new Day(qwd.getDate()); double value = qwd.getDeltaW(); boolean interpolate = qwd.getInterpolated(); if (interpolate) { if(interpol.addOrUpdate(rtp, value) == null) { annoIdxMap.put( 0, new int[]{1, idxInterpol}); idxInterpol++; } } else { if(series.addOrUpdate(rtp, value) == null) { annoIdxMap.put( 0, new int[]{0, idxRegular}); idxRegular++; } } tsc.addSeries(series); tsc.addSeries(interpol); addAxisDataset(tsc, 0, visible); addAttribute(desc + "interpol", "interpolate"); addAttribute(desc, "outline"); doQWDTextAnnotations(annoIdxMap, tsc, qwd, theme, visible); } /** * @param annoIdxMap map of index in qwds to series/data item indices in tsc. */ protected void doQWDTextAnnotations(Map<Integer, int[]> annoIdxMap, TimeSeriesCollection tsc, QWD qwd, Document theme, boolean visible) { logger.debug("doQWDTextAnnotation()"); if (!visible || !ThemeUtil.parseShowPointLabel(theme)) { logger.debug("doQWDTextAnnotation: annotation not visible"); return; } List<XYTextAnnotation> textAnnos = new ArrayList<XYTextAnnotation>(); Set<Map.Entry<Integer, int[]>> entries = annoIdxMap.entrySet(); for(Map.Entry<Integer, int[]> entry : entries) { int[] idxs = entry.getValue(); double x = tsc.getXValue(idxs[0], idxs[1]); XYTextAnnotation anno = new CollisionFreeXYTextAnnotation( qwd.getQ() + " m\u00B3/s", x, qwd.getDeltaW()); textAnnos.add(anno); } FLYSAnnotation flysAnno = new FLYSAnnotation(null, null, null, theme); flysAnno.setTextAnnotations(textAnnos); addAnnotations(flysAnno); } protected void doReferenceEventsOut( FLYSArtifact artifact, Object data, String desc, Document theme, boolean visible ) { logger.debug("doReferenceEventsOut: desc = " + desc); QWD qwd = (QWD) data; doQWDEventsOut(qwd, desc, theme, visible); } protected void doDeviationOut( FLYSArtifact artifact, Object data, String desc, Document theme, boolean visible ) { logger.debug("doDeviationOut: desc = " + desc); if (data == null || !visible) { logger.debug("no standard deviation"); return; } double[] value = (double[]) data; StyledDomainMarker lower = new StyledDomainMarker((value[0] * -1), 0, theme); StyledDomainMarker upper = new StyledDomainMarker(0, value[0], theme); valueMarker.add(lower); valueMarker.add(upper); } protected void doAnalysisPeriodsOut( FLYSArtifact artifact, Object data, String desc, Document theme, boolean visible ) { logger.debug("doHistoricalDischargeDifferenceOut: desc = " + desc); DateRange[] ranges = (DateRange[]) data; if (ranges == null || !visible) { return; } for (int i = 0; i < ranges.length; i++) { logger.debug("creating domain marker"); RegularTimePeriod start = new Month(ranges[i].getFrom()); RegularTimePeriod end = new Month(ranges[i].getTo()); StyledDomainMarker marker = new StyledDomainMarker(start.getMiddleMillisecond(), end.getMiddleMillisecond(), theme); marker.useSecondColor(i % 2 == 0); domainMarker.add(marker); } logger.debug("domainmarkers: " + domainMarker.size()); } @Override public void init(Document request, OutputStream out, CallContext context) { super.init(request, out, context); Double currentKm = getCurrentKmFromRequest(); if (logger.isDebugEnabled()) { logger.debug("currentKm = " + currentKm); } context.putContextValue("currentKm", currentKm); StyledValueMarker marker = new StyledValueMarker(0, request); valueMarker.add(marker); } protected Double getCurrentKmFromRequest() { Element km = (Element)XMLUtils.xpath( request, XPATH_CHART_CURRENTKM, XPathConstants.NODE, ArtifactNamespaceContext.INSTANCE); if (km == null) { return Double.valueOf(-1d); } String uri = ArtifactNamespaceContext.NAMESPACE_URI; // XXX: When using XPath already why is the 'km' // attribute not fetched directly? String currentKm = km.getAttributeNS(uri, "km"); try { return Double.valueOf(currentKm); } catch (NumberFormatException nfe) { return Double.valueOf(-1d); } } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :