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 :