changeset 82:5eb62df21f9a

Added Support for Vertical Profiles Marnet, STAUN, IMIS gnv-artifacts/trunk@111 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Tim Englich <tim.englich@intevation.de>
date Tue, 22 Sep 2009 13:20:30 +0000
parents 9b41f3688610
children 5c8e54726a58
files gnv-artifacts/Changelog gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java gnv-artifacts/src/main/java/de/intevation/gnv/chart/ChartFactory.java gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java gnv-artifacts/src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java gnv-artifacts/src/main/java/de/intevation/gnv/transition/TransitionBase.java gnv-artifacts/src/main/java/de/intevation/gnv/transition/describedata/DefaultKeyValueDescribeData.java gnv-artifacts/src/main/java/de/intevation/gnv/transition/describedata/KeyValueDescibeData.java gnv-artifacts/src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java gnv-artifacts/src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java gnv-artifacts/src/test/ressources/conf.xml gnv-artifacts/src/test/ressources/queries.properties
diffstat 12 files changed, 688 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/gnv-artifacts/Changelog	Mon Sep 21 11:50:47 2009 +0000
+++ b/gnv-artifacts/Changelog	Tue Sep 22 13:20:30 2009 +0000
@@ -1,3 +1,28 @@
+2009-09-22  Tim Englich  <tim.englich@intevation.de>
+
+    * src/test/ressources/queries.properties Edited:
+      Added Queries for the Workfloe of collecting the
+      required Information to generate a vertical Profile 
+    * src/test/ressources/conf.xml Edited: 
+      Added the Configuration of the VerticalProfileArtifact
+    * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (getCollection) Edited:
+      Some Codrefactoring done for reuse of Functionality in extended Classes. 
+    * src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java Added:
+    Outputtransition for the Support of VerticalPropfiles 
+    * src/main/java/de/intevation/gnv/transition/describedata/KeyValueDescibeData.java (getKey),
+      src/main/java/de/intevation/gnv/transition/describedata/DefaultKeyValueDescribeData.java (getKey) Edietd, 
+      src/main/java/de/intevation/gnv/transition/TransitionBase.java (purifyResult) Edited:
+     Change KEY-Attribute of KeyValueDescribeData from Integer to String for the required 
+     Representation of Date-KeyValue-Pairs 
+    * src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java Added:
+     ArtifactClass for the representation of VerticalProfiles 
+    * src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java (createSelectBox) Edited:
+      Added support for selected Products in static UI. 
+    * src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java Added:
+      Factory for producing VerticalCharts added. 
+    * src/main/java/de/intevation/gnv/chart/ChartFactory.java Edited:
+      Names of Getter for Columns Changed. 
+
 2009-09-21  Tim Englich  <tim.englich@intevation.de>
 
     * src/test/ressources/queries.properties Edited:
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java	Mon Sep 21 11:50:47 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java	Tue Sep 22 13:20:30 2009 +0000
@@ -371,6 +371,9 @@
             Product p = it.next();
             Element itemNode = xmlUtilities.createXFormElement(document, "item");
             
+            if (this.current != null && this.current.getName().equals(p.getName())){
+                itemNode.setAttribute("selected", "true");
+            }
             
             Element choiceLableNode = xmlUtilities.createXFormElement(document, "label");
             choiceLableNode.setTextContent(p.getName());
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/chart/ChartFactory.java	Mon Sep 21 11:50:47 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/ChartFactory.java	Tue Sep 22 13:20:30 2009 +0000
@@ -244,9 +244,9 @@
             			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("TIMEVALUE");
+            			lDate = lRow0.getDate("XORDINATE");
             			lDate0 = lDate;
-            			lValue = lRow0.getDouble("DATAVALUE");
+            			lValue = lRow0.getDouble("YORDINATE");
             			if (lValue > lLowerCut && lValue < lUpperCut){
             				//lTimeseries.addOrUpdate(new Minute(lDate), lValue);
             				lTimeseries.add(new Minute(lDate), lValue);
@@ -254,8 +254,8 @@
                 	}
 				//for (int i = pStart+1; i <= pEnd; i++) {
 					lRow1 =lRow;
-					lDate = lRow1.getDate("TIMEVALUE");
-					lValue = lRow1.getDouble("DATAVALUE");
+					lDate = lRow1.getDate("XORDINATE");
+					lValue = lRow1.getDouble("YORDINATE");
 					lDateDiff = lDate.getTime() - lDate0.getTime();
 					if (lDateDiff > maxGap) {
 						// add 1 minute in millisecs to left hand side Date
@@ -298,7 +298,7 @@
 		TimeSeriesCollection lTimeSeriesCollection = new TimeSeriesCollection();
 		try{
 			Date dStart = null, dEnd= null;
-			int break1, break2, break3;
+			String break1, break2, break3;
 			int mStart = 0;
 			int mEnd = 0;
 			
@@ -308,31 +308,31 @@
     //			Row row = new Row(sArrayStrLine);
     			Result row = resultIterator.next();
     			
-    			break1 = row.getInteger("PARAMETERID").intValue(); // 2
-    			break2 = row.getInteger("MEASUREMENTID").intValue();  //3
-    			break3 = row.getInteger("TIMESERIESID").intValue(); // 4
-    			dStart = row.getDate("TIMEVALUE");
+    			break1 = row.getString("GROUP1"); // 2
+    			break2 = row.getString("GROUP2");  //3
+    			break3 = row.getString("GROUP3"); // 4
+    			dStart = row.getDate("XORDINATE");
     			int i = 1;
     			while (resultIterator.hasNext()) {
     			    row = resultIterator.next();
-    				if (break1 != row.getInteger("PARAMETERID").intValue()
-    						|| break2 != row.getInteger("MEASUREMENTID").intValue()
-    					    || break3 != row.getInteger("TIMESERIESID").intValue()){
+    				if (!break1.equals(row.getString("GROUP1"))
+    						|| !break2 .equals(row.getString("GROUP2"))
+    					    || !break3.equals(row.getString("GROUP3"))){
     					String mTimeSeriesName = findValueTitle(parameters,break1)+" "+
     					                         findValueTitle(measurements,break2)+"m";
     					
     					lTimeSeriesCollection.addSeries(createTimeSeries(mTimeSeriesName,
     							resultSet, lUpperCut, lLowerCut, mStart, mEnd, dStart, dEnd));
     					mStart = i;
-    					dStart = row.getDate("TIMEVALUE");
-    					break1 = row.getInteger("PARAMETERID").intValue();
-    					break2 = row.getInteger("MEASUREMENTID").intValue();  //3
-    					break3 = row.getInteger("TIMESERIESID").intValue(); // 4
+    					dStart = row.getDate("XORDINATE");
+    					break1 = row.getString("GROUP1");
+    					break2 = row.getString("GROUP2");  //3
+    					break3 = row.getString("GROUP3"); // 4
     	
     				}
     				mEnd = i;
     				//mEnd ++;
-    				dEnd = row.getDate("TIMEVALUE");
+    				dEnd = row.getDate("XORDINATE");
     				i = i + 1;
     			}
 			
@@ -369,11 +369,19 @@
 	
 }
 
-    private String findValueTitle(Collection<KeyValueDescibeData> values,int pMmtId){
-    	Iterator<KeyValueDescibeData> it = values.iterator();
+    private String findValueTitle(Collection<KeyValueDescibeData> values, String pMmtId){
+    	int id = 0;
+    	try {
+            id = Integer.parseInt(pMmtId);
+        } catch (NumberFormatException e) {
+            sLogger.warn(e,e);
+            return pMmtId;
+        }
+        
+        Iterator<KeyValueDescibeData> it = values.iterator();
     	while(it.hasNext()){
     	    KeyValueDescibeData data = it.next();
-    		if ((long) pMmtId ==data.getKey()){
+    		if (id  ==Integer.parseInt(data.getKey())){ // TODO just a hack
     		    return data.getValue();
     		}
     	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java	Tue Sep 22 13:20:30 2009 +0000
@@ -0,0 +1,348 @@
+/**
+ * Title:           ChartFactory, $Header: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/chart/ChartFactory.java,v 1.8 2007/12/21 12:31:15 blume Exp $
+ * Source:          $Source: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/chart/ChartFactory.java,v $
+ * created by:      Stefan Blume (blume)
+ * erstellt am:     06.12.2007
+ * Copyright:       con terra GmbH, 2005
+ *
+ * modified by:     $Author: blume $
+ * modified on:     $Date: 2007/12/21 12:31:15 $
+ * Version:         $Revision: 1.8 $
+ * TAG:             $Name:  $
+ * locked from:     $Locker:  $
+ * CVS State:       $State: Exp $
+ * Project:         $ProjectName$
+ */
+package de.intevation.gnv.chart;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.AxisLocation;
+import org.jfree.chart.axis.DateAxis;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.NumberTickUnit;
+import org.jfree.chart.encoders.KeypointPNGEncoderAdapter;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.data.general.Series;
+import org.jfree.data.time.Minute;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+import org.jfree.data.xy.DefaultXYDataset;
+import org.jfree.data.xy.XYDataset;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+import org.jfree.ui.RectangleInsets;
+
+import de.intevation.gnv.chart.exception.TechnicalChartException;
+import de.intevation.gnv.geobackend.base.Result;
+import de.intevation.gnv.transition.describedata.KeyValueDescibeData;
+
+/**
+ * The class <code>ChartFactory</code> fulfills the following purposes:
+ * <ol>
+ * <li></li>
+ * </ol>
+ * 
+ * @author blume
+ * @version 1.0
+ * @serial 1.0
+ * @see
+ * @since 06.12.2007 17:25:59
+ */
+public class VerticalProfileChartFactory {
+
+	/**
+	 * Default Logging instance
+	 */
+	private static Logger sLogger = Logger.getLogger(VerticalProfileChartFactory.class);
+	private static boolean sDebug = sLogger.isDebugEnabled();
+
+
+	public synchronized void createSimpleVerticalProfileChart(ChartLabels pLabels, ChartStyle pStyle, String name, Collection<KeyValueDescibeData> parameters, Collection<KeyValueDescibeData> measurements, OutputStream outputStream, Collection<Result> resultSet) throws IOException, TechnicalChartException {
+		if (sDebug)
+			sLogger.debug("createSimpleTimeSeriesChart()");
+		int lLowerLevel = Integer.MIN_VALUE;
+		int lUpperLevel = Integer.MAX_VALUE;
+		if (pStyle.isUseUpperDataLevel()
+				&& pStyle.getUpperLevel() < Integer.MAX_VALUE) {
+			lUpperLevel = pStyle.getUpperLevel();
+		}
+		if (pStyle.isUseLowerDataLevel()
+				&& pStyle.getLowerLevel() > Integer.MIN_VALUE) {
+			lLowerLevel = pStyle.getLowerLevel();
+		}
+		if (sDebug)
+			sLogger.debug("  vor createDataset()");
+		XYDataset lSet = createDataset(name, resultSet, lUpperLevel,
+				lLowerLevel,parameters,measurements);
+		if (sDebug)
+			sLogger.debug("  nach createDataset()");
+		final Color[] color = {Color.black, Color.red, Color.green, Color.blue};
+		NumberAxis domain = new NumberAxis("Tiefe");
+        NumberAxis axis;
+        StandardXYItemRenderer renderer = new StandardXYItemRenderer();
+		XYPlot plot = new XYPlot();
+		//Global  settings
+		
+		plot.setOrientation(PlotOrientation.HORIZONTAL);
+		plot.setBackgroundPaint(Color.lightGray);
+		plot.setDomainGridlinePaint(Color.white);
+		plot.setRangeGridlinePaint(Color.white);
+		plot.setAxisOffset(new RectangleInsets(5.0,5.0,5.0,5.0));
+		//plot.getRangeAxis().setFixedDimension(10.0);
+		plot.setDomainAxis(domain);
+		plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
+		if (parameters.size() == 1) {
+		    KeyValueDescibeData parameter = parameters.iterator().next();
+			axis = new NumberAxis(parameter.getValue());
+			if(parameter.getValue().contains("richtung")){
+				NumberAxis axis1 = new NumberAxis(
+						((String) parameter.getValue()));//,new Range(0.0,360.0));
+			    axis1.setTickUnit(new NumberTickUnit(30.0));
+				axis1.setUpperBound(360.0);
+				axis1.setLowerBound(0.0);
+                //axis1.setDisplayRange(0.0,360.0);				    
+				plot.setRangeAxis( axis1);
+			}else{
+			axis.setFixedDimension(10.0);
+			axis.setAutoRangeIncludesZero(false);
+			plot.setRangeAxis(axis);
+			}
+			axis.configure();
+			plot.setRangeAxisLocation( AxisLocation.BOTTOM_OR_LEFT);
+			plot.setRenderer(renderer);
+			plot.setDataset(lSet);
+		} else {
+			// Individual settings for different parameters
+			for (int i = 0; i < lSet.getSeriesCount(); i++) {
+
+				plot.setDataset(i, getDataset((XYSeriesCollection) lSet, i));
+				Color mColor=color[i % color.length];  // zyklische Farbvergabe
+				mColor = color[0];
+				// if ( pParameterId.length==1){
+				
+				if(((String) lSet.getSeriesKey(i)).contains("richtung")){
+					NumberAxis axis1 = new NumberAxis(((String) lSet.getSeriesKey(i)));//,new Range(0.0,360.0));
+				    axis1.setTickUnit(new NumberTickUnit(30.0));
+                    //axis1.setDisplayRange(0.0,360.0);				    
+					axis1.setLabelPaint(mColor);
+					axis1.setTickLabelPaint(mColor);
+					axis1.setUpperBound(360.0);
+					axis1.setLowerBound(0.0);
+					plot.setRangeAxis(i, axis1);
+					
+			    
+				}
+				else {
+					axis = new NumberAxis((String) lSet.getSeriesKey(i));
+					axis.setFixedDimension(10.0);
+					axis.setAutoRangeIncludesZero(false);
+					axis.setLabelPaint(mColor);
+					axis.setTickLabelPaint(mColor);
+					plot.setRangeAxis(i, axis);
+					axis.configure();
+				}
+				if (i % 2 != 0)
+					plot.setRangeAxisLocation(i, AxisLocation.BOTTOM_OR_RIGHT);
+				else
+					plot.setRangeAxisLocation(i, AxisLocation.BOTTOM_OR_LEFT);
+				plot.mapDatasetToRangeAxis(i, i);
+				// }
+				renderer = new StandardXYItemRenderer();
+				renderer.setSeriesPaint(i, mColor);
+				// renderer.setSeriesStroke(i,stroke[j]);
+				plot.setRenderer(i, renderer);
+			}
+		}
+		JFreeChart chart = new JFreeChart(
+				pLabels.getTitle(),
+				new Font ("SansSerif",Font.BOLD,24),
+				plot,true);
+		
+
+		setStyle(chart, pStyle);
+		configureRenderingOptions(chart);
+		if (sDebug)
+			sLogger.debug("  vor encodeChart()");
+		
+		encodeChart(chart, pStyle, outputStream);
+	}
+    private static XYDataset getDataset(XYSeriesCollection T, int pIndex){ //throws TechnicalChartException{
+    	//if (T.getSeriesCount() < pIndex) throw TechnicalChartException();
+        XYSeriesCollection XYSC = new XYSeriesCollection();
+    	XYSC.addSeries(T.getSeries(pIndex));
+    	return (XYDataset) XYSC;
+    }
+    
+	private void configureRenderingOptions(JFreeChart pJfreechart) {
+		org.jfree.chart.renderer.xy.XYItemRenderer xyitemrenderer = ((XYPlot) pJfreechart
+				.getPlot()).getRenderer();
+		if (xyitemrenderer instanceof XYLineAndShapeRenderer) {
+			XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyitemrenderer;
+			xylineandshaperenderer.setBaseShapesVisible(true);
+			xylineandshaperenderer.setBaseShapesFilled(true);
+		}
+	}
+
+	private void setStyle(JFreeChart pJfreechart, ChartStyle pStyle) {
+		if (sDebug)
+			sLogger.debug("setStyle()");
+		pJfreechart.setBackgroundPaint(pStyle.getCanvasColor());
+		XYPlot xyplot = (XYPlot) pJfreechart.getPlot();
+		xyplot.setBackgroundPaint(pStyle.getPlotBackgroundColor());
+		xyplot.setDomainGridlinePaint(pStyle.getDomainGridlineColor());
+		xyplot.setRangeGridlinePaint(pStyle.getRangeGridlineColor());
+
+		Insets lOffsets = pStyle.getAxisOffset();
+		RectangleInsets lRectangleInsets = new RectangleInsets(lOffsets.mUpper,
+				lOffsets.mLeft, lOffsets.mLower, lOffsets.mRight);
+		xyplot.setAxisOffset(lRectangleInsets);
+		xyplot.setDomainCrosshairVisible(pStyle.isDomainCrosshairVisible());
+		xyplot.setRangeCrosshairVisible(pStyle.isRangeCrosshairVisible());
+
+	}
+	
+	
+	protected XYSeries createXYSeries(String seriesName,  Collection<Result> resultSet, 
+			int lUpperCut, int lLowerCut,int pStart,int pEnd) throws TechnicalChartException{
+		if (sDebug)
+			sLogger.debug("createXYSeries()");
+		XYSeries series = new XYSeries(seriesName);
+		try {
+			double xValue=0;
+			double yValue=0;
+			int i = 0;
+			Iterator<Result> resultIterator = resultSet.iterator();
+            while (resultIterator.hasNext()){
+                Result lRow = resultIterator.next();
+                if (i >= pStart && i <= pEnd ){
+        			xValue = lRow.getDouble("XORDINATE");
+        			yValue = lRow.getDouble("YORDINATE");
+        			series.add(xValue, yValue);
+        		    sLogger.debug(seriesName+" Added Value "+xValue+" / "+yValue);
+        			
+                }else if (i > pEnd){
+                    return series;
+                }
+                i++;
+            }
+		} catch (OutOfMemoryError e) { 
+			sLogger.error(e.getMessage(), e);
+			return series;
+		
+		} catch (Exception e) { //TechnicalChartException
+			sLogger.error(e.getMessage(), e);
+		}
+		finally {
+		}
+		
+		return series;
+	}
+
+	private XYDataset createDataset(String name, Collection<Result> resultSet,
+			int lUpperCut, int lLowerCut,Collection<KeyValueDescibeData> parameters, Collection<KeyValueDescibeData> measurements) throws TechnicalChartException {
+		
+	    XYSeriesCollection xyDataset = new XYSeriesCollection();
+
+		try{
+			String break1, break2, break3;
+			int mStart = 0;
+			int mEnd = 0;
+			
+	
+			Iterator<Result> resultIterator = resultSet.iterator();
+			if (resultIterator.hasNext()){
+    //			Row row = new Row(sArrayStrLine);
+    			Result row = resultIterator.next();
+    			
+    			break1 = row.getString("GROUP1"); // 2
+    			break2 = row.getString("GROUP2");  //3
+    			break3 = row.getString("GROUP3"); // 4
+    			int i = 0;
+    			while (resultIterator.hasNext()) {
+    			    row = resultIterator.next();
+    				if (!break1.equals(row.getString("GROUP1"))
+    						|| !break2 .equals(row.getString("GROUP2"))
+    					    || !break3.equals(row.getString("GROUP3"))){
+    					String seriesName = findValueTitle(parameters,break1)+" "+
+    					                         findValueTitle(measurements,break2);
+    					sLogger.debug("Neuer Datensatz "+seriesName+ "von Datensätzen "+mStart+" / "+mEnd);
+    					xyDataset.addSeries(createXYSeries(seriesName,
+    							resultSet, lUpperCut, lLowerCut, mStart, mEnd));
+    					mStart = i;
+    					
+    					break1 = row.getString("GROUP1");
+    					break2 = row.getString("GROUP2");  //3
+    					break3 = row.getString("GROUP3"); // 4
+    	
+    				}
+    				mEnd = i;
+    				//mEnd ++;
+    				i = i + 1;
+    			}
+			
+			String seriesName = findValueTitle(parameters,break1)+" "+
+	                                 findValueTitle(measurements,break2);
+			sLogger.debug("Neuer Datensatz "+seriesName+ "von Datensätzen "+mStart+" / "+mEnd);
+			xyDataset.addSeries(createXYSeries(seriesName,
+					resultSet, lUpperCut, lLowerCut, mStart, mEnd));
+			}
+		}
+		catch (Exception e){
+			sLogger.error(e.getMessage(), e);
+		}
+		finally{
+		}
+		return xyDataset;
+	}
+
+
+
+	private void encodeChart(JFreeChart pChart, ChartStyle pStyle, OutputStream outputStream)
+			throws IOException {
+		if (sDebug)
+			sLogger.debug("encodeChart()");
+		KeypointPNGEncoderAdapter lEncoder = new KeypointPNGEncoderAdapter();
+		lEncoder.setEncodingAlpha(true);
+
+		int lWidth = (int) pStyle.getChartSize().getWidth();
+		int lHeight = (int) pStyle.getChartSize().getHeight();
+
+		BufferedImage lImage = pChart.createBufferedImage(lWidth, lHeight,
+				BufferedImage.BITMASK, null);
+	
+		lEncoder.encode(lImage, outputStream);
+	
+}
+
+    private String findValueTitle(Collection<KeyValueDescibeData> values, String pMmtId){
+    	int id = 0;
+    	try {
+            id = Integer.parseInt(pMmtId);
+        } catch (NumberFormatException e) {
+            sLogger.warn(e,e);
+            return pMmtId;
+        }
+        
+        Iterator<KeyValueDescibeData> it = values.iterator();
+    	while(it.hasNext()){
+    	    KeyValueDescibeData data = it.next();
+    		if (id  ==Integer.parseInt(data.getKey())){ // TODO just a hack
+    		    return data.getValue();
+    		}
+    	}
+    	return "";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java	Tue Sep 22 13:20:30 2009 +0000
@@ -0,0 +1,55 @@
+/**
+ *
+ */
+package de.intevation.gnv.profile.vertical;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+
+import de.intevation.artifacts.ArtifactFactory;
+import de.intevation.artifacts.CallContext;
+import de.intevation.gnv.artifacts.GNVArtifactBase;
+
+/**
+ * @author Tim Englich <tim.englich@intevation.de>
+ *
+ */
+public class VerticalProfileArtifact extends GNVArtifactBase {
+    /**
+     * the logger, used to log exceptions and additonaly information
+     */
+    private static Logger log = Logger.getLogger(VerticalProfileArtifact.class);
+    
+    
+    /**
+     * The UID of this class
+     */
+    private static final long serialVersionUID = -8291547966693867205L;
+    
+    /**
+     * Constructor
+     */
+    public VerticalProfileArtifact(){
+        super();
+        log.debug("VerticalProfileArtifact.Constructor");
+        this.name = "verticalProfile";
+    }
+
+    /**
+     * @see de.intevation.artifactdatabase.DefaultArtifact#describe(java.lang.Object)
+     */
+    @Override
+    public Document describe(CallContext context) {
+        log.debug("VerticalProfileArtifact.describe");
+        return super.createDescibeOutput();
+    }
+
+    /**
+     * @see de.intevation.gnv.artifacts.GNVArtifactBase#setup(java.lang.String, de.intevation.artifacts.ArtifactFactory, java.lang.Object)
+     */
+    @Override
+    public void setup(String identifier, ArtifactFactory factory, Object context) {
+        log.debug("VerticalProfileArtifact.setup");
+        super.setup(identifier,factory,context);
+    }
+}
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/transition/TransitionBase.java	Mon Sep 21 11:50:47 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/TransitionBase.java	Tue Sep 22 13:20:30 2009 +0000
@@ -329,7 +329,7 @@
         keyValueDescibeData.setMultiSelect(this.dataMultiSelect);
         while(rit.hasNext()){
             Result resultValue = rit.next();
-            keyValueDescibeData.add(new DefaultKeyValueDescribeData(resultValue.getInteger("KEY").intValue(), resultValue.getString("VALUE")));
+            keyValueDescibeData.add(new DefaultKeyValueDescribeData(resultValue.getString("KEY"), resultValue.getString("VALUE")));
         }
         this.descibeData.add(keyValueDescibeData);
     }
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/transition/describedata/DefaultKeyValueDescribeData.java	Mon Sep 21 11:50:47 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/describedata/DefaultKeyValueDescribeData.java	Tue Sep 22 13:20:30 2009 +0000
@@ -13,13 +13,13 @@
      */
     private static final long serialVersionUID = -924469415242703108L;
 
-    private int key;
+    private String key;
     
     private String value = null;
     
     private boolean selected = false;
     
-    public DefaultKeyValueDescribeData(int key, String value) {
+    public DefaultKeyValueDescribeData(String key, String value) {
         super();
         this.key = key;
         this.value = value;
@@ -28,7 +28,7 @@
     /**
      * @see de.intevation.gnv.transition.describedata.KeyValueDescibeData#getKey()
      */
-    public int getKey() {
+    public String getKey() {
        return this.key;
     }
 
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/transition/describedata/KeyValueDescibeData.java	Mon Sep 21 11:50:47 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/describedata/KeyValueDescibeData.java	Tue Sep 22 13:20:30 2009 +0000
@@ -11,7 +11,7 @@
  */
 public interface KeyValueDescibeData extends Serializable {
     
-    public int getKey();
+    public String getKey();
     
     public String getValue();
     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java	Tue Sep 22 13:20:30 2009 +0000
@@ -0,0 +1,55 @@
+/**
+ *
+ */
+package de.intevation.gnv.transition.profile.vertical;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.Iterator;
+
+import de.intevation.gnv.chart.ChartFactory;
+import de.intevation.gnv.chart.ChartLabels;
+import de.intevation.gnv.chart.ChartStyle;
+import de.intevation.gnv.chart.VerticalProfileChartFactory;
+import de.intevation.gnv.chart.exception.TechnicalChartException;
+import de.intevation.gnv.transition.describedata.KeyValueDescibeData;
+import de.intevation.gnv.transition.timeseries.TimeSeriesOutputTransition;
+
+/**
+ * @author Tim Englich <tim.englich@intevation.de>
+ *
+ */
+public class VerticalProfileOutputTransition extends TimeSeriesOutputTransition {
+    /**
+     *
+     */
+    private static final long serialVersionUID = 4401516087492028840L;
+
+    /**
+     * Constructor
+     */
+    public VerticalProfileOutputTransition() {
+    }
+
+    @Override
+    protected Collection<KeyValueDescibeData> getMeasurements() {
+        String collectionName = "dateid";
+        return this.getCollection(collectionName);
+    }
+    
+    @Override
+    protected void createChart(OutputStream outputStream,
+            Collection<KeyValueDescibeData> parameters,
+            Collection<KeyValueDescibeData> measurements,
+            String timeSeriesName, ChartStyle chartStyle,
+            ChartLabels chartLables) throws IOException,
+            TechnicalChartException {
+        VerticalProfileChartFactory chartFactory = new VerticalProfileChartFactory();
+        chartFactory.createSimpleVerticalProfileChart(chartLables, chartStyle, timeSeriesName, 
+                                                 parameters, measurements, 
+                                                 outputStream, this.chartResult);
+    }
+    
+
+}
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java	Mon Sep 21 11:50:47 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java	Tue Sep 22 13:20:30 2009 +0000
@@ -55,7 +55,7 @@
         log.debug("TimeSeriesOutputTransition");
         try {
             this.advance(); // TODO nur neu holen wenn hash auf chartResult sich ge�ndert hat
-            ChartFactory chartFactory = new ChartFactory();
+           
             
             Collection<KeyValueDescibeData> parameters = this.getParameters();
             Collection<KeyValueDescibeData> measurements = this.getMeasurements();
@@ -65,9 +65,8 @@
             lDiagramTitle.append(/*mSelectedFis.getTitle()*/ "FIS-TITLE").append(" - ").append(/*mSelectedFeatureId[0].getTitle()*/"FeatureTitle"); // TODO: FIXME
             String domainLable = "BLA"; // TODO woher bekommen wir das
             ChartLabels chartLables = new ChartLabels(lDiagramTitle.toString(),domainLable , /*mSelectedParams[0].getTitle()*/ "Selected Params Title");
-            chartFactory.createSimpleTimeSeriesChart(chartLables, chartStyle, timeSeriesName, 
-                                                     parameters, measurements, 
-                                                     outputStream, this.chartResult);
+            createChart(outputStream, parameters, measurements, timeSeriesName,
+                    chartStyle, chartLables);
         } catch (IOException e) {
             log.error(e,e);
             throw new TransitionException(e);
@@ -77,6 +76,27 @@
         }
     }
 
+/**
+ * @param outputStream
+ * @param parameters
+ * @param measurements
+ * @param timeSeriesName
+ * @param chartStyle
+ * @param chartLables
+ * @throws IOException
+ * @throws TechnicalChartException
+ */
+protected void createChart(OutputStream outputStream,
+        Collection<KeyValueDescibeData> parameters,
+        Collection<KeyValueDescibeData> measurements, String timeSeriesName,
+        ChartStyle chartStyle, ChartLabels chartLables) throws IOException,
+        TechnicalChartException {
+    ChartFactory chartFactory = new ChartFactory();
+    chartFactory.createSimpleTimeSeriesChart(chartLables, chartStyle, timeSeriesName, 
+                                             parameters, measurements, 
+                                             outputStream, this.chartResult);
+}
+
     /**
      * @see de.intevation.gnv.transition.TransitionBase#purifyResult(java.util.Collection)
      */
@@ -93,29 +113,29 @@
     }
     
     protected Collection<KeyValueDescibeData> getParameters(){
-        Iterator<Object> it = this.descibeData.iterator();
-        
-        while (it.hasNext()){
-           
-           Object o = it.next();
-           if (o instanceof NamedCollection<?>){
-               NamedCollection<KeyValueDescibeData> nc = (NamedCollection<KeyValueDescibeData>)o;
-               if (nc.getName().equals("parameterid")){ // TODO: konfigurierbar machen.
-                   return nc;
-               }
-           }
-        }
-        return null;
+        String collectionName = "parameterid";
+        return this.getCollection(collectionName);
     }
     
     protected Collection<KeyValueDescibeData> getMeasurements(){
+        String collectionName = "measurementid";
+        return this.getCollection(collectionName);
+    }
+
+    /**
+     * @param collectionName
+     * @return
+     */
+    protected Collection<KeyValueDescibeData> getCollection(
+            String collectionName) {
         Iterator<Object> it = this.descibeData.iterator();
         while (it.hasNext()){
            
            Object o = it.next();
+           
            if (o instanceof NamedCollection<?>){
                NamedCollection<KeyValueDescibeData> nc = (NamedCollection<KeyValueDescibeData>)o;
-               if (nc.getName().equals("measurementid")){ // TODO: konfigurierbar machen.
+               if (nc.getName().equals(collectionName)){ // TODO: konfigurierbar machen.
                    return nc;
                }
            }
--- a/gnv-artifacts/src/test/ressources/conf.xml	Mon Sep 21 11:50:47 2009 +0000
+++ b/gnv-artifacts/src/test/ressources/conf.xml	Tue Sep 22 13:20:30 2009 +0000
@@ -23,6 +23,13 @@
                         <parameter name="sourceid" value="4"/>
                     </parameters>
                 </product>
+                 <product name= "verticalProfile">
+                    <artifact-factory name="timeSeries" description="Artiefactfactory for Instantiating the Artifact for the FIS Modeldata"  
+                             ttl="300000" artifact="de.intevation.gnv.profile.vertical.VerticalProfileArtifact">de.intevation.artifactdatabase.DefaultArtifactFactory</artifact-factory>
+                    <parameters>
+                        <parameter name="sourceid" value="4"/>
+                    </parameters>
+                </product>
             </products>
         </artifact>
         <artifact name="fis_imis">
@@ -34,6 +41,13 @@
                         <parameter name="sourceid" value="18"/>
                     </parameters>
                 </product>
+                <product name= "verticalProfile">
+                    <artifact-factory name="timeSeries" description="Artiefactfactory for Instantiating the Artifact for the FIS Modeldata"  
+                             ttl="300000" artifact="de.intevation.gnv.profile.vertical.VerticalProfileArtifact">de.intevation.artifactdatabase.DefaultArtifactFactory</artifact-factory>
+                    <parameters>
+                        <parameter name="sourceid" value="18"/>
+                    </parameters>
+                </product>
             </products>
         </artifact>
         <artifact name="fis_staun">
@@ -45,6 +59,13 @@
                         <parameter name="sourceid" value="17"/>
                     </parameters>
                 </product>
+                <product name= "verticalProfile">
+                    <artifact-factory name="timeSeries" description="Artiefactfactory for Instantiating the Artifact for the FIS Modeldata"  
+                             ttl="300000" artifact="de.intevation.gnv.profile.vertical.VerticalProfileArtifact">de.intevation.artifactdatabase.DefaultArtifactFactory</artifact-factory>
+                    <parameters>
+                        <parameter name="sourceid" value="17"/>
+                    </parameters>
+                </product>
             </products>
         </artifact>
         <artifact name="fis_modeldata">
@@ -227,6 +248,61 @@
                 
             </transitions>
         </artifact>
+        
+        <artifact name="verticalProfile">
+            <transitions>
+                <transition id="verticalprofile_timeseriespoint" description="timeseries_timeseriespoint" transition="de.intevation.gnv.transition.DefaultTransition">
+                    <queryID>verticalprofile_point</queryID>
+                    <dataname>featureid</dataname>
+                    <data-multiselect>false</data-multiselect>
+                    <reachableTransitions>
+                        <transition>verticalprofile_parameter</transition>
+                    </reachableTransitions>
+                    <inputvalues>
+                        <inputvalue name="sourceid" type="Integer" multiselect="false"/>
+                    </inputvalues>
+                </transition>
+                
+                <transition id="verticalprofile_parameter" description="timeseries_parameter" transition="de.intevation.gnv.transition.DefaultTransition">
+                    <queryID>verticalprofile_parameter</queryID>
+                    <dataname>parameterid</dataname>
+                    <data-multiselect>true</data-multiselect>
+                    <reachableTransitions>
+                        <transition>verticalprofile_date</transition>
+                    </reachableTransitions>
+                    <inputvalues>
+                        <inputvalue name="featureid" type="Integer" multiselect="false"/>
+                    </inputvalues>
+                </transition>
+                
+                <transition id="verticalprofile_date" description="verticalprofile_date" transition="de.intevation.gnv.transition.DefaultTransition">
+                    <queryID>verticalprofile_date</queryID>
+                    <dataname>dateid</dataname>
+                    <data-multiselect>true</data-multiselect>
+                    <reachableTransitions>
+                         <transition>verticalprofile_calculate_results</transition>
+                    </reachableTransitions>
+                    <inputvalues>
+                        <inputvalue name="featureid" type="Integer" multiselect="false"/>
+                        <inputvalue name="parameterid" type="Integer" multiselect="true"/>
+                    </inputvalues>
+                </transition>
+                
+                <transition id="verticalprofile_calculate_results" description="verticalprofile_calculate_results" transition="de.intevation.gnv.transition.profile.vertical.VerticalProfileOutputTransition">
+                    <queryID>verticalprofile_chart_data</queryID>
+                    <inputvalues>
+                        <inputvalue name="featureid" type="Integer" multiselect="false"/>
+                        <inputvalue name="parameterid" type="Integer" multiselect="true"/>
+                        <inputvalue name="dateid" type="String" multiselect="true"/>
+                    </inputvalues>
+                    <outputsModes>
+                        <outputsMode name="chart" description="Chartrepresentation of the Values" mime-type="image/png"/>
+                        <outputsMode name="csv" description="CSV-Export der Daten" mime-type="test/plain"/>
+                        <outputsMode name="statistics" description="Statistik zu den Daten" mime-type="test/plain"/>
+                    </outputsModes>
+                </transition>
+            </transitions>
+        </artifact>
     </artifacts>
     <geo-backend>
         <backend-configuration>../geo-backend/src/test/ressources/ArcSDEConnectionPoolTestCase.properties</backend-configuration>
--- a/gnv-artifacts/src/test/ressources/queries.properties	Mon Sep 21 11:50:47 2009 +0000
+++ b/gnv-artifacts/src/test/ressources/queries.properties	Tue Sep 22 13:20:30 2009 +0000
@@ -2,7 +2,7 @@
 timeseries_parameter=SELECT DISTINCT p.PARAMETERID KEY, p.GERMANNAME VALUE from MEDIAN.PARAMETER p where p.PARAMETERID in (select distinct ts.PARAMETERID from MEDIAN.TIMESERIES ts where ts.TIMESERIESID in (select distinct tsv.TIMESERIESID from MEDIAN.TIMESERIESVALUE tsv where tsv.MEASUREMENTID in (select m.MEASUREMENTID from MEDIAN.MEASUREMENT m, MEDIAN.TIMESERIESPOINT tsp where m.FEATUREID = tsp.FEATUREID and tsp.FEATUREID IN ( ? )))) ORDER BY p.GERMANNAME
 timeseries_depth_height=SELECT DISTINCT m.MEASUREMENTID KEY, m.ZLOCATION VALUE from MEDIAN.MEASUREMENT m where m.MEASUREMENTID in (SELECT DISTINCT  t_v.MEASUREMENTID from MEDIAN.TIMESERIESVALUE t_v where t_v.TIMESERIESID in (SELECT DISTINCT  t.TIMESERIESID from MEDIAN.TIMESERIES t where t.PARAMETERID in (SELECT DISTINCT  p.PARAMETERID from MEDIAN.PARAMETER p where m.FEATUREID IN ( ? ) and p.PARAMETERID IN (?))))ORDER BY m.ZLOCATION DESC
 timeseries_interval=select min(tv.TIMEVALUE) MIN, max(tv.TIMEVALUE) MAX from MEDIAN.TIMESERIES t , MEDIAN.TIMESERIESVALUE tv where tv.TIMESERIESID = t.TIMESERIESID AND t.PARAMETERID IN ( ? ) AND tv.MEASUREMENTID IN ( ? )
-timeseries_chart_data=SELECT tv.TIMEVALUE, tv.DATAVALUE, t.PARAMETERID, tv.MEASUREMENTID, tv.TIMESERIESID FROM MEDIAN.TIMESERIESVALUE tv, MEDIAN.TIMESERIES t WHERE tv.TIMESERIESID = t.TIMESERIESID AND t.PARAMETERID IN ( ? ) AND tv.MEASUREMENTID IN ( ? ) AND tv.TIMEVALUE > TO_DATE ('?', 'YYYY.MM.DD HH24:MI:SS') AND tv.TIMEVALUE < TO_DATE ('?', 'YYYY.MM.DD HH24:MI:SS') ORDER BY tv.MEASUREMENTID ,tv.TIMESERIESID ,t.PARAMETERID ,tv.TIMEVALUE
+timeseries_chart_data=SELECT tv.TIMEVALUE XORDINATE, tv.DATAVALUE YORDINATE, t.PARAMETERID GROUP1, tv.MEASUREMENTID GROUP2, tv.TIMESERIESID GROUP3 FROM MEDIAN.TIMESERIESVALUE tv, MEDIAN.TIMESERIES t WHERE tv.TIMESERIESID = t.TIMESERIESID AND t.PARAMETERID IN ( ? ) AND tv.MEASUREMENTID IN ( ? ) AND tv.TIMEVALUE > TO_DATE ('?', 'YYYY.MM.DD HH24:MI:SS') AND tv.TIMEVALUE < TO_DATE ('?', 'YYYY.MM.DD HH24:MI:SS') ORDER BY tv.MEASUREMENTID ,tv.TIMESERIESID ,t.PARAMETERID ,tv.TIMEVALUE
 
 
 # Zeitserie Mesh
@@ -12,5 +12,58 @@
 timeseries_meshpoint_depth = select mp.FEATUREID KEY, -ml.UPPERZLOCATION || ' - '|| -ml.LOWERZLOCATION as VALUE from MEDIAN.MESHLAYER ml, MEDIAN.MESHPOINT mp where ml.KPOSITION = mp.KPOSITION and ml.MESHID = mp.MESHID and mp.FEATUREID in ( select FEATUREID from MEDIAN.MESHPOINT mp, MEDIAN.MESH m where m.OBJECTID = ? AND mp.MESHID = m.MESHID  AND IPOSITION = (select IPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?) and JPOSITION = (select JPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?)) order by ml.UPPERZLOCATION desc
 timeseries_mesh_parameter=SELECT distinct p.PARAMETERID KEY , p.GERMANNAME VALUE  from MEDIAN.PARAMETER p, MEDIAN.MESHSCALARVALUE msc, MEDIAN.MESH m  where m.OBJECTID = ? AND msc.PARTID = m.PARTIDMIN AND msc.PARAMETERID = p.PARAMETERID
 timeseries_mesh_interval=select /*+ parallel(TIMEVALUE,5) */ min(TIMEVALUE) MIN, max(TIMEVALUE) MAX from MEDIAN.MESHSCALARVALUE msc , MEDIAN.MESH m where m.OBJECTID = ?  AND msc.PARTID >= m.PARTIDMIN AND msc.PARTID <= m.PARTIDMAX
-timeseries_mesh_chart_data=select /*+ parallel(timevalue,10) */ msv.TIMEVALUE, msv.DATAVALUE, msv.PARAMETERID, msv.FEATUREID MEASUREMENTID, mp.FEATUREID TIMESERIESID from MEDIAN.MESHSCALARVALUE msv , MEDIAN.MESHPOINT mp, MEDIAN.MESH m where (m.OBJECTID = ? AND msv.PARTID >= m.PARTIDMIN AND msv.PARTID <= m.PARTIDMAX ) AND msv.FEATUREID in ( ? ) and msv.PARAMETERID in ( ? ) AND mp.FEATUREID = ? and TIMEVALUE >= to_date('?', 'YYYY.MM.DD HH24:MI:SS') and TIMEVALUE <= to_date('?', 'YYYY.MM.DD HH24:MI:SS') order by msv.FEATUREID, msv.PARAMETERID, msv.TIMEVALUE
+timeseries_mesh_chart_data=select /*+ parallel(timevalue,10) */ msv.TIMEVALUE XORDINATE, msv.DATAVALUE YORDINATE, msv.PARAMETERID GROUP1, msv.FEATUREID GROUP2, mp.FEATUREID GROUP3 from MEDIAN.MESHSCALARVALUE msv , MEDIAN.MESHPOINT mp, MEDIAN.MESH m where (m.OBJECTID = ? AND msv.PARTID >= m.PARTIDMIN AND msv.PARTID <= m.PARTIDMAX ) AND msv.FEATUREID in ( ? ) and msv.PARAMETERID in ( ? ) AND mp.FEATUREID = ? and TIMEVALUE >= to_date('?', 'YYYY.MM.DD HH24:MI:SS') and TIMEVALUE <= to_date('?', 'YYYY.MM.DD HH24:MI:SS') order by msv.FEATUREID, msv.PARAMETERID, msv.TIMEVALUE
 
+# Vertikalprofil
+
+verticalprofile_point=SELECT DISTINCT \
+           tsp.FEATUREID KEY, \
+           tsp.NAME VALUE \
+    FROM MEDIAN.TIMESERIESPOINT tsp, \
+           MEDIAN.MEASUREMENT mmt \
+    WHERE tsp.FEATUREID =  mmt.FEATUREID AND \
+           mmt.SOURCEID = ? \
+    order by tsp.name
+
+verticalprofile_parameter=SELECT DISTINCT \
+           p.PARAMETERID KEY, \
+           p.GERMANNAME VALUE \
+    from MEDIAN.PARAMETER p, \
+           MEDIAN.TIMESERIES ts, \
+           MEDIAN.TIMESERIESVALUE tsv, \
+           MEDIAN.MEASUREMENT m \
+    where ts.PARAMETERID = p.PARAMETERID and \
+          ts.TIMESERIESID = tsv.TIMESERIESID and \
+          m.MEASUREMENTID = tsv.MEASUREMENTID and \
+          m.FEATUREID = ? \
+    ORDER BY p.GERMANNAME
+
+verticalprofile_date=select distinct \
+           tsv.TIMEVALUE KEY, \
+           tsv.TIMEVALUE VALUE \
+    from MEDIAN.TIMESERIES ts , \
+         MEDIAN.TIMESERIESVALUE tsv, \
+         MEDIAN.MEASUREMENT m \
+    where ts.TIMESERIESID = tsv.TIMESERIESID and \
+          m.MEASUREMENTID = tsv.MEASUREMENTID and \
+          m.FEATUREID = ? and \
+          ts.PARAMETERID IN ( ? ) \
+    order by tsv.TIMEVALUE 
+
+verticalprofile_chart_data= SELECT m.ZLOCATION XORDINATE, \
+           tsv.DATAVALUE YORDINATE, \
+           ts.PARAMETERID GROUP1, \
+           tsv.TIMEVALUE GROUP2, \
+           1 GROUP3 \
+    from MEDIAN.TIMESERIES ts, \
+         MEDIAN.TIMESERIESVALUE tsv, \
+         MEDIAN.MEASUREMENT m \
+    where ts.TIMESERIESID = tsv.TIMESERIESID and \
+          m.MEASUREMENTID = tsv.MEASUREMENTID and \
+          m.FEATUREID = ? and \
+          ts.PARAMETERID IN ( ? ) AND \
+          tsv.TIMEVALUE IN (TO_DATE ('?', 'YYYY.MM.DD HH24:MI:SS')) \
+    ORDER BY tsv.TIMEVALUE , \
+             tsv.TIMESERIESID , \
+             ts.PARAMETERID , \
+             tsv.TIMEVALUE

http://dive4elements.wald.intevation.org