Statistics
| Revision:

root / trunk / extensions / extSextanteGvsigBindings / src / es / unex / sextante / gvsig / core / gvRasterLayer.java @ 34832

History | View | Annotate | Download (14.9 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package es.unex.sextante.gvsig.core;
23

    
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.Rectangle2D;
26
import java.io.BufferedWriter;
27
import java.io.File;
28
import java.io.FileWriter;
29
import java.io.IOException;
30
import java.text.DecimalFormat;
31
import java.text.DecimalFormatSymbols;
32
import java.util.Locale;
33
import java.util.logging.Logger;
34

    
35
import org.cresques.cts.IProjection;
36
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
37
import org.gvsig.raster.buffer.RasterBufferInvalidException;
38
import org.gvsig.raster.buffer.WriterBufferServer;
39
import org.gvsig.raster.dataset.GeoRasterWriter;
40
import org.gvsig.raster.dataset.IBuffer;
41
import org.gvsig.raster.dataset.NotSupportedExtensionException;
42
import org.gvsig.raster.dataset.Params;
43
import org.gvsig.raster.dataset.io.RasterDriverException;
44
import org.gvsig.raster.grid.Grid;
45
import org.gvsig.raster.grid.GridException;
46

    
47
import com.iver.andami.Utilities;
48

    
49
import es.unex.sextante.dataObjects.AbstractRasterLayer;
50
import es.unex.sextante.dataObjects.IRasterLayer;
51
import es.unex.sextante.rasterWrappers.GridExtent;
52

    
53
/**
54
 * {@link IRasterLayer} implementation to be used in gvSIG. Allows to read
55
 * information from a {@link FLyrRasterSE} or to create a new Grid to be
56
 * written.
57
 * 
58
 * @author gvSIG Team
59
 * @version $Id$
60
 */
61
public class gvRasterLayer extends AbstractRasterLayer {
62

    
63
        private IProjection projection = null;
64
        private FLyrRasterSE rasterLayer;
65
        private Grid grid = null;
66
        private int dataType = -1;
67
        /**
68
         * Cached value optimization: the getNoDataValue() method seems to be called
69
         * by sextante for each pixel.
70
         */
71
        private double noDataValue;
72
        /**
73
         * Cached value optimization: the getBandsCount() method seems to be called
74
         * by sextante for each pixel.
75
         */
76
        private int bandsCount;
77

    
78
        private String filename = null;
79
        private String name;
80

    
81
        private GridExtent sextanteExtent;
82

    
83
        private double DEFAULT_NO_DATA_VALUE = -99999.0D;
84

    
85
        public void create(Grid grid, int bandsCount, double noDataValue,
86
                        IProjection projection, String name, String fileName) {
87

    
88
                this.grid = grid;
89
                this.bandsCount = bandsCount;
90
                this.noDataValue = noDataValue;
91
                this.projection = projection;
92
                this.name = name;
93
                this.filename = fileName;
94
                if (grid != null) {
95
                        this.dataType = grid.getDataType();
96
                }
97
        }
98

    
99
        public void create(FLyrRasterSE rasterLayer) {
100

    
101
                Grid grid = createReadOnlyGrid(rasterLayer);
102
                create(grid, rasterLayer.getBandCount(), rasterLayer.getNoDataValue(),
103
                                rasterLayer.getProjection(), rasterLayer.getName(), rasterLayer
104
                                                .getDataSource().getDataset(0)[0].getFName());
105
                this.rasterLayer = rasterLayer;
106
                this.m_BaseDataObject = rasterLayer;
107
        }
108

    
109
        public void create(String sName, String sFilename, GridExtent ge,
110
                        int iDataType, int iNumBands, Object crs) {
111
                
112
                int[] bands = new int[iNumBands];
113
                for (int i = 0; i < bands.length; i++) {
114
                        bands[i] = i;
115
                }
116
                org.gvsig.raster.grid.GridExtent gridExtent = new org.gvsig.raster.grid.GridExtent(
117
                                ge.getXMin(), ge.getYMin(), ge.getXMax(), ge.getYMax(),
118
                                ge.getCellSize());
119
                try {
120
                        grid = new Grid(gridExtent, gridExtent, iDataType, bands);
121
                } catch (RasterBufferInvalidException e) {
122
                        throw new RuntimeException(
123
                                        "Error creating a new empty writable Grid with: GridExtent = "
124
                                                        + gridExtent + ", data type = " + iDataType
125
                                                        + ", bands = " + iNumBands, e);
126
                }
127
                grid.setNoDataValue(DEFAULT_NO_DATA_VALUE);
128

    
129
                IProjection projection = crs instanceof IProjection ? (IProjection) crs
130
                                : null;
131

    
132
                this.sextanteExtent = ge;
133
                create(grid, iNumBands, DEFAULT_NO_DATA_VALUE, projection, sName, sFilename);
134
        }
135

    
136
        public void create(String sName, String sFilename, GridExtent ge,
137
                        int iDataType, Object crs) {
138

    
139
                create(sName, sFilename, ge, iDataType, 1, crs);
140
        }
141

    
142
        public int getDataType() {
143
                return grid.getDataType();
144
        }
145

    
146
        @Override
147
        public void assign(double dValue) {
148
                if (isWritable()) {
149
                        super.assign(dValue);
150
                }
151
        }
152

    
153
        @Override
154
        public void assign(IRasterLayer layer) {
155
                if (isWritable()) {
156
                        super.assign(layer);
157
                }
158
        }
159

    
160
        /**
161
         * If the contained grid is a writable one.
162
         * 
163
         * @return if the contained grid is a writable one
164
         */
165
        private final boolean isWritable() {
166
                return rasterLayer == null;
167
        }
168

    
169
        @Override
170
        public void setNoData(int x, int y) {
171
                if (isWritable()) {
172
                        try {
173
                                grid.setNoData(x, y);
174
                        } catch (InterruptedException e) {
175
                                throw new RuntimeException(
176
                                                "Interrupted while setting to NoData the cell x = " + x
177
                                                                + ", y = " + y, e);
178
                        }
179
                }
180
        }
181

    
182
        public void setNoDataValue(double dNoDataValue) {
183
                grid.setNoDataValue(dNoDataValue);
184
                this.noDataValue = dNoDataValue;
185
        }
186

    
187
        public double getNoDataValue() {
188
                // Safer approach:
189
                // return isWritable() ? noDataValue : rasterLayer.getNoDataValue();
190
                // More efficient approach:
191
                return noDataValue;
192
        }
193

    
194
        public double getCellValueInLayerCoords(int x, int y, int band) {
195

    
196
                IBuffer buffer = grid.getRasterBuf();
197
                try {
198
                        switch (dataType) {
199
                        case IBuffer.TYPE_DOUBLE:
200
                                return buffer.getElemDouble(y, x, band);
201
                        case IBuffer.TYPE_FLOAT:
202
                                return buffer.getElemFloat(y, x, band);
203
                        case IBuffer.TYPE_INT:
204
                                return buffer.getElemInt(y, x, band);
205
                        case IBuffer.TYPE_SHORT:
206
                        case IBuffer.TYPE_USHORT:
207
                                return buffer.getElemShort(y, x, band);
208
                        case IBuffer.TYPE_BYTE:
209
                                return (buffer.getElemByte(y, x, band) & 0xff);
210
                        default:
211
                                return grid.getNoDataValue();
212
                        }
213
                } catch (InterruptedException e) {
214
                        throw new RuntimeException(
215
                                        "Interrupted while getting value of cell x = " + x
216
                                                        + ", y = " + y + ", band = " + band, e);
217
                }
218
        }
219

    
220
        public void setCellValue(int x, int y, int band, double dValue) {
221
                if (isWritable()) {
222
                        IBuffer buffer = grid.getRasterBuf();
223
                        try {
224
                                switch (grid.getDataType()) {
225
                                case IBuffer.TYPE_DOUBLE:
226
                                        buffer.setElem(y, x, band, dValue);
227
                                        break;
228
                                case IBuffer.TYPE_FLOAT:
229
                                        buffer.setElem(y, x, band, (float) dValue);
230
                                        break;
231
                                case IBuffer.TYPE_INT:
232
                                        buffer.setElem(y, x, band, (int) dValue);
233
                                        break;
234
                                case IBuffer.TYPE_SHORT:
235
                                case IBuffer.TYPE_USHORT:
236
                                        buffer.setElem(y, x, band, (short) dValue);
237
                                        break;
238
                                case IBuffer.TYPE_BYTE:
239
                                        buffer.setElem(y, x, band, (byte) dValue);
240
                                        break;
241
                                }
242
                        } catch (InterruptedException e) {
243
                                throw new RuntimeException(
244
                                                "Interrupted while setting value of cell x = " + x
245
                                                                + ", y = " + y + ", band = " + band
246
                                                                + ", value = " + dValue, e);
247
                        }
248
                }
249
        }
250

    
251
        public int getBandsCount() {
252
                return isWritable() ? bandsCount : rasterLayer.getBandCount();
253
        }
254

    
255
        public void fitToGridExtent(GridExtent ge) {
256
                if (isWritable()) {
257
                        int iNX, iNY;
258
                        int x, y;
259
                        int iBand;
260

    
261
                        if (ge != null) {
262
                                if (!ge.equals(getWindowGridExtent())) {
263
                                        if (isWritable()) {
264

    
265
                                                FLyrRasterSE gvSIGLayer = getRasterLayer(
266
                                                                Long.toString(System.currentTimeMillis())
267
                                                                                .toString(), projection);
268
                                                gvRasterLayer orgLayer = new gvRasterLayer();
269
                                                orgLayer.create(gvSIGLayer);
270
                                                orgLayer.setFullExtent();
271

    
272
                                                iNX = ge.getNX();
273
                                                iNY = ge.getNY();
274

    
275
                                                m_BaseDataObject = null;
276

    
277
                                                create(this.getName(), getFilename(), ge,
278
                                                                this.getDataType(), this.getBandsCount());
279
                                                for (iBand = 0; iBand < this.getBandsCount(); iBand++) {
280
                                                        for (y = 0; y < iNY; y++) {
281
                                                                for (x = 0; x < iNX; x++) {
282
                                                                        setCellValue(x, y, iBand,
283
                                                                                        orgLayer.getCellValueAsDouble(x, y,
284
                                                                                                        iBand));
285
                                                                }
286
                                                        }
287
                                                }
288
                                        }
289
                                }
290
                        }
291
                }
292
        }
293

    
294
        public FLyrRasterSE getRasterLayer(String sDescription,
295
                        IProjection projection) {
296

    
297
                FLyrRasterSE layer;
298
                String sFilename = getFilename(sDescription, "tif");
299
                try {
300
                        exportToGeoTiff(sFilename, projection);
301
                        layer = FLyrRasterSE.createLayer(sDescription, new File(sFilename),
302
                                        projection);
303
                        layer.setNoDataValue(this.getNoDataValue());
304
                        return layer;
305
                } catch (Exception e) {
306
                        e.printStackTrace();
307
                        return null;
308
                }
309

    
310
        }
311

    
312
        public static String getFilename(String sRoot, String sExtension) {
313

    
314
                String sFilename;
315
                int i = 1;
316

    
317
                sRoot = sRoot.toLowerCase();
318
                sRoot = sRoot.replaceAll(" ", "_");
319
                sRoot = sRoot.replaceAll("\\)", "");
320
                sRoot = sRoot.replaceAll("\\(", "_");
321
                sRoot = sRoot.replaceAll("\\[", "_");
322
                sRoot = sRoot.replaceAll("\\]", "");
323
                sRoot = sRoot.replaceAll("<", "_");
324
                sRoot = sRoot.replaceAll(">", "_");
325
                sRoot = sRoot.replaceAll("__", "_");
326

    
327
                while (true) {
328
                        sFilename = Utilities.createTempDirectory() + File.separator
329
                                        + sRoot + Integer.toString(i) + "." + sExtension;
330
                        File file = new File(sFilename);
331
                        if (file.exists()) {
332
                                i++;
333
                        } else {
334
                                return sFilename;
335
                        }
336
                }
337

    
338
        }
339

    
340
        public void postProcess() {
341
                if (isWritable()) {
342
                        export(getFilename(), projection);
343
                        FLyrRasterSE rasterLayer = (FLyrRasterSE) FileTools.openLayer(
344
                                        getFilename(), getName(), null);
345
                        create(rasterLayer);
346
                        rasterLayer.setNoDataValue(getNoDataValue());
347
                }
348
        }
349

    
350
        private Grid createReadOnlyGrid(FLyrRasterSE rasterLayer) {
351
                try {
352
                        return rasterLayer.getReadOnlyFullGrid(false);
353
                } catch (GridException e) {
354
                        throw new RuntimeException(
355
                                        "Error getting a read only grid from the FlyrRasterSE: "
356
                                                        + rasterLayer, e);
357
                } catch (InterruptedException e) {
358
                        throw new RuntimeException(
359
                                        "Error getting a read only grid from the FlyrRasterSE: "
360
                                                        + rasterLayer, e);
361
                }
362
        }
363

    
364
        public void open() {
365
                if (!isWritable() && grid == null) {
366
                        this.grid = createReadOnlyGrid(this.rasterLayer);
367
                        this.dataType = grid.getDataType();
368
                }
369
        }
370

    
371
        public void close() {
372
                if (grid != null) {
373
                        grid.getRasterBuf().free();
374
                }
375
                grid = null;
376
                dataType = -1;
377
                // bandsCount = -1;
378
                // projection = null;
379
                // name = null;
380
                // rasterLayer = null;
381
                // m_BaseDataObject = null;
382
                // noDataValue = DEFAULT_NO_DATA_VALUE;
383
                // filename = null;
384
        }
385

    
386
        public Rectangle2D getFullExtent() {
387
                if (isWritable()) {
388
                        return getLayerGridExtent().getAsRectangle2D();
389
                }
390
                else {
391
                        return rasterLayer.getFullExtent();
392
                }
393
        }
394

    
395
        public GridExtent getLayerGridExtent() {
396
                if (isWritable()) {
397
                        return sextanteExtent;
398
                } else {
399
                        final GridExtent extent = new GridExtent();
400
                        extent.setXRange(rasterLayer.getMinX(), rasterLayer.getMaxX());
401
                        extent.setYRange(rasterLayer.getMinY(), rasterLayer.getMaxY());
402
                        extent.setCellSize(rasterLayer.getCellSize());
403
                        return extent;
404
                }
405
        }
406

    
407
        public double getLayerCellSize() {
408
                return grid.getCellSize();
409
        }
410

    
411
        public String getFilename() {
412
                return isWritable() ? filename : rasterLayer.getFileName()[0];
413
        }
414

    
415
        public Object getCRS() {
416
                return isWritable() ? projection : rasterLayer.getProjection();
417
        }
418

    
419
        public String getName() {
420
                return isWritable() ? name : rasterLayer.getName();
421
        }
422

    
423
        public void setName(String name) {
424
                this.name = name;
425
                if (rasterLayer != null) {
426
                        rasterLayer.setName(name);
427
                }
428
        }
429

    
430
        private void export(String sFilename, IProjection projection) {
431

    
432
                if (sFilename.endsWith("asc")) {
433
                        exportToArcInfoASCIIFile(sFilename);
434
                } else {
435
                        exportToGeoTiff(sFilename, projection);
436
                }
437

    
438
        }
439

    
440
        private void exportToArcInfoASCIIFile(String sFilename) {
441

    
442
                try {
443
                        FileWriter f = new FileWriter(sFilename);
444
                        BufferedWriter fout = new BufferedWriter(f);
445
                        DecimalFormat df = new DecimalFormat("##.###");
446
                        df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
447
                        df.setDecimalSeparatorAlwaysShown(true);
448

    
449
                        GridExtent m_GridExtent = getLayerGridExtent();
450

    
451
                        fout.write("ncols " + Integer.toString(m_GridExtent.getNX()));
452
                        fout.newLine();
453
                        fout.write("nrows " + Integer.toString(m_GridExtent.getNY()));
454
                        fout.newLine();
455
                        fout.write("xllcorner " + Double.toString(m_GridExtent.getXMin()));
456
                        fout.newLine();
457
                        fout.write("yllcorner " + Double.toString(m_GridExtent.getYMin()));
458
                        fout.newLine();
459
                        fout.write("cellsize "
460
                                        + Double.toString(m_GridExtent.getCellSize()));
461
                        fout.newLine();
462
                        fout.write("nodata_value " + Double.toString(getNoDataValue()));
463
                        fout.newLine();
464

    
465
                        for (int i = 0; i < m_GridExtent.getNY(); i++) {
466
                                for (int j = 0; j < m_GridExtent.getNX(); j++) {
467
                                        fout.write(df.format(getCellValueAsDouble(j, i)) + " ");
468
                                }
469
                                fout.newLine();
470
                        }
471
                        fout.close();
472
                        f.close();
473
                } catch (IOException e) {
474
                        throw new RuntimeException(
475
                                        "Error exporting the generated raster to the file: "
476
                                                        + sFilename, e);
477
                }
478
        }
479

    
480
        private void exportToGeoTiff(String sFilename, IProjection projection) {
481

    
482
                IBuffer buf = grid.getRasterBuf();
483
                WriterBufferServer writerBufferServer = new WriterBufferServer();
484
                writerBufferServer.setBuffer(buf, -1);
485

    
486
                GridExtent m_GridExtent = getLayerGridExtent();
487
                /*
488
                 * Extent ext = new Extent(m_GridExtent.getAsRectangle2D());
489
                 * ViewPortData vpData = new ViewPortData(projection, ext, new
490
                 * Dimension(m_GridExtent.getNX(),m_GridExtent.getNY()));
491
                 */
492
                try {
493
                        Params params = GeoRasterWriter.getWriter(sFilename).getParams();
494
                        AffineTransform affineTransform = new AffineTransform(
495
                                        m_GridExtent.getCellSize(), 0, 0,
496
                                        -m_GridExtent.getCellSize(), m_GridExtent.getXMin(),
497
                                        m_GridExtent.getYMax());
498
                        GeoRasterWriter writer = GeoRasterWriter
499
                                        .getWriter(writerBufferServer, sFilename,
500
                                                        buf.getBandCount(), affineTransform,
501
                                                        m_GridExtent.getNX(), m_GridExtent.getNY(),
502
                                                        buf.getDataType(), params, projection);
503
                        writer.dataWrite();
504
                        writer.writeClose();
505
                } catch (NotSupportedExtensionException e) {
506
                        throw new RuntimeException(
507
                                        "Error exporting the generated raster to the file: "
508
                                                        + sFilename, e);
509
                } catch (RasterDriverException e) {
510
                        throw new RuntimeException(
511
                                        "Error exporting the generated raster to the file: "
512
                                                        + sFilename, e);
513
                } catch (IOException e) {
514
                        throw new RuntimeException(
515
                                        "Error exporting the generated raster to the file: "
516
                                                        + sFilename, e);
517
                } catch (InterruptedException e) {
518
                        throw new RuntimeException(
519
                                        "Error exporting the generated raster to the file: "
520
                                                        + sFilename, e);
521
                }
522

    
523
        }
524

    
525
}