Statistics
| Revision:

gvsig-raster / org.gvsig.raster.netcdf / trunk / org.gvsig.raster.netcdf / org.gvsig.raster.netcdf.io / src / main / java / org / gvsig / raster / netcdf / io / NetCDFProvider.java @ 2891

History | View | Annotate | Download (27.5 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 org.gvsig.raster.netcdf.io;
23

    
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.Point2D;
26
import java.awt.geom.Rectangle2D;
27
import java.io.IOException;
28
import java.util.List;
29

    
30
import org.gvsig.fmap.dal.DALFileLocator;
31
import org.gvsig.fmap.dal.DALLocator;
32
import org.gvsig.fmap.dal.DataStore;
33
import org.gvsig.fmap.dal.coverage.RasterLocator;
34
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
35
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
36
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
37
import org.gvsig.fmap.dal.coverage.exception.BandAccessException;
38
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
39
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
40
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
41
import org.gvsig.fmap.dal.coverage.exception.ParsingException;
42
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
43
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
44
import org.gvsig.fmap.dal.coverage.store.parameter.RasterFileStoreParameters;
45
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
46
import org.gvsig.fmap.dal.exception.OpenException;
47
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
48
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
49
import org.gvsig.metadata.MetadataLocator;
50
import org.gvsig.raster.cache.tile.provider.TileServer;
51
import org.gvsig.raster.impl.DefaultRasterManager;
52
import org.gvsig.raster.impl.buffer.SpiRasterQuery;
53
import org.gvsig.raster.impl.datastruct.DefaultNoData;
54
import org.gvsig.raster.impl.datastruct.ExtentImpl;
55
import org.gvsig.raster.impl.provider.AbstractRasterProvider;
56
import org.gvsig.raster.impl.provider.RasterProvider;
57
import org.gvsig.raster.impl.provider.tile.FileTileServer;
58
import org.gvsig.raster.impl.store.DefaultRasterStore;
59
import org.gvsig.raster.impl.store.DefaultStoreFactory;
60
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
61
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
62
import org.gvsig.tools.ToolsLocator;
63
import org.slf4j.Logger;
64
import org.slf4j.LoggerFactory;
65

    
66
import ucar.ma2.Array;
67
import ucar.ma2.DataType;
68
import ucar.ma2.InvalidRangeException;
69
import ucar.ma2.Range;
70
import ucar.nc2.dt.GridDatatype;
71
import ucar.nc2.dt.grid.GridDataset;
72
import ucar.unidata.geoloc.ProjectionRect;
73
/**
74
 * Data provider for NetCDF files with raster data
75
 *
76
 * @author Nacho Brodin (nachobrodin@gmail.com)
77
 */
78
public class NetCDFProvider extends AbstractRasterProvider {
79
        public static String                     NAME                     = "NetCDF Raster";
80
        public static String                     DESCRIPTION              = "NetCDF Raster file";
81
        public final String                      METADATA_DEFINITION_NAME = NAME;
82
        private Extent                           viewRequest              = null;
83
        private TileServer                       tileServer               = null;
84
        private boolean                          open                     = false;
85
        
86
    private GridDataset                      gridNetCDF               = null;
87
    private List<GridDatatype>               gridList                 = null;
88
    private GridDatatype                     selectedGridDataType     = null;
89
    private DataStoreTransparency            fileTransparency         = null;
90
    private static final Logger              logger                   = LoggerFactory.getLogger(NetCDFProvider.class);
91
    protected static String[]                formatList               = null;
92
    
93
        public static void register() {
94
                DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
95
                RasterLocator.getManager().getProviderServices().registerFileProvidersTiled(NetCDFProvider.class);
96
                registerFormats();
97
                
98
                if (dataman != null && !dataman.getStoreProviders().contains(NAME)) {
99
                        dataman.registerStoreProvider(NAME,
100
                                        NetCDFProvider.class, NetCDFDataParametersImpl.class);
101
                }
102
        
103

    
104
                /*if (!dataman.getExplorerProviders().contains(NetCDFFilesystemServerExplorer.NAME)) {
105
                        dataman.registerExplorerProvider(NetCDFFilesystemServerExplorer.NAME, NetCDFFilesystemServerExplorer.class, NetCDFServerExplorerParameters.class);
106
                }*/
107
                
108
                if(DALFileLocator.getFilesystemServerExplorerManager() != null)
109
                        DALFileLocator.getFilesystemServerExplorerManager().registerProvider(
110
                                        NAME, DESCRIPTION,
111
                                        NetCDFFilesystemServerExplorer.class);
112
                
113
                
114
                dataman.registerStoreFactory(NAME, DefaultStoreFactory.class);
115
        }
116
        
117
        private static void registerFormats() {
118
                formatList      = new String[] {"nc", "nc4"};
119
                for (int i = 0; i < formatList.length; i++) 
120
                        RasterLocator.getManager().getProviderServices().addFormat(formatList[i], NetCDFProvider.class);
121
        }
122
        
123
        public String[] getFormatList() {
124
                return formatList;
125
        }
126
        
127
        /**
128
         * Returns true if the extension is supported and false if doesn't
129
         * @param ext
130
         * @return
131
         */
132
        public boolean isExtensionSupported(String ext) {
133
                if(ext.indexOf(".") != -1)
134
                        ext = ext.substring(ext.lastIndexOf(".") + 1, ext.length());
135
                for (int i = 0; i < formatList.length; i++) {
136
                        if(formatList[i].compareTo(ext) == 0)
137
                                return true;
138
                }
139
                return false;
140
        }
141
        
142
        public NetCDFProvider() {
143
        }
144
        
145
        /**
146
         * Opens the dataset.
147
         * @param proj Projection
148
         * @param fName File name
149
         * @throws NotSupportedExtensionException
150
         */
151
        public NetCDFProvider(String params) throws NotSupportedExtensionException, OpenException {
152
                super(params);
153
                if(params instanceof String) {
154
                        NetCDFDataParameters p = new NetCDFDataParametersImpl();
155
                        p.setURI((String)params);
156
                        super.init(p, null, ToolsLocator.getDynObjectManager()
157
                                        .createDynObject(
158
                                                        MetadataLocator.getMetadataManager().getDefinition(
159
                                                                        DataStore.METADATA_DEFINITION_NAME)));
160
                        init(p, null);
161
                }
162
        }
163
        
164
        public NetCDFProvider (NetCDFDataParameters params,
165
                        DataStoreProviderServices storeServices) throws NotSupportedExtensionException, OpenException {
166
                super(params, storeServices, ToolsLocator.getDynObjectManager()
167
                                .createDynObject(
168
                                                MetadataLocator.getMetadataManager().getDefinition(
169
                                                                DataStore.METADATA_DEFINITION_NAME)));
170
                init(params, storeServices);
171
        }
172

    
173
        /**
174
         * Build file references
175
         * @param proj Projection
176
         * @param param Load parameters
177
         * @throws NotSupportedExtensionException
178
         */
179
        public void init (NetCDFDataParameters params,
180
                        DataStoreProviderServices storeServices) throws NotSupportedExtensionException, OpenException {
181
                
182
                if(((RasterFileStoreParameters)params).getFile().exists()) {
183
                        String fileName = ((RasterFileStoreParameters)params).getFile().getAbsolutePath();
184
            try { 
185
                    gridNetCDF = GridDataset.open(fileName);
186
                    gridList = gridNetCDF.getGrids();
187
                    if(gridList.size() == 0)
188
                            throw new OpenException("There is not a grid variable", null);
189
                    selectedGridDataType = gridList.get(0);
190
                //netCDFFile = NetcdfFile.open(((RasterFileStoreParameters)params).getFile().getAbsolutePath());
191
            } catch (IOException e) {
192
                throw new OpenException("Imposible to read the file", e);
193
            }  
194
            
195
            /*List<Variable> variableList = netCDFFile.getVariables();
196
            Iterator<Variable> it = variableList.iterator();
197
            while(it.hasNext()) {
198
                    Variable var = it.next();
199
                    System.out.println("===>>" + var.getName());
200
            }*/
201
            
202
                        setParam(storeServices, params);
203
                        reloadMetadataFromGrid();
204
                        
205
                        noData = new DefaultNoData(Double.NaN, Double.NaN, fileName);
206
                        load();
207
                } else
208
                        setParam(storeServices, params);
209
                
210
                super.init();
211
                selectSubdataset(getId(0, 0, 0));
212
                try {
213
                        loadFromRmf(getRmfBlocksManager());
214
                } catch (ParsingException e) {
215
                        //No lee desde rmf
216
                }
217
                open = true;
218
        }
219
        
220
        /**
221
         * Reloads metadata using the selected grid
222
         */
223
        private void reloadMetadataFromGrid() {
224
                //wktProjection = null;
225
                //CrsWkt crs = new CrsWkt(wktProjection);
226
                //IProjection proj = CRSFactory.getCRS("EPSG:23030");
227
                
228
                /*LatLonRect gcs = selectedGridDataType.getCoordinateSystem().getLatLonBoundingBox();
229
                getColorInterpretation();
230
                double scaleX = gcs.getWidth() / selectedGridDataType.getXDimension().getLength();
231
                double scaleY = gcs.getHeight() / selectedGridDataType.getYDimension().getLength();
232
                ownTransformation = new AffineTransform(
233
                                scaleX, 0, 
234
                                0, -scaleY, 
235
                                gcs.getLonMin(), 
236
                                gcs.getLatMax());*/
237
                
238
                ProjectionRect pRect = selectedGridDataType.getCoordinateSystem().getBoundingBox();
239
                double scaleX = pRect.getWidth() / selectedGridDataType.getXDimension().getLength();
240
                double scaleY = pRect.getHeight() / selectedGridDataType.getYDimension().getLength();
241
                ownTransformation = new AffineTransform(
242
                                scaleX, 0, 
243
                                0, -scaleY, 
244
                                pRect.getMinX(), 
245
                                pRect.getMaxY());
246
                externalTransformation = (AffineTransform)ownTransformation.clone();
247
                bandCount = 1; //One variable is always shown
248
                setDataType();
249
        }
250
        
251
        /**
252
         * @param dataType The dataType to set.
253
         */
254
        private void setDataType() {
255
                DataType dt = selectedGridDataType.getDataType();
256
                int type = Buffer.TYPE_UNDEFINED;
257
                if(dt.name() == DataType.BYTE.name()) {
258
                        type = Buffer.TYPE_BYTE;
259
                }
260
                if(dt.name() == DataType.SHORT.name()) {
261
                        type = Buffer.TYPE_SHORT;
262
                }
263
                if(dt.name() == DataType.INT.name()) {
264
                        type = Buffer.TYPE_INT;
265
                }
266
                if(dt.name() == DataType.DOUBLE.name()) {
267
                        type = Buffer.TYPE_DOUBLE;
268
                }
269
                if(dt.name() == DataType.FLOAT.name()) {
270
                        type = Buffer.TYPE_FLOAT;
271
                }
272
                if(dt.name() == DataType.LONG.name()) {
273
                        type = Buffer.TYPE_DOUBLE;
274
                }
275
                
276
                int[] dtype = new int[getBandCount()];
277
                for (int i = 0; i < dtype.length; i++)
278
                        dtype[i] = type;
279
                setDataType(dtype);
280
        }
281

    
282
        public RasterProvider load() {
283
                return this;
284
        }
285
        
286
        public boolean isOpen() {
287
                return open;
288
        }
289

    
290
        public void close() {
291
                try {
292
                        gridNetCDF.close();
293
                } catch (IOException e) {
294
                        logger.error("Error closing file", e);
295
                }
296
        }
297

    
298
        public String translateFileName(String fileName) {
299
                return fileName;
300
        }
301

    
302
        /**
303
         * Asigna el extent de la vista actual. existe un fichero .rmf debemos hacer una transformaci�n
304
         * de la vista asignada ya que la petici�n viene en coordenadas del fichero .rmf y la vista (v)
305
         * ha de estar en coordenadas del fichero.
306
         */
307
        public void setView(Extent e) {
308
                viewRequest = new ExtentImpl(e);
309
        }
310

    
311
        public Extent getView() {
312
                return viewRequest;
313
        }
314

    
315
        public double getWidth() {
316
                return selectedGridDataType.getXDimension().getLength();
317
        }
318

    
319
        public double getHeight() {
320
                return selectedGridDataType.getYDimension().getLength();
321
        }
322

    
323
        public Object readBlock(int pos, int blockHeight, double scale)
324
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
325
                NetCDFDataParameters p = (NetCDFDataParameters)param;
326
                if(pos < 0)
327
                        throw new InvalidSetViewException("Request out of grid");
328

    
329
                if((pos + blockHeight) > getHeight())
330
                        blockHeight = Math.abs(((int)getHeight()) - pos);
331
                
332
                Buffer buf = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], (int)getWidth(), blockHeight, 1, true);
333
                try {
334
                        int time = p.getFieldTime();
335
                        int level = getLevelValue();
336
                        Range rangeY = new Range(pos, pos + blockHeight - 1, 1);
337
                        Range rangeX = new Range(0, (int)(getWidth() - 1), 1);
338
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null /*getTime(1), getLevel(1)*/, rangeY, rangeX);
339
                        Array values = dt.readDataSlice(time, level, -1, -1);
340
                        return arrayValuesToBuffer(values, buf, rangeX.length(), rangeY.length(), null);
341
                } catch (IOException e) {
342
                        throw new RasterDriverException("Error reading a slice", e);
343
                } catch (InvalidRangeException e) {
344
                        throw new RasterDriverException("Error reading a slice", e);
345
                }
346
        }
347

    
348
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
349
                NetCDFDataParameters p = (NetCDFDataParameters)param;
350
                if(x < 0 || y < 0 || x >= getWidth() || y >= getHeight())
351
                        throw new InvalidSetViewException("Request out of grid");
352
                try {
353
                        int strideX = 1;
354
                        int strideY = 1;
355
                        Range rangeY = new Range((int)(getHeight() - y), (int)(getHeight() - y), strideY);
356
                        Range rangeX = new Range(x, x, strideX);
357
                        
358
                        selectSubdataset();
359
                        int time = p.getFieldTime();
360
                        int level = getLevelValue();
361
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null, rangeY, rangeX);
362
                        Array values = dt.readDataSlice(time, level, -1, -1);
363
                        Object data = null;
364
                        
365
                        if(getDataType()[0] == Buffer.TYPE_BYTE) {
366
                                data = new java.lang.Integer(values.getByte(0));
367
                        }
368

    
369
                        if(getDataType()[0] == Buffer.TYPE_SHORT) {
370
                                data = new java.lang.Integer(values.getShort(0));
371
                        }
372

    
373
                        if(getDataType()[0] == Buffer.TYPE_INT) {
374
                                data = new java.lang.Integer(values.getInt(0));
375
                        }
376

    
377
                        if(getDataType()[0] == Buffer.TYPE_FLOAT) {
378
                                data = new java.lang.Float(values.getFloat(0));
379
                        }
380
                        if(getDataType()[0] == Buffer.TYPE_DOUBLE) {
381
                                data = new java.lang.Double(values.getDouble(0));
382
                        }
383
                        return data;
384
                } catch (IOException e) {
385
                        throw new RasterDriverException("Error reading a slice", e);
386
                } catch (InvalidRangeException e) {
387
                        throw new RasterDriverException("Error reading a slice", e);
388
                }
389
        }
390
        
391
        @Override
392
        public void loadBuffer(SpiRasterQuery query)
393
                        throws ProcessInterruptedException, RasterDriverException {
394
                NetCDFDataParameters p = (NetCDFDataParameters)param;
395
                setView(query.getAdjustedRequestBoundingBox());
396
                
397
                Point2D ul = new Point2D.Double(viewRequest.getULX(), viewRequest.getULY());
398
                Point2D lr = new Point2D.Double(viewRequest.getLRX(), viewRequest.getLRY());
399
                ul = worldToRaster(ul);
400
                lr = worldToRaster(lr);
401
                ul.setLocation(ul.getX() < 0 ? 0 : ul.getX(), ul.getY() < 0 ? 0 : ul.getY());
402
                lr.setLocation(lr.getX() < 0 ? 0 : lr.getX(), lr.getY() < 0 ? 0 : lr.getY());
403
                ul.setLocation(ul.getX() >= getWidth() ? getWidth() - 1 : ul.getX(), ul.getY() >= getHeight() ? getHeight() - 1 : ul.getY());
404
                lr.setLocation(lr.getX() >= getWidth() ? getWidth() - 1 : lr.getX(), lr.getY() >= getHeight() ? getHeight() - 1 : lr.getY());
405
                
406
                adjustPoints(ul, lr);
407
                
408
                //int width = Math.abs(((int)lr.getX()) - ((int)ul.getX()));
409
                //int height = Math.abs(((int)lr.getY()) - ((int)ul.getY()));
410
                try {
411
                        int strideX = 1;
412
                        int strideY = 1;
413
                        Range rangeY = new Range((int)(getHeight() - lr.getY()), (int)(getHeight() - ul.getY() - 1), strideY <= 0 ? 1 : strideY);
414
                        Range rangeX = new Range((int)ul.getX(), (int)(lr.getX() - 1), strideX <= 0 ? 1 : strideX);
415
                        
416
                        selectSubdataset();
417
                        int time = p.getFieldTime();
418
                        int level = getLevelValue();
419
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null /*getTime(strideX), getLevel(strideX)*/, rangeY, rangeX);
420
                        Array values = dt.readDataSlice(time, level, -1, -1);
421
                        Rectangle2D r = query.getBufferForProviders().getDataExtent();
422
                        Buffer rasterBuf = arrayValuesToBuffer(
423
                                        values, 
424
                                        query.getBufferForProviders(), 
425
                                        rangeX.length(), 
426
                                        rangeY.length(), 
427
                                        query.getBandList());
428
                        rasterBuf.setDataExtent(r);
429
                        query.setBufferResult(rasterBuf);
430
                } catch (IOException e) {
431
                        throw new RasterDriverException("Error reading a slice", e);
432
                } catch (InvalidRangeException e) {
433
                        throw new RasterDriverException("Error reading a slice", e);
434
                }
435
                
436
        }
437

    
438

    
439
        /*public Buffer getWindow(Extent extent, BandList bandList, Buffer rasterBuf, TaskStatus status) 
440
                throws ProcessInterruptedException, RasterDriverException {
441
                NetCDFDataParameters p = (NetCDFDataParameters)param;
442
                setView(extent);
443

444
                Point2D ul = new Point2D.Double(viewRequest.getULX(), viewRequest.getULY());
445
                Point2D lr = new Point2D.Double(viewRequest.getLRX(), viewRequest.getLRY());
446
                ul = worldToRaster(ul);
447
                lr = worldToRaster(lr);
448
                ul.setLocation(ul.getX() < 0 ? 0 : ul.getX(), ul.getY() < 0 ? 0 : ul.getY());
449
                lr.setLocation(lr.getX() < 0 ? 0 : lr.getX(), lr.getY() < 0 ? 0 : lr.getY());
450
                ul.setLocation(ul.getX() > getWidth() ? getWidth() : ul.getX(), ul.getY() > getHeight() ? getHeight() : ul.getY());
451
                lr.setLocation(lr.getX() > getWidth() ? getWidth() : lr.getX(), lr.getY() > getHeight() ? getHeight() : lr.getY());
452
                
453
                adjustPoints(ul, lr);
454
                 
455
                try {
456
                        int strideX = 1;
457
                        int strideY = 1;
458
                        Range rangeY = new Range((int)(getHeight() - lr.getY()), (int)(getHeight() - ul.getY() - 1), strideY);
459
                        Range rangeX = new Range((int)ul.getX(), (int)(lr.getX() - 1), strideX);
460
                        
461
                        selectSubdataset();
462
                        int time = p.getFieldTime();
463
                        int level = getLevelValue();
464
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null , rangeY, rangeX);
465
                        Array values = dt.readDataSlice(time, level, -1, -1);
466
                        rasterBuf = arrayValuesToBuffer(values, rasterBuf, rangeX.length(), rangeY.length(), bandList);
467
                } catch (IOException e) {
468
                        throw new RasterDriverException("Error reading a slice", e);
469
                } catch (InvalidRangeException e) {
470
                        throw new RasterDriverException("Error reading a slice", e);
471
                }
472
                
473
                return rasterBuf;
474
        }*/
475
        
476
        /*public Buffer getWindow(Extent extent, int bufWidth, int bufHeight, 
477
                        BandList bandList, Buffer rasterBuf, boolean adjustToExtent, TaskStatus status) throws ProcessInterruptedException, RasterDriverException {
478
                NetCDFDataParameters p = (NetCDFDataParameters)param;
479
                setView(extent);
480

481
                Point2D ul = new Point2D.Double(viewRequest.getULX(), viewRequest.getULY());
482
                Point2D lr = new Point2D.Double(viewRequest.getLRX(), viewRequest.getLRY());
483
                ul = worldToRaster(ul);
484
                lr = worldToRaster(lr);
485
                ul.setLocation(ul.getX() < 0 ? 0 : ul.getX(), ul.getY() < 0 ? 0 : ul.getY());
486
                lr.setLocation(lr.getX() < 0 ? 0 : lr.getX(), lr.getY() < 0 ? 0 : lr.getY());
487
                ul.setLocation(ul.getX() >= getWidth() ? getWidth() - 1 : ul.getX(), ul.getY() >= getHeight() ? getHeight() - 1 : ul.getY());
488
                lr.setLocation(lr.getX() >= getWidth() ? getWidth() - 1 : lr.getX(), lr.getY() >= getHeight() ? getHeight() - 1 : lr.getY());
489
                
490
                adjustPoints(ul, lr);
491
                
492
                int width = Math.abs(((int)lr.getX()) - ((int)ul.getX()));
493
                int height = Math.abs(((int)lr.getY()) - ((int)ul.getY()));
494
                
495
                try {
496
                        int strideX = width / rasterBuf.getWidth();
497
                        int strideY = height / rasterBuf.getHeight();
498
                        Range rangeY = new Range((int)(getHeight() - lr.getY()), (int)(getHeight() - ul.getY() - 1), strideY <= 0 ? 1 : strideY);
499
                        Range rangeX = new Range((int)ul.getX(), (int)(lr.getX() - 1), strideX <= 0 ? 1 : strideX);
500
                        
501
                        selectSubdataset();
502
                        int time = p.getFieldTime();
503
                        int level = getLevelValue();
504
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null , rangeY, rangeX);
505
                        Array values = dt.readDataSlice(time, level, -1, -1);
506
                        rasterBuf = arrayValuesToBuffer(values, rasterBuf, rangeX.length(), rangeY.length(), bandList);
507
                } catch (IOException e) {
508
                        throw new RasterDriverException("Error reading a slice", e);
509
                } catch (InvalidRangeException e) {
510
                        throw new RasterDriverException("Error reading a slice", e);
511
                }
512
                
513
                return rasterBuf;
514
        }*/
515
        
516
        /*public Buffer getWindow(int x, int y, int w, int h, 
517
                        BandList bandList, Buffer rasterBuf, TaskStatus status) throws ProcessInterruptedException, RasterDriverException {
518
                try {
519
                        NetCDFDataParameters p = (NetCDFDataParameters)param;
520
                        int strideX = 1;
521
                        int strideY = 1;
522
                        Range rangeY = new Range((int)(h - y), (int)(h - y - 1), strideY);
523
                        Range rangeX = new Range((int)x, (int)(x + w - 1), strideX);
524
                        
525
                        selectSubdataset();
526
                        int time = p.getFieldTime();
527
                        int level = getLevelValue();
528
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null, rangeY, rangeX);
529
                        Array values = dt.readDataSlice(time, level, -1, -1);
530
                        rasterBuf = arrayValuesToBuffer(values, rasterBuf, rangeX.length(), rangeY.length(), bandList);
531
                } catch (IOException e) {
532
                        throw new RasterDriverException("Error reading a slice", e);
533
                } catch (InvalidRangeException e) {
534
                        throw new RasterDriverException("Error reading a slice", e);
535
                }
536
                
537
                return rasterBuf;
538
        }*/
539
        
540
        /**
541
         * Gets the Range of the selected time or null if there is not a selected time
542
         * @param strideX
543
         * @return
544
         * @throws InvalidRangeException
545
         */
546
        @SuppressWarnings("unused")
547
        private Range getTime(int strideX) throws InvalidRangeException {
548
                NetCDFDataParameters p = (NetCDFDataParameters)param;
549
                int time = p.getFieldTime();
550
                return new Range(time, time, strideX);
551
        }
552
        
553
        /*private int getTimeValue() {
554
                int time = 0;
555
                if(param.hasDynValue(NetCDFDataParameters.FIELD_TIME))
556
                        time = ((Integer)param.getDynValue(NetCDFDataParameters.FIELD_TIME)).intValue();
557
                return time;
558
        }*/
559
        
560
        /**
561
         * Gets the Range of the selected level or null if there is not a selected level
562
         * @param strideX
563
         * @return
564
         * @throws InvalidRangeException
565
         */
566
        @SuppressWarnings("unused")
567
        private Range getLevel(int strideX) throws InvalidRangeException {
568
                int level = getLevelValue();
569
                return new Range(level, level, strideX);
570
        }
571
        
572
        private int getLevelValue() {
573
                int level = 0;
574
                if(param.hasDynValue(NetCDFDataParameters.FIELD_LEVEL) && param.getDynValue(NetCDFDataParameters.FIELD_LEVEL) != null)
575
                        level = ((Integer)param.getDynValue(NetCDFDataParameters.FIELD_LEVEL)).intValue();
576
                return level;
577
        }
578
        
579
        
580
        /**
581
         * Selects the GridDataType using the selected variable in the parameters
582
         */
583
        public void selectSubdataset() {
584
                if(param.hasDynValue(NetCDFDataParameters.FIELD_VARIABLE)) {
585
                        NetCDFDataParameters p = (NetCDFDataParameters)param;
586
                        String variable = (String)param.getDynValue(NetCDFDataParameters.FIELD_VARIABLE);
587
                        if(variable != null) {
588
                                for (int j = 0; j < gridList.size(); j++) {
589
                                        if(gridList.get(j).getName().compareTo(variable) == 0) {
590
                                                selectedGridDataType = gridList.get(j);
591
                                                reloadMetadataFromGrid();
592
                                                super.selectSubdataset(getId(j, getLevelValue(), p.getFieldTime()));
593
                                        }
594
                                }
595
                        }
596
                }
597
        }
598

    
599
        /**
600
         * Gets the identifier of a subdataset
601
         * @param grid
602
         * @param level
603
         * @param time
604
         * @return
605
         */
606
        private String getId(int grid, int level, int time) {
607
                return grid + "-" + level + "-" +  time;
608
        }
609
        
610
        /**
611
         * Loads a Buffer object from an netCDF Array. 
612
         * @param values
613
         * @param rasterBuf
614
         * @param w
615
         * @param h
616
         * @return
617
         */
618
        private Buffer arrayValuesToBuffer(Array values, Buffer rasterBuf, int w, int h, BandList bandList) {
619
                Buffer buf = null;
620
                boolean resampling = false;
621
                
622
                if((rasterBuf.getWidth() * rasterBuf.getHeight()) != values.getSize()) {
623
                        buf = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], w, h, rasterBuf.getBandCount(), true);
624
                        resampling = true;
625
                } else
626
                        buf = rasterBuf;
627
                
628
                int[] drawableBands = bandList != null ? bandList.getBufferBandToDraw(getURIOfFirstProvider(), 0) : new int[1];
629
                if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
630
                        return rasterBuf;
631
                
632
                if(getDataType()[0] == Buffer.TYPE_BYTE) {
633
                        for (int i = 0; i < values.getSize(); i++) {
634
                                int[] rc = getColAndRow(i, buf);
635
                                for (int iBands = 0; iBands < drawableBands.length; iBands++) 
636
                                        buf.setElem(rc[0], rc[1], drawableBands[iBands], values.getByte(i));
637
                        }
638
                }
639

    
640
                if(getDataType()[0] == Buffer.TYPE_SHORT) {
641
                        for (int i = 0; i < values.getSize(); i++) {
642
                                int[] rc = getColAndRow(i, buf);
643
                                for (int iBands = 0; iBands < drawableBands.length; iBands++) 
644
                                        buf.setElem(rc[0], rc[1], drawableBands[iBands], values.getShort(i));
645
                        }
646
                }
647

    
648
                if(getDataType()[0] == Buffer.TYPE_INT) {
649
                        for (int i = 0; i < values.getSize(); i++) {
650
                                int[] rc = getColAndRow(i, buf);
651
                                for (int iBands = 0; iBands < drawableBands.length; iBands++) 
652
                                        buf.setElem(rc[0], rc[1], drawableBands[iBands], values.getInt(i));
653
                        }
654
                }
655

    
656
                if(getDataType()[0] == Buffer.TYPE_FLOAT) {
657
                        for (int i = 0; i < values.getSize(); i++) {
658
                                int[] rc = getColAndRow(i, buf);
659
                                for (int iBands = 0; iBands < drawableBands.length; iBands++) 
660
                                        buf.setElem(rc[0], rc[1], drawableBands[iBands], values.getFloat(i));
661
                        }
662
                }
663

    
664
                if(getDataType()[0] == Buffer.TYPE_DOUBLE) {
665
                        for (int i = 0; i < values.getSize(); i++) {
666
                                int[] rc = getColAndRow(i, buf);
667
                                for (int iBands = 0; iBands < drawableBands.length; iBands++) 
668
                                        buf.setElem(rc[0], rc[1], drawableBands[iBands], values.getDouble(i));
669
                        }
670
                }
671
                if(resampling) {
672
                        try {
673
                                Buffer result = null;
674
                                result = buf.getAdjustedWindow(rasterBuf.getWidth(), rasterBuf.getHeight(), Buffer.INTERPOLATION_NearestNeighbour);
675
                                if(result != buf)
676
                                        buf.dispose();
677
                                return result;
678
                        } catch (ProcessInterruptedException e) {
679
                                return buf;
680
                        }
681
                }
682
                return buf;
683
        }
684
        
685
        /**
686
         * Calculates the row and column number for the position i in the
687
         * array of data
688
         * @param i
689
         * @param buf
690
         * @return
691
         */
692
        private int[] getColAndRow(int i, Buffer buf) {
693
                int auxRow = (int)(i / buf.getWidth());
694
                return new int[]{ 
695
                                (int)buf.getHeight() - auxRow - 1,
696
                                i - (auxRow * buf.getWidth())
697
                                };
698
        }
699

    
700
        private void adjustPoints(Point2D ul, Point2D lr) {
701
                double a = (ul.getX() - (int)ul.getX());
702
                double b = (ul.getY() - (int)ul.getY());
703
                ul.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(ul.getX()) : ul.getX(), 
704
                                                (b > 0.95 || b < 0.05) ? Math.round(ul.getY()) : ul.getY());
705
                lr.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(lr.getX()) : lr.getX(), 
706
                                                (b > 0.95 || b < 0.05) ? Math.round(lr.getY()) : lr.getY());
707
        }
708

    
709
        public int getBlockSize(){
710
                return 0;
711
        }
712

    
713
        public ColorInterpretation getColorInterpretation() {
714
                if(super.getColorInterpretation() == null) {
715
                        setColorInterpretation(new DataStoreColorInterpretation(new String[]{ColorInterpretation.GRAY_BAND}));
716
                }
717
                return super.getColorInterpretation();
718
        }
719

    
720
        public DataStoreTransparency getTransparency() {
721
                if(fileTransparency == null)
722
                        fileTransparency = new DataStoreTransparency(getColorInterpretation());
723
                return fileTransparency;
724
        }
725

    
726
        /**
727
         * Informa de si el driver ha supersampleado en el �ltimo dibujado. Es el driver el que colocar�
728
         * el valor de esta variable cada vez que dibuja.
729
         * @return true si se ha supersampleado y false si no se ha hecho.
730
         */
731
        public boolean isSupersampling() {
732
                return false;
733
        }
734

    
735
        public void setAffineTransform(AffineTransform t){
736
                super.setAffineTransform(t);
737
        }
738

    
739
        public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
740
                if(band >= getBandCount())
741
                        throw new BandAccessException("Wrong band");
742
                return 0;
743
        }
744

    
745
        public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
746
                if (band >= getBandCount())
747
                        throw new BandAccessException("Wrong band");
748
                return 0;
749
        }
750

    
751
        public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
752
                if (band >= getBandCount())
753
                        throw new BandAccessException("Wrong band");
754
                return 0;
755
        }
756

    
757
        public boolean isOverviewsSupported() {
758
                return true;
759
        }
760

    
761
        public boolean isReproyectable() {
762
                return true;
763
        }
764

    
765
        public String getProviderName() {
766
                return NAME;
767
        }
768
        
769
        public void setStatus(RasterProvider provider) {
770
                if(provider instanceof NetCDFProvider) {
771
                        //Not implemented yet
772
                }
773
        }
774
        
775
        public boolean isTimeSupported() {
776
                return true;
777
        }
778
        
779
        public TileServer getTileServer() {
780
                if(tileServer == null) {
781
                        DefaultRasterStore store = new DefaultRasterStore();
782
                        store.setProvider(this);
783
                        tileServer = new FileTileServer(store);
784
                }
785
                return tileServer;
786
        }
787
}