view gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java @ 431:422275fc9927

Refactored the XYColumn and Point2d code a bit to be more reusable in 3D. gnv-artifacts/trunk@479 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Wed, 23 Dec 2009 06:53:46 +0000
parents bed9735adf84
children 6a70e8883307
line wrap: on
line source
/**
 *
 */
package de.intevation.gnv.state.profile.verticalcrosssection;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

import org.apache.log4j.Logger;

import org.jfree.chart.ChartTheme;

import org.w3c.dom.Node;

import net.sf.ehcache.Element;

import au.com.bytecode.opencsv.CSVWriter;

import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;

import de.intevation.artifactdatabase.Config;
import de.intevation.gnv.artifacts.cache.CacheFactory;
import de.intevation.gnv.chart.Chart;
import de.intevation.gnv.chart.ChartLabels;
import de.intevation.gnv.chart.ChartStyle;
import de.intevation.gnv.chart.exception.TechnicalChartException;
import de.intevation.gnv.geobackend.base.Result;
import de.intevation.gnv.geobackend.base.ResultDescriptor;
import de.intevation.gnv.geobackend.base.query.QueryExecutor;
import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory;
import de.intevation.gnv.geobackend.base.query.exception.QueryException;

import de.intevation.gnv.math.AttributedXYColumns;
import de.intevation.gnv.math.HeightValue;
import de.intevation.gnv.math.XYColumn;
import de.intevation.gnv.math.IJKey;

import de.intevation.gnv.state.describedata.KeyValueDescibeData;
import de.intevation.gnv.state.exception.StateException;
import de.intevation.gnv.state.timeseries.TimeSeriesOutputState;
import de.intevation.gnv.statistics.Statistics;
import de.intevation.gnv.statistics.VerticalProfileStatistics;
import de.intevation.gnv.utils.WKTUtils;

/**
 * @author Tim Englich <tim.englich@intevation.de>
 * 
 */
public class VerticalCrossSectionOutputState extends TimeSeriesOutputState {

    public static final String[] ATTRIBUTE_LIST = {
        "SHAPE",
        "Z",
        "YORDINATE",
        "IPOSITION",
        "JPOSITION",
        "KPOSITION"
    };

    private static Logger log = Logger.getLogger(
        VerticalCrossSectionOutputState.class);

    private String ijkQueryID = "horizontalprofile_meshpoint_cross_ij";

    /**
     * The UID of this Class
     */
    private static final long serialVersionUID = 3233620652465061860L;

    /**
     * Constructor
     */
    public VerticalCrossSectionOutputState() {
        super();
        super.domainLable = "chart.verticalcrosssection.title.xaxis";
    }


    @Override
    protected Object getChartResult(String uuid) {
        log.debug("VerticalCrossSectionOutputState.getChartResult");
        Collection<Result> result = null;
        String key = uuid + super.getID();

        Element element = CacheFactory.getInstance().getCache().get(key);
        if (element != null)
            return element.getObjectValue();

        log.debug("No results in cache yet.");
        if (inputData.containsKey("mesh_linestring")) {

            try {
                LineString ls = (LineString) new WKTReader().read(
                    inputData.get("mesh_linestring").getValue());

                Coordinate[] coords = ls.getCoordinates();

                String additionWhere = WKTUtils.worldCoordinatesToIndex(
                    result,
                    inputData,
                    ijkQueryID
                );


                String[] filterValues =
                    generateFilterValuesFromInputData();
                String[] addedFilterValues =
                    new String[filterValues.length + 1];

                System.arraycopy(
                    filterValues, 0,
                    addedFilterValues, 0,
                    filterValues.length
                );
                addedFilterValues[filterValues.length] = additionWhere;

                QueryExecutor exec = QueryExecutorFactory
                    .getInstance()
                    .getQueryExecutor();

                result = exec.executeQuery(queryID, addedFilterValues);
            }
            catch (ParseException pe) {
                log.error(pe, pe);
            }
            catch (QueryException qe) {
                log.error(qe, qe);
            }
        }
        else {
            // TODO What should happen if there is no linestring?
            log.warn("No linestring in inputData.");
        }

        Object obj = process(preProcess(result));
        CacheFactory.getInstance().getCache().put(new Element(key, obj));

        return obj;
    }


    protected Object process(AttributedXYColumns columns) {

        // TODO Implement me
        return null;
    }


    protected AttributedXYColumns preProcess(Collection results) {
        AttributedXYColumns attColumns = new AttributedXYColumns();
        Map        map                 = new HashMap(1013);
        Iterator   iter                = results.iterator();

        int sIdx = -1;
        int iIdx = -1;
        int jIdx = -1;
        int kIdx = -1;
        int vIdx = -1;
        int zIdx = -1;

        while (iter.hasNext()) {
            Result result = (Result) iter.next();

            if (sIdx == -1) {
                ResultDescriptor rd = result.getResultDescriptor();
                int columnCount     = rd.getColumnCount();

                sIdx = rd.getColumnIndex("SHAPE");
                iIdx = rd.getColumnIndex("IPOSITION");
                jIdx = rd.getColumnIndex("JPOSITION");
                kIdx = rd.getColumnIndex("KPOSITION");
                vIdx = rd.getColumnIndex("YORDINATE");
                zIdx = rd.getColumnIndex("Z");

                for (int i = 0; i < columnCount; i++) {
                    String colName = rd.getColumnName(i);

                    if (!attributeInList(colName)) {
                        attColumns.setAttribute(
                            colName,
                            result.getObject(colName));
                    }
                }
            }

            try {
                Point point  = (Point) new WKTReader().read(
                    result.getString(sIdx));
                double v     = result.getDouble(vIdx);
                int i        = result.getInteger(iIdx);
                int j        = result.getInteger(jIdx);
                int k        = result.getInteger(kIdx);
                int z        = result.getInteger(zIdx);

                IJKey key = new IJKey(i, j);

                XYColumn col = (XYColumn)map.get(key);

                if (col == null) {
                    col = new XYColumn(point.getX(), point.getY(), i, j);
                    map.put(key, col);
                }

                col.add(new HeightValue(z, v, k));
            }
            catch (ParseException pe) {
                log.warn("Error while parsing geometry.", pe);
            }
        }

        XYColumn[] cols = (XYColumn[])map.values().toArray(
            new XYColumn[map.size()]);
        attColumns.setXYColumns(cols);

        return attColumns;
    }


    protected boolean attributeInList(String name) {
        for (int i = 0; i < ATTRIBUTE_LIST.length; i++) {
            if (name.equals(ATTRIBUTE_LIST[i]))
                return true;
        }

        return false;
    }


    @Override
    protected Chart getChart(
        ChartLabels  chartLables,
        ChartTheme   theme,
        Collection   parameters,
        Collection   measurements,
        Collection   dates,
        Object       result,
        Locale       locale,
        String       uuid,
        boolean      linesVisible,
        boolean      shapesVisible
    ) {
        Chart chart = null;

        if (CACHE_CHART) {
            log.info("Try to get verticalcrosssection chart from cache.");
            chart = (Chart) getChartFromCache(uuid);
        }

        if (chart != null)
            return chart;

        log.info("Chart not in cache yet.");

        log.warn("This sort of chart is not implemented yet.");
        /* TODO Implement a special chart for this sort of charts.
        chart = new VerticalProfileChart(
            chartLables,
            chartTheme,
            parameters,
            measurements,
            result,
            dates,
            locale
        );
        chart.generateChart();

        if (CACHE_CHART) {
            log.info("Put chart into cache.");
            purifyChart(chart, uuid);
        }
        */

        return chart;
    }

    /**
     * @see de.intevation.gnv.state.timeseries.TimeSeriesOutputState#createChart(java.io.OutputStream,
     *      java.util.Collection, java.util.Collection, java.lang.String,
     *      de.intevation.gnv.chart.ChartStyle,
     *      de.intevation.gnv.chart.ChartLabels)
     */
    /*
    @Override
    protected void createChart(OutputStream outputStream,
                               Collection<KeyValueDescibeData> parameters,
                               Collection<KeyValueDescibeData> measurements,
                               Collection<KeyValueDescibeData> dates,
                               ChartStyle chartStyle, ChartLabels chartLables,
                               String uuid) throws IOException,
                                           TechnicalChartException {
        new VerticalCrossSectionChartFactory().createProfileChart(chartLables,
                chartStyle, parameters, measurements, dates, outputStream, this
                        .getChartResult(uuid));
    }
    */

    /**
     * @see de.intevation.gnv.state.timeseries.TimeSeriesOutputState#getStatisticsGenerator()
     */
    @Override
    protected Statistics getStatisticsGenerator() {
        return new VerticalProfileStatistics();
    }

    /**
     * @see de.intevation.gnv.state.timeseries.TimeSeriesOutputState#createCSV(java.io.OutputStream, java.util.Collection)
     */
    @Override
    protected void createCSV(OutputStream outputStream,
                             Collection<Result> chartResult)
                                                            throws UnsupportedEncodingException,
                                                            IOException,
                                                            StateException {
        if (chartResult != null) {
            try {
                CSVWriter writer = new CSVWriter(new OutputStreamWriter(
                        outputStream, "ISO-8859-1"), ','); 
                // USE THIS ENCODING BECAUSE OF
                // PROBLEMS WITH EXCEL AND UTF-8
                Iterator<Result> it = chartResult.iterator();
                WKTReader wktReader = new WKTReader();
                while (it.hasNext()) {
                    Result result = it.next();
                    int i = 0;
                    String[] entries = new String[9];
                    Point p = (Point)wktReader.read(result.getString("SHAPE"));
                    entries[i++] = ""+p.getX();
                    entries[i++] = ""+p.getY();
                    entries[i++] = result.getString("Z");
                    entries[i++] = result.getString("YORDINATE");
                    entries[i++] = result.getString("GROUP1");
                    entries[i++] = result.getString("GROUP2");
                    entries[i++] = result.getString("IPOSITION");
                    entries[i++] = result.getString("JPOSITION");
                    entries[i++] = result.getString("KPOSITION");
                    writer.writeNext(entries);
                }
                writer.close();
            } catch (ParseException e) {
                log.error(e,e);
                throw new StateException(
                "Exception occured while parsing an Point from WKT.");
            }
        } else {
            log.error("No Data given for generating an CSV-File.");
            throw new StateException(
                    "No Data given for generating an CSV-File.");
        }
    }

}

http://dive4elements.wald.intevation.org