Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/DischargeTablesOverview.java @ 5346:615e25b6440e
Fix HWSKind column name for the name of the kind
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Wed, 20 Mar 2013 16:32:07 +0100 |
parents | f987d25627aa |
children | 02f6741f80d4 |
line wrap: on
line source
package de.intevation.flys.artifacts.services; import java.awt.Color; import java.text.DateFormat; import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.log4j.Logger; import org.hibernate.Session; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.Marker; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import de.intevation.artifacts.CallMeta; import de.intevation.artifacts.GlobalContext; import de.intevation.flys.artifacts.model.DischargeTables; import de.intevation.flys.artifacts.model.GaugeFinder; import de.intevation.flys.artifacts.model.GaugeFinderFactory; import de.intevation.flys.artifacts.model.GaugeRange; import de.intevation.flys.artifacts.model.GaugesFactory; import de.intevation.flys.artifacts.resources.Resources; import de.intevation.flys.backend.SessionHolder; import de.intevation.flys.model.DischargeTable; import de.intevation.flys.model.Gauge; import de.intevation.flys.model.TimeInterval; /** Generate Discharge Table chart. */ public class DischargeTablesOverview extends AbstractChartService { private static final Logger log = Logger .getLogger(DischargeTablesOverview.class); private static final long serialVersionUID = 1L; public static final String I18N_CHART_TITLE = "gauge.discharge.service.chart.title"; public static final String DEFAULT_CHART_TITLE = "Pegel: XXX"; public static final String I18N_CHART_X_AXIS_TITLE = "gauge.discharge.service.chart.x.title"; public static final String DEFAULT_X_AXIS_TITLE = "Q [m^3/s]"; public static final String I18N_CHART_Y_AXIS_TITLE = "gauge.discharge.service.chart.y.title"; public static final String DEFAULT_Y_AXIS_TITLE = "W [cm]"; public static final String I18N_CHART_SERIES_TITLE = "gauge.discharge.service.chart.series.title"; public static final String DEFAULT_CHART_SERIES_TITLE = "Abflusskurve"; public static final String I18N_CHART_SERIES_TITLE_MASTER = "gauge.discharge.service.chart.series.title.master"; public static final String DEFAULT_CHART_SERIES_TITLE_MASTER = "Aktuelle Abflusskurve"; public static final DateFormat DATE_FORMAT = DateFormat.getDateInstance( DateFormat.SHORT, Locale.GERMANY); private Session session; @Override protected void init() { session = SessionHolder.acquire(); } @Override protected void finish() { if (session != null) { session.close(); SessionHolder.release(); } } protected JFreeChart createChart(Document data, GlobalContext globalContext, CallMeta callMeta) { Gauge gauge = extractGauge(data); if (gauge == null) { log.warn("Could not determine Gauge from request!"); return null; } log.info("create discharge chart for gauge '" + gauge.getName() + "'"); TimeInterval timerange = extractTimeInterval(data); List<DischargeTable> dts = getDischargeTables(gauge, timerange); XYSeriesCollection dataset = new XYSeriesCollection(); for (DischargeTable dt : dts) { try { XYSeries series = createSeries(callMeta, dt); if (series != null) { dataset.addSeries(series); } } catch (IllegalArgumentException iae) { log.warn("unable to create discharge curve: " + iae.getMessage()); } } String title = Resources.format(callMeta, I18N_CHART_TITLE, DEFAULT_CHART_TITLE, gauge.getName()); String xAxis = Resources.getMsg(callMeta, I18N_CHART_X_AXIS_TITLE, DEFAULT_X_AXIS_TITLE); String yAxis = Resources.format(callMeta, I18N_CHART_Y_AXIS_TITLE, DEFAULT_Y_AXIS_TITLE); JFreeChart chart = ChartFactory.createXYLineChart(title, xAxis, yAxis, null, PlotOrientation.VERTICAL, true, true, false); chart.setBackgroundPaint(Color.white); XYPlot plot = (XYPlot) chart.getPlot(); plot.setDataset(0, dataset); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.gray); plot.setRangeGridlinePaint(Color.gray); plot.setDomainGridlinesVisible(true); plot.setRangeGridlinesVisible(true); applyMainValueMarkers( plot, gauge.getRiver().getName(), gauge.getStation().doubleValue(), callMeta); return chart; } protected XYSeries createSeries(CallMeta callMeta, DischargeTable dt) throws IllegalArgumentException { double[][] xy = null; if (dt.getKind() == DischargeTables.MASTER) { xy = DischargeTables.loadDischargeTableValues(dt, DischargeTables.MASTER_SCALE); } else { xy = DischargeTables.loadDischargeTableValues(dt, DischargeTables.HISTORICAL_SCALE); } XYSeries series = new XYSeries(createSeriesTitle(callMeta, dt), false); for (int i = 0, n = xy[0].length; i < n; i++) { series.add(xy[0][i], xy[1][i]); } return series; } /** Add domain markers to plot that indicate (only some Q) mainvalues. */ protected static void applyMainValueMarkers( XYPlot plot, String river, double km, CallMeta meta ) { GaugeFinderFactory ggf = GaugeFinderFactory.getInstance(); GaugeFinder gf = ggf.getGaugeFinder(river); if (gf == null) { log.warn("No gauge finder found for river '" + river + "'"); return; } GaugeRange gr = gf.find(km); if (gr == null) { log.debug("No gauge range found for km " + km + " on river " + river + "."); return; } if (log.isDebugEnabled()) { log.debug(gr); } for (Map.Entry<String, Double> entry: gr.getMainValues().entrySet()) { Marker m = FixingsKMChartService.createQSectorMarker( entry.getValue(), entry.getKey()); if (m != null) { plot.addDomainMarker(m); } } } protected String createSeriesTitle(CallMeta callMeta, DischargeTable dt) throws IllegalArgumentException { TimeInterval timeInterval = dt.getTimeInterval(); if (timeInterval == null) { return Resources.format(callMeta, DEFAULT_CHART_SERIES_TITLE); } Date start = timeInterval.getStartTime(); Date end = timeInterval.getStopTime(); if (start != null && end != null) { return Resources.format(callMeta, I18N_CHART_SERIES_TITLE, DEFAULT_CHART_SERIES_TITLE, start, end); } else if (start != null) { return Resources.format(callMeta, I18N_CHART_SERIES_TITLE_MASTER, DEFAULT_CHART_SERIES_TITLE, start); } else { throw new IllegalArgumentException( "Missing start date of DischargeTable " + dt.getId()); } } protected Gauge extractGauge(Document data) { NodeList gauges = data.getElementsByTagName("gauge"); if (gauges.getLength() > 0) { String name = ((Element) gauges.item(0)).getAttribute("name"); try { long officialNumber = Long.valueOf(name); return Gauge.getGaugeByOfficialNumber(officialNumber); } catch (NumberFormatException nfe) { // it seems, that the client uses the name of the gauge instead // of its official number } if (name != null && name.length() > 0) { return GaugesFactory.getGauge(name); } } return null; } protected TimeInterval extractTimeInterval(Document data) { NodeList timeranges = data.getElementsByTagName("timerange"); if (timeranges != null && timeranges.getLength() > 0) { Element timerange = (Element) timeranges.item(0); String lower = timerange.getAttribute("lower"); String upper = timerange.getAttribute("upper"); if (lower != null && upper != null) { try { Date d1 = DATE_FORMAT.parse(lower); Date d2 = DATE_FORMAT.parse(upper); return new TimeInterval(d1, d2); } catch (ParseException pe) { log.warn("Wrong time format: " + pe.getMessage()); } } } return null; } protected List<DischargeTable> getDischargeTables(Gauge gauge, TimeInterval timerange) { List<DischargeTable> all = gauge.getDischargeTables(); Collections.sort(all); if (timerange == null) { return all; } List<DischargeTable> dts = new ArrayList<DischargeTable>(all.size()); long startDate = timerange.getStartTime().getTime(); long stopDate = timerange.getStopTime().getTime(); for (DischargeTable dt : all) { TimeInterval tmp = dt.getTimeInterval(); if (tmp == null) { // this should never happen because all discharge tables should // have a time interval set! continue; } Date start = tmp.getStartTime(); Date stop = tmp.getStartTime(); if (start.getTime() > startDate && start.getTime() < stopDate) { dts.add(dt); continue; } else if (stop != null && stop.getTime() < stopDate && stop.getTime() > startDate) { dts.add(dt); continue; } } return dts; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :