1 |
package appl.util; |
2 |
|
3 |
import gtmig.org.geotools.gce.arcgrid.ArcGridRaster; |
4 |
|
5 |
import java.awt.image.DataBuffer; |
6 |
import java.io.File; |
7 |
import java.io.FileInputStream; |
8 |
import java.io.FileNotFoundException; |
9 |
import java.io.IOException; |
10 |
import java.io.InputStreamReader; |
11 |
|
12 |
import org.opengis.referencing.crs.CoordinateReferenceSystem; |
13 |
|
14 |
import schmitzm.data.WritableGrid; |
15 |
import schmitzm.geotools.io.GeoImportUtil; |
16 |
|
17 |
/** |
18 |
* This Class provides some simple mostly independent functions |
19 |
* related to Geo-Rasters and {@link WritableGrid WritableGrids}. |
20 |
* |
21 |
* @author Dominik Appl |
22 |
* |
23 |
*/ |
24 |
|
25 |
public class RasterUtil { |
26 |
|
27 |
/** |
28 |
* Extracts metadata out of a ArcGridASCII File without reading the |
29 |
* whole Grid (only the Header is parsed). |
30 |
* |
31 |
* @param src the ArcInfoASCII file |
32 |
* @return the meta data |
33 |
*/ |
34 |
public static RasterMetaData getRasterMetaData_from_ArcGridASCII_File( |
35 |
File src) { |
36 |
|
37 |
try { |
38 |
ArcGridRaster raster = new ArcGridRaster(new InputStreamReader( |
39 |
new FileInputStream(src)), false); |
40 |
raster.parseHeader(); |
41 |
CoordinateReferenceSystem crs = GeoImportUtil.determineProjection(src); |
42 |
return new RasterMetaData(DataBuffer.TYPE_FLOAT, raster.getNCols(), |
43 |
raster.getNRows(), 0, 0, raster.getXlCorner(), raster |
44 |
.getYlCorner(), raster.getCellSize(),crs); |
45 |
|
46 |
} catch (FileNotFoundException e) { |
47 |
// TODO Auto-generated catch block |
48 |
e.printStackTrace(); |
49 |
} catch (IOException e) { |
50 |
// TODO Auto-generated catch block |
51 |
e.printStackTrace(); |
52 |
} |
53 |
return new RasterMetaData(DataBuffer.TYPE_UNDEFINED, 0, 0, 0, 0, 0, 0, |
54 |
0,null); |
55 |
} |
56 |
|
57 |
/** |
58 |
* Runs through every grid cell and checks if the two Grids are equal (based |
59 |
* on the {@link RasterMetaData} of the first Grid. If the difference is |
60 |
* smaller than 0.0001 only conversion Warning is given. Output to console |
61 |
* may be enabled. Writes out warning to sysout, if metaData is not equal, |
62 |
* but continues checking |
63 |
* |
64 |
* @param a |
65 |
* 1st grid |
66 |
* @param b |
67 |
* 2nd grid |
68 |
* @param outputToConsole |
69 |
* if true the results and some infos are written on System.out |
70 |
* @return true, if the grids match |
71 |
*/ |
72 |
public static boolean checkEqual(WritableGrid a, WritableGrid b, |
73 |
boolean outputToConsole) { |
74 |
|
75 |
if (a == null && b == null) |
76 |
return true; |
77 |
if (a == null || b == null) |
78 |
return false; |
79 |
|
80 |
//for errors which are probably caused by rounding |
81 |
float diffTolerance = 1.0e-5f; |
82 |
float maxdiff = 0; // maximum difference found |
83 |
int maxdiffX = 0, maxdiffY = 0; // coordinates of maxdiff |
84 |
|
85 |
RasterMetaData metaData = new RasterMetaData(a); |
86 |
if (!metaData.equals(new RasterMetaData(b))) { |
87 |
if (outputToConsole) |
88 |
System.out |
89 |
.println("Warning! Metadata of the two Grids is not equal!"); |
90 |
} |
91 |
|
92 |
// run through the whole grid |
93 |
float aValue, bValue; |
94 |
float currentdiff; |
95 |
int counter = 0; |
96 |
for (int y = metaData.getMinY(); y < metaData.getHeight() |
97 |
- metaData.getMinY(); y++) |
98 |
for (int x = metaData.getMinX(); x < metaData.getWidth() |
99 |
- metaData.getMinY(); x++) { |
100 |
counter++; |
101 |
aValue = a.getRasterSampleAsFloat(x, y); |
102 |
bValue = b.getRasterSampleAsFloat(x, y); |
103 |
//check equal |
104 |
if (aValue == bValue) |
105 |
continue; |
106 |
if (Float.isNaN(aValue) && Float.isNaN(bValue)) |
107 |
continue; |
108 |
|
109 |
//check for light differences which might indicate conversionErrors |
110 |
currentdiff = Math.abs(aValue - bValue); |
111 |
if (currentdiff < diffTolerance) { |
112 |
if (currentdiff > maxdiff) { |
113 |
maxdiff = currentdiff; |
114 |
maxdiffX = x; |
115 |
maxdiffY = y; |
116 |
} |
117 |
continue; |
118 |
} |
119 |
// else not equal: |
120 |
if (outputToConsole) |
121 |
System.out |
122 |
.println("Warning: Two Grids were not equal at pos (" |
123 |
+ x |
124 |
+ "," |
125 |
+ y |
126 |
+ ") --- first value " |
127 |
+ a.getRasterSampleAsFloat(x, y) |
128 |
+ " and second value " |
129 |
+ b.getRasterSampleAsFloat(x, y)); |
130 |
return false; |
131 |
} |
132 |
if (outputToConsole && !(maxdiff == 0)) |
133 |
System.out |
134 |
.println("The Gridvalues differ slightly. The maximum Difference is: " |
135 |
+ maxdiff |
136 |
+ " at (" |
137 |
+ maxdiffX |
138 |
+ "," |
139 |
+ maxdiffY |
140 |
+ "). Finished grid compare after " |
141 |
+ counter |
142 |
+ " checks"); |
143 |
else if (outputToConsole) |
144 |
System.out |
145 |
.println("Grids found equal after " + counter + " checks"); |
146 |
return true; |
147 |
} |
148 |
|
149 |
|
150 |
/** |
151 |
* Copies all values from a {@link WritableGrid} into another |
152 |
* {@link WritableGrid}. Of course the grids must have the same dimensions. |
153 |
* |
154 |
* @param src |
155 |
* @param target |
156 |
* @throws UnsupportedOperationException |
157 |
* if the dimensions of the grids does not match or one of the |
158 |
* grids is null |
159 |
*/ |
160 |
public static void copyInto(WritableGrid src, WritableGrid target){ |
161 |
if(src==null || target==null) |
162 |
throw new UnsupportedOperationException("Error: One of the grids was null"); |
163 |
//check if width and height are matching: |
164 |
if((src.getHeight()!=target.getHeight()) || (src.getWidth()!=target.getWidth())) |
165 |
throw new UnsupportedOperationException("The bounds of the two rasters don't not match! Copy failed!"); |
166 |
for(int y=0; y < src.getHeight();y++) |
167 |
for(int x=0; x < src.getWidth(); x++) |
168 |
target.setRasterSample(src.getRasterSample(x,y), x,y); |
169 |
|
170 |
} |
171 |
|
172 |
/** |
173 |
* Prints the grid to the console (useful for testing). |
174 |
* |
175 |
* @param grid the grid to be printed |
176 |
* @param spacing the space to be reserved for one cell-value |
177 |
* @param precision the decimal places to be printed out |
178 |
* @param name the name will be shown in the heading of the output |
179 |
*/ |
180 |
public static void printGrid(WritableGrid grid, int spacing, int precision, String name){ |
181 |
//generate format String |
182 |
System.out.println("****************************** " + name + " ******************************"); |
183 |
int width =grid.getWidth(); |
184 |
int noOfCells = grid.getWidth() * grid.getHeight(); |
185 |
Object[] cellarray = new Object[noOfCells]; |
186 |
StringBuffer buffer = new StringBuffer(noOfCells * 9); |
187 |
String singleCellFormatString = "%" + spacing + "." + precision + "f "; |
188 |
buffer.append("%n "); |
189 |
for(int y=0; y < grid.getHeight();y++){ |
190 |
for(int x=0; x < grid.getWidth(); x++){ |
191 |
buffer.append(singleCellFormatString); |
192 |
cellarray[y*width+x]=grid.getRasterSampleAsFloat(x,y); |
193 |
} |
194 |
buffer.append("%n "); |
195 |
} |
196 |
|
197 |
System.out.printf(buffer.toString(), cellarray); |
198 |
} |
199 |
|
200 |
/** |
201 |
* Prints the grid to the console (useful for testing). |
202 |
* Spacing will be 5 and precision will be 2. |
203 |
* |
204 |
* @param grid the grid to be printed |
205 |
* @param name the name will be shown in the heading of the output |
206 |
*/ |
207 |
public static void printGrid(WritableGrid grid, String name){ |
208 |
printGrid(grid,5,2,name); |
209 |
} |
210 |
|
211 |
/** |
212 |
* Prints the grid to the console (useful for testing). |
213 |
* Spacing will be 5 and precision will be 2. |
214 |
* |
215 |
* @param grid the grid to be printed |
216 |
*/ |
217 |
public static void printGrid(WritableGrid grid){ |
218 |
printGrid(grid," "); |
219 |
} |
220 |
} |