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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 114 - (hide 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 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 appl.parallel.data.WritableGridArrayPartition;
17     import appl.parallel.spmd.split.SplittableResource;
18     import appl.parallel.spmd.split.WritableGridPartition;
19 mojays 114 import de.appl.util.RasterMetaData;
20     import de.schmitzm.geotools.data.WritableGrid;
21 mojays 2
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