org.geopublishing.atlasStyler.classification.RasterClassification.java Source code

Java tutorial

Introduction

Here is the source code for org.geopublishing.atlasStyler.classification.RasterClassification.java

Source

/*******************************************************************************
 * Copyright (c) 2010 Stefan A. Tzeggai.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Stefan A. Tzeggai - initial API and implementation
 ******************************************************************************/
package org.geopublishing.atlasStyler.classification;

import hep.aida.bin.DynamicBin1D;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.util.Arrays;

import org.apache.log4j.Logger;
import org.geopublishing.atlasStyler.ASUtil;
import org.geotools.coverage.grid.GridCoverage2D;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.statistics.HistogramDataset;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.TextAnchor;

import cern.colt.list.DoubleArrayList;
import de.schmitzm.geotools.styling.StyledGridCoverageReaderInterface;
import de.schmitzm.lang.LangUtil;

/**
 * A quantitative classification. The inveralls are defined by upper and lower
 * limits
 * 
 * 
 * @param <T>
 *            The type of the value field
 * 
 * @author stefan
 */
public class RasterClassification extends Classification {

    final private static Logger LOGGER = LangUtil.createLogger(RasterClassification.class);

    private final StyledGridCoverageReaderInterface styledRaster;

    /**
     * Working on the first band is the default.
     */
    private int band = 0;

    public RasterClassification(StyledGridCoverageReaderInterface styledRaster) {
        this.styledRaster = styledRaster;
    }

    @Override
    public BufferedImage createHistogramImage(boolean showMean, boolean showSd, int histogramBins,
            String label_xachsis) throws InterruptedException, IOException {
        HistogramDataset hds = new HistogramDataset();

        DoubleArrayList valuesAL;
        valuesAL = getStatistics().elements();
        double[] elements = Arrays.copyOf(valuesAL.elements(), getStatistics().size());
        hds.addSeries(1, elements, histogramBins);

        /** Statically label the Y Axis **/
        String label_yachsis = ASUtil.R("QuantitiesClassificationGUI.Histogram.YAxisLabel");

        JFreeChart chart = org.jfree.chart.ChartFactory.createHistogram(null, label_xachsis, label_yachsis, hds,
                PlotOrientation.VERTICAL, false, true, true);

        /***********************************************************************
         * Paint the classes into the JFreeChart
         */
        int countLimits = 0;
        for (Double cLimit : getClassLimits()) {
            ValueMarker marker = new ValueMarker(cLimit);
            XYPlot plot = chart.getXYPlot();
            marker.setPaint(Color.orange);
            marker.setLabel(String.valueOf(countLimits));
            marker.setLabelAnchor(RectangleAnchor.TOP_LEFT);
            marker.setLabelTextAnchor(TextAnchor.TOP_RIGHT);
            plot.addDomainMarker(marker);

            countLimits++;
        }

        /***********************************************************************
         * Optionally painting SD and MEAN into the histogram
         */
        try {
            if (showSd) {
                ValueMarker marker;
                marker = new ValueMarker(getSD(), Color.green.brighter(), new BasicStroke(1.5f));
                XYPlot plot = chart.getXYPlot();
                marker.setLabel(ASUtil.R("QuantitiesClassificationGUI.Histogram.SD.ShortLabel"));
                marker.setLabelAnchor(RectangleAnchor.BOTTOM_LEFT);
                marker.setLabelTextAnchor(TextAnchor.BOTTOM_RIGHT);
                plot.addDomainMarker(marker);
            }

            if (showMean) {
                ValueMarker marker;
                marker = new ValueMarker(getMean(), Color.green.darker(), new BasicStroke(1.5f));
                XYPlot plot = chart.getXYPlot();
                marker.setLabel(ASUtil.R("QuantitiesClassificationGUI.Histogram.Mean.ShortLabel"));
                marker.setLabelAnchor(RectangleAnchor.BOTTOM_LEFT);
                marker.setLabelTextAnchor(TextAnchor.BOTTOM_RIGHT);
                plot.addDomainMarker(marker);
            }

        } catch (Exception e) {
            LOGGER.error("Painting SD and MEAN into the histogram", e);
        }

        /***********************************************************************
         * Render the Chart
         */
        BufferedImage image = chart.createBufferedImage(400, 200);

        return image;
    }

    /**
     * This is where the magic happens. Here the attributes of the features are
     * summarized in a {@link DynamicBin1D} class.
     * 
     * @throws IOException
     */
    @Override
    synchronized public DynamicBin1D getStatistics() throws InterruptedException, IOException {

        cancelCalculation.set(false);

        if (stats == null) {
            GridCoverage2D coverage = getStyledRaster().getGeoObject().read(null);

            stats = new DynamicBin1D();

            noDataValuesCount.set(0);

            final RenderedImage rim = coverage.getRenderedImage();

            long size = Long.valueOf(rim.getHeight()) * Long.valueOf(rim.getWidth());
            long maxPixels = 3000000l;
            if (size > maxPixels) {
                setSubsampling((int) (size / maxPixels));
                LOGGER.info("Subsampling to every " + getSubsampling() + " pixel");
            }

            for (int row = 0; row < rim.getHeight(); row++) {

                if (row % getSubsampling() != 0) {
                    // Skipping this line for Subsampling
                    continue;
                } else {
                    // DO
                    //               System.out.println("");
                }

                int x1 = 0;
                int w = rim.getWidth();

                int y1 = row;
                int h = 1;

                Raster data = rim.getData(new Rectangle(x1, y1, w, h));
                double[] values = data.getSamples(0, y1, w, h, getBand(), (double[]) null);

                final DoubleArrayList doubleArrayList = new DoubleArrayList(values);

                if (getStyledRaster().getNodataValue() != null) {
                    int sizewithNodata = doubleArrayList.size();
                    doubleArrayList
                            .removeAll(new DoubleArrayList(new double[] { getStyledRaster().getNodataValue() }));
                    noDataValuesCount.addAndGet(sizewithNodata - doubleArrayList.size());
                }

                stats.addAllOf(doubleArrayList);

                //            LOGGER.debug("Added "+doubleArrayList.size()+" to statistics");
                //            LOGGER.debug(stats.size()+" in stats");
                doubleArrayList.clear();
            }

        }
        return stats;
    }

    public StyledGridCoverageReaderInterface getStyledRaster() {
        return styledRaster;
    }

    public void setBand(int band) {
        if (band != this.band) {
            // Statistik wegschmeissen
            stats = null;
        }
        this.band = band;
    }

    public int getBand() {
        return band;
    }

}