1 |
mojays |
2 |
/* |
2 |
|
|
* Geotools2 - OpenSource mapping toolkit |
3 |
|
|
* http://geotools.org |
4 |
|
|
* (C) 2002, Geotools Project Managment Committee (PMC) |
5 |
|
|
* |
6 |
|
|
* This library is free software; you can redistribute it and/or |
7 |
|
|
* modify it under the terms of the GNU Lesser General Public |
8 |
|
|
* License as published by the Free Software Foundation; |
9 |
|
|
* version 2.1 of the License. |
10 |
|
|
* |
11 |
|
|
* This library is distributed in the hope that it will be useful, |
12 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 |
|
|
* Lesser General Public License for more details. |
15 |
|
|
* |
16 |
|
|
*/ |
17 |
|
|
package appl.parallel.data.xulugridfile; |
18 |
|
|
import org.geotools.gce.arcgrid.ArcGridRaster; |
19 |
|
|
import org.geotools.resources.NIOUtilities; |
20 |
|
|
|
21 |
|
|
import appl.util.RasterMetaData; |
22 |
|
|
|
23 |
|
|
import java.awt.image.DataBuffer; |
24 |
|
|
import java.awt.image.Raster; |
25 |
|
|
import java.awt.image.WritableRaster; |
26 |
|
|
import java.io.BufferedReader; |
27 |
|
|
import java.io.ByteArrayOutputStream; |
28 |
|
|
import java.io.File; |
29 |
|
|
import java.io.FileInputStream; |
30 |
|
|
import java.io.FileNotFoundException; |
31 |
|
|
import java.io.IOException; |
32 |
|
|
import java.io.InputStream; |
33 |
|
|
import java.io.InputStreamReader; |
34 |
|
|
import java.io.PrintWriter; |
35 |
|
|
import java.io.RandomAccessFile; |
36 |
|
|
import java.io.Reader; |
37 |
|
|
import java.io.StreamTokenizer; |
38 |
|
|
import java.net.URL; |
39 |
|
|
import java.nio.ByteBuffer; |
40 |
|
|
import java.nio.CharBuffer; |
41 |
|
|
import java.nio.channels.FileChannel; |
42 |
|
|
import java.nio.charset.Charset; |
43 |
|
|
import java.nio.charset.CharsetDecoder; |
44 |
|
|
import javax.media.jai.RasterFactory; |
45 |
|
|
|
46 |
|
|
|
47 |
|
|
/** |
48 |
|
|
* This class converts a ArcGridInfo_ASCII file to a {@link XuluGridFile}. It directly writes from |
49 |
|
|
* the the ArcGridInfo to the given file. It does not use the memory! |
50 |
|
|
* |
51 |
|
|
* It is a modified geotools import class. Buffering was added. |
52 |
|
|
* |
53 |
|
|
* @author Dominik Appl <br> |
54 |
|
|
* For reading this class is based partly on the Geotools class {@link ArcGridRaster}. This was |
55 |
|
|
* done to make sure that EVERY ArcInfoASCII can be read. The used {@link ArcGridRaster} was created by <br> |
56 |
|
|
* @author <a href="mailto:[email protected]">Christiaan ten Klooster</a> |
57 |
|
|
* @author <a href="mailto:[email protected]">Andrea Aime</a> |
58 |
|
|
* @author <a href="mailto:[email protected]">Simone Giannecchini |
59 |
|
|
* (simboss)</a> |
60 |
|
|
* @see XuluGridFile |
61 |
|
|
* @see http://svn.geotools.org/geotools/tags/2.2.0/plugin/arcgrid/src/org/geotools/gce/arcgrid/ArcGridRaster.java |
62 |
|
|
*/ |
63 |
|
|
|
64 |
|
|
public class XuluGridFileConverter extends ArcGridRaster { |
65 |
|
|
|
66 |
|
|
protected final File inputArcInfoGrid; |
67 |
|
|
protected final File outputXuluGridFile; |
68 |
|
|
|
69 |
|
|
/** |
70 |
|
|
* @throws FileNotFoundException |
71 |
|
|
*/ |
72 |
|
|
public XuluGridFileConverter(File inputArcInfoGrid, File outputXuluGridFile) throws FileNotFoundException { |
73 |
|
|
super(new BufferedReader(new InputStreamReader(new FileInputStream(inputArcInfoGrid))), false); |
74 |
|
|
this.inputArcInfoGrid = inputArcInfoGrid; |
75 |
|
|
this.outputXuluGridFile = outputXuluGridFile; |
76 |
|
|
} |
77 |
|
|
|
78 |
|
|
|
79 |
|
|
/** |
80 |
|
|
* partly copied from Geotools. www.geotools.org. |
81 |
|
|
* |
82 |
|
|
* @param type the type of the values. Use the |
83 |
|
|
* {@link DataBuffer} constants to identify the type |
84 |
|
|
* |
85 |
|
|
* @return the new XuluGridFile |
86 |
|
|
* |
87 |
|
|
* @throws IOException |
88 |
|
|
* @throws XuluGridFileException |
89 |
|
|
*/ |
90 |
|
|
public XuluGridFile convertArcInfoToXuluGridFile(int type) throws IOException, XuluGridFileException { |
91 |
|
|
|
92 |
|
|
|
93 |
|
|
|
94 |
|
|
// open reader and make tokenizer |
95 |
|
|
Reader reader = openReader(); |
96 |
|
|
StreamTokenizer st = new StreamTokenizer(reader); |
97 |
|
|
|
98 |
|
|
// parse header |
99 |
|
|
parseHeader(st); |
100 |
|
|
|
101 |
|
|
//create metadata and outputFile |
102 |
|
|
RasterMetaData meta = new RasterMetaData(type,getNCols(),getNRows(),0,0,getXlCorner(),getYlCorner(),getCellSize(),null); |
103 |
|
|
RandomAccessFile outputFile = new RandomAccessFile(outputXuluGridFile,"rw"); |
104 |
|
|
|
105 |
|
|
// reconfigure tokenizer |
106 |
|
|
st.resetSyntax(); |
107 |
|
|
st.parseNumbers(); |
108 |
|
|
st.whitespaceChars(' ', ' '); |
109 |
|
|
st.whitespaceChars(' ', '\t'); |
110 |
|
|
st.whitespaceChars('\n', '\n'); |
111 |
|
|
st.whitespaceChars('\r', '\r'); //linefeed (on windows only?) |
112 |
|
|
st.whitespaceChars('\f', '\f'); //form feed (on printers????) |
113 |
|
|
st.eolIsSignificant(false); |
114 |
|
|
st.ordinaryChars('E', 'E'); |
115 |
|
|
|
116 |
|
|
|
117 |
|
|
|
118 |
|
|
// Read values from grid and put into raster. |
119 |
|
|
// Values must be numbers, which may be simple <num>, or expressed |
120 |
|
|
// in scientific notation <num>E<exp>. |
121 |
|
|
// The following loop can read both, even if mixed. |
122 |
|
|
// The loop expects a token to be read already |
123 |
|
|
st.nextToken(); |
124 |
|
|
|
125 |
|
|
|
126 |
|
|
for (int y = 0; y < getNRows(); y++) { |
127 |
|
|
ByteArrayOutputStream baos; |
128 |
|
|
if(type == DataBuffer.TYPE_DOUBLE) |
129 |
|
|
baos = new ByteArrayOutputStream(getNCols()*8); |
130 |
|
|
else |
131 |
|
|
baos = new ByteArrayOutputStream(getNCols()*4); |
132 |
|
|
|
133 |
|
|
for (int x = 0; x < getNCols(); x++) { |
134 |
|
|
// this call always reads the next token |
135 |
|
|
double d = readCell(st, x, y); |
136 |
|
|
|
137 |
|
|
// mask no data values with NaN |
138 |
|
|
if (d == getNoData()) { |
139 |
|
|
d = Double.NaN; |
140 |
|
|
} else { |
141 |
|
|
minValue = Math.min(minValue, d); |
142 |
|
|
maxValue = Math.max(maxValue, d); |
143 |
|
|
} |
144 |
|
|
switch(type){ |
145 |
|
|
case DataBuffer.TYPE_FLOAT: |
146 |
|
|
BufferedHelper.writeInt(Float.floatToIntBits((float)d),baos); |
147 |
|
|
break; |
148 |
|
|
case DataBuffer.TYPE_DOUBLE: |
149 |
|
|
BufferedHelper.writeLong(Double.doubleToLongBits(d),baos); |
150 |
|
|
case DataBuffer.TYPE_INT: |
151 |
|
|
BufferedHelper.writeInt((int)d,baos); |
152 |
|
|
break; |
153 |
|
|
default: |
154 |
|
|
throw new UnsupportedOperationException("Unsupported datatype"); |
155 |
|
|
} |
156 |
|
|
outputFile.write(baos.toByteArray()); |
157 |
|
|
baos.reset(); |
158 |
|
|
} |
159 |
|
|
} |
160 |
|
|
reader.close(); |
161 |
|
|
try { |
162 |
|
|
XuluGridFile.writeWorldFileForMetaData(outputXuluGridFile, meta); |
163 |
|
|
} catch (XuluGridFileException e) { |
164 |
|
|
throw new IOException ("Could not write WorldFile"); |
165 |
|
|
} |
166 |
|
|
return new XuluGridFile(outputXuluGridFile,"rw"); |
167 |
|
|
} |
168 |
|
|
|
169 |
|
|
/** |
170 |
|
|
*copied unmodified form superclass (had to be copied, because the geotools method was private) |
171 |
|
|
*/ |
172 |
|
|
private double readCell(StreamTokenizer st, int x, int y) |
173 |
|
|
throws IOException { |
174 |
|
|
double d = 0; |
175 |
|
|
|
176 |
|
|
// read a token, expected: a number |
177 |
|
|
switch (st.ttype) { |
178 |
|
|
case StreamTokenizer.TT_NUMBER: |
179 |
|
|
d = (float) st.nval; |
180 |
|
|
|
181 |
|
|
break; |
182 |
|
|
|
183 |
|
|
case StreamTokenizer.TT_EOF: |
184 |
|
|
throw new IOException("Unexpected EOF at " + x + "," + y); |
185 |
|
|
|
186 |
|
|
default: |
187 |
|
|
throw new IOException("Unknown token " + st.ttype); |
188 |
|
|
} |
189 |
|
|
|
190 |
|
|
// read another. May be an exponent of this number. |
191 |
|
|
// If its not an exponent, its the next number. Fall through |
192 |
|
|
// and token is prefetched for next loop... |
193 |
|
|
switch (st.nextToken()) { |
194 |
|
|
case 'e': |
195 |
|
|
case 'E': |
196 |
|
|
|
197 |
|
|
// now read the exponent |
198 |
|
|
st.nextToken(); |
199 |
|
|
|
200 |
|
|
if (st.ttype != StreamTokenizer.TT_NUMBER) { |
201 |
|
|
throw new IOException("Expected exponent at " + x + "," + y); |
202 |
|
|
} |
203 |
|
|
|
204 |
|
|
// calculate |
205 |
|
|
d = d * Math.pow(10.0, st.nval); |
206 |
|
|
|
207 |
|
|
// prefetch for next loop |
208 |
|
|
st.nextToken(); |
209 |
|
|
|
210 |
|
|
break; |
211 |
|
|
|
212 |
|
|
case StreamTokenizer.TT_NUMBER: |
213 |
|
|
case StreamTokenizer.TT_EOF: |
214 |
|
|
break; |
215 |
|
|
|
216 |
|
|
default: |
217 |
|
|
throw new IOException("Expected Number or EOF"); |
218 |
|
|
} |
219 |
|
|
|
220 |
|
|
return d; |
221 |
|
|
} |
222 |
|
|
|
223 |
|
|
/** You can use this method to manually convert datatypes |
224 |
|
|
* @param args |
225 |
|
|
*/ |
226 |
|
|
public static void main(String[] args) { |
227 |
|
|
int type=DataBuffer.TYPE_FLOAT; |
228 |
|
|
if((args.length!=2 && args.length!=3)){ |
229 |
|
|
parameterMessage(); |
230 |
|
|
return; |
231 |
|
|
} |
232 |
|
|
if(!args[1].endsWith(".xgrid")){ |
233 |
|
|
parameterMessage(); |
234 |
|
|
return; |
235 |
|
|
} |
236 |
|
|
if(args.length==3){ |
237 |
|
|
if(args[2].equals("INT")) |
238 |
|
|
type=DataBuffer.TYPE_INT; |
239 |
|
|
if(args[2].equals("DOUBLE")) |
240 |
|
|
type = DataBuffer.TYPE_DOUBLE; |
241 |
|
|
} |
242 |
|
|
XuluGridFileConverter converter; |
243 |
|
|
try { |
244 |
|
|
converter = new XuluGridFileConverter(new File(args[0]),new File(args[1])); |
245 |
|
|
converter.convertArcInfoToXuluGridFile(type); |
246 |
|
|
} catch (FileNotFoundException e) { |
247 |
|
|
System.out.println("Could not find file " + args[0]); |
248 |
|
|
} catch (IOException e) { |
249 |
|
|
System.out.println("IOException while converting: " + e.getMessage()); |
250 |
|
|
} catch (XuluGridFileException e) { |
251 |
|
|
System.out.println("XuluGridFileException while converting: " + e.getMessage()); |
252 |
|
|
} |
253 |
|
|
|
254 |
|
|
|
255 |
|
|
} |
256 |
|
|
public static void parameterMessage(){ |
257 |
|
|
System.out.println("Syntax: XuluGridFileConverter Source Target [type], where \n" + |
258 |
|
|
"Source = a raster in the ArcInfo_ASCII format \n" + |
259 |
|
|
"Target = the new XuluGridFile with the extension .xgrid \n" + |
260 |
|
|
"[type] = (optional) the type of the XuluGridFile. Possible Values: INT,FLOAT,DOUBLE\n" + |
261 |
|
|
" default type is FLOAT"); |
262 |
|
|
} |
263 |
|
|
} |
264 |
|
|
|