/[xulu]/trunk/src/appl/parallel/data/xulugridfile/XuluGridFile.java
ViewVC logotype

Contents of /trunk/src/appl/parallel/data/xulugridfile/XuluGridFile.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 114 - (show annotations)
Mon Jul 11 11:31:25 2011 UTC (13 years, 5 months ago) by mojays
File size: 23811 byte(s)
SCHMITZM library updated to current version (2.6-SNAPSHOT)
Added gt-xsd-filter.jar, gt-xsd-gml2.jar, picocontainer.jar and xsd.jar from Geotools 2.6.5
1 package appl.parallel.data.xulugridfile;
2
3 import java.awt.Rectangle;
4 import java.awt.image.DataBuffer;
5 import java.io.ByteArrayInputStream;
6 import java.io.ByteArrayOutputStream;
7 import java.io.File;
8 import java.io.FileInputStream;
9 import java.io.FileNotFoundException;
10 import java.io.FileOutputStream;
11 import java.io.IOException;
12 import java.io.ObjectInputStream;
13 import java.io.ObjectOutputStream;
14 import java.io.RandomAccessFile;
15
16 import appl.parallel.data.WritableGridArrayPartition;
17 import appl.parallel.spmd.split.SplittableResource;
18 import appl.parallel.spmd.split.WritableGridPartition;
19 import de.appl.util.RasterMetaData;
20 import de.schmitzm.geotools.data.WritableGrid;
21
22 /**
23 * A XuluGridfile is a memory- and 2D-access optimized file format
24 * which can be used for parallel programming. All data is accessed
25 * on disk only (and not loaded into memory).
26 * For this the data is stored in a special uncompressed format.<p/>
27 *
28 * The values are stored line by line in the GridFile. The result is, that
29 * every value is stored at a well known position in the file,
30 * so that the position of the value in the file can be calculated.
31 * Because of this it is not necessary to search the file for a value
32 * of a given coordinate.<br>
33 * If a partition is requested it is possible to read the data directly from
34 * the file.<p/>
35 *
36 * The filename of the XuluGridFile must end with ".xgrid"
37 * The metadata of the gird is stored in a separate file with the same name in
38 * the same directory ending with ".xworld".<p/>
39 *
40 * The XuluGridFile is buffered, it can handle Float, Double and Int values.
41 * To create a XuluGridFile you can use {@link #XuluGridFile(File, RasterMetaData) this} constructor, or
42 * you can convert an existing Grid into the {@link XuluGridFile} format using
43 * the {@link XuluGridFileConverter}.<p/>
44 *
45 * A monitor is used to guarantee that only one XuluGridFile is accessed at a time.
46 * This guarantees a high disk performance.<p/>
47 *
48 * For use in the XuluPlatform you can use the {@link XuluWritableGridFile}, which
49 * implements the {@link WritableGrid} interface.<p/>
50 *
51 *
52 * @author Dominik Appl
53 *
54 */
55 public class XuluGridFile {
56
57 protected RandomAccessFile gridFile = null;
58
59 protected RasterMetaData metaData = null;
60
61 //length of one datavalue in bytes
62 private int dataValueSize = 4;
63
64 //buffer of 256 kb
65 private int buffersize = 262144;
66
67 private final File outputFile;
68
69 //the monitor is used to guarantee that only one XuluGridFile is accessed at a time
70 private static Object monitor = new Object();
71
72 /**
73 * Opens an <b>existing</b> Xulu Grid File. The File must have the ending ".xgrid" and there
74 * must be a xuluGrid world file in the same directory with the ending ".xworld"
75 *
76 * @param file the filename to read from and write to
77 * @param mode the input mode as specified at {@link RandomAccessFile#RandomAccessFile(java.lang.String, java.lang.String)}
78 * <blockquote><table summary="Access mode permitted values and meanings">
79 *<tr><th><p align="left">Value</p></th><th><p align="left">Meaning</p></th></tr>
80 *<tr><td valign="top"><tt>"r"</tt></td>
81 * <td> Open for reading only. Invoking any of the <tt>write</tt>
82 * methods of the resulting object will cause an <A HREF="../../java/io/IOException.html" title="class in java.io"><CODE>IOException</CODE></A> to be thrown. </td></tr>
83 *
84 *<tr><td valign="top"><tt>"rw"</tt></td>
85 * <td> Open for reading and writing. If the file does not already
86 * exist then an attempt will be made to create it. </td></tr>
87 *<tr><td valign="top"><tt>"rws"</tt></td>
88 * <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
89 * require that every update to the file's content or metadata be
90 * written synchronously to the underlying storage device. </td></tr>
91 *<tr><td valign="top"><tt>"rwd"&nbsp;&nbsp;</tt></td>
92 * <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
93 * require that every update to the file's content be written
94 * synchronously to the underlying storage device. </td></tr>
95 *</table></blockquote>
96 *
97 * @throws FileNotFoundException
98 * @see RandomAccessFile
99 * */
100 public XuluGridFile(File file, String mode) throws FileNotFoundException,
101 XuluGridFileException {
102 outputFile = file;
103 checkFileName(file);
104 try {
105 //gridFile = new BufferedRandomAccessFile(file.getAbsolutePath(), mode, buffersize);
106 gridFile = new RandomAccessFile(file.getAbsolutePath(), mode);
107 } catch (IOException e) {
108 // TODO Auto-generated catch block
109 e.printStackTrace();
110 }
111 String worldFileName = file.getAbsolutePath().replaceAll(".xgrid$",
112 ".xworld");
113 this.metaData = readXuluGridWorldFile(new File(worldFileName));
114 }
115
116 /**
117 * Opens an<b> existing</b> gridfile in read/write mode.
118 *
119 * @param file the existing XuluGridFile to be opened
120 * @throws FileNotFoundException
121 * @throws XuluGridFileException
122 */
123 public XuluGridFile(File file) throws FileNotFoundException,
124 XuluGridFileException {
125 this(file, "rw");
126 }
127
128 /**
129 * Creates a <b>NEW</b> File with the sample given as {@link RasterMetaData}
130 * @param targetFile the file the new grid will be written to. <b>Has to end with ".xgrid"!</b>
131 * @param metaData the metadata of the new grid. Width and height are used to allocate the space for the new XGrid.
132 * @throws XuluGridFileException
133 */
134 public XuluGridFile(File targetFile, RasterMetaData metaData)
135 throws XuluGridFileException {
136 outputFile = targetFile;
137 this.metaData = metaData;
138 checkFileName(targetFile);
139 writeWorldFileForMetaData(targetFile, metaData);
140 setByteLength(metaData);
141 try {
142 //gridFile = new BufferedRandomAccessFile(targetFile.getAbsolutePath(), "rw",buffersize );
143 gridFile = new RandomAccessFile(targetFile.getAbsolutePath(), "rw");
144 //allocate space by extending the file
145 gridFile.setLength(metaData.getWidth() * metaData.getHeight()
146 * dataValueSize);
147 } catch (FileNotFoundException e) {
148 // TODO Auto-generated catch block
149 e.printStackTrace();
150 } catch (IOException e) {
151 // TODO Auto-generated catch block
152 e.printStackTrace();
153 }
154
155 }
156
157 /**
158 * Sets the bytelength (4 bytes for float/int, 8 for double)
159 *
160 * @param meta the metadata object of the grid
161 * @throws XuluGridFileException
162 */
163 private void setByteLength(RasterMetaData meta)
164 throws XuluGridFileException {
165 switch (metaData.getDataType()) {
166 case DataBuffer.TYPE_DOUBLE:
167 dataValueSize = 8;
168 break;
169 case DataBuffer.TYPE_FLOAT:
170 case DataBuffer.TYPE_INT:
171 dataValueSize = 4;
172 break;
173 default:
174 throw new XuluGridFileException(
175 "XuluGridFile supports only float,double and int Datatypes!");
176 }
177 }
178
179 /**
180 * Creates a new XuluGridFile out of an existing Writable Grid and opens it in read-write mode. The {@link WritableGrid}-Method
181 * {@link WritableGrid#getSampleType() getSampleType} is used to determine the type and
182 * the bytelength (4 bytes for Float/Int and 8 bytes for doubleValues);
183 * @param grid
184 * @param output
185 * @throws XuluGridFileException
186 */
187 public XuluGridFile(WritableGrid grid, File output)
188 throws XuluGridFileException {
189 this.outputFile = output;
190 //make a new MetaData object out of the grid
191 RasterMetaData metaData = new RasterMetaData(grid);
192
193 setByteLength(metaData);
194
195 //write the metadata file
196 writeWorldFileForMetaData(output, metaData);
197
198 // Write out the GridFile (32Bit and float only until now)
199 // for this go through the Grid line by line upwards
200
201 try {
202 output.createNewFile();
203 gridFile = new BufferedRandomAccessFile(output.getAbsolutePath(),
204 "rw", buffersize);
205
206 for (int y = metaData.getMinY(); y < metaData.getHeight()
207 - metaData.getMinY(); y++)
208 for (int x = metaData.getMinY(); x < metaData.getWidth()
209 - metaData.getMinX(); x++)
210 gridFile.writeFloat(grid.getRasterSampleAsFloat(x, y));
211
212 gridFile.close();
213
214 } catch (FileNotFoundException e) {
215 // TODO Auto-generated catch block
216 e.printStackTrace();
217 } catch (IOException e) {
218 // TODO Auto-generated catch block
219 e.printStackTrace();
220 }
221 }
222
223 /**
224 * Returns a partition of a {@link WritableGrid} as a
225 * {@link WritableGridArray}. Notice, that the minX and minY values are
226 * ignored and will be set to 0 (see {@link WritableGrid} for more
227 * information about minX and minY). If the given {@link WritableGrid} is
228 * not an instance of {@link WritableGridPartition} it is assumed that the
229 * topLeft corner of the source grid is (0,0). If it is a
230 * {@link WritableGridPartition} it is assumed that the the bounds of the
231 * two Partition refer to the same coordinate system. Real coordinates are
232 * supposed to reference the South(!)-West Corner.
233 *
234 * @param partitionBounds
235 * the rectangle describing the partition
236 *
237 * @return the new partition including the given corners
238 * @throws XuluGridFileException
239 * if the reading goes wrong
240 */
241 public WritableGridPartition getPartitialGrid2D(
242 Rectangle partitionBounds) throws XuluGridFileException {
243 synchronized (monitor){
244
245 // get Metadata of the big Grid
246 RasterMetaData bigMeta = this.metaData;
247
248 // create MetaData for the new partitial Grid
249 // Height an width of the partitial Grid
250 int pHeight = (int) partitionBounds.getHeight();
251 int pWidth = (int) partitionBounds.getWidth();
252
253 // real coordinates of the partitial Grid (which are referenced by the
254 // SW Corner)
255 double pX = partitionBounds.getX() * bigMeta.getCellWidth()
256 + bigMeta.getX();
257 double pY = (partitionBounds.getY() + partitionBounds.getHeight() - 1)
258 * bigMeta.getCellHeight() + bigMeta.getY();
259 double pRealWidth = pWidth * bigMeta.getCellWidth();
260 double pRealHeight = pHeight * bigMeta.getCellHeight();
261
262 // the MetaData of the new Grid
263 RasterMetaData pMetaData = new RasterMetaData(bigMeta.getDataType(),
264 pWidth, pHeight, 0, 0, pX, pY, pRealWidth, pRealHeight, bigMeta.getCoordinateReferenceSystem());
265
266 // if the sourceGrid is a partition itself then we do not want to to
267 // start reading from (0,0)
268 // but shifted relative to the global coordinate system. So we calculate
269 // now the start values:
270
271 // for standard WritableGrids these are simply the bounds of the new
272 // partition...
273 int startX = (int) partitionBounds.getX();
274 int startY = (int) partitionBounds.getY();
275
276 try {
277 //seek to starting Position offset (= datavalues until startx)
278 long offset = ((startY) * metaData.getWidth() // number of rows to skip
279 + startX) // number of Colums to skip
280 * dataValueSize; // length of one value in bytes
281 gridFile.seek(offset);
282 //the read-buffer is as wide as the grid (because we read line by line)
283 byte[] buffer = new byte[pWidth * dataValueSize];
284
285 // create empty return Grid
286 WritableGridPartition pGrid;
287
288 //switch structures are a bad smell, but necessary here because of the
289 //implementation of WritableGridArray
290 switch (bigMeta.getDataType()) {
291 case DataBuffer.TYPE_INT:
292 pGrid = new WritableGridArrayPartition.Integer(pMetaData,
293 getRootID(), partitionBounds);
294
295 // read the data into the raster from left to right and upwards
296 for (int y = 0; y < pHeight; y++) {
297 //for buffered reading read first into a bytearray
298 gridFile.read(buffer);
299 ByteArrayInputStream stream = new ByteArrayInputStream(
300 buffer);
301 for (int x = 0; x < pWidth; x++) {
302 int data = BufferedHelper.readIntFromStream(stream);
303 pGrid.setRasterSample(data, x, y);
304 }
305 //seek to the next input position (if not last row)
306 int seek = (metaData.getWidth() - pWidth) * dataValueSize;
307 if (!(y == pHeight - 1))
308 gridFile.skipBytes(seek);
309 }
310 break;
311
312 case DataBuffer.TYPE_DOUBLE:
313 pGrid = new WritableGridArrayPartition.Double(pMetaData,
314 getRootID(), partitionBounds);
315
316 // read the data into the raster from left to right and upwards
317 for (int y = 0; y < pHeight; y++) {
318 //for buffered reading read first into a bytearray
319 gridFile.read(buffer);
320 ByteArrayInputStream stream = new ByteArrayInputStream(
321 buffer);
322
323 for (int x = 0; x < pWidth; x++) {
324 double data = Double.longBitsToDouble(BufferedHelper
325 .readLongFromStream(stream));
326 pGrid.setRasterSample(data, x, y);
327 }
328 //seek to the next input position (if not last row)
329 int seek = (metaData.getWidth() - pWidth) * dataValueSize;
330 if (!(y == pHeight - 1))
331 gridFile.skipBytes(seek);
332 }
333 break;
334
335 case DataBuffer.TYPE_FLOAT:
336 pGrid = new WritableGridArrayPartition.Float(pMetaData,
337 getRootID(), partitionBounds);
338
339 // read the data into the raster from left to right and downwards
340 System.out.print("[getX]");
341 for (int y = 0; y < pHeight; y++) {
342 //for buffered reading read first into a bytearray
343 gridFile.read(buffer);
344 ByteArrayInputStream stream = new ByteArrayInputStream(
345 buffer);
346
347 for (int x = 0; x < pWidth; x++) {
348 float data = Float.intBitsToFloat(BufferedHelper
349 .readIntFromStream(stream));
350 pGrid.setRasterSample(data, x, y);
351 }
352
353 // seek to the next input position (if not last row)
354 int seek = (metaData.getWidth() - pWidth) * dataValueSize;
355 if (!(y == pHeight - 1)) {
356 long currentOffset = gridFile.getFilePointer();
357 if (currentOffset + seek > gridFile.length())
358 System.err.println("Error: offset was "
359 + gridFile.getFilePointer()
360 + " and seek was " + seek
361 + " but file has only " + gridFile.length()
362 + " bytes");
363 gridFile.skipBytes(seek);
364 }
365 }
366 break;
367 default:
368 throw new UnsupportedOperationException("No value found");
369 }
370 return pGrid;
371
372 } catch (IOException e) {
373
374 throw new XuluGridFileException(
375 "IOException while operating on XuluGridFile. Reason was: \n"
376 + e.getCause());
377 }
378 }
379 }
380
381 /**
382 * @return the hashcode of this object
383 * @see SplittableResource#getRootID()
384 */
385 public int getRootID() {
386 return this.hashCode();
387 }
388
389 /**
390 * Overwrites the data at the location specified by the {@link Rectangle} with
391 * the given partition-data. It is assumed that the topLeft corner is (0,0).
392 * The method is synchronized over a static variable to ensure that only
393 * one XuluGridFile is read/write at a time. This reduces (hopefully) harddisk
394 * seek times and increases the overall performance.
395 *
396 * @param gridPartition the grid to be inserted
397 * @param partitionBounds the excact location in coordinates of the baseGrid
398 * @throws XuluGridFileException if the writing goes wrong
399 */
400 public void setPartition(WritableGrid gridPartition,
401 Rectangle partitionBounds) throws XuluGridFileException {
402 synchronized (monitor){
403 //Check if partition and the rectangle fit
404 if ((gridPartition.getWidth() != partitionBounds.getWidth())
405 || (gridPartition.getHeight() != partitionBounds.getHeight()))
406 throw new UnsupportedOperationException(
407 "The partition width/height does not match the rectangle width/height");
408
409 if (this.metaData.getDataType() != gridPartition.getSampleType())
410 throw new UnsupportedOperationException("Datatypes incompatible: "
411 + this.metaData.getDataType() + "!="
412 + gridPartition.getSampleType());
413 //the start coodinates
414 int startX = (int) partitionBounds.getX();
415 int startY = (int) partitionBounds.getY();
416 int pHeight = (int) partitionBounds.getHeight();
417 int pWidth = (int) partitionBounds.getWidth();
418
419 try {
420 // seek to starting Position offset = datavalues until startx
421 long offset = ((startY) * metaData.getWidth() // number of rows to skip
422 + startX) // number of Colums to skip
423 * dataValueSize; // length of one value in bytes
424 gridFile.seek(offset);
425 //the buffer is exactly as wide as the grid
426 ByteArrayOutputStream bos = new ByteArrayOutputStream(dataValueSize
427 * pWidth);
428
429 switch (this.metaData.getDataType()) {
430 case DataBuffer.TYPE_FLOAT:
431 System.out.print("[setX]");
432 for (int y = 0; y < pHeight; y++) {
433 for (int x = 0; x < pWidth; x++) {
434 float data = gridPartition.getRasterSampleAsFloat(x, y);
435 BufferedHelper
436 .writeInt(Float.floatToIntBits(data), bos);
437 }
438 //write buffered bytes to file
439 gridFile.write(bos.toByteArray());
440 //clear the bos
441 bos.reset();
442 // seek to the next input position
443 gridFile.skipBytes((metaData.getWidth() - pWidth)
444 * dataValueSize);
445 }
446 break;
447 case DataBuffer.TYPE_INT:
448 for (int y = 0; y < pHeight; y++) {
449 for (int x = 0; x < pWidth; x++) {
450 int data = gridPartition.getRasterSampleAsInt(x, y);
451 this.gridFile.writeInt(data);
452 }
453 // seek to the next input position
454 gridFile.skipBytes((metaData.getWidth() - pWidth)
455 * dataValueSize);
456 }
457 break;
458 case DataBuffer.TYPE_DOUBLE:
459 for (int y = 0; y < pHeight; y++) {
460 for (int x = 0; x < pWidth; x++) {
461 double data = gridPartition.getRasterSampleAsDouble(x,
462 y);
463 this.gridFile.writeDouble(data);
464 }
465 // seek to the next input position
466 gridFile.skipBytes((metaData.getWidth() - pWidth)
467 * dataValueSize);
468 }
469 }
470
471 } catch (Exception e) {
472 throw new XuluGridFileException(
473 "Error while writing in XuluGridFile");
474 }
475 }
476 }
477
478 /**
479 * Closes all used Filehandles. Should be called before destroying the
480 * object.
481 */
482 public void close() {
483 try {
484 gridFile.close();
485 } catch (IOException e) {
486 // TODO Auto-generated catch block
487 e.printStackTrace();
488 }
489 }
490
491
492 /**
493 * @return the metadata for this object
494 */
495 public RasterMetaData getMetaData() {
496 return metaData;
497 }
498
499 /**
500 * The Xulu world file ist just a serialized RasterMetaData-Object!
501 *
502 * @param worldFile the world file
503 * @return a {@link RasterMetaData} Object, that contains all the raster meta data
504 * @throws XuluGridFileException if an error occures
505 */
506 public RasterMetaData readXuluGridWorldFile(File worldFile)
507 throws XuluGridFileException {
508 try {
509 FileInputStream fis = new FileInputStream(worldFile);
510 ObjectInputStream ois = new ObjectInputStream(fis);
511 RasterMetaData meta = (RasterMetaData) ois.readObject();
512 ois.close();
513 fis.close();
514 return meta;
515
516 } catch (IOException e) {
517 throw new XuluGridFileException(
518 "IOException while reading Worldfile"
519 + worldFile.toString());
520 } catch (ClassNotFoundException e) {
521 throw new XuluGridFileException(
522 "ClassNotFoundException while reading Worldfile"
523 + worldFile.toString());
524 }
525 }
526
527 /**
528 * Writes the given Grid to a XuluGridFile. Warning: unbuffered write.
529 *
530 * @param grid the input grid
531 * @param output the output file
532 * @throws XuluGridFileException if something goes wrong
533 */
534 public static void writeToXuluGridFile(WritableGrid grid, File output)
535 throws XuluGridFileException {
536 RasterMetaData metaData = new RasterMetaData(grid);
537
538 writeWorldFileForMetaData(output, metaData);
539
540 // Write out the GridFile (32Bit and float only until now)
541 // for this go through the Grid line by line upwards
542
543 try {
544 output.createNewFile();
545 RandomAccessFile randomFile = new RandomAccessFile(output, "rw");
546 // fos = new FileOutputStream(output);
547 // BufferedOutputStream bos = new BufferedOutputStream(fos);
548 // ObjectOutputStream oos = new ObjectOutputStream(bos);
549 for (int y = metaData.getMinY(); y < metaData.getHeight()
550 - metaData.getMinY(); y++)
551 for (int x = metaData.getMinY(); x < metaData.getWidth()
552 - metaData.getMinX(); x++)
553 randomFile.writeFloat(grid.getRasterSampleAsFloat(x, y));
554 // oos.close();
555 // bos.close();
556 // fos.close();
557 randomFile.close();
558
559 } catch (FileNotFoundException e) {
560 // TODO Auto-generated catch block
561 e.printStackTrace();
562 } catch (IOException e) {
563 // TODO Auto-generated catch block
564 e.printStackTrace();
565 }
566 }
567
568 /**
569 * Writes data out of a XuluGridFile into a {@link WritableGrid}. Warning: unbuffered. May be slow.
570 * For buffered read use {@link #getWholeGrid()} instead.
571 * @param grid the Grid in which the data should be written
572 * @param input the File with the XuluGridFile
573 *
574 * */
575 public static void readIntoGridFromXuluGridFile(WritableGrid grid,
576 File input) throws XuluGridFileException {
577 synchronized (monitor) {
578
579 RasterMetaData metaData = new RasterMetaData(grid);
580
581 // Read from File into the given grid
582
583 try {
584 RandomAccessFile randomFile = new RandomAccessFile(input, "r");
585 for (int y = metaData.getMinY(); y < metaData.getHeight()
586 - metaData.getMinY(); y++)
587 for (int x = metaData.getMinY(); x < metaData.getWidth()
588 - metaData.getMinX(); x++)
589 grid.setRasterSample(randomFile.readFloat(), x, y);
590
591 } catch (FileNotFoundException e) {
592 // TODO Auto-generated catch block
593 e.printStackTrace();
594 } catch (IOException e) {
595 // TODO Auto-generated catch block
596 e.printStackTrace();
597 }
598 }
599 }
600
601 /**
602 * This File simply serializes the given {@link appl.util.RasterMetaData}
603 * Object to the given file.
604 */
605 public static void writeWorldFileForMetaData(File XuluGridFile,
606 RasterMetaData meta) throws XuluGridFileException {
607 try {
608 File xuluWorldFile = getWorldFileNameForGridFile(XuluGridFile);
609 xuluWorldFile.createNewFile();
610 FileOutputStream fos = new FileOutputStream(xuluWorldFile);
611 ObjectOutputStream oos = new ObjectOutputStream(fos);
612 oos.writeObject(meta);
613 oos.close();
614 fos.close();
615 } catch (FileNotFoundException e) {
616 throw new XuluGridFileException(
617 "Exception while processing WorldFile of XuluGridFile "
618 + XuluGridFile);
619 } catch (IOException e) {
620 throw new XuluGridFileException(
621 "Exception while processing WorldFile of XuluGridFile "
622 + XuluGridFile);
623 }
624 }
625
626
627 /**
628 * Returns a worldfilename. For this the extension xgrid is replaced by xworld
629 */
630 private static File getWorldFileNameForGridFile(File xuluGridFile)
631 throws XuluGridFileException {
632 checkFileName(xuluGridFile);
633 // create worldfilename by exchanging the file extension
634 File worldFile = new File(xuluGridFile.getAbsolutePath().replaceAll(
635 ".xgrid$", ".xworld"));
636 return worldFile;
637 }
638
639 /**
640 * Checks if the given filename is a valid grid file name. To be valid the name must end with .xgrid
641 * @param xuluGridFile the file to be checked
642 * @throws XuluGridFileException if this is not the case
643 *
644 */
645 static void checkFileName(File xuluGridFile) throws XuluGridFileException {
646 if (!xuluGridFile.getAbsolutePath().endsWith(".xgrid"))
647 throw new XuluGridFileException(
648 "XuluGridFiles must have the extension \".xgrid\"");
649
650 }
651
652 /**
653 * gives back the whole grid as a {@link WritableGridArray} in memory! Notice
654 * that this destroys all memory advantages of the GridFile. Is used e.g. by visualisation classes
655 *
656 */
657 public WritableGrid getWholeGrid() throws XuluGridFileException {
658 return getPartitialGrid2D(new Rectangle(0, 0, metaData.getWidth(),
659 metaData.getHeight()));
660 }
661
662 /**
663 * @return the underlying file
664 */
665 public File getOutputFile() {
666 return outputFile;
667 }
668
669 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26