All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.agrosense.client.grid.util.RasterHelper Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2008-2012 AgroSense Foundation.
 *
 * AgroSense is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * There are special exceptions to the terms and conditions of the GPLv3 as it is applied to
 * this software, see the FLOSS License Exception
 * .
 *
 * AgroSense is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even 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 AgroSense.  If not, see .
 * 
 * Contributors:
 *    johan - initial API and implementation and/or initial documentation
 */
package eu.agrosense.client.grid.util;

import java.awt.Point;
import java.awt.image.DataBuffer;
import java.awt.image.WritableRaster;
import nl.cloudfarming.client.geoviewer.Grid;
import nl.cloudfarming.client.lib.geotools.GeometryTools;
import org.geotools.coverage.CoverageFactoryFinder;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridCoverageFactory;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.geometry.BoundingBox;

/**
 * Helps with creation of a Raster and wraps around it to hold derived values.
 * 
 * @author johan
 */
public abstract class RasterHelper {
    private WritableRaster raster;
    // envelope coordinates in degrees:
    protected Double minx;
    protected Double miny;
    protected Double maxx;
    protected Double maxy;
    // envelope dimensions in degrees:
    private double diffx;
    private double diffy;
    // envelope dimensions in meters:
    private Double width;
    private Double height;
    // raster dimensions in pixels:
    private int nCols;
    private int nRows;
    // derived:
    private Double cellArea; // in m^2

    // initialize min/max x/y coordinates
    protected abstract void initEnvelopeCoordinates();

    protected void initDimensions(int size) {
        // width height and ratio in coordinates
        diffx = maxx - minx;
        diffy = maxy - miny;
        double ratio = diffy / diffx;
        // in pixels
        nCols = (int) Math.ceil(Math.sqrt(size / ratio));
        nRows = (int) Math.ceil(Math.sqrt(size / ratio));
    }

    // ensure all coordinates have gotten a value and form a rectangle:
    public final boolean hasValidEnvelope() {
        return minx != null && maxx != null && miny != null & maxy != null && !minx.equals(maxx) && !miny.equals(maxy);
    }

    // translate longitude to raster/pixel column index
    public Integer getX(double lon) {
        int x = (int) Math.floor((lon - minx) / (diffx / (nCols - 1)));
        if (x < 0 || x >= nCols) {
            return null;
        }
        return x;
    }

    // translate latitude to raster/pixel row index
    public Integer getY(double lat) {
        int y = (int) Math.floor((maxy - lat) / (diffy / (nRows - 1))); // incl. flip
        if (y < 0 || y >= nRows) {
            return null;
        }
        return y;
    }

    public BoundingBox createBoundingBox() {
        return new ReferencedEnvelope(minx, maxx, miny, maxy, DefaultGeographicCRS.WGS84);
    }

    public GridCoverage2D createCoverage() {
        GridCoverageFactory factory = CoverageFactoryFinder.getGridCoverageFactory(null);
        return factory.create("name", getRaster(), createBoundingBox());
    }
    
    public WritableRaster getRaster() {
        if (raster == null) {
            int bands = 1;
            Point location = new Point(0, 0);
            // DataBuffer.TYPE_DOUBLE is unsupported, may have to add a multiplication factor if rate/yield values are small
            raster = WritableRaster.createBandedRaster(DataBuffer.TYPE_INT, nCols, nRows, bands, location);
            for (int iw = 0; iw < nRows; iw++) {
                for (int ih = 0; ih < nCols; ih++) {
                    raster.setSample(iw, ih, 0, Grid.EMPTY_VALUE);
                }
            }
        }
        return raster;
    }
    
    public void setSamples(int[] values) {
        assert values != null;
        assert values.length == nCols * nRows;
        getRaster().setSamples(0, 0, nCols, nRows, 0, values);
    }

    public int getNumberOfColumns() {
        return nCols;
    }

    public int getNumberOfRows() {
        return nRows;
    }

    // in meters
    public Double getWidth() {
        if (width == null) {
            width = GeometryTools.getDistance(miny, minx, miny, maxx);
        }
        return width;
    }

    // in meters
    public Double getHeight() {
        if (height == null) {
            height = GeometryTools.getDistance(miny, minx, maxy, minx);
        }
        return height;
    }

    // in m^2
    public Double getCellArea() {
        if (cellArea == null) {
            cellArea = getWidth() * getHeight() / (nCols * nRows);
        }
        return cellArea;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy