raster.java
来自「geotools的源码」· Java 代码 · 共 1,460 行 · 第 1/3 页
JAVA
1,460 行
package uk.ac.leeds.ccg.raster;
import java.lang.*;
import java.io.*;
import java.net.*;
import java.awt.image.*;
import java.awt.*;
//import java.util.*;
import com.sun.java.util.collections.*; //change for 1.2!
import uk.ac.leeds.ccg.geotools.*;
/**
* A class to hold raster data sets
* @author <a href="http://www.geog.leeds.ac.uk/staff/i.turton/i.turton.html">
* Ian Turton</a> Centre for
* Computaional Geography, University of Leeds, LS2 9JT, 1998.<br>
* <a href="mailto:ian@geog.leeds.ac.uk">i.turton@geog.leeds.ac.uk</a>
**/
/**
* It is common to want to distinguish between a missing value (nodata) and a
* value that is zero or another value that does not effect the result of a
* calulation (e.g. The value 0.0d in addition and subtraction, and the value
* 1.0d as an exponent power or as a value in a multiplication or the
* denominator in a division).
*
* A default value can be defined as the value which every cell has if it is not
* in an (id,list) hashtable containing the other values. In version 1.9 of
* Raster the default value was always 0.0d. This was changed to be nodata in
* version 1.10 and get and set methods for this value were provided.
*
* There are advantages in terms of memory usage to using a hashtable if more
* than half the values are the default value (because of the need to store the
* id otherwise in the hashtable).
*
* There are various options for Raster storage that should be considered for
* geoTools2. The nature of the values in a Raster and its size determine what
* what storage is best in terms of memory usage and speed of getting and
* setting values.
**/
public class Raster extends SimpleGeoData implements Serializable{
private final static boolean DEBUG=true;
String name="Raster";
/**
* the value below which a cell is considered zero, defaults to 1e-7
* @see #getTol()
* @see #setTol()
*/
double TOL =1e-7;
/**
* proportion of raster with missing values
*/
double sparseness;
/**
* The left hand edge of the raster
* @see #getOriginx()
* @see #getOrigin()
*/
protected double originx;
/**
* The bottom edge of the raster
* @see #getOriginy()
* @see #getOrigin()
*/
protected double originy;
/**
* The cell size of the raster
* @see #getCellSize()
*/
protected double cellsize;
/**
* The nodata value of the raster
* @see #getNoDataValue()
*/
protected double nodata;
/**
* GeoData missing value code
* double MISSING=Double.NaN;
* @see #getMissingValueCode()
*/
double missing = GeoData.MISSING;
/**
* The minimum value of the raster
* @see #getMin()
*/
protected double min;
protected double nzmin;
/**
* The maximum value of the raster
* @see #getMax()
*/
protected double max;
/**
* The height of the raster in cells
* @see #getHeight()
*/
protected int height;
/**
* The width of the raster in cells
* @see #getWidth()
*/
protected int width;
/**
* the values of the raster
* @see #sparse
*/
protected double cells[];
/**
* Vector to store a sparse raster
* @see #sparse
*/
//private Vector scells = new Vector(1,2000);
protected Hashtable scells = new Hashtable();
/**
* Is this Raster stored in a sparse form or not
* @see #setSparse()
* @see #isSparse()
*/
protected boolean sparse=false;
/**
* @see #public class MyInt()
*/
MyInt in = new MyInt();
/**
* build a new empty raster of size 0.
*/
public Raster() {
this(new GeoRectangle(),1.0);
}
/**
* builds a new raster from an image.
*/
public Raster(Image im, int width, int height, GeoRectangle gr) {
this(gr,gr.getWidth()/(double)width);
double xsize=gr.getWidth()/(double)width;
double ysize = gr.getHeight()/(double)(height);
if(DEBUG)System.out.println("Ra-->width "+width+" -> "+this.width+" "+xsize);
if(DEBUG)System.out.println("Ra-->height "+height+" -> "+this.height+" "+ysize);
if(DEBUG)System.out.println("Ra-->cellsize "+cellsize);
Canvas obs = new Canvas();
//int width = im.getWidth(obs);
//int height = im.getHeight(obs);
int[] data = new int[(height*width)];
if(DEBUG)System.out.println("Ra-->image "+width+" by "+height);
PixelGrabber pg = new PixelGrabber(im,0,0,width,height,data,0,width);
if(DEBUG)System.out.println("Ra-->about to grab");
try {
pg.grabPixels();
} catch (InterruptedException e) {
System.err.println("Ra-->interrupted waiting for pixels!");
return;
}
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
System.err.println("Ra-->image fetch aborted or errored");
setBounds(new GeoRectangle());
return ;
}
if(DEBUG)System.out.println("Ra-->Post grab");
im=null;
System.gc();
ColorModel cm = ColorModel.getRGBdefault();
int k=0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
//int alpha = (data[k] >> 24) & 0xff;
//int red = (data[k] >> 16) & 0xff;
//int green = (data[k] >> 8) & 0xff;
//int blue = (data[k] ) & 0xff;
//int alpha = cm.getAlpha(data[k]);
//int red = cm.getRed(data[k]);
//int green = cm.getGreen(data[k]);
//int blue = cm.getBlue(data[k]);
//addToCell(originx+i*xsize,originy+j*ysize,(double)green);
//addToCell(originx+i*xsize,originy+j*ysize,(double)green);
//System.out.println("Ra-->on? "+onSurface(j,i));
addToCell(j,i,(double)(data[k]));
//System.out.println("Ra-->"+(j)+ " "+(i)+ " "+red+" "+green+" "+blue+" "+getCell(j,i));
k++;
}
}
}
/**
* build a new empty raster
* @param top the top of the raster in geographic space
* @param left the left edge of the raster in geographic space
* @param size the cellsize of the raster in geographic units
* @param h the height of the raster in cells
* @param w the width of the raster in cells
*/
public Raster(double top, double left, double size, int h, int w){
if(DEBUG)System.out.println("---->uk.ac.leeds.ccg.raster.Raster constructed. Will identify itself as Ra-->");
cellsize=size;
originx=left;
originx=Math.floor(left/cellsize)*cellsize; // Integerizes originx!
originy=top-h;
originy=Math.floor(originy/cellsize)*cellsize; // Integerizes originy!
height=h;
width=w;
sparse=true;
//cells= new double[h*w];
}
public Raster(GeoRectangle m,double size,double[] data){
if(DEBUG)System.out.println("---->uk.ac.leeds.ccg.raster.Raster constructed. Will identify itself as Ra-->");
cellsize=size;
originx=m.x;
originx=Math.floor(m.x/cellsize)*cellsize;
originy=m.y;
originy=Math.floor(m.y/cellsize)*cellsize;
this.height=(int)Math.round(m.height/cellsize);
this.width=(int)Math.round(m.width/cellsize);
cells=new double[height*width];
//if(DEBUG)System.out.println("Ra-->h = "+height);
//if(DEBUG)System.out.println("Ra-->w = "+width);
int p=0;
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
//if(DEBUG)System.out.println("Ra-->p = "+p+" d = "+data[p]);
addToCell(i,j,data[p++]); // alternatively putCell(i,j,data[p]); p++;
}
}
if(getSparseness()>50.0d) {
setSparse(true);
}
}
public Raster(GeoRectangle m,double size,XYVData[] data){
if(DEBUG)System.out.println("---->uk.ac.leeds.ccg.raster.Raster constructed. Will identify itself as Ra-->");
cellsize=size;
originx=m.x;
originx=Math.floor(m.x/cellsize)*cellsize;
originy=m.y;
originy=Math.floor(m.y/cellsize)*cellsize;
sparseness=0d;
height=(int)Math.round(m.height/cellsize);
width=(int)Math.round(m.width/cellsize);
sparse=true;
scells=new Hashtable();
//cells=new double[height*width];
cells=new double[1];
min=Double.MAX_VALUE;
nzmin=Double.MAX_VALUE;
max=Double.MIN_VALUE;
if(data==null) {
min=0.0;
max=0.0;
return;
}
for(int i=0;i<data.length;i++){
addToCell(data[i].x,data[i].y,data[i].value);
min=Math.min(min,data[i].value);
max=Math.max(max,data[i].value);
if(data[i].value>0.0) nzmin=Math.min(nzmin,data[i].value);
}
if(getSparseness()<50.0d) {
setSparse(false);
}
}
public Raster(GeoRectangle m,double size,RCVData[] data){
cellsize=size;
originx=m.x;
originx=Math.floor(m.x/cellsize)*cellsize;
originy=m.y;
originy=Math.floor(m.y/cellsize)*cellsize;
sparseness=0d;
height=(int)Math.round(m.height/cellsize);
width=(int)Math.round(m.width/cellsize);
sparse=true;
scells=new Hashtable();
//cells=new double[height*width];
min=Double.MAX_VALUE;
nzmin=Double.MAX_VALUE;
max=Double.MIN_VALUE;
if(data==null) return;
for(int i=0;i<data.length;i++){
addToCell(data[i].row,data[i].col,data[i].value);
min=Math.min(min,data[i].value);
max=Math.max(max,data[i].value);
if(data[i].value>0.0) nzmin=Math.min(nzmin,data[i].value);
}
if(getSparseness()<50.0d) {
setSparse(false);
}
}
public Raster(GeoRectangle m, double size){
if(DEBUG)System.out.println("---->uk.ac.leeds.ccg.raster.Raster constructed. Will identify itself as Ra-->");
cellsize=size;
originx=m.x;
originx=Math.floor(m.x/cellsize)*cellsize;
originy=m.y;
originy=Math.floor(m.y/cellsize)*cellsize;
sparseness=0d;
height=(int)Math.round(m.height/cellsize);
width=(int)Math.round(m.width/cellsize);
sparse=true;
scells=new Hashtable();
cells=new double[1];
}
/**
* read in an arc/info ascii grid file
* @param name the name of the file to read from
* @exception IOException if there are any problems with the file
*/
public Raster(String name) throws java.io.IOException { // this is broken - originx and origin y are probably wrong!!!
String tok;
int type,n;
double val,left,bot,size;
InputStream in = new FileInputStream(name);
Reader r = new BufferedReader(new InputStreamReader(in));
StreamTokenizer st = new StreamTokenizer(r);
st.parseNumbers();
st.wordChars('_','_');
st.eolIsSignificant(false);
st.lowerCaseMode(true);
// get ncols
type=st.nextToken();
type=st.nextToken();
width=(int)st.nval;
// get nrows
type=st.nextToken();
type=st.nextToken();
height=(int)st.nval;
// get xllcorner
type=st.nextToken();
type=st.nextToken();
originx=st.nval;
// get yllcorner
type=st.nextToken();
type=st.nextToken();
originy=st.nval;
// get cellsize
type=st.nextToken();
type=st.nextToken();
cellsize=st.nval;
// try to get nodata - its optional!
type=st.nextToken();
if(type==StreamTokenizer.TT_NUMBER){
st.pushBack(); // put it back if its a number - thats data
//nodata=0.0d;
nodata=missing;
}else{
type=st.nextToken();
nodata=st.nval;
}
st.ordinaryChars('E','E');
// Set array to store the data;
cells= new double[height*width];
int pt=0;
max=Double.NEGATIVE_INFINITY;
min=Double.POSITIVE_INFINITY;
/*if (DEBUG) {
System.out.println("ncols "+ncols);
System.out.println("nrows "+nrows);
System.out.println("xllcorner "+xllcorner);
System.out.println("yllcorner "+yllcorner);
System.out.println("noDataValue "+noDataValue);
}*/
// Read and write values.
double d1;
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
st.nextToken();
d1=st.nval;
type=st.nextToken();
if (type!=StreamTokenizer.TT_NUMBER && type!=StreamTokenizer.TT_EOF) {
/* Either an exponent term number or end of file marker or something is wrong (eg. grid value is non-numeric)! */
st.nextToken();
d1=d1*Math.pow(10.0,st.nval);
//if (DEBUG) {System.out.println("Exponent!");}
}
else {
st.pushBack();
}
putCell(i,j,d1);
/* see putCell()
if (getCell(i,j)!=nodata) {
min=Math.min(getCell(i,j));
max=Math.max(max,getCell(i,j));
}*/
}
}
//recalc();
if(getSparseness()>50.0d) {
setSparse(true);
}
}
/**
* determine if the geographic coordinate given is on the surface.
* @param x the x location in geographic units
* @param y the y location in geographic units
*/
public final boolean onSurface(double x,double y){
return(x>=originx&&x<originx+(width*cellsize)&&y>=originy&&y<originy+((height)*cellsize));
}
public final boolean onSurface(int row,int col){
return(row>=0&&row<(height)&&col>=0&&col<width);
}
protected final int getCellRow(double y){
// System.out.println("Ra-->h "+(height)+" y "+y+" "+originy+" cell "+cellsize+
//" = "+((((double)(height)*cellsize-y+originy)/cellsize))+
//" = "+((int)Math.round(((double)(height)*cellsize-y+originy)/cellsize)));
return((int)Math.floor(((double)(height)*cellsize-y+originy)/cellsize));
}
protected final int getCellCol(double x){
return((int)Math.floor((x-originx)/cellsize));
}
protected final double getXCell(int col){
return (originx+(double)col*(double)cellsize);
}
protected final double getYCell(int row){
return (originy+((double)((height)-row)*(double)cellsize));
}
/**
* convert a geographic location to a pointer to the array of data
* @param x the x location in geographic units
* @param y the y location in geographic units
* @return position in the array
*/
protected final int getCellPos(double x,double y){
//int row=(int)(((height)*cellsize-y+originy)/cellsize);
//int col=(int)((x-originx)/cellsize);
int row = getCellRow(y);
int col = getCellCol(x);
//if(col<0||col>=width)System.out.println("Ra-->X = "+x+"-> "+col+" w "+width);
//if(row<0||row>=height)System.out.println("Ra-->Y = "+y+"-> "+row+" h "+height);
return getCellID( col, row );
}
/**
* Converts a x/y grid coordinate to a location in the array of data (ID).
* @param xCoord the x coordinate of a gridCell (column)
* @param yCoord the y coordinate of a gridCell (row)
* @return the ID for this grid coordinate
**/
protected final int getCellID( int xCoord, int yCoord ) {
return (yCoord * getWidth()) + xCoord;
}
final public double getTol(){
return TOL;
}
final public void setTol(double t){
TOL=t;
recalc();
}
/**
* @return the minimium value in the raster
*/
final public double getMin(){
return min;
}
final public double getNZMin(){
return nzmin;
}
/**
* @return the maximum value in the raster
*/
final public double getMax(){
return max;
}
/**
* @param row the row required in cells (from the top).
* @param col the column required in cells (from the left).
* @return the value at the row and col of the raster.
*/
final public double getCell(int row,int col){
if(sparse){
in.setValue(row*width+col);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?