# HG changeset patch # User Tim Englich # Date 1256831927 0 # Node ID 3dcd2b0b456e4cf99a0ec2d34c12dc6c6887f658 # Parent 9db263ee267893b992fd957184ad4775dae29636 Added configurable TimeGap Support to the TimeSeries-Chart-Generation. issu45 gnv-artifacts/trunk@275 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 9db263ee2678 -r 3dcd2b0b456e gnv-artifacts/ChangeLog --- a/gnv-artifacts/ChangeLog Wed Oct 28 16:26:03 2009 +0000 +++ b/gnv-artifacts/ChangeLog Thu Oct 29 15:58:47 2009 +0000 @@ -1,3 +1,22 @@ +2009-10-29 Tim Englich + + * doc/conf/products/timeseries/timegap_definition.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml: + Added the Configuration for TimeGaps to the TimeSeries-Configurations. issue45 + + * doc/conf/queries.properties: + Added TimeGapIp to the Queries for the Resultdata of TimeSeriesArtifacts. issue45 + + * src/main/java/de/intevation/gnv/timeseries/gap/DefaultTimeGap.java, + src/main/java/de/intevation/gnv/timeseries/gap/TimeGap.java, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (setup): + src/main/java/de/intevation/gnv/chart/ChartFactory.java (calculateMaxGap): + Added configurable TimeGap Support to the TimeSeries-Chart-Generation. issue45 + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java (readConfiguration): + Moved Method from GNVArtifactBase to make it assesible for more Objects. issue45 + 2009-10-28 Tim Englich * src/main/java/de/intevation/gnv/profile/horizontalcrosssection/HorizontalCrossSectionMeshArtifact.java (HorizontalCrossSectionMeshArtifact):, diff -r 9db263ee2678 -r 3dcd2b0b456e gnv-artifacts/doc/conf/products/timeseries/conf_timeseriespoint.xml --- a/gnv-artifacts/doc/conf/products/timeseries/conf_timeseriespoint.xml Wed Oct 28 16:26:03 2009 +0000 +++ b/gnv-artifacts/doc/conf/products/timeseries/conf_timeseriespoint.xml Thu Oct 29 15:58:47 2009 +0000 @@ -74,6 +74,7 @@ + diff -r 9db263ee2678 -r 3dcd2b0b456e gnv-artifacts/doc/conf/products/timeseries/timegap_definition.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/timeseries/timegap_definition.xml Thu Oct 29 15:58:47 2009 +0000 @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 9db263ee2678 -r 3dcd2b0b456e gnv-artifacts/doc/conf/queries.properties --- a/gnv-artifacts/doc/conf/queries.properties Wed Oct 28 16:26:03 2009 +0000 +++ b/gnv-artifacts/doc/conf/queries.properties Thu Oct 29 15:58:47 2009 +0000 @@ -54,7 +54,8 @@ tv.DATAVALUE YORDINATE, \ t.PARAMETERID GROUP1, \ tv.MEASUREMENTID GROUP2, \ - tv.TIMESERIESID GROUP3 \ + tv.TIMESERIESID GROUP3, \ + t.TIMEINTERVAL GAPID \ FROM MEDIAN.TIMESERIESVALUE tv, \ MEDIAN.TIMESERIES t \ WHERE tv.TIMESERIESID = t.TIMESERIESID AND \ @@ -125,7 +126,8 @@ msv.DATAVALUE YORDINATE, \ msv.PARAMETERID GROUP1, \ msv.FEATUREID GROUP2, \ - mp.FEATUREID GROUP3 \ + mp.FEATUREID GROUP3, \ + -1 GAPID \ from MEDIAN.MESHSCALARVALUE msv , \ MEDIAN.MESHPOINT mp, \ MEDIAN.MESH m \ diff -r 9db263ee2678 -r 3dcd2b0b456e gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Wed Oct 28 16:26:03 2009 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Thu Oct 29 15:58:47 2009 +0000 @@ -172,29 +172,11 @@ String link = configurationNode.getAttribute("xlink:href"); if (link != null ){ String absolutFileName = Config.replaceConfigDir(link); - configurationNode = (Element)this.readConfiguration(absolutFileName); + configurationNode = (Element)new ArtifactXMLUtilities().readConfiguration(absolutFileName); } return configurationNode; } - - - private Node readConfiguration(String fileName){ - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setValidating(false); - return factory.newDocumentBuilder().parse(fileName).getChildNodes().item(0); - } catch (SAXException e) { - log.error(e,e); - return null; - } catch (IOException e) { - log.error(e,e); - return null; - } catch (ParserConfigurationException e) { - log.error(e,e); - return null; - } - } /** * @see de.intevation.artifactdatabase.DefaultArtifact#feed(org.w3c.dom.Document, diff -r 9db263ee2678 -r 3dcd2b0b456e gnv-artifacts/src/main/java/de/intevation/gnv/chart/ChartFactory.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/chart/ChartFactory.java Wed Oct 28 16:26:03 2009 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/ChartFactory.java Thu Oct 29 15:58:47 2009 +0000 @@ -44,6 +44,7 @@ import de.intevation.gnv.chart.exception.TechnicalChartException; import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.timeseries.gap.TimeGap; import de.intevation.gnv.transition.describedata.KeyValueDescibeData; /** @@ -72,7 +73,8 @@ Collection parameters, Collection measurements, OutputStream outputStream, - Collection resultSet) + Collection resultSet, + Collection timeGaps) throws IOException, TechnicalChartException { if (sDebug) @@ -90,7 +92,7 @@ if (sDebug) sLogger.debug(" vor createDataset()"); XYDataset lSet = this.createDataset(resultSet, lUpperLevel, - lLowerLevel, parameters, measurements); + lLowerLevel, parameters, measurements,timeGaps); if (sDebug) sLogger.debug(" nach createDataset()"); final Color[] color = { Color.black, Color.red, Color.green, Color.blue }; @@ -219,8 +221,7 @@ private TimeSeries createTimeSeries(String pTimeSeriesName, Collection resultSet, int lUpperCut, int lLowerCut, - int pStart, int pEnd, Date dStart, - Date dEnd) + int pStart, int pEnd, long maxGap) throws TechnicalChartException { if (sDebug) sLogger.debug("createTimeSeries()"); @@ -231,9 +232,9 @@ TimeSeries lTimeseries = new TimeSeries(pTimeSeriesName, org.jfree.data.time.Minute.class); try { - long maxGap = 0, lDateDiff = 0; + long lDateDiff = 0; double lValue = 0; - + int i = 0; Iterator resultIterator = resultSet.iterator(); while (resultIterator.hasNext()) { @@ -241,28 +242,6 @@ if (i >= pStart + 1 && i <= pEnd) { if (i == pStart + 1) { lRow0 = lRow;// - - // Handle Gaps > 0.5% timeserieslength, i.e do not draw - // here - // +TODO mache maxGap variabel über diagram options - maxGap = (dEnd.getTime() - dStart.getTime()) / 200; // 0,5 - // prozent - // der - // Länge - if (maxGap < 3600000) - maxGap = 3600010; - if (maxGap < (dEnd.getTime() - dStart.getTime()) - / (pEnd - pStart)) - maxGap = (dEnd.getTime() - dStart.getTime()) - / (pEnd - pStart) + 1000; - - if (sDebug) - sLogger.debug("MaxGap : " + maxGap / 1000 - + " Länge : " - + (dEnd.getTime() - dStart.getTime()) - / 1000 + "Intervall " - + (dEnd.getTime() - dStart.getTime()) - / (pEnd - pStart) / 1000); lDate = lRow0.getDate("XORDINATE"); lDate0 = lDate; lValue = lRow0.getDouble("YORDINATE"); @@ -316,7 +295,8 @@ private XYDataset createDataset(Collection resultSet, int lUpperCut, int lLowerCut, Collection parameters, - Collection measurements) + Collection measurements, + Collection timeGaps) throws TechnicalChartException { TimeSeriesCollection lTimeSeriesCollection = new TimeSeriesCollection(); @@ -335,6 +315,7 @@ break3 = row.getString("GROUP3"); // 4 dStart = row.getDate("XORDINATE"); int i = 1; + Integer gapID = -1; while (resultIterator.hasNext()) { row = resultIterator.next(); if (!break1.equals(row.getString("GROUP1")) @@ -345,10 +326,14 @@ + " " + findValueTitle(measurements, break2) + "m"; - + long maxGap = this.calculateMaxGap(dStart, dEnd,mStart, + mEnd, gapID.intValue(), + timeGaps); + + lTimeSeriesCollection.addSeries(createTimeSeries( mTimeSeriesName, resultSet, lUpperCut, - lLowerCut, mStart, mEnd, dStart, dEnd)); + lLowerCut, mStart, mEnd,maxGap)); mStart = i; dStart = row.getDate("XORDINATE"); break1 = row.getString("GROUP1"); @@ -358,6 +343,7 @@ } mEnd = i; dEnd = row.getDate("XORDINATE"); + gapID = row.getInteger("GAPID"); i = i + 1; } @@ -365,13 +351,17 @@ + " " + findValueTitle(measurements, break2) + "m"; + long maxGap = this.calculateMaxGap(dStart, dEnd,mStart, + mEnd,gapID.intValue(), + timeGaps); lTimeSeriesCollection.addSeries(createTimeSeries( mTimeSeriesName, resultSet, lUpperCut, lLowerCut, - mStart, mEnd, dStart, dEnd)); + mStart, mEnd, maxGap)); }else{ + // Es sind keine Daten vorhanden: Es wird eine Zeitserie eingefügt. lTimeSeriesCollection.addSeries(createTimeSeries( "", resultSet, lUpperCut, lLowerCut, - mStart, mEnd, dStart, dEnd)); + mStart, mEnd, 999999)); } } catch (Exception e) { sLogger.error(e.getMessage(), e); @@ -380,6 +370,74 @@ return lTimeSeriesCollection; } + /** + * @param dStart + * @param dEnd + */ + private long calculateMaxGap(Date dStart, Date dEnd, int pStart , + int pEnd, int gapID, + Collection timeGaps) { + + // umgesetzt nach issue 45 + // Handle Gaps > 0.5% timeserieslength, + // i.e do not draw here + long maxGap = (dEnd.getTime() - dStart.getTime()) / 200; + // 0,5 prozent der Länge + long timeInterval = this.getTimeGapValue(dStart, dEnd, pStart, + pEnd, gapID, timeGaps); + + if (maxGap < timeInterval){ + maxGap = timeInterval + 10; + } +// if (maxGap < (dEnd.getTime() - dStart.getTime()) +// / (pEnd - pStart)) +// maxGap = (dEnd.getTime() - dStart.getTime()) +// / (pEnd - pStart) + 1000; + + return maxGap; + } + + private long getTimeGapValue(Date dStart, Date dEnd, + int pStart ,int pEnd, + int gapID, Collection timeGaps){ + long gap = 0; + + if (gapID < 0 || gapID >= 99){ + if (pEnd-pStart < 60) + gap = (3/(pEnd-pStart)) * (dEnd.getTime() - dStart.getTime()); + }else{ + + Iterator it = timeGaps.iterator(); + + while (it.hasNext()){ + TimeGap tempTimeGap = it.next(); + if (tempTimeGap.getKey() == gapID){ + int gapValue = tempTimeGap.getValue(); + String unit = tempTimeGap.getUnit(); + + if (unit.equals(TimeGap.TIME_UNIT_MINUTE)){ + gap = gapValue * TimeGap.MINUTE_IN_MILLIS; + }else if (unit.equals(TimeGap.TIME_UNIT_HOUR)){ + gap = gapValue * TimeGap.HOUR_IN_MILLIS; + }else if (unit.equals(TimeGap.TIME_UNIT_DAY)){ + gap = gapValue * TimeGap.DAY_IN_MILLIS; + }else if (unit.equals(TimeGap.TIME_UNIT_WEEK)){ + gap = gapValue * TimeGap.WEEK_IN_MILLIS; + }else if (unit.equals(TimeGap.TIME_UNIT_MONTH)){ + // TODO wie soll das laufen + gap = gapValue * (TimeGap.DAY_IN_MILLIS *30); + }else if (unit.equals(TimeGap.TIME_UNIT_YEAR)){ + // TODO wie soll das laufen für schaltjahre + gap = gapValue * (TimeGap.DAY_IN_MILLIS *365); + } + break; + } + } + } + + return gap; + } + private void encodeChart(JFreeChart pChart, ChartStyle pStyle, OutputStream outputStream) throws IOException { if (sDebug) diff -r 9db263ee2678 -r 3dcd2b0b456e gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/gap/DefaultTimeGap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/gap/DefaultTimeGap.java Thu Oct 29 15:58:47 2009 +0000 @@ -0,0 +1,64 @@ +/** + * + */ +package de.intevation.gnv.timeseries.gap; +/** + * @author Tim Englich + * + */ +public class DefaultTimeGap implements TimeGap{ + + /** + * The UNIT of the TimeGap + * See the Constants in de.intevation.gnv.timeseries.gap.TimeGap + */ + private String unit; + + /** + * The Key of the TimeGap which must be äquivalent to the + * Key used in the DWH + */ + private int key; + + /** + * The Value of the Gap. + * Use the Unit and the Time Constants to Calculate the + * value in Milliseconds + */ + private int value; + + /** + * Constructor + * @param unit + * @param key + * @param value + */ + public DefaultTimeGap(String unit, int key, int value) { + super(); + this.unit = unit; + this.key = key; + this.value = value; + } + + /** + * @see de.intevation.gnv.timeseries.gap.TimeGap#getUnit() + */ + public String getUnit() { + return this.unit; + } + + /** + * @see de.intevation.gnv.timeseries.gap.TimeGap#getKey() + */ + public int getKey() { + return this.key; + } + + /** + * @see de.intevation.gnv.timeseries.gap.TimeGap#getValue() + */ + public int getValue() { + return this.value; + } + +} diff -r 9db263ee2678 -r 3dcd2b0b456e gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/gap/TimeGap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/gap/TimeGap.java Thu Oct 29 15:58:47 2009 +0000 @@ -0,0 +1,35 @@ +package de.intevation.gnv.timeseries.gap; +public interface TimeGap { + + public final static String TIME_UNIT_MINUTE = "m"; + public final static String TIME_UNIT_HOUR = "h"; + public final static String TIME_UNIT_DAY = "D"; + public final static String TIME_UNIT_WEEK = "W"; + public final static String TIME_UNIT_MONTH = "M"; + public final static String TIME_UNIT_YEAR = "Y"; + + public final static long MINUTE_IN_MILLIS = 60 * 1000; + public final static long HOUR_IN_MILLIS = 60 * MINUTE_IN_MILLIS; + public final static long DAY_IN_MILLIS = 24 * HOUR_IN_MILLIS; + public final static long WEEK_IN_MILLIS = 7 * DAY_IN_MILLIS; + + + /** + * Returns the Lookup-Key for the TimeGap + * @return + */ + int getKey(); + + /** + * Returns the Value of the TimeValue in the Unit which is also given. + * @return + */ + int getValue(); + + /** + * Returns the Unit of the Timegap (e.g. Minutes, Hours, Days, Weeks, Months, Years) + * @return + */ + String getUnit(); + +} diff -r 9db263ee2678 -r 3dcd2b0b456e gnv-artifacts/src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java Wed Oct 28 16:26:03 2009 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java Thu Oct 29 15:58:47 2009 +0000 @@ -9,9 +9,13 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; +import java.util.List; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; @@ -24,6 +28,8 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; import au.com.bytecode.opencsv.CSVWriter; import de.intevation.artifactdatabase.Config; @@ -40,6 +46,8 @@ import de.intevation.gnv.statistics.Statistics; import de.intevation.gnv.statistics.TimeseriesStatistics; import de.intevation.gnv.statistics.exception.StatisticsException; +import de.intevation.gnv.timeseries.gap.DefaultTimeGap; +import de.intevation.gnv.timeseries.gap.TimeGap; import de.intevation.gnv.transition.InputData; import de.intevation.gnv.transition.OutputTransitionBase; import de.intevation.gnv.transition.describedata.KeyValueDescibeData; @@ -63,6 +71,9 @@ */ private static Logger log = Logger .getLogger(TimeSeriesOutputTransition.class); + + + private static List timeGapDefinitions = null; protected String domainLable = "Zeit [UTC]"; @@ -270,7 +281,7 @@ ChartFactory chartFactory = new ChartFactory(); chartFactory.createSimpleTimeSeriesChart(chartLables, chartStyle, parameters, measurements, outputStream, this - .getChartResult(uuid)); + .getChartResult(uuid),timeGapDefinitions); } protected ChartStyle creatStyle(int witdh, int height) { @@ -329,8 +340,40 @@ if (dateNameValue != null) { this.dateValueName = dateNameValue; } + if (timeGapDefinitions == null){ + Element gapDefinition = (Element)Config.getNodeXPath(configuration, + "time-gap-definition"); + synchronized (this.getClass()) { + if (gapDefinition != null){ + String link = gapDefinition.getAttribute("xlink:href"); + if (link != null ){ + String absolutFileName = Config.replaceConfigDir(link); + gapDefinition = (Element)new ArtifactXMLUtilities(). + readConfiguration(absolutFileName); + } + + NodeList gapDefinitions = Config.getNodeSetXPath(gapDefinition, + "/time-gaps/time-gap"); + if (gapDefinition != null){ + timeGapDefinitions = new ArrayList(gapDefinitions. + getLength()); + for (int i = 0; i < gapDefinitions.getLength(); i++){ + Element gapNode = (Element)gapDefinitions.item(i); + String unit = gapNode.getAttribute("unit"); + int key = Integer.parseInt(gapNode.getAttribute("key")); + int value = Integer.parseInt(gapNode.getAttribute("gap")); + log.info("Add new Timegap: "+key+" "+value+" "+ unit); + timeGapDefinitions.add(new DefaultTimeGap(unit, + key, + value)); + } + } + + } + } + } } - + /** * @param collectionName * @return diff -r 9db263ee2678 -r 3dcd2b0b456e gnv-artifacts/src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java Wed Oct 28 16:26:03 2009 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java Thu Oct 29 15:58:47 2009 +0000 @@ -24,6 +24,7 @@ import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.xml.sax.SAXException; import de.intevation.artifacts.ArtifactNamespaceContext; @@ -141,5 +142,22 @@ reportNode.appendChild(successNode); return document; } + + public Node readConfiguration(String fileName){ + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); + return factory.newDocumentBuilder().parse(fileName).getChildNodes().item(0); + } catch (SAXException e) { + log.error(e,e); + return null; + } catch (IOException e) { + log.error(e,e); + return null; + } catch (ParserConfigurationException e) { + log.error(e,e); + return null; + } + } }