org.n52.oxf.render.sos.TimeSeriesChartRenderer4xPhenomenons.java Source code

Java tutorial

Introduction

Here is the source code for org.n52.oxf.render.sos.TimeSeriesChartRenderer4xPhenomenons.java

Source

/**
 * Copyright (C) 2012
 * by 52 North Initiative for Geospatial Open Source Software GmbH
 *
 * Contact: Andreas Wytzisk
 * 52 North Initiative for Geospatial Open Source Software GmbH
 * Martin-Luther-King-Weg 24
 * 48155 Muenster, Germany
 * info@52north.org
 *
 * This program is free software; you can redistribute and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation.
 *
 * This program is distributed WITHOUT ANY WARRANTY; even without the implied
 * WARRANTY OF MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program (see gnu-gpl v2.txt). If not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA or
 * visit the Free Software Foundation web page, http://www.fsf.org.
 */

package org.n52.oxf.render.sos;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.text.SimpleDateFormat;
import java.util.Map;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.data.time.Second;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleInsets;
import org.n52.oxf.adapter.ParameterContainer;
import org.n52.oxf.adapter.ParameterShell;
import org.n52.oxf.feature.OXFFeatureCollection;
import org.n52.oxf.feature.sos.ObservationSeriesCollection;
import org.n52.oxf.feature.sos.ObservedValueTuple;
import org.n52.oxf.render.IChartRenderer;
import org.n52.oxf.render.IVisualization;
import org.n52.oxf.render.StaticVisualization;
import org.n52.oxf.valueDomains.time.ITimePosition;

/**
 * @author <a href="mailto:broering@52north.org">Arne Broering</a>
 * 
 */
public class TimeSeriesChartRenderer4xPhenomenons implements IChartRenderer {

    private String[] observedProperties;

    /**
     * The resulting IVisualization shows a chart which consists a TimeSeries for each FeatureOfInterest
     * contained in the observationCollection.
     */
    public IVisualization renderChart(OXFFeatureCollection observationCollection, ParameterContainer paramCon,
            int width, int height) {
        JFreeChart chart = renderChart(observationCollection, paramCon);

        // draw plot into image:
        Plot plot = chart.getPlot();
        BufferedImage chartImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D chartGraphics = chartImage.createGraphics();
        chartGraphics.setColor(Color.white);
        chartGraphics.fillRect(0, 0, width, height);
        plot.draw(chartGraphics, new Rectangle2D.Float(0, 0, width, height), null, null, null);

        // draw legend into image:
        LegendTitle legend = chart.getLegend();
        BufferedImage legendImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D legendGraphics = legendImage.createGraphics();
        legendGraphics.setColor(Color.white);
        legendGraphics.fillRect(0, 0, (int) legend.getWidth(), (int) legend.getHeight());
        legend.draw(legendGraphics, new Rectangle2D.Float(0, 0, width, height));

        return new StaticVisualization(chartImage, legendImage);
    }

    public JFreeChart renderChart(OXFFeatureCollection observationCollection, ParameterContainer paramCon) {
        // which observedProperty has been used?:
        ParameterShell observedPropertyPS = paramCon.getParameterShellWithServiceSidedName("observedProperty");
        if (observedPropertyPS.hasMultipleSpecifiedValues()) {
            observedProperties = observedPropertyPS.getSpecifiedTypedValueArray(String[].class);
        } else if (observedPropertyPS.hasSingleSpecifiedValue()) {
            observedProperties = new String[] { (String) observedPropertyPS.getSpecifiedValue() };
        } else {
            throw new IllegalArgumentException("no observedProperties found.");
        }

        String[] foiIdArray;
        ParameterShell foiParamShell = paramCon.getParameterShellWithServiceSidedName("featureOfInterest");
        if (foiParamShell.hasMultipleSpecifiedValues()) {
            foiIdArray = foiParamShell.getSpecifiedTypedValueArray(String[].class);
        } else {
            foiIdArray = new String[] { (String) foiParamShell.getSpecifiedValue() };
        }

        ObservationSeriesCollection tuples4FOI = new ObservationSeriesCollection(observationCollection, foiIdArray,
                observedProperties, false);

        JFreeChart chart = ChartFactory.createTimeSeriesChart(null, // title
                "Date", // x-axis label
                observedProperties[0], // y-axis label
                createDataset(foiIdArray, tuples4FOI, 0), // data
                true, // create legend?
                true, // generate tooltips?
                false // generate URLs?
        );

        chart.setBackgroundPaint(Color.white);

        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setBackgroundPaint(Color.white);
        plot.setDomainGridlinePaint(Color.lightGray);
        plot.setRangeGridlinePaint(Color.lightGray);
        plot.setAxisOffset(new RectangleInsets(2.0, 2.0, 2.0, 2.0));
        plot.setDomainCrosshairVisible(true);
        plot.setRangeCrosshairVisible(true);

        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
        renderer.setBaseShapesVisible(true);
        renderer.setBaseShapesFilled(true);

        // add additional datasets:

        DateAxis axis = (DateAxis) plot.getDomainAxis();
        axis.setDateFormatOverride(new SimpleDateFormat());

        for (int i = 1; i < observedProperties.length; i++) {
            XYDataset additionalDataset = createDataset(foiIdArray, tuples4FOI, i);
            plot.setDataset(i, additionalDataset);
            plot.setRangeAxis(i, new NumberAxis(observedProperties[i]));
            plot.getRangeAxis(i).setRange((Double) tuples4FOI.getMinimum(i), (Double) tuples4FOI.getMaximum(i));
            plot.mapDatasetToRangeAxis(i, i);
        }

        return chart;
    }

    protected TimeSeriesCollection createDataset(String[] foiIdArray, ObservationSeriesCollection tuples4FOI,
            int observedPropertyIndex) {
        TimeSeriesCollection dataset = new TimeSeriesCollection();

        for (String featureID : foiIdArray) {
            Map<ITimePosition, ObservedValueTuple> tupleMap = tuples4FOI.getAllTuples(featureID);

            if (tupleMap != null) {

                // for each selected <feature,observedPropertyIndex> pair construct a new TimeSeries:
                TimeSeries timeSeries = new TimeSeries(
                        featureID + "___" + this.observedProperties[observedPropertyIndex], Second.class);

                for (ITimePosition timePos : tupleMap.keySet()) {
                    ObservedValueTuple tuple = tupleMap.get(timePos);

                    Number result = (Number) tuple.getValue(observedPropertyIndex);

                    timeSeries.add(new Second(new Float(timePos.getSecond()).intValue(), timePos.getMinute(),
                            timePos.getHour(), timePos.getDay(), timePos.getMonth(),
                            new Long(timePos.getYear()).intValue()), result);
                }
                dataset.addSeries(timeSeries);
            }
        }
        dataset.setDomainIsPointsInTime(true);

        return dataset;
    }

    /**
     * @return a plain text description of this Renderer.
     */
    public String getDescription() {
        return "TimeSeriesChartRenderer - visualizes a time series chart for a selected phenomenon";
    }

    public String toString() {
        return getDescription();
    }

    /**
     * @return the type of the service whose data can be rendered with this ServiceRenderer. In this case
     *         "OGC:SOS" will be returned.
     */
    public String getServiceType() {
        return "OGC:SOS";
    }

    /**
     * @return the versions of the services whose data can be rendered with this ServiceRenderer. In this case
     *         {"1.0.0"} will be returned.
     */
    public String[] getSupportedVersions() {
        return new String[] { "0.0.0" };
    }
}