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 + -
显示快捷键?