tim@335: /** tim@335: * tim@335: */ tim@335: package de.intevation.gnv.state.profile.verticalcrosssection; tim@335: tim@335: import java.io.IOException; tim@335: import java.io.OutputStream; tim@335: import java.io.OutputStreamWriter; tim@335: import java.io.UnsupportedEncodingException; sascha@432: tim@335: import java.util.Collection; ingo@429: import java.util.HashMap; tim@335: import java.util.Iterator; tim@335: import java.util.Locale; ingo@429: import java.util.Map; sascha@432: import java.util.ArrayList; sascha@440: import java.util.Arrays; sascha@440: import java.util.List; tim@335: tim@335: import org.apache.log4j.Logger; tim@335: ingo@358: import org.jfree.chart.ChartTheme; ingo@358: ingo@429: import net.sf.ehcache.Element; ingo@429: tim@335: import au.com.bytecode.opencsv.CSVWriter; tim@335: tim@335: import com.vividsolutions.jts.geom.Point; ingo@429: import com.vividsolutions.jts.geom.Coordinate; tim@335: sascha@439: import de.intevation.artifacts.CallContext; sascha@439: ingo@429: import de.intevation.gnv.artifacts.cache.CacheFactory; sascha@432: tim@335: import de.intevation.gnv.chart.Chart; tim@335: import de.intevation.gnv.chart.ChartLabels; tim@335: import de.intevation.gnv.chart.ChartStyle; sascha@432: tim@335: import de.intevation.gnv.chart.exception.TechnicalChartException; sascha@432: tim@335: import de.intevation.gnv.geobackend.base.Result; ingo@429: import de.intevation.gnv.geobackend.base.ResultDescriptor; sascha@432: ingo@429: import de.intevation.gnv.geobackend.base.query.QueryExecutor; ingo@429: import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; ingo@429: import de.intevation.gnv.geobackend.base.query.exception.QueryException; sascha@431: ingo@429: import de.intevation.gnv.math.AttributedXYColumns; ingo@429: import de.intevation.gnv.math.HeightValue; ingo@429: import de.intevation.gnv.math.XYColumn; sascha@431: import de.intevation.gnv.math.IJKey; sascha@431: sascha@440: import de.intevation.gnv.state.InputData; sascha@440: tim@335: import de.intevation.gnv.state.describedata.KeyValueDescibeData; tim@335: import de.intevation.gnv.state.exception.StateException; tim@335: import de.intevation.gnv.state.timeseries.TimeSeriesOutputState; sascha@432: tim@335: import de.intevation.gnv.statistics.Statistics; tim@335: import de.intevation.gnv.statistics.VerticalProfileStatistics; sascha@432: ingo@429: import de.intevation.gnv.utils.WKTUtils; sascha@439: import de.intevation.gnv.utils.StringUtils; tim@335: tim@335: /** tim@335: * @author Tim Englich tim@335: * tim@335: */ tim@335: public class VerticalCrossSectionOutputState extends TimeSeriesOutputState { tim@335: ingo@429: public static final String[] ATTRIBUTE_LIST = { ingo@429: "SHAPE", ingo@429: "Z", ingo@429: "YORDINATE", ingo@429: "IPOSITION", ingo@429: "JPOSITION", ingo@429: "KPOSITION" ingo@429: }; ingo@429: ingo@429: private static Logger log = Logger.getLogger( ingo@429: VerticalCrossSectionOutputState.class); ingo@429: ingo@429: private String ijkQueryID = "horizontalprofile_meshpoint_cross_ij"; ingo@429: tim@335: /** tim@335: * The UID of this Class tim@335: */ tim@335: private static final long serialVersionUID = 3233620652465061860L; tim@335: tim@335: /** tim@335: * Constructor tim@335: */ tim@335: public VerticalCrossSectionOutputState() { tim@335: super(); ingo@343: super.domainLable = "chart.verticalcrosssection.title.xaxis"; tim@335: } tim@335: ingo@429: ingo@429: @Override sascha@439: protected Object getChartResult(String uuid, CallContext callContext) { ingo@429: log.debug("VerticalCrossSectionOutputState.getChartResult"); ingo@429: Collection result = null; ingo@429: String key = uuid + super.getID(); ingo@429: ingo@429: Element element = CacheFactory.getInstance().getCache().get(key); ingo@429: if (element != null) ingo@429: return element.getObjectValue(); ingo@429: ingo@429: log.debug("No results in cache yet."); ingo@429: sascha@440: InputData meshLine = inputData.get("mesh_linestring"); sascha@440: InputData meshId = inputData.get("meshid"); ingo@429: sascha@440: if (meshLine == null) { sascha@440: log.error("mesh_linestring is not defined"); sascha@440: throw new IllegalStateException("missing mesh_linestring"); ingo@429: } ingo@429: sascha@440: if (meshId == null) { sascha@440: log.error("meshid is not defined"); sascha@440: throw new IllegalStateException("missing meshid"); sascha@440: } sascha@440: sascha@440: Coordinate [] coords = WKTUtils.toCoordinates( sascha@440: meshLine.getValue()); sascha@440: sascha@440: if (coords == null) { sascha@440: throw new IllegalStateException("cannot read coordinates"); sascha@440: } sascha@440: sascha@440: try { sascha@440: String additionWhere = WKTUtils.worldCoordinatesToIndex( sascha@440: coords, sascha@440: result, sascha@440: meshId.getValue(), sascha@440: ijkQueryID); sascha@440: sascha@440: String[] addedFilterValues = StringUtils.append( sascha@440: generateFilterValuesFromInputData(), sascha@440: additionWhere); sascha@440: sascha@440: QueryExecutor exec = QueryExecutorFactory sascha@440: .getInstance() sascha@440: .getQueryExecutor(); sascha@440: sascha@440: result = exec.executeQuery(queryID, addedFilterValues); sascha@440: } sascha@440: catch (QueryException qe) { sascha@440: log.error(qe, qe); sascha@440: } sascha@440: sascha@440: Object obj = process( sascha@440: Arrays.asList(coords), sascha@440: preProcess(result), sascha@440: callContext); sascha@440: ingo@429: CacheFactory.getInstance().getCache().put(new Element(key, obj)); ingo@429: ingo@429: return obj; ingo@429: } ingo@429: ingo@429: sascha@440: protected Object process( sascha@440: List path, sascha@440: AttributedXYColumns columns, sascha@440: CallContext callContext sascha@440: ) { ingo@429: ingo@429: // TODO Implement me ingo@429: return null; ingo@429: } ingo@429: ingo@429: ingo@429: protected AttributedXYColumns preProcess(Collection results) { sascha@432: ingo@429: AttributedXYColumns attColumns = new AttributedXYColumns(); sascha@432: Map map = new HashMap(1013); ingo@429: Iterator iter = results.iterator(); ingo@429: ingo@429: int sIdx = -1; ingo@429: int iIdx = -1; ingo@429: int jIdx = -1; ingo@429: int kIdx = -1; ingo@429: int vIdx = -1; ingo@429: int zIdx = -1; ingo@429: ingo@429: while (iter.hasNext()) { ingo@429: Result result = (Result) iter.next(); ingo@429: ingo@429: if (sIdx == -1) { ingo@429: ResultDescriptor rd = result.getResultDescriptor(); ingo@429: int columnCount = rd.getColumnCount(); ingo@429: ingo@429: sIdx = rd.getColumnIndex("SHAPE"); ingo@429: iIdx = rd.getColumnIndex("IPOSITION"); ingo@429: jIdx = rd.getColumnIndex("JPOSITION"); ingo@429: kIdx = rd.getColumnIndex("KPOSITION"); ingo@429: vIdx = rd.getColumnIndex("YORDINATE"); ingo@429: zIdx = rd.getColumnIndex("Z"); ingo@429: ingo@429: for (int i = 0; i < columnCount; i++) { ingo@429: String colName = rd.getColumnName(i); ingo@429: sascha@439: if (!StringUtils.contains(ATTRIBUTE_LIST, colName)) { ingo@429: attColumns.setAttribute( ingo@429: colName, ingo@429: result.getObject(colName)); ingo@429: } ingo@429: } ingo@429: } ingo@429: sascha@432: double v = result.getDouble(vIdx); sascha@432: double z = result.getDouble(zIdx); sascha@432: int i = result.getInteger(iIdx); sascha@432: int j = result.getInteger(jIdx); sascha@432: int k = result.getInteger(kIdx); ingo@429: sascha@432: IJKey key = new IJKey(i, j); sascha@431: sascha@432: XYColumn col = (XYColumn)map.get(key); ingo@429: sascha@432: if (col == null) { sascha@432: Coordinate coord = WKTUtils.toCoordinate(result.getString(sIdx)); sascha@432: if (coord == null) coord = new Coordinate(); sascha@432: col = new XYColumn(coord.x, coord.z, i, j); sascha@432: map.put(key, col); ingo@429: } sascha@432: sascha@432: col.add(new HeightValue(z, v, k)); ingo@429: } ingo@429: sascha@432: ArrayList cols = new ArrayList(map.values()); ingo@429: attColumns.setXYColumns(cols); ingo@429: ingo@429: return attColumns; ingo@429: } ingo@429: ingo@429: 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 verticalcrosssection 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."); ingo@429: tim@335: log.warn("This sort of chart is not implemented yet."); tim@335: /* TODO Implement a special chart for this sort of charts. tim@335: chart = new VerticalProfileChart( tim@335: chartLables, tim@335: chartTheme, tim@335: parameters, tim@335: measurements, tim@335: result, tim@335: dates, tim@335: locale 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: tim@335: return chart; tim@335: } tim@335: tim@335: /** tim@335: * @see de.intevation.gnv.state.timeseries.TimeSeriesOutputState#createChart(java.io.OutputStream, tim@335: * java.util.Collection, java.util.Collection, java.lang.String, tim@335: * de.intevation.gnv.chart.ChartStyle, tim@335: * de.intevation.gnv.chart.ChartLabels) tim@335: */ tim@335: /* tim@335: @Override tim@335: protected void createChart(OutputStream outputStream, tim@335: Collection parameters, tim@335: Collection measurements, tim@335: Collection dates, tim@335: ChartStyle chartStyle, ChartLabels chartLables, tim@335: String uuid) throws IOException, tim@335: TechnicalChartException { tim@335: new VerticalCrossSectionChartFactory().createProfileChart(chartLables, tim@335: chartStyle, parameters, measurements, dates, outputStream, this tim@335: .getChartResult(uuid)); tim@335: } tim@335: */ tim@335: tim@335: /** tim@335: * @see de.intevation.gnv.state.timeseries.TimeSeriesOutputState#getStatisticsGenerator() tim@335: */ tim@335: @Override tim@335: protected Statistics getStatisticsGenerator() { tim@335: return new VerticalProfileStatistics(); tim@335: } ingo@429: tim@335: /** tim@335: * @see de.intevation.gnv.state.timeseries.TimeSeriesOutputState#createCSV(java.io.OutputStream, java.util.Collection) tim@335: */ tim@335: @Override sascha@432: protected void createCSV( sascha@432: OutputStream outputStream, sascha@432: Collection chartResult sascha@432: ) sascha@432: throws UnsupportedEncodingException, IOException, StateException sascha@432: { sascha@432: /* // TODO: Implement a substitution which makes sense. tim@335: if (chartResult != null) { tim@335: try { tim@335: CSVWriter writer = new CSVWriter(new OutputStreamWriter( tim@335: outputStream, "ISO-8859-1"), ','); tim@335: // USE THIS ENCODING BECAUSE OF tim@335: // PROBLEMS WITH EXCEL AND UTF-8 tim@335: Iterator it = chartResult.iterator(); tim@335: WKTReader wktReader = new WKTReader(); tim@335: while (it.hasNext()) { tim@335: Result result = it.next(); tim@335: int i = 0; tim@335: String[] entries = new String[9]; tim@335: Point p = (Point)wktReader.read(result.getString("SHAPE")); tim@335: entries[i++] = ""+p.getX(); tim@335: entries[i++] = ""+p.getY(); tim@335: entries[i++] = result.getString("Z"); tim@335: entries[i++] = result.getString("YORDINATE"); tim@335: entries[i++] = result.getString("GROUP1"); tim@335: entries[i++] = result.getString("GROUP2"); tim@335: entries[i++] = result.getString("IPOSITION"); tim@335: entries[i++] = result.getString("JPOSITION"); tim@335: entries[i++] = result.getString("KPOSITION"); tim@335: writer.writeNext(entries); tim@335: } tim@335: writer.close(); tim@335: } catch (ParseException e) { tim@335: log.error(e,e); tim@335: throw new StateException( tim@335: "Exception occured while parsing an Point from WKT."); tim@335: } tim@335: } else { tim@335: log.error("No Data given for generating an CSV-File."); tim@335: throw new StateException( tim@335: "No Data given for generating an CSV-File."); tim@335: } sascha@432: */ tim@335: } tim@335: } sascha@432: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: