raster.java
来自「geotools的源码」· Java 代码 · 共 1,460 行 · 第 1/3 页
JAVA
1,460 行
Double v=(Double)scells.get(in);
if(v!=null){
//if(!v.isNaN()){
//if(DEBUG)System.out.println("Ra--><-"+row+" "+col+" "+in+" "+v);
return v.doubleValue();
}else{
//return(0.0d);
//return missing;
return nodata;
}
}else{
return(cells[row*width+col]);
}
}
/**
* @param x location in geographic space
* @param y location in geographic space
* @return the value at (x,y) of the raster or GeoData.MISSING
* @see uk.ac.leeds.ccg.geotools.GeoData
*/
final public double getCell(double x,double y){
if(onSurface(x,y)){
int row=getCellRow(y);
int col=getCellCol(x);
return getCell(row,col);
}else{
//return(0.0d);
//return missing;
return nodata;
}
}
/**
* Adds a value to a cell
* @param row the row required in cells (from the top).
* @param col the column required in cells (from the left).
* @param value the value to be added to the cell
*/
final public double addToCell(int row,int col,double value){
double v=getCell(row,col);
if (v!=missing && v!=nodata) {
if (value!=nodata && value!=missing) {
return putCell(row,col,v+value);
}
else {
// What is in the cell is right already so do nothing!
return v;
}
}
else {
return putCell(row,col,value);
}
/*
// In some cases this is slower than the above. When what is in the cell is
// the correct answer already this still calls the putCell(int,int,double)
// method rather than simply returning the answer that it has already got.
if (v!=missing && v!=nodata) {
if (value!=nodata && value!=missing) {
v+=value;
}
}
else {
v=value;
}
return putCell(row,col,v);
*/
/*if(onSurface(row,col)){
if(sparse){
if(Math.abs(value-0.0d)>TOL){
in.setValue(row*width+col);
Double v=(Double)scells.get(in);
//if(DEBUG)System.out.println("Ra-->+>"+in+" "+value+" ("+v+")");
if(v!=null){
scells.remove(in);
scells.put(in,new Double(v.doubleValue()+value));
min=Math.min(min,v.doubleValue()+value);
nzmin=Math.min(nzmin,v.doubleValue()+value);
max=Math.max(max,v.doubleValue()+value);
}else{
sparseness+=1.0;
scells.put(in,new Double(value));
min=Math.min(min,value);
nzmin=Math.min(nzmin,value);
max=Math.max(max,value);
}
}
}else{
if(Math.abs(value-0.0d)>TOL&&(Math.abs(cells[row*width+col]-0.0d)<TOL))
sparseness+=1.0;
// if there is already a value then adding to it doesn't increment
// the full cell count.
cells[row*width+col]+=value;
min=Math.min(min,cells[row*width+col]);
nzmin=Math.min(nzmin,cells[row*width+col]);
max=Math.max(max,cells[row*width+col]);
}
}*/
}
/**
* Adds a value to a cell
* @param x the x location of the cell
* @param y the y location of the cell
* @param value the value to be added to the cell
*/
final public double addToCell(double x,double y,double value){
int row=getCellRow(y);
int col=getCellCol(x);
return addToCell(row,col,value);
}
/**
* Puts a value in to the cell at row,col of the raster.
* carries out a check to see if the cell is valid and ignores the call
* if it is not.
* @see #onSurface()
*/
final public double putCell(int row,int col,double value){
if(onSurface(row,col)){
if (value!=nodata) {
//!!!Warning min may not be the current minimum value of the Raster.
// (e.g consider the case where the value in row col was the
// unique minimum value in the Raster and it was replaced by a
// higher number.)
//!!!min really stores the minimum value this Raster has ever
// contained!!!
//!!!Warning max may not be the current maximum value of the Raster.
// (e.g consider the case where the value in row col was the
// unique maximum value in the Raster and it was replaced by a
// lower number.)
//!!!max really stores the maximum value this Raster has ever
// contained!!!
//!!!There are various ways around this problem.
min=Math.min(min,value);
max=Math.max(max,value);
}
if(sparse){
in.setValue(row*width+col);
// Remove and correct sparseness if there is a data value there already
if (getCell(row,col)!=nodata) {
scells.remove(in);
sparseness-=1.0d;
}
if (value!=nodata) {
sparseness+=1.0d;
scells.put(in,new Double(value));
}
}
else{
if (value!=nodata) {
sparseness+=1.0d;
}
if (cells[row*width+col]!=nodata) {
sparseness-=1.0d;
}
cells[row*width+col]=value;
}
//recalc();
return value;
}
else{
//if(DEBUG)System.out.println("Ra-->"+row+" "+col+" off surface");
return -1.0d;
}
}
/**
* Puts a value in to the cell at x,y of the raster.
* carries out a check to see if the cell is valid and ignores the call
* if it is not.
* @see #onSurface()
*/
final public double putCell(double x,double y,double value) {
if(onSurface(x,y)) {
int row=getCellRow(y);
int col=getCellCol(x);
return putCell(row,col,value);
}
return -1.0d;
}
public double getMissingValueCode(){
return missing;
}
public void setMissingValueCode(double mv){
missing=mv;
}
public void setNoDataValue(double d) {
nodata=d;
//setMissingValueCode(d);
}
public double getNoDataValue() {
return nodata;
}
/**
* calculate and return the bounding box of the raster.
* @return the bounding box of the raster
*/
public GeoRectangle getBounds(){
GeoRectangle box = new
GeoRectangle(originx,originy,(double)width*(double)cellsize,(double)height*(double)cellsize);
//if(DEBUG)System.out.println("Ra-->Ras "+box);
return(box);
}
/**
* set the bounds of the raster to a new value
* the new bounding box may be larger or smaller as required, if the new
* bounding box is smaller information may be lost if it falls outside
* the new bounding box.
*/
public void setBounds(GeoRectangle m){
XYVData[] data=getXYVData();
//if(DEBUG)System.out.println("Ra-->old "+getBounds());
// set the origin to a round number of cellsizes !!
originx=Math.floor(m.x/cellsize)*cellsize;
//if(DEBUG)System.out.println("Ra-->mx "+m.x+" ox "+originx);
originy=Math.floor(m.y/cellsize)*cellsize;
//if(DEBUG)System.out.println("Ra-->my "+m.y+" oy "+originy);
width=(int)((m.width)/cellsize);
height=(int)((m.height)/cellsize);
//if(DEBUG)System.out.println("Ra-->new "+getBounds());
sparseness=0.0d;
if(sparse) {
scells=new Hashtable();
}else{
cells=new double[width*height];
if(data!=null){
for(int i=0;i<data.length;i++){
putCell(data[i].x,data[i].y,data[i].value);
}
}
}
}
/**
* set originx
*/
public void setOriginX(double d) {
originx=d;
}
/**
* set originy
*/
public void setOriginY(double d) {
originy=d;
}
/**
* @return the cell size of the raster
*/
public double getCellSize(){
return cellsize;
}
/**
* @return the width of the raster in cells
*/
public int getWidth(){
return width;
}
/**
* @return the height of the raster in cells
*/
public int getHeight(){
return height;
}
/**
* @return the origin of the raster in geographic space
*/
public GeoPoint getOrigin(){
GeoPoint p = new GeoPoint(originx,originy);
return(p);
}
/**
* @return the x origin of the raster in geographic space
*/
public double getOriginx(){
return originx;
}
/**
* @return the y origin of the raster in geographic space
*/
public double getOriginy(){
return originy;
}
/**
* @return the name of the raster
*/
public String getName(){
return name;
}
/**
* Sets the name of the raster.
*/
public void setName(String n){
name=n;
}
/**
* gives a value that may be the coresponding cell id
* @param id the cell id
* @return the cell value or a GeoData.MISSING if too high or low.
*/
public double getValue(int id){
if(id>=width*height){
//return missing;
//return 0.0d;
return nodata;
}
if(id<0){
//return missing;
//return 0.0d;
return nodata;
}
if(sparse){
in.setValue(id);
Double v=(Double)scells.get(in);
if(v!=null){
return v.doubleValue();
}else{
//return 0.0d;
//return missing;
return nodata;
}
}else{
return(cells[id]);
}
}
/**
* @return the size of the raster in cells
*/
public int getSize(){
return(height*width);
}
public String getText(int id){
return new Double(getValue(id)).toString();
}
/**
* @return if the raster is stored sparsly
*/
public boolean isSparse(){
return sparse;
}
/**
* change if the raster is to be stored in a sparse form
* @param flag the state to be set.
*/
public void setSparse(boolean flag){
if(flag==sparse) return;
if(flag==true){
switchtosparse();
}else{
switchtofull();
}
}
private void recalc(){
//public void recalc(){
int p=0;
if(sparse){
switchtofull();
if(getSparseness()>50)switchtosparse();
}else{
switchtosparse();
if(getSparseness()<50)switchtofull();
}
}
private void switchtosparse(){
int p=0;
sparseness=0d;
sparse=true;
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
//if(Math.abs(cells[p]-0.0d)>TOL){
//if (cells[p]!=nodata) {
putCell(i,j,cells[p]);
//}
p++;
}
}
cells=new double[1];
System.gc();// we need to free cells
return;
}
private void switchtofull(){
int p=0;
cells=new double[height*width];
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
cells[p++]=getCell(i,j);
}
}
scells = new Hashtable(1);
System.gc();
sparse=false;
return;
}
/**
* Returns the percentage of the raster that is non-zero
*/
public double getSparseness(){
return 100.0d -(sparseness/(width*height)*100.0d);
}
public int getMissingCount(){
return (int)((width*height)-sparseness);
}
/**
* returns a double array containing the data of the raster
* @see #getSize()
*/
public double[] getData(){
double out[]=new double[height*width];
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
out[i*width+j]=getCell(i,j);
}
}
return(out);
}
public void setData(double[] in){
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
//if(DEBUG)System.out.println("Ra-->"+i+" "+j+" "+(i*width+j)+" "+in[i*width+j]);
putCell(i,j,in[i*width+j]);
//if(DEBUG)System.out.println("Ra-->"+in[i*width+j]+" "+getCell(i,j));
}
}
if(getSparseness()>50.0d&&isSparse()==false) {
if(DEBUG)System.out.println("Ra-->Going sparse");
setSparse(true);
}
if(getSparseness()<50.0d&&isSparse()==true) {
if(DEBUG)System.out.println("Ra-->Going full");
setSparse(false);
}
}
/**
* set cellsize
*/
public void setCellSize(double d) {
cellsize=d;
}
/**
* internal class that stores raster data in row column value form
* @see #XYVData
*/
static class RCVData{
int row,col;
double value;
}
/**
* internal class that stores raster data in geographic coordinates value
*/
class XYVData{
double x,y;
double value;
}
/**
* save a raster to the file named in name.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?