/*******************************************************************************
GridExtent.java
Copyright (C) Victor Olaya
This program 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 2 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*******************************************************************************/
package org.openjump.core.rasterimage.sextante.rasterWrappers;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import org.openjump.core.rasterimage.sextante.ISextanteLayer;
import org.openjump.core.rasterimage.sextante.ISextanteRasterLayer;
/**
* This class defines a grid system (coordinates and cellsize)
* @author Victor Olaya
*
*/
public class GridExtent {
//these values are cell border coordinates, not centered ones
double m_dXMin;
double m_dYMin;
double m_dXMax;
double m_dYMax;
double m_dCellSize = 1;
int m_iNX;
int m_iNY;
public GridExtent(){}
/**
* Creates a new grid extent using the extent of a layer
* If it is a raster layer, it will also use its cellsize
* @param layer a layer
*/
public GridExtent (ISextanteLayer layer){
m_dXMin = layer.getFullExtent().getMinX();
m_dXMax = layer.getFullExtent().getMaxX();
m_dYMin = layer.getFullExtent().getMinY();
m_dYMax = layer.getFullExtent().getMaxY();
if(layer instanceof ISextanteRasterLayer){
ISextanteRasterLayer rasterLayer = (ISextanteRasterLayer) layer;
m_dCellSize = rasterLayer.getLayerGridExtent().getCellSize();
}
recalculateNXAndNY();
}
/**
* Sets a new range for X coordinates. Coordinates are not center
* cell ones, but border ones
* @param dXMin the minimum x coordinate of the extent.
* @param dXMax the maximum x coordinate of the extent
*/
public void setXRange(double dXMin, double dXMax){
m_dXMin = Math.min(dXMin, dXMax);
m_dXMax = Math.max(dXMin, dXMax);
recalculateNXAndNY();
}
/**
* Sets a new range for Y coordinates. Coordinates are not center
* cell ones, but border ones
* @param dYMin the minimum Y coordinate of the extent.
* @param dYMax the maximum Y coordinate of the extent
*/
public void setYRange(double dYMin, double dYMax){
m_dYMin = Math.min(dYMin, dYMax);
m_dYMax = Math.max(dYMin, dYMax);
recalculateNXAndNY();
}
/**
* Returns the cellsize of this extent
* @return the cells size of this extent
*/
public double getCellSize() {
return m_dCellSize;
}
/**
* Sets a new cellsize for this extent
* @param cellSize the new cellsize
*/
public void setCellSize(double cellSize) {
m_dCellSize = cellSize;
recalculateNXAndNY();
}
/**
* Returns the number of columns in the extent
* @return the number of columns
*/
public int getNX() {
return m_iNX;
}
/**
* Returns the number of rows in the extent
* @return the number of rows
*/
public int getNY() {
return m_iNY;
}
private void recalculateNXAndNY(){
m_iNY = (int) Math.floor((m_dYMax - m_dYMin) / m_dCellSize);
m_iNX = (int) Math.floor((m_dXMax - m_dXMin) / m_dCellSize);
m_dXMax = m_dXMin + m_dCellSize * m_iNX;
m_dYMax = m_dYMin + m_dCellSize * m_iNY;
}
/**
* Return the minimum x coordinate of the extent. This is not the
* coordinate of the center of the left-most cell, but the the
* coordinate of its left border
* @return the minimum x coordinate of the extent
*/
public double getXMin() {
return m_dXMin;
}
/**
* Return the maximum x coordinate of the extent. This is not the
* coordinate of the center of the right-most cell, but the the
* coordinate of its right border
* @return the maximum x coordinate of the extent
*/
public double getXMax() {
return m_dXMax;
}
/**
* Return the minimum x coordinateof the extent. This is not the
* coordinate of the center of the lower cell, but the the
* coordinate of its lower border
* @return the minimum y coordinate of the extent
*/
public double getYMin() {
return m_dYMin;
}
/**
* Return the maximum y coordinate of the extent. This is not the
* coordinate of the center of the upper cell, but the the
* coordinate of its upper border
* @return the maximum x coordinate of the extent
*/
public double getYMax() {
return m_dYMax;
}
/**
* Returns the real X distance spanned by this extent
* @return the real X distance spanned by this extent
*/
public double getWidth(){
return m_dXMax - m_dXMin;
}
/**
* Returns the real Y distance spanned by this extent
* @return the real Y distance spanned by this extent
*/
public double getHeight(){
return m_dYMax - m_dYMin;
}
/**
* Returns true if the given point falls within the area covered
* by this extent
* @param x the x coordinate of the point
* @param y the y coordinate of the point
* @return whether the given point falls within the area covered
* by this extent
*/
public boolean contains(double x, double y){
return (x >= m_dXMin && x <= m_dXMax && y >= m_dYMin && y <= m_dYMax);
}
/**
* Returns true if the given extents matches the grid defined by this
* grid extent (has same size and cell boundaries match)
* @param extent
* @return whether the passed extent matches fits into this extent
*/
public boolean fitsIn(GridExtent extent){
boolean bFitsX, bFitsY;
double dOffset;
double dOffsetCols;
double dOffsetRows;
final double MIN_DIF = 0.00001;
if (extent.getCellSize() != this.getCellSize()){
return false;
}
dOffset = Math.abs(extent.getXMin() - this.getXMin());
dOffsetCols = dOffset / this.getCellSize();
bFitsX = (dOffsetCols - Math.floor(dOffsetCols + 0.5) < MIN_DIF);
dOffset = Math.abs(extent.getYMax() - this.getYMax());
dOffsetRows = dOffset / this.getCellSize();
bFitsY = (Math.abs(dOffsetRows - Math.floor(dOffsetRows + 0.5)) < MIN_DIF);
return bFitsX && bFitsY;
}
/**
* Returns true if this extent has them same characteristics as a given one
* @param extent
* @return whether this extent equals the given extent
*/
public boolean equals(GridExtent extent){
return m_dXMin == extent.getXMin()
&& m_dXMax == extent.getXMax()
&& m_dYMin == extent.getYMin()
&& m_dYMax == extent.getYMax()
&& m_dCellSize == extent.getCellSize();
}
/**
* Modifies this extent to incorporate another one into its
* boundaries
* @param extent the extent to add
*/
public void addExtent(GridExtent extent){
m_dXMin = Math.min(extent.getXMin(), m_dXMin);
m_dXMax = Math.max(extent.getXMax(), m_dXMax);
m_dYMin = Math.min(extent.getYMin(), m_dYMin);
m_dYMax = Math.max(extent.getYMax(), m_dYMax);
m_dCellSize = Math.min(extent.getCellSize(), m_dCellSize);
recalculateNXAndNY();
}
/**
* Converts a world coordinate to grid coordinates
* @param pt a point in world coordinates
* @return a grid cell with coordinates of the given point in
* grid coordinates referred to this grid extent
*/
public GridCell getGridCoordsFromWorldCoords(Point2D pt){
int x = (int)Math.floor((pt.getX() - m_dXMin) / m_dCellSize);
int y = (int)Math.floor((m_dYMax - pt.getY()) / m_dCellSize);
GridCell cell = new GridCell(x, y, 0.0);
return cell;
}
/**
* Converts a world coordinate to grid coordinates
* @param x the x coordinate of the point
* @param y the y coordinate of the point
* @return a grid cell representing the given point in
* grid coordinates referred to this grid extent
*/
public GridCell getGridCoordsFromWorldCoords(double x, double y){
return getGridCoordsFromWorldCoords(new Point2D.Double(x,y));
}
/**
/**
* Converts a grid cell into a world coordinate representing
* the center of that cell
* @param cell the cell to convert
* @return a point representing the given cell in world coordinates
*/
public Point2D getWorldCoordsFromGridCoords(GridCell cell){
double x = m_dXMin + (cell.getX() + 0.5) * m_dCellSize;
double y = m_dYMax - (cell.getY() + 0.5) * m_dCellSize;
Point2D pt = new Point2D.Double(x, y);
return pt;
}
/**
* Converts a grid cell into a world coordinate representing
* the center of that cell
* @param x the x coordinate (col) of the cell
* @param y the y coordinate (row) of the cell
* @return a point representing the given cell in world coordinates
*/
public Point2D getWorldCoordsFromGridCoords(int x, int y){
return getWorldCoordsFromGridCoords(new GridCell(x, y, 0));
}
public String toString(){
String s = Double.toString(m_dXMin) + ", "
+ Double.toString(m_dYMin) + ", "
+ Double.toString(m_dXMax) + ", "
+ Double.toString(m_dYMax) + ", "
+ Double.toString(m_dCellSize);
return s;
}
// public String asCommandLineParameters(){
//
// String s = "\"" + Double.toString(m_dXMin) + "\", "
// + "\"" + Double.toString(m_dYMin) + "\", "
// + "\"" + Double.toString(m_dXMax) + "\", "
// + "\"" + Double.toString(m_dYMax) + "\", "
// + "\"" + Double.toString(m_dCellSize) + "\"";
//
// return s;
//
// }
/**
* Enlarges this grid extent one cell in each direction
*/
public void enlargeOneCell() {
m_dYMin = m_dYMin - m_dCellSize;
m_dXMin = m_dXMin - m_dCellSize;
m_dXMax = m_dXMax + m_dCellSize;
m_dYMax = m_dYMax + m_dCellSize;
this.recalculateNXAndNY();
}
/**
* Returns this extent as a Java Rectangle2D
* @return the extent of this grid extent as a Jave Rectangle2D
*/
public Rectangle2D getAsRectangle2D(){
Rectangle2D rect = new Rectangle2D.Double();
rect.setRect(m_dXMin, m_dYMin, m_dXMax - m_dXMin, m_dYMax - m_dYMin);
return rect;
}
/**
* Returns true if the cell is within the limits of this
* grid extent
* @param x the x coordinate (col) of the cell
* @param y the y coordinate (row) of the cell
* @return whether the cell is within the limits of this
* grid extent
*/
public boolean containsCell(int x, int y) {
return x >= 0 && x < m_iNX && y >= 0 && y < m_iNY;
}
}