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

eu.agrosense.client.grid.GridCellSize 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:
 *    Timon Veenstra  - initial API and implementation and/or initial documentation
 */
package eu.agrosense.client.grid;

import com.vividsolutions.jts.geom.Coordinate;
import java.awt.Dimension;
import java.awt.Point;
import org.opengis.geometry.BoundingBox;

/**
 * Constant enumeration for grid cell sizes.
 *
 * Each subsequent grid cell size is 4 times the size of the previous one. This
 * way grid sizes remain compatible with eachother
 *
 *
 *
 * @author Timon Veenstra 
 */
public enum GridCellSize{

    /**
     * cell sizes of roughly 1x1 meter
     */
    S1(1),
    /**
     * cell sizes of roughly 2x2 meter, 4 times size of {@link S1}
     */
    S2(2),
    /**
     * cell sizes of roughly 4x4 meter, 4 times size of {@link S2}
     */
    S4(4),
    /**
     * cell sizes of roughly 16x16 meter, 4 times size of {@link S4}
     */
    S16(16),
    /**
     * cell sizes of roughly 32x32 meter, 4 times size of {@link S16}
     */
    S32(32);
    private int factor;
    // 1 degree is aproximately 111km, 
    public static final double ONE_METER_DEGREE = 0.000009009;

    private GridCellSize(int factor) {
        this.factor = factor;
    }

    /**
     * width of a grid cell in degrees
     *
     * @return
     */
    public double getLongitude() {
        return factor * ONE_METER_DEGREE;
    }

    /**
     * height of a grid cell in degrees
     *
     * @return
     */
    public double getLatitude() {
        return factor * ONE_METER_DEGREE;
    }

    /**
     * Calculate how many cells are needed to cover provided size in degrees
     *
     *
     * 
     *
     * @param sizeInDegrees
     * @return
     */
    //FIXME this won't work, we need to know where it is, since the area could start half way in a cell!!!!
    public Dimension getDimension(BoundingBox boundingBox) {
        //
        // gps coordinates have a x range from -180 to 180
        // for calculation we move this to 0-360 
        //
        int leftRow = new Double(Math.ceil((boundingBox.getMinX() + 180) / (factor * ONE_METER_DEGREE))).intValue();
        int rightRow = new Double(Math.ceil((boundingBox.getMaxX() + 180) / (factor * ONE_METER_DEGREE))).intValue();

        //
        // gps coordinates have a y range from -90 to 90
        // for calculation we move this to 0-180
        //
        int topRow = new Double(Math.ceil((boundingBox.getMinY() + 90) / (factor * ONE_METER_DEGREE))).intValue();
        int bottomRow = new Double(Math.ceil((boundingBox.getMaxY() + 90) / (factor * ONE_METER_DEGREE))).intValue();

        return new Dimension((rightRow - leftRow) + 1, (bottomRow - topRow) + 1);
    }

    /**
     * get the cell point (0 index raster position) for the given coordinate
     *
     * @param boundingBox
     * @param coordinate
     * @return
     */
    public Point getCell(BoundingBox boundingBox, Coordinate coordinate) {
        assert boundingBox.contains(coordinate.x, coordinate.y):"ERROR:cell requested for coordinate "+coordinate+" outside boundingbox "+boundingBox;
        int leftRow = new Double(Math.ceil((boundingBox.getMinX() + 180) / (factor * ONE_METER_DEGREE))).intValue();
        int bottomRow = new Double(Math.ceil((boundingBox.getMinY() + 90) / (factor * ONE_METER_DEGREE))).intValue();
        int cellX = new Double(Math.ceil((coordinate.x + 180) / (factor * ONE_METER_DEGREE))).intValue();
        int cellY = new Double(Math.ceil((coordinate.y + 90) / (factor * ONE_METER_DEGREE))).intValue();



        int x = cellX - (leftRow);
        int y = cellY - (bottomRow);
        Dimension dimension = getDimension(boundingBox);
        y = Math.abs(y - (dimension.height-1));
        // y axis in a raster starts at the top instead of the bottom, so we need to flip the y value

        assert (x >= 0 && x <= dimension.width) : "x position ("+x+") of cell not within raster bounds (0-"+dimension.width+")";
        assert (y >= 0 && y <= dimension.height) : "y position ("+y+")of cell not within raster bounds (0-"+dimension.height+")";

        return new Point(x, y);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy