|
1 |
/*
|
|
2 |
* Created on 18-dic-2004
|
|
3 |
*/
|
|
4 |
package org.cresques.io;
|
|
5 |
|
|
6 |
import java.awt.Image;
|
|
7 |
import java.awt.image.BufferedImage;
|
|
8 |
import java.awt.image.DataBuffer;
|
|
9 |
import java.awt.image.DataBufferByte;
|
|
10 |
import java.awt.image.DataBufferShort;
|
|
11 |
import java.awt.image.DataBufferInt;
|
|
12 |
import java.awt.image.DataBufferFloat;
|
|
13 |
import java.awt.image.DataBufferDouble;
|
|
14 |
import java.io.BufferedReader;
|
|
15 |
import java.io.File;
|
|
16 |
import java.io.FileReader;
|
|
17 |
import java.io.IOException;
|
|
18 |
import java.io.InputStreamReader;
|
|
19 |
import java.io.Reader;
|
|
20 |
import java.util.StringTokenizer;
|
|
21 |
import java.util.zip.ZipEntry;
|
|
22 |
|
|
23 |
import org.cresques.cts.ICoordTrans;
|
|
24 |
import org.cresques.cts.IProjection;
|
|
25 |
import org.cresques.px.Extent;
|
|
26 |
import org.cresques.px.IObjList;
|
|
27 |
|
|
28 |
/**
|
|
29 |
* @author Luis W. Sevilla (sevilla_lui@gva.es)
|
|
30 |
*/
|
|
31 |
public class AscArcGridFile extends GeoRasterFile implements QueryableRaster {
|
|
32 |
public final static byte NODATA_BYTE = Byte.MIN_VALUE;
|
|
33 |
public final static short NODATA_SHORT = Short.MIN_VALUE;
|
|
34 |
public final static int NODATA_INT = Integer.MIN_VALUE;
|
|
35 |
public final static float NODATA_FLOAT = Float.MIN_VALUE;
|
|
36 |
public final static double NODATA_DOUBLE = Double.MIN_VALUE;
|
|
37 |
private String formatName = "AscArcGrid";
|
|
38 |
|
|
39 |
private BufferedReader fi;
|
|
40 |
private String buf = null;
|
|
41 |
private int width = 0, height = 0;
|
|
42 |
private int xCnt = 0, yCnt = 0;
|
|
43 |
private BufferedImage im = null;
|
|
44 |
private double posX, posY, cellSize;
|
|
45 |
|
|
46 |
private Number noData = null;
|
|
47 |
private int dataType = TYPE_UNDEFINED;
|
|
48 |
private DataBuffer data;
|
|
49 |
|
|
50 |
private boolean toCorner = true;
|
|
51 |
|
|
52 |
/**
|
|
53 |
* Lector de ArcGrid ascii.
|
|
54 |
*
|
|
55 |
* @param proj
|
|
56 |
* @param name
|
|
57 |
*/
|
|
58 |
public AscArcGridFile(IProjection proj, String name) {
|
|
59 |
super(proj, name);
|
|
60 |
}
|
|
61 |
|
|
62 |
/* (non-Javadoc)
|
|
63 |
* @see org.cresques.io.GeoFile#load()
|
|
64 |
*/
|
|
65 |
public GeoFile load() {
|
|
66 |
System.out.println(formatName+": Intento de carga de '" + getName() + "'.");
|
|
67 |
long t1, t2;
|
|
68 |
try {
|
|
69 |
if (FileFolder.isUrl(getName())) {
|
|
70 |
ZipFileFolder zFolder = new ZipFileFolder(getName());
|
|
71 |
ZipEntry ze = zFolder.getZipEntry(getName());
|
|
72 |
setFileSize(ze.getSize());
|
|
73 |
|
|
74 |
// El primero calcula el tama?o, el segundo la imagen
|
|
75 |
t1 = getTime();
|
|
76 |
load(new InputStreamReader(zFolder.getInputStream(ze)));
|
|
77 |
t2 = getTime();
|
|
78 |
System.out.println(formatName+": Primer load: " + (t2-t1)/1000 + " seg.");
|
|
79 |
/*t1 = getTime();
|
|
80 |
load(new InputStreamReader(zFolder.getInputStream(ze)));
|
|
81 |
t2 = getTime();
|
|
82 |
System.out.println(formatName+": Segundo load: " + (t2-t1)/1000 + " seg.");*/
|
|
83 |
} else {
|
|
84 |
File f = new File(getName());
|
|
85 |
setFileSize(f.length());
|
|
86 |
|
|
87 |
// El primero calcula el tama?o, el segundo la imagen
|
|
88 |
t1 = getTime();
|
|
89 |
load(new FileReader(getName()));
|
|
90 |
t2 = getTime();
|
|
91 |
System.out.println(formatName+": Primer load: " + (t2-t1)/1000 + " seg.");
|
|
92 |
/*t1 = getTime();
|
|
93 |
load(new FileReader(getName()));
|
|
94 |
t2 = getTime();
|
|
95 |
System.out.println(formatName+": Segundo load: " + (t2-t1)/1000 + " seg.");*/
|
|
96 |
}
|
|
97 |
//v = new Extent(getExtent());
|
|
98 |
return this;
|
|
99 |
} catch (Exception e) {
|
|
100 |
System.err.println(formatName+": ERROR: "+lineCnt+" lineas leidas ("+bytesReaded+"/"+getFileSize()+") bytes.");
|
|
101 |
//if (e instanceof java.lang.ArrayIndexOutOfBoundsException)
|
|
102 |
// System.err.println(" row = "+rowAct+", col ="+colAct);
|
|
103 |
e.printStackTrace();
|
|
104 |
}
|
|
105 |
return this;
|
|
106 |
}
|
|
107 |
|
|
108 |
public GeoFile load(Reader fr) throws IOException {
|
|
109 |
lineCnt = 0;
|
|
110 |
if (im == null){
|
|
111 |
System.out.println(formatName+": Cargando "+getName()+" ...");
|
|
112 |
} else
|
|
113 |
System.out.println(formatName+": Generando imagen ...");
|
|
114 |
fi = new BufferedReader(fr);
|
|
115 |
while ((buf = fi.readLine()) != null) {
|
|
116 |
bytesReaded += buf.length()+1;
|
|
117 |
parseLine(buf);
|
|
118 |
lineCnt++;
|
|
119 |
}
|
|
120 |
fi.close();
|
|
121 |
System.out.println(formatName+": Fichero cargado; "+lineCnt+" l?neas procesadas.\n"+
|
|
122 |
" extent = "+getExtent());
|
|
123 |
return this;
|
|
124 |
}
|
|
125 |
|
|
126 |
public void parseLine(String buf) {
|
|
127 |
//System.out.println("lin "+lineCnt+" Length = "+buf.length());
|
|
128 |
if (lineCnt < 6) {
|
|
129 |
String value = buf.substring(14);
|
|
130 |
if (buf.toLowerCase().startsWith("ncols"))
|
|
131 |
width = Integer.parseInt(value);
|
|
132 |
else if (buf.toLowerCase().startsWith("nrows"))
|
|
133 |
height = Integer.parseInt(value);
|
|
134 |
/* xllcorner e yllcorner se refiere a la esquina
|
|
135 |
* inferior izquierda de la celda inferior izquierda
|
|
136 |
* del raster.
|
|
137 |
* xllcenter e yllcenter se refiere al centro de la
|
|
138 |
* misma celda.
|
|
139 |
*/
|
|
140 |
else if (buf.toLowerCase().startsWith("xllcorner")) {
|
|
141 |
posX = Double.parseDouble(value);
|
|
142 |
toCorner = true;
|
|
143 |
} else if (buf.toLowerCase().startsWith("yllcorner")) {
|
|
144 |
posY = Double.parseDouble(value);
|
|
145 |
toCorner = true;
|
|
146 |
} else if (buf.toLowerCase().startsWith("xllcenter")) {
|
|
147 |
posX = Double.parseDouble(value);
|
|
148 |
toCorner = false;
|
|
149 |
} else if (buf.toLowerCase().startsWith("yllcenter")) {
|
|
150 |
posY = Double.parseDouble(value);
|
|
151 |
toCorner = false;
|
|
152 |
} else if (buf.toLowerCase().startsWith("cellsize")) {
|
|
153 |
cellSize = Double.parseDouble(value);
|
|
154 |
/* TODO WARNING: Este c?lculo solo estar? bien en el hemisferio
|
|
155 |
* norte.
|
|
156 |
*/
|
|
157 |
double x1 = posX, y1 = posY;
|
|
158 |
if (!toCorner) {
|
|
159 |
x1 -= cellSize/2.0; y1 -= cellSize/2.0; }
|
|
160 |
double x2 = x1 + ((double)width)*cellSize,
|
|
161 |
y2 = y1 + ((double) height)*cellSize;
|
|
162 |
extent = new Extent (x1, y2, x2, y1);
|
|
163 |
} else if (buf.startsWith("NODATA_value")) {
|
|
164 |
if (dataType == TYPE_UNDEFINED)
|
|
165 |
dataType = TYPE_FLOAT;
|
|
166 |
switch (dataType) {
|
|
167 |
case TYPE_FLOAT:
|
|
168 |
noData = Float.valueOf(value);
|
|
169 |
data = new DataBufferFloat(width, height);
|
|
170 |
break;
|
|
171 |
case TYPE_DOUBLE:
|
|
172 |
noData = Double.valueOf(value);
|
|
173 |
data = new DataBufferDouble(width, height);
|
|
174 |
break;
|
|
175 |
case TYPE_INT:
|
|
176 |
noData = Integer.valueOf(value);
|
|
177 |
data = new DataBufferInt(width, height);
|
|
178 |
break;
|
|
179 |
case TYPE_BYTE:
|
|
180 |
noData = Byte.valueOf(value);
|
|
181 |
data = new DataBufferByte(width, height);
|
|
182 |
break;
|
|
183 |
case TYPE_SHORT:
|
|
184 |
noData = Short.valueOf(value);
|
|
185 |
data = new DataBufferShort(width, height);
|
|
186 |
break;
|
|
187 |
}
|
|
188 |
}
|
|
189 |
return;
|
|
190 |
}
|
|
191 |
|
|
192 |
StringTokenizer st = new StringTokenizer(buf, " ");
|
|
193 |
xCnt = 0;
|
|
194 |
while (st.hasMoreTokens()) {
|
|
195 |
setData(xCnt, yCnt, st.nextToken());
|
|
196 |
//System.out.print(".");
|
|
197 |
xCnt++;
|
|
198 |
}
|
|
199 |
//System.out.println(yCnt+" ");
|
|
200 |
|
|
201 |
/* int nextIndex=0, lastIndex = 0;
|
|
202 |
String value;
|
|
203 |
xCnt = 0;
|
|
204 |
while (lastIndex < buf.length()) {
|
|
205 |
nextIndex = buf.indexOf(' ', lastIndex);
|
|
206 |
if (nextIndex == -1) nextIndex = buf.length();
|
|
207 |
value = buf.substring(lastIndex, nextIndex);
|
|
208 |
System.out.print(".");
|
|
209 |
setData(xCnt, yCnt, value);
|
|
210 |
lastIndex = nextIndex+1;
|
|
211 |
xCnt++;
|
|
212 |
System.out.println(xCnt+" ");
|
|
213 |
}*/
|
|
214 |
yCnt++;
|
|
215 |
}
|
|
216 |
|
|
217 |
private void setData(int x, int y, String value) {
|
|
218 |
switch (dataType) {
|
|
219 |
case TYPE_BYTE:
|
|
220 |
case TYPE_SHORT:
|
|
221 |
case TYPE_INT:
|
|
222 |
//data.setElem(y, x, Integer.parseInt(value));
|
|
223 |
data.setElem(y, x, (int) Double.parseDouble(value));
|
|
224 |
break;
|
|
225 |
case TYPE_FLOAT:
|
|
226 |
data.setElemFloat(y, x, Float.parseFloat(value));
|
|
227 |
break;
|
|
228 |
case TYPE_DOUBLE:
|
|
229 |
data.setElemDouble(y, x, Double.parseDouble(value));
|
|
230 |
break;
|
|
231 |
}
|
|
232 |
}
|
|
233 |
|
|
234 |
/* (non-Javadoc)
|
|
235 |
* @see org.cresques.io.GeoFile#close()
|
|
236 |
*/
|
|
237 |
public void close() {
|
|
238 |
// TODO Auto-generated method stub
|
|
239 |
|
|
240 |
}
|
|
241 |
|
|
242 |
/* (non-Javadoc)
|
|
243 |
* @see org.cresques.io.GeoFile#getObjects()
|
|
244 |
*/
|
|
245 |
public IObjList getObjects() {
|
|
246 |
// TODO Auto-generated method stub
|
|
247 |
return null;
|
|
248 |
}
|
|
249 |
|
|
250 |
public int getWidth() { return width;}
|
|
251 |
|
|
252 |
public int getHeight() { return height;}
|
|
253 |
|
|
254 |
/* (non-Javadoc)
|
|
255 |
* @see org.cresques.io.GeoRasterFile#setView(org.cresques.px.Extent)
|
|
256 |
*/
|
|
257 |
public void setView(Extent e) {
|
|
258 |
// TODO Auto-generated method stub
|
|
259 |
|
|
260 |
}
|
|
261 |
|
|
262 |
/* (non-Javadoc)
|
|
263 |
* @see org.cresques.io.GeoRasterFile#getView()
|
|
264 |
*/
|
|
265 |
public Extent getView() {
|
|
266 |
// TODO Auto-generated method stub
|
|
267 |
return null;
|
|
268 |
}
|
|
269 |
|
|
270 |
/* (non-Javadoc)
|
|
271 |
* @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans)
|
|
272 |
*/
|
|
273 |
public Image updateImage(int width, int height, ICoordTrans rp) {
|
|
274 |
// TODO Auto-generated method stub
|
|
275 |
return null;
|
|
276 |
}
|
|
277 |
|
|
278 |
public Object getNoData() { return noData; }
|
|
279 |
|
|
280 |
/* (non-Javadoc)
|
|
281 |
* @see org.cresques.io.GeoRasterFile#getData(int, int, int)
|
|
282 |
*/
|
|
283 |
public Object getData(int x, int y, int band) {
|
|
284 |
return getElem(y, x, band);
|
|
285 |
}
|
|
286 |
|
|
287 |
public Object getElem(int x, int y, int band) {
|
|
288 |
switch (dataType) {
|
|
289 |
case TYPE_FLOAT:
|
|
290 |
return new Double(data.getElemFloat(y, x));
|
|
291 |
case TYPE_DOUBLE:
|
|
292 |
return new Double(data.getElemDouble(y, x));
|
|
293 |
}
|
|
294 |
return new Integer(data.getElem(y, x));
|
|
295 |
}
|
|
296 |
|
|
297 |
public int getElemInt(int x, int y, int band) {
|
|
298 |
return data.getElem(y, x);
|
|
299 |
}
|
|
300 |
|
|
301 |
public double getElemDouble(int x, int y, int band) {
|
|
302 |
return data.getElem(y, x);
|
|
303 |
}
|
|
304 |
|
|
305 |
public float getElemFloat(int x, int y, int band) {
|
|
306 |
return data.getElem(y, x);
|
|
307 |
}
|
|
308 |
/* (non-Javadoc)
|
|
309 |
* @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans, java.awt.Image, int)
|
|
310 |
*/
|
|
311 |
public Image updateImage(int width, int height, ICoordTrans rp, Image img, int flags) {
|
|
312 |
// TODO Auto-generated method stub
|
|
313 |
return null;
|
|
314 |
}
|
|
315 |
|
|
316 |
/* (non-Javadoc)
|
|
317 |
* @see org.cresques.geo.Projected#reProject(org.cresques.cts.ICoordTrans)
|
|
318 |
*/
|
|
319 |
public void reProject(ICoordTrans rp) {
|
|
320 |
// TODO Auto-generated method stub
|
|
321 |
|
|
322 |
}
|
|
323 |
|
|
324 |
/* (non-Javadoc)
|
|
325 |
* @see org.cresques.io.QueryableRaster#getDataType()
|
|
326 |
*/
|
|
327 |
public int getDataType() {
|
|
328 |
return dataType;
|
|
329 |
}
|
|
330 |
|
|
331 |
/* (non-Javadoc)
|
|
332 |
* @see org.cresques.io.QueryableRaster#setDataType(int)
|
|
333 |
*/
|
|
334 |
public void setDataType(int dt) {
|
|
335 |
dataType = dt;
|
|
336 |
}
|
|
337 |
|
|
338 |
/* (non-Javadoc)
|
|
339 |
* @see org.cresques.io.QueryableRaster#startQuerying()
|
|
340 |
*/
|
|
341 |
public void startQuerying() {
|
|
342 |
// TODO Auto-generated method stub
|
|
343 |
}
|
|
344 |
|
|
345 |
}
|
0 |
346 |
|