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