/[xulu]/branches/1.8-gt2-2.6/src/appl/parallel/data/xulugridfile/XuluGridFile.java
ViewVC logotype

Annotation of /branches/1.8-gt2-2.6/src/appl/parallel/data/xulugridfile/XuluGridFile.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 47 - (hide annotations)
Mon Aug 31 14:23:19 2009 UTC (15 years, 3 months ago) by mojays
File size: 23837 byte(s)
Branch 1.8-gt2-2.6 (from rev 45) for geotools 2.6 migration
1 mojays 2 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