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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26