ingo@1115: /*
ingo@1115: * Copyright (c) 2010 by Intevation GmbH
ingo@1115: *
ingo@1115: * This program is free software under the LGPL (>=v2.1)
ingo@1115: * Read the file LGPL.txt coming with the software for details
ingo@1115: * or visit http://www.gnu.org/licenses/ if it does not exist.
ingo@1115: */
ingo@1115:
tim@335: package de.intevation.gnv.state.profile.horizontal;
tim@335:
tim@335: import java.io.IOException;
tim@335: import java.io.OutputStream;
tim@335: import java.io.UnsupportedEncodingException;
ingo@740: import java.text.ParseException;
tim@335: import java.text.SimpleDateFormat;
tim@335: import java.util.Collection;
tim@335: import java.util.Date;
tim@335: import java.util.Iterator;
tim@335: import java.util.Locale;
tim@335:
tim@335: import org.apache.log4j.Logger;
tim@823: import org.jfree.chart.ChartTheme;
tim@335:
tim@823: import de.intevation.artifacts.CallContext;
ingo@855: import de.intevation.gnv.artifacts.ressource.RessourceFactory;
tim@823: import de.intevation.gnv.chart.Chart;
tim@823: import de.intevation.gnv.chart.ChartLabels;
tim@823: import de.intevation.gnv.chart.HorizontalProfileChart;
tim@823: import de.intevation.gnv.exports.DefaultExport;
tim@823: import de.intevation.gnv.exports.DefaultProfile;
tim@823: import de.intevation.gnv.exports.ShapeDataCollector;
tim@823: import de.intevation.gnv.exports.Export.Profile;
tim@823: import de.intevation.gnv.geobackend.base.Result;
tim@823: import de.intevation.gnv.state.InputData;
ingo@855: import de.intevation.gnv.state.State;
tim@823: import de.intevation.gnv.state.describedata.KeyValueDescibeData;
tim@823: import de.intevation.gnv.state.exception.StateException;
tim@823: import de.intevation.gnv.state.timeseries.TimeSeriesOutputState;
tim@823: import de.intevation.gnv.statistics.HorizontalProfileStatistics;
tim@823: import de.intevation.gnv.statistics.Statistics;
ingo@358:
tim@335: /**
ingo@811: * This OutputState
is used for 'Horizontalprofile' products.
sascha@835: *
sascha@780: * @author Tim Englich
sascha@780: * @author Ingo Weinzierl
tim@335: */
ingo@368: public class HorizontalProfileOutputState
ingo@368: extends TimeSeriesOutputState
sascha@778: {
tim@762: public static final String [] HORIZONTAL_PROFILE_MESH_COLUMNS = {
ingo@368: "SHAPE",
ingo@368: "YORDINATE",
tim@762: "GROUP1",
tim@762: "MESHID"
tim@762: };
sascha@778:
tim@762: public static final String [] HORIZONTAL_PROFILE_MEASUREMENT_COLUMNS = {
tim@762: "SHAPE",
tim@762: "YORDINATE",
tim@762: "GROUP1",
tim@762: "SURVEYID"
ingo@368: };
ingo@368:
ingo@368:
ingo@368: public static final String [] HORIZONTAL_MESH_CSV_COLUMN_LABEL = {
ingo@368: "Longitude",
ingo@368: "Latitude",
ingo@368: "Value",
ingo@368: "ParameterID",
tim@762: "MeshID"
ingo@368: };
ingo@368:
ingo@368:
ingo@368: public static final String [] HORIZONTAL_MEASUREMENT_CSV_COLUMN_LABEL = {
ingo@368: "Longitude",
ingo@368: "Latitude",
ingo@368: "Value",
ingo@368: "ParameterID",
tim@762: "SurveyID"
ingo@368: };
sascha@778:
tim@335: /**
tim@335: * The UID of this class
tim@335: */
tim@335: private static final long serialVersionUID = 4401516087492028840L;
tim@335:
tim@335: private static Logger log = Logger
tim@335: .getLogger(HorizontalProfileOutputState.class);
tim@335:
tim@335: public static final String DATE_FORMAT = "yyyy.MM.dd HH:mm:ss";
tim@335:
tim@335: public static final String [] CHART_TITLE_META = {
tim@335: "CRUISE",
tim@335: "DEPTH",
tim@335: "SHAPE"
tim@335: };
tim@335:
tim@335:
tim@335: public static final String [] CHART_TITLE_META_RESSOURCES = {
tim@335: "cruiseid",
tim@335: "depth",
tim@335: "coordinate"
tim@335: };
tim@335:
tim@335: public static final String [] TIMESERIES_CSV_PROFILE_NAMES = {
tim@335: "SHAPE",
tim@335: "YORDINATE",
tim@335: "GROUP1",
tim@335: "GROUP2",
tim@335: "GROUP3"
tim@335: };
tim@335:
tim@335: public static final Profile TIMESERIES_CSV_PROFILE =
tim@335: new DefaultProfile(
tim@335: null,
tim@335: ',',
tim@335: '"',
tim@335: '"',
tim@335: "CSV",
tim@335: "ISO-8859-1");
tim@335:
tim@335: /**
tim@335: * Constructor
tim@335: */
tim@335: public HorizontalProfileOutputState() {
tim@335: super();
ingo@343: super.domainLable = "chart.horizontalprofile.title.xaxis";
tim@335: }
tim@335:
tim@335:
ingo@811: /**
ingo@811: * This method creates a chart and returns it.
ingo@811: *
ingo@811: * @param chartLables Labels used to decorate the chart.
ingo@811: * @param theme The theme used to adjust the look of the chart.
ingo@811: * @param parameters A collection with parameters this chart contains.
ingo@811: * @param measurements A collection with measurement this chart contains.
ingo@811: * @param dates A collection with dates this chart contains.
ingo@811: * @param result The data collection used to be displayed in this chart.
ingo@811: * @param locale The Locale used to determine the language.
ingo@811: * @param uuid The uuid of the current artifact.
ingo@811: * @param linesVisible A boolean property to determine the visibility of
ingo@811: * lines connecting two points in a chart (not used in this chart type).
ingo@811: * @param shapesVisible A boolean property to determine the visiblity of
ingo@811: * datapoints in this chart (not used in this chart type).
ingo@811: * @param callContext The CallContext object.
ingo@811: * @return a HorizontalProfileChart
.
ingo@811: */
tim@335: @Override
tim@335: protected Chart getChart(
tim@335: ChartLabels chartLables,
ingo@358: ChartTheme theme,
tim@335: Collection parameters,
tim@335: Collection measurements,
tim@335: Collection dates,
ingo@429: Object result,
tim@335: Locale locale,
tim@335: String uuid,
tim@335: boolean linesVisible,
sascha@439: boolean shapesVisible,
sascha@439: CallContext callContext
tim@335: ) {
tim@335: Chart chart = null;
tim@335:
tim@335: if (CACHE_CHART) {
tim@335: log.info("Try to get horizontalprofile chart from cache.");
sascha@439: chart = (Chart) getChartFromCache(uuid, callContext);
tim@335: }
tim@335:
tim@335: if (chart != null)
tim@335: return chart;
tim@335:
tim@335: log.info("Chart not in cache yet.");
tim@335: chart = new HorizontalProfileChart(
tim@335: chartLables,
ingo@358: theme,
tim@335: parameters,
tim@335: measurements,
tim@335: dates,
ingo@429: (Collection)result,
tim@335: null,
tim@335: locale,
tim@335: linesVisible,
tim@335: shapesVisible
tim@335: );
tim@335: chart.generateChart();
tim@335:
tim@335: if (CACHE_CHART) {
tim@335: log.info("Put chart into cache.");
tim@335: purifyChart(chart, uuid);
tim@335: }
tim@335:
tim@335: return chart;
tim@335: }
tim@335:
tim@335:
tim@335: @Override
tim@335: protected Statistics getStatisticsGenerator() {
tim@335: return new HorizontalProfileStatistics();
tim@335: }
tim@335:
ingo@368:
tim@335: @Override
ingo@368: protected void createCSV(OutputStream out, Collection results)
ingo@368: throws UnsupportedEncodingException, IOException, StateException
ingo@368: {
ingo@368: log.debug("Create csv export for horizontal profiles.");
ingo@368: Iterator iter = results.iterator();
ingo@368: Result res = iter.hasNext() ? (Result) iter.next() : null;
ingo@368:
ingo@368: if (res == null)
ingo@368: return;
ingo@368:
ingo@368: Profile profile = null;
ingo@368: int dataid = res.getInteger("DATAID").intValue();
tim@762: DefaultExport export = null;
ingo@368: // on meshes
ingo@368: if (dataid == 2) {
ingo@368: profile = new DefaultProfile(
ingo@368: HORIZONTAL_MESH_CSV_COLUMN_LABEL,
ingo@368: ',',
ingo@368: '"',
ingo@368: '"',
ingo@368: "CSV",
ingo@368: "ISO-8859-1");
tim@762: export = new DefaultExport(
tim@762: new ShapeDataCollector(HORIZONTAL_PROFILE_MESH_COLUMNS));
ingo@368: }
ingo@368:
ingo@368: // on measurements
ingo@368: else {
ingo@368: profile = new DefaultProfile(
ingo@368: HORIZONTAL_MEASUREMENT_CSV_COLUMN_LABEL,
ingo@368: ',',
ingo@368: '"',
ingo@368: '"',
ingo@368: "CSV",
ingo@368: "ISO-8859-1");
tim@762: export = new DefaultExport(
tim@762: new ShapeDataCollector(HORIZONTAL_PROFILE_MEASUREMENT_COLUMNS));
ingo@368: }
ingo@368:
sascha@778:
ingo@368: export.create(profile, out, results);
tim@335: }
tim@335:
tim@335:
ingo@811: /**
ingo@811: * Creates and returns the chart title.
ingo@811: *
ingo@811: * @param locale The Locale used to adjust the language of the title.
ingo@811: * @param uuid The UUID of the current artifact.
ingo@811: * @return the name of the selected fis.
ingo@811: */
ingo@811: @Override
tim@335: protected String createChartTitle(Locale locale, String uuid) {
tim@335: String fisName = getFisName(locale);
tim@335: log.debug("created title for horizontal profile chart: " + fisName);
tim@335:
tim@335: return fisName;
tim@335: }
tim@335:
tim@335:
ingo@811: @Override
tim@335: protected String createChartSubtitle(Locale locale, String uuid) {
ingo@855: log.debug("Create subtitle for horizontalprofile chart on meshes.");
tim@335:
ingo@855: StringBuilder sb = new StringBuilder();
ingo@855: String ship = getData(locale, "vehicleid");
ingo@855: if (ship != null) {
ingo@855: sb.append(ship);
tim@335: }
tim@335:
ingo@855: String cruise = getData(locale, "cruiseid");
ingo@855: if (cruise != null) {
ingo@855: if (ship != null)
ingo@855: sb.append("\n");
ingo@855:
ingo@855: sb.append(cruise);
ingo@855: }
ingo@855:
ingo@855: String track = getData(locale, "trackid");
ingo@855: if (track != null) {
ingo@855: if (cruise != null)
ingo@855: sb.append("\n");
ingo@855:
ingo@855: sb.append(track);
ingo@855: }
ingo@855:
ingo@855: return sb.toString();
tim@335: }
tim@335:
tim@335:
ingo@855: protected String getData(Locale locale, String data) {
ingo@855: InputData input = null;
tim@335:
ingo@855: State parent = this;
ingo@855: do {
ingo@855: input = inputData.get(data);
tim@335:
ingo@855: if (input != null)
ingo@855: break;
ingo@855: }
ingo@855: while ((parent = parent.getParent()) != null);
ingo@855:
ingo@855: if (input == null) {
ingo@855: log.warn("No data found for: " + data);
ingo@855: return null;
tim@335: }
tim@335:
ingo@855: String value = input.getDescription(input.getValue());
ingo@855: String title = RessourceFactory.getInstance().getRessource(
ingo@855: locale, data, data);
ingo@855:
ingo@855: return (title + ": " + value);
tim@335: }
tim@335:
tim@335:
ingo@811: /**
ingo@811: * Creates a timeperiod taking account for all data items used in charts.
ingo@811: *
ingo@811: * @param locale The Locale used to adjust the language of the subtitle.
ingo@811: * @param uuid The UUID of the current artifact.
ingo@811: * @return a human readable timeperiod.
ingo@811: */
tim@335: protected String createTimePeriod(Locale locale, String uuid) {
tim@335: log.debug("create time period for chart subtitle.");
tim@335: String subTitle = null;
tim@335: Date startDate = null;
tim@335: Date endDate = null;
tim@335:
tim@335: Collection dates = getDates(uuid);
tim@335: if (dates == null) {
tim@335: log.debug("No time period for subtitle.");
tim@335: return "";
tim@335: }
tim@335:
tim@335: SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
tim@335: KeyValueDescibeData data = null;
tim@335:
tim@335: Iterator iter = dates.iterator();
tim@335: while (iter.hasNext()) {
tim@335: try {
tim@335: data = (KeyValueDescibeData)iter.next();
tim@335:
tim@335: if (!data.isSelected())
tim@335: continue;
tim@335:
tim@335: Date current = format.parse(data.getValue());
tim@335: long time = current.getTime();
tim@335:
tim@335: if (startDate == null) {
tim@335: startDate = current;
tim@335: endDate = current;
tim@335: }
tim@335: else if (time < startDate.getTime()) {
tim@335: startDate = current;
tim@335: }
tim@335: else if (time > endDate.getTime()) {
tim@335: endDate = current;
tim@335: }
tim@335: }
ingo@740: catch (ParseException pe) {
tim@335: log.warn("Error while parsing date: " + data.getValue(), pe);
tim@335: }
tim@335: }
tim@335:
ingo@348: if (startDate != null && endDate != null)
ingo@348: subTitle = format.format(startDate)+" - "+format.format(endDate);
ingo@348:
ingo@348: subTitle = subTitle == null ? "" : subTitle;
ingo@348:
tim@335: log.debug("created title for horizontal profile chart: " + subTitle);
tim@335:
tim@335: return subTitle;
tim@335: }
tim@335: }
sascha@836: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :