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 @ 4181

History | View | Annotate | Download (28.7 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.File;
28
import java.io.IOException;
29
import java.net.URI;
30
import java.net.URISyntaxException;
31
import java.util.List;
32

    
33
import org.slf4j.Logger;
34
import org.slf4j.LoggerFactory;
35

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

    
71
import ucar.ma2.Array;
72
import ucar.ma2.DataType;
73
import ucar.ma2.InvalidRangeException;
74
import ucar.ma2.Range;
75
import ucar.nc2.dt.GridDatatype;
76
import ucar.nc2.dt.grid.GridDataset;
77
import ucar.unidata.geoloc.ProjectionRect;
78
/**
79
 * Data provider for NetCDF files with raster data
80
 *
81
 * @author Nacho Brodin (nachobrodin@gmail.com)
82
 */
83
public class NetCDFProvider extends AbstractRasterProvider {
84
        public static String                     NAME                     = "NetCDF Raster";
85
        public static String                     DESCRIPTION              = "NetCDF Raster file";
86
        public final String                      METADATA_DEFINITION_NAME = NAME;
87
        private Extent                           viewRequest              = null;
88
        private TileServer                       tileServer               = null;
89
        private boolean                          open                     = false;
90

    
91
    private GridDataset                      gridNetCDF               = null;
92
    private List<GridDatatype>               gridList                 = null;
93
    private GridDatatype                     selectedGridDataType     = null;
94
    private DataStoreTransparency            fileTransparency         = null;
95
    private static final Logger              logger                   = LoggerFactory.getLogger(NetCDFProvider.class);
96
    protected static String[]                formatList               = null;
97

    
98
        public static void register() {
99
                DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
100
                RasterLocator.getManager().getProviderServices().registerFileProvidersTiled(NetCDFProvider.class);
101
                registerFormats();
102

    
103
                if (dataman != null && !dataman.getStoreProviders().contains(NAME)) {
104
                        dataman.registerStoreProvider(NAME,
105
                                        NetCDFProvider.class, NetCDFDataParametersImpl.class);
106
                }
107

    
108

    
109
                /*if (!dataman.getExplorerProviders().contains(NetCDFFilesystemServerExplorer.NAME)) {
110
                        dataman.registerExplorerProvider(NetCDFFilesystemServerExplorer.NAME, NetCDFFilesystemServerExplorer.class, NetCDFServerExplorerParameters.class);
111
                }*/
112

    
113
                if(DALFileLocator.getFilesystemServerExplorerManager() != null)
114
                        DALFileLocator.getFilesystemServerExplorerManager().registerProvider(
115
                                        NAME, DESCRIPTION,
116
                                        NetCDFFilesystemServerExplorer.class);
117

    
118

    
119
                dataman.registerStoreFactory(NAME, DefaultStoreFactory.class);
120
        }
121

    
122
        private static void registerFormats() {
123
                formatList      = new String[] {"nc", "nc4"};
124
                for (int i = 0; i < formatList.length; i++)
125
                        RasterLocator.getManager().getProviderServices().addFormat(formatList[i], NetCDFProvider.class);
126
        }
127

    
128
        public String[] getFormatList() {
129
                return formatList;
130
        }
131

    
132
        /**
133
         * Returns true if the extension is supported and false if doesn't
134
         * @param ext
135
         * @return
136
         */
137
        public boolean isExtensionSupported(String ext) {
138
                if(ext.indexOf(".") != -1)
139
                        ext = ext.substring(ext.lastIndexOf(".") + 1, ext.length());
140
                for (int i = 0; i < formatList.length; i++) {
141
                        if(formatList[i].compareTo(ext) == 0)
142
                                return true;
143
                }
144
                return false;
145
        }
146

    
147
        public NetCDFProvider() {
148
        }
149

    
150
        /**
151
         * Opens the dataset.
152
         * @param proj Projection
153
         * @param fName File name
154
         * @throws NotSupportedExtensionException
155
     * @deprecated use {@link #NetCDFProvider(URI)}, this constructor will be removed in gvSIG 2.5
156
         */
157
        public NetCDFProvider(String params) throws NotSupportedExtensionException, OpenException {
158
                super(params);
159
        logger.info("Deprecated use of NetCDFProvider constructor");
160
                if(params instanceof String) {
161
                        NetCDFDataParameters p = new NetCDFDataParametersImpl();
162
                        URI uriObj;
163
            try {
164
                uriObj = new URI((String)params);
165
            } catch (URISyntaxException e) {
166
                throw new OpenException("Can't create URI from "+(String)params, e);
167
            }
168
                        p.setURI(uriObj);
169
                        super.init(p, null, ToolsLocator.getDynObjectManager()
170
                                        .createDynObject(
171
                                                        MetadataLocator.getMetadataManager().getDefinition(
172
                                                                        DataStore.METADATA_DEFINITION_NAME)));
173
                        init(p, null);
174
                }
175
        }
176

    
177
    /**
178
     * Opens the dataset.
179
     * @param proj Projection
180
     * @param fName File name
181
     * @throws NotSupportedExtensionException
182
     */
183
    public NetCDFProvider(URI uri) throws NotSupportedExtensionException, OpenException {
184
        super(uri);
185
        NetCDFDataParameters p = new NetCDFDataParametersImpl();
186
        p.setURI(uri);
187
        super.init(
188
            p,
189
            null,
190
            ToolsLocator.getDynObjectManager().createDynObject(
191
                MetadataLocator.getMetadataManager().getDefinition(DataStore.METADATA_DEFINITION_NAME)));
192
        init(p, null);
193
    }
194

    
195
    public NetCDFProvider (NetCDFDataParameters params,
196
                        DataStoreProviderServices storeServices) throws NotSupportedExtensionException, OpenException {
197
                super(params, storeServices, ToolsLocator.getDynObjectManager()
198
                                .createDynObject(
199
                                                MetadataLocator.getMetadataManager().getDefinition(
200
                                                                DataStore.METADATA_DEFINITION_NAME)));
201
                init(params, storeServices);
202
        }
203

    
204
        /**
205
         * Build file references
206
         * @param proj Projection
207
         * @param param Load parameters
208
         * @throws NotSupportedExtensionException
209
         */
210
        public void init (NetCDFDataParameters params,
211
                        DataStoreProviderServices storeServices) throws NotSupportedExtensionException, OpenException {
212

    
213
                if(((RasterFileStoreParameters)params).getFile().exists()) {
214
                        String fileName = ((RasterFileStoreParameters)params).getFile().getAbsolutePath();
215
            try {
216
                    gridNetCDF = GridDataset.open(fileName);
217
                    gridList = gridNetCDF.getGrids();
218
                    if(gridList.size() == 0)
219
                            throw new OpenException("There is not a grid variable", null);
220
                    selectedGridDataType = gridList.get(0);
221
                //netCDFFile = NetcdfFile.open(((RasterFileStoreParameters)params).getFile().getAbsolutePath());
222
            } catch (IOException e) {
223
                throw new OpenException("Imposible to read the file", e);
224
            }
225

    
226
            /*List<Variable> variableList = netCDFFile.getVariables();
227
            Iterator<Variable> it = variableList.iterator();
228
            while(it.hasNext()) {
229
                    Variable var = it.next();
230
                    System.out.println("===>>" + var.getName());
231
            }*/
232

    
233
                        setParam(storeServices, params);
234
                        reloadMetadataFromGrid();
235

    
236
                        noData = new DefaultNoData(Double.NaN, Double.NaN, fileName);
237
                        load();
238
                } else
239
                        setParam(storeServices, params);
240

    
241
                super.init();
242
                selectSubdataset(getId(0, 0, 0));
243
                try {
244
                        loadFromRmf(getRmfBlocksManager());
245
                } catch (ParsingException e) {
246
                        //No lee desde rmf
247
                }
248
                open = true;
249
        }
250

    
251
        /**
252
         * Reloads metadata using the selected grid
253
         */
254
        private void reloadMetadataFromGrid() {
255
                //wktProjection = null;
256
                //CrsWkt crs = new CrsWkt(wktProjection);
257
                //IProjection proj = CRSFactory.getCRS("EPSG:23030");
258

    
259
                /*LatLonRect gcs = selectedGridDataType.getCoordinateSystem().getLatLonBoundingBox();
260
                getColorInterpretation();
261
                double scaleX = gcs.getWidth() / selectedGridDataType.getXDimension().getLength();
262
                double scaleY = gcs.getHeight() / selectedGridDataType.getYDimension().getLength();
263
                ownTransformation = new AffineTransform(
264
                                scaleX, 0,
265
                                0, -scaleY,
266
                                gcs.getLonMin(),
267
                                gcs.getLatMax());*/
268

    
269
                ProjectionRect pRect = selectedGridDataType.getCoordinateSystem().getBoundingBox();
270
                double scaleX = pRect.getWidth() / selectedGridDataType.getXDimension().getLength();
271
                double scaleY = pRect.getHeight() / selectedGridDataType.getYDimension().getLength();
272
                ownTransformation = new AffineTransform(
273
                                scaleX, 0,
274
                                0, -scaleY,
275
                                pRect.getMinX(),
276
                                pRect.getMaxY());
277
                externalTransformation = (AffineTransform)ownTransformation.clone();
278
                bandCount = 1; //One variable is always shown
279
                setDataType();
280
        }
281

    
282
        /**
283
         * @param dataType The dataType to set.
284
         */
285
        private void setDataType() {
286
                DataType dt = selectedGridDataType.getDataType();
287
                int type = Buffer.TYPE_UNDEFINED;
288
                if(dt.name() == DataType.BYTE.name()) {
289
                        type = Buffer.TYPE_BYTE;
290
                }
291
                if(dt.name() == DataType.SHORT.name()) {
292
                        type = Buffer.TYPE_SHORT;
293
                }
294
                if(dt.name() == DataType.INT.name()) {
295
                        type = Buffer.TYPE_INT;
296
                }
297
                if(dt.name() == DataType.DOUBLE.name()) {
298
                        type = Buffer.TYPE_DOUBLE;
299
                }
300
                if(dt.name() == DataType.FLOAT.name()) {
301
                        type = Buffer.TYPE_FLOAT;
302
                }
303
                if(dt.name() == DataType.LONG.name()) {
304
                        type = Buffer.TYPE_DOUBLE;
305
                }
306

    
307
                int[] dtype = new int[getBandCount()];
308
                for (int i = 0; i < dtype.length; i++)
309
                        dtype[i] = type;
310
                setDataType(dtype);
311
        }
312

    
313
        public RasterProvider load() {
314
                return this;
315
        }
316

    
317
        public boolean isOpen() {
318
                return open;
319
        }
320

    
321
        public void close() {
322
                try {
323
                        gridNetCDF.close();
324
                } catch (IOException e) {
325
                        logger.error("Error closing file", e);
326
                }
327
        }
328

    
329
    public URI translateURI(URI uri) {
330
        return uri;
331
    }
332

    
333
        /**
334
         * Asigna el extent de la vista actual. existe un fichero .rmf debemos hacer una transformaci�n
335
         * de la vista asignada ya que la petici�n viene en coordenadas del fichero .rmf y la vista (v)
336
         * ha de estar en coordenadas del fichero.
337
         */
338
        public void setView(Extent e) {
339
                viewRequest = new ExtentImpl(e);
340
        }
341

    
342
        public Extent getView() {
343
                return viewRequest;
344
        }
345

    
346
        public double getWidth() {
347
                return selectedGridDataType.getXDimension().getLength();
348
        }
349

    
350
        public double getHeight() {
351
                return selectedGridDataType.getYDimension().getLength();
352
        }
353

    
354
        public Object readBlock(int pos, int blockHeight, double scale)
355
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
356
                NetCDFDataParameters p = (NetCDFDataParameters)param;
357
                if(pos < 0)
358
                        throw new InvalidSetViewException("Request out of grid");
359

    
360
                if((pos + blockHeight) > getHeight())
361
                        blockHeight = Math.abs(((int)getHeight()) - pos);
362

    
363
                Buffer buf = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], (int)getWidth(), blockHeight, 1, true);
364
                try {
365
                        int time = p.getFieldTime();
366
                        int level = getLevelValue();
367
                        Range rangeY = new Range(pos, pos + blockHeight - 1, 1);
368
                        Range rangeX = new Range(0, (int)(getWidth() - 1), 1);
369
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null /*getTime(1), getLevel(1)*/, rangeY, rangeX);
370
                        Array values = dt.readDataSlice(time, level, -1, -1);
371
                        return arrayValuesToBuffer(values, buf, rangeX.length(), rangeY.length(), null);
372
                } catch (IOException e) {
373
                        throw new RasterDriverException("Error reading a slice", e);
374
                } catch (InvalidRangeException e) {
375
                        throw new RasterDriverException("Error reading a slice", e);
376
                }
377
        }
378

    
379
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
380
                NetCDFDataParameters p = (NetCDFDataParameters)param;
381
                if(x < 0 || y < 0 || x >= getWidth() || y >= getHeight())
382
                        throw new InvalidSetViewException("Request out of grid");
383
                try {
384
                        int strideX = 1;
385
                        int strideY = 1;
386
                        Range rangeY = new Range((int)(getHeight() - y), (int)(getHeight() - y), strideY);
387
                        Range rangeX = new Range(x, x, strideX);
388

    
389
                        selectSubdataset();
390
                        int time = p.getFieldTime();
391
                        int level = getLevelValue();
392
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null, rangeY, rangeX);
393
                        Array values = dt.readDataSlice(time, level, -1, -1);
394
                        Object data = null;
395

    
396
                        if(getDataType()[0] == Buffer.TYPE_BYTE) {
397
                                data = new java.lang.Integer(values.getByte(0));
398
                        }
399

    
400
                        if(getDataType()[0] == Buffer.TYPE_SHORT) {
401
                                data = new java.lang.Integer(values.getShort(0));
402
                        }
403

    
404
                        if(getDataType()[0] == Buffer.TYPE_INT) {
405
                                data = new java.lang.Integer(values.getInt(0));
406
                        }
407

    
408
                        if(getDataType()[0] == Buffer.TYPE_FLOAT) {
409
                                data = new java.lang.Float(values.getFloat(0));
410
                        }
411
                        if(getDataType()[0] == Buffer.TYPE_DOUBLE) {
412
                                data = new java.lang.Double(values.getDouble(0));
413
                        }
414
                        return data;
415
                } catch (IOException e) {
416
                        throw new RasterDriverException("Error reading a slice", e);
417
                } catch (InvalidRangeException e) {
418
                        throw new RasterDriverException("Error reading a slice", e);
419
                }
420
        }
421

    
422
        @Override
423
        public void loadBuffer(SpiRasterQuery query)
424
                        throws ProcessInterruptedException, RasterDriverException {
425
                NetCDFDataParameters p = (NetCDFDataParameters)param;
426
                setView(query.getAdjustedRequestBoundingBox());
427

    
428
                Point2D ul = new Point2D.Double(viewRequest.getULX(), viewRequest.getULY());
429
                Point2D lr = new Point2D.Double(viewRequest.getLRX(), viewRequest.getLRY());
430
                ul = worldToRaster(ul);
431
                lr = worldToRaster(lr);
432
                ul.setLocation(ul.getX() < 0 ? 0 : ul.getX(), ul.getY() < 0 ? 0 : ul.getY());
433
                lr.setLocation(lr.getX() < 0 ? 0 : lr.getX(), lr.getY() < 0 ? 0 : lr.getY());
434
                ul.setLocation(ul.getX() >= getWidth() ? getWidth() - 1 : ul.getX(), ul.getY() >= getHeight() ? getHeight() - 1 : ul.getY());
435
                lr.setLocation(lr.getX() >= getWidth() ? getWidth() - 1 : lr.getX(), lr.getY() >= getHeight() ? getHeight() - 1 : lr.getY());
436

    
437
                adjustPoints(ul, lr);
438

    
439
                //int width = Math.abs(((int)lr.getX()) - ((int)ul.getX()));
440
                //int height = Math.abs(((int)lr.getY()) - ((int)ul.getY()));
441
                try {
442
                        int strideX = 1;
443
                        int strideY = 1;
444
                        Range rangeY = new Range((int)(getHeight() - lr.getY()), (int)(getHeight() - ul.getY() - 1), strideY <= 0 ? 1 : strideY);
445
                        Range rangeX = new Range((int)ul.getX(), (int)(lr.getX() - 1), strideX <= 0 ? 1 : strideX);
446

    
447
                        selectSubdataset();
448
                        int time = p.getFieldTime();
449
                        int level = getLevelValue();
450
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null /*getTime(strideX), getLevel(strideX)*/, rangeY, rangeX);
451
                        Array values = dt.readDataSlice(time, level, -1, -1);
452
                        Rectangle2D r = query.getBufferForProviders().getDataExtent();
453
                        Buffer rasterBuf = arrayValuesToBuffer(
454
                                        values,
455
                                        query.getBufferForProviders(),
456
                                        rangeX.length(),
457
                                        rangeY.length(),
458
                                        query.getBandList());
459
                        rasterBuf.setDataExtent(r);
460
                        query.setBufferResult(rasterBuf);
461
                } catch (IOException e) {
462
                        throw new RasterDriverException("Error reading a slice", e);
463
                } catch (InvalidRangeException e) {
464
                        throw new RasterDriverException("Error reading a slice", e);
465
                }
466

    
467
        }
468

    
469

    
470
        /*public Buffer getWindow(Extent extent, BandList bandList, Buffer rasterBuf, TaskStatus status)
471
                throws ProcessInterruptedException, RasterDriverException {
472
                NetCDFDataParameters p = (NetCDFDataParameters)param;
473
                setView(extent);
474

475
                Point2D ul = new Point2D.Double(viewRequest.getULX(), viewRequest.getULY());
476
                Point2D lr = new Point2D.Double(viewRequest.getLRX(), viewRequest.getLRY());
477
                ul = worldToRaster(ul);
478
                lr = worldToRaster(lr);
479
                ul.setLocation(ul.getX() < 0 ? 0 : ul.getX(), ul.getY() < 0 ? 0 : ul.getY());
480
                lr.setLocation(lr.getX() < 0 ? 0 : lr.getX(), lr.getY() < 0 ? 0 : lr.getY());
481
                ul.setLocation(ul.getX() > getWidth() ? getWidth() : ul.getX(), ul.getY() > getHeight() ? getHeight() : ul.getY());
482
                lr.setLocation(lr.getX() > getWidth() ? getWidth() : lr.getX(), lr.getY() > getHeight() ? getHeight() : lr.getY());
483

484
                adjustPoints(ul, lr);
485

486
                try {
487
                        int strideX = 1;
488
                        int strideY = 1;
489
                        Range rangeY = new Range((int)(getHeight() - lr.getY()), (int)(getHeight() - ul.getY() - 1), strideY);
490
                        Range rangeX = new Range((int)ul.getX(), (int)(lr.getX() - 1), strideX);
491

492
                        selectSubdataset();
493
                        int time = p.getFieldTime();
494
                        int level = getLevelValue();
495
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null , rangeY, rangeX);
496
                        Array values = dt.readDataSlice(time, level, -1, -1);
497
                        rasterBuf = arrayValuesToBuffer(values, rasterBuf, rangeX.length(), rangeY.length(), bandList);
498
                } catch (IOException e) {
499
                        throw new RasterDriverException("Error reading a slice", e);
500
                } catch (InvalidRangeException e) {
501
                        throw new RasterDriverException("Error reading a slice", e);
502
                }
503

504
                return rasterBuf;
505
        }*/
506

    
507
        /*public Buffer getWindow(Extent extent, int bufWidth, int bufHeight,
508
                        BandList bandList, Buffer rasterBuf, boolean adjustToExtent, TaskStatus status) throws ProcessInterruptedException, RasterDriverException {
509
                NetCDFDataParameters p = (NetCDFDataParameters)param;
510
                setView(extent);
511

512
                Point2D ul = new Point2D.Double(viewRequest.getULX(), viewRequest.getULY());
513
                Point2D lr = new Point2D.Double(viewRequest.getLRX(), viewRequest.getLRY());
514
                ul = worldToRaster(ul);
515
                lr = worldToRaster(lr);
516
                ul.setLocation(ul.getX() < 0 ? 0 : ul.getX(), ul.getY() < 0 ? 0 : ul.getY());
517
                lr.setLocation(lr.getX() < 0 ? 0 : lr.getX(), lr.getY() < 0 ? 0 : lr.getY());
518
                ul.setLocation(ul.getX() >= getWidth() ? getWidth() - 1 : ul.getX(), ul.getY() >= getHeight() ? getHeight() - 1 : ul.getY());
519
                lr.setLocation(lr.getX() >= getWidth() ? getWidth() - 1 : lr.getX(), lr.getY() >= getHeight() ? getHeight() - 1 : lr.getY());
520

521
                adjustPoints(ul, lr);
522

523
                int width = Math.abs(((int)lr.getX()) - ((int)ul.getX()));
524
                int height = Math.abs(((int)lr.getY()) - ((int)ul.getY()));
525

526
                try {
527
                        int strideX = width / rasterBuf.getWidth();
528
                        int strideY = height / rasterBuf.getHeight();
529
                        Range rangeY = new Range((int)(getHeight() - lr.getY()), (int)(getHeight() - ul.getY() - 1), strideY <= 0 ? 1 : strideY);
530
                        Range rangeX = new Range((int)ul.getX(), (int)(lr.getX() - 1), strideX <= 0 ? 1 : strideX);
531

532
                        selectSubdataset();
533
                        int time = p.getFieldTime();
534
                        int level = getLevelValue();
535
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null , rangeY, rangeX);
536
                        Array values = dt.readDataSlice(time, level, -1, -1);
537
                        rasterBuf = arrayValuesToBuffer(values, rasterBuf, rangeX.length(), rangeY.length(), bandList);
538
                } catch (IOException e) {
539
                        throw new RasterDriverException("Error reading a slice", e);
540
                } catch (InvalidRangeException e) {
541
                        throw new RasterDriverException("Error reading a slice", e);
542
                }
543

544
                return rasterBuf;
545
        }*/
546

    
547
        /*public Buffer getWindow(int x, int y, int w, int h,
548
                        BandList bandList, Buffer rasterBuf, TaskStatus status) throws ProcessInterruptedException, RasterDriverException {
549
                try {
550
                        NetCDFDataParameters p = (NetCDFDataParameters)param;
551
                        int strideX = 1;
552
                        int strideY = 1;
553
                        Range rangeY = new Range((int)(h - y), (int)(h - y - 1), strideY);
554
                        Range rangeX = new Range((int)x, (int)(x + w - 1), strideX);
555

556
                        selectSubdataset();
557
                        int time = p.getFieldTime();
558
                        int level = getLevelValue();
559
                        GridDatatype dt = selectedGridDataType.makeSubset(null, null, null, null, rangeY, rangeX);
560
                        Array values = dt.readDataSlice(time, level, -1, -1);
561
                        rasterBuf = arrayValuesToBuffer(values, rasterBuf, rangeX.length(), rangeY.length(), bandList);
562
                } catch (IOException e) {
563
                        throw new RasterDriverException("Error reading a slice", e);
564
                } catch (InvalidRangeException e) {
565
                        throw new RasterDriverException("Error reading a slice", e);
566
                }
567

568
                return rasterBuf;
569
        }*/
570

    
571
        /**
572
         * Gets the Range of the selected time or null if there is not a selected time
573
         * @param strideX
574
         * @return
575
         * @throws InvalidRangeException
576
         */
577
        @SuppressWarnings("unused")
578
        private Range getTime(int strideX) throws InvalidRangeException {
579
                NetCDFDataParameters p = (NetCDFDataParameters)param;
580
                int time = p.getFieldTime();
581
                return new Range(time, time, strideX);
582
        }
583

    
584
        /*private int getTimeValue() {
585
                int time = 0;
586
                if(param.hasDynValue(NetCDFDataParameters.FIELD_TIME))
587
                        time = ((Integer)param.getDynValue(NetCDFDataParameters.FIELD_TIME)).intValue();
588
                return time;
589
        }*/
590

    
591
        /**
592
         * Gets the Range of the selected level or null if there is not a selected level
593
         * @param strideX
594
         * @return
595
         * @throws InvalidRangeException
596
         */
597
        @SuppressWarnings("unused")
598
        private Range getLevel(int strideX) throws InvalidRangeException {
599
                int level = getLevelValue();
600
                return new Range(level, level, strideX);
601
        }
602

    
603
        private int getLevelValue() {
604
                int level = 0;
605
                if(param.hasDynValue(NetCDFDataParameters.FIELD_LEVEL) && param.getDynValue(NetCDFDataParameters.FIELD_LEVEL) != null)
606
                        level = ((Integer)param.getDynValue(NetCDFDataParameters.FIELD_LEVEL)).intValue();
607
                return level;
608
        }
609

    
610

    
611
        /**
612
         * Selects the GridDataType using the selected variable in the parameters
613
         */
614
        public void selectSubdataset() {
615
                if(param.hasDynValue(NetCDFDataParameters.FIELD_VARIABLE)) {
616
                        NetCDFDataParameters p = (NetCDFDataParameters)param;
617
                        String variable = (String)param.getDynValue(NetCDFDataParameters.FIELD_VARIABLE);
618
                        if(variable != null) {
619
                                for (int j = 0; j < gridList.size(); j++) {
620
                                        if(gridList.get(j).getName().compareTo(variable) == 0) {
621
                                                selectedGridDataType = gridList.get(j);
622
                                                reloadMetadataFromGrid();
623
                                                super.selectSubdataset(getId(j, getLevelValue(), p.getFieldTime()));
624
                                        }
625
                                }
626
                        }
627
                }
628
        }
629

    
630
        /**
631
         * Gets the identifier of a subdataset
632
         * @param grid
633
         * @param level
634
         * @param time
635
         * @return
636
         */
637
        private String getId(int grid, int level, int time) {
638
                return grid + "-" + level + "-" +  time;
639
        }
640

    
641
        /**
642
         * Loads a Buffer object from an netCDF Array.
643
         * @param values
644
         * @param rasterBuf
645
         * @param w
646
         * @param h
647
         * @return
648
         */
649
        private Buffer arrayValuesToBuffer(Array values, Buffer rasterBuf, int w, int h, BandList bandList) {
650
                Buffer buf = null;
651
                boolean resampling = false;
652

    
653
                if((rasterBuf.getWidth() * rasterBuf.getHeight()) != values.getSize()) {
654
                        buf = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], w, h, rasterBuf.getBandCount(), true);
655
                        resampling = true;
656
                } else
657
                        buf = rasterBuf;
658

    
659
                int[] drawableBands = bandList != null ? bandList.getBufferBandToDraw(getURIOfFirstProvider().getPath(), 0) : new int[1];
660
                if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
661
                        return rasterBuf;
662

    
663
                if(getDataType()[0] == Buffer.TYPE_BYTE) {
664
                        for (int i = 0; i < values.getSize(); i++) {
665
                                int[] rc = getColAndRow(i, buf);
666
                                for (int iBands = 0; iBands < drawableBands.length; iBands++)
667
                                        buf.setElem(rc[0], rc[1], drawableBands[iBands], values.getByte(i));
668
                        }
669
                }
670

    
671
                if(getDataType()[0] == Buffer.TYPE_SHORT) {
672
                        for (int i = 0; i < values.getSize(); i++) {
673
                                int[] rc = getColAndRow(i, buf);
674
                                for (int iBands = 0; iBands < drawableBands.length; iBands++)
675
                                        buf.setElem(rc[0], rc[1], drawableBands[iBands], values.getShort(i));
676
                        }
677
                }
678

    
679
                if(getDataType()[0] == Buffer.TYPE_INT) {
680
                        for (int i = 0; i < values.getSize(); i++) {
681
                                int[] rc = getColAndRow(i, buf);
682
                                for (int iBands = 0; iBands < drawableBands.length; iBands++)
683
                                        buf.setElem(rc[0], rc[1], drawableBands[iBands], values.getInt(i));
684
                        }
685
                }
686

    
687
                if(getDataType()[0] == Buffer.TYPE_FLOAT) {
688
                        for (int i = 0; i < values.getSize(); i++) {
689
                                int[] rc = getColAndRow(i, buf);
690
                                for (int iBands = 0; iBands < drawableBands.length; iBands++)
691
                                        buf.setElem(rc[0], rc[1], drawableBands[iBands], values.getFloat(i));
692
                        }
693
                }
694

    
695
                if(getDataType()[0] == Buffer.TYPE_DOUBLE) {
696
                        for (int i = 0; i < values.getSize(); i++) {
697
                                int[] rc = getColAndRow(i, buf);
698
                                for (int iBands = 0; iBands < drawableBands.length; iBands++)
699
                                        buf.setElem(rc[0], rc[1], drawableBands[iBands], values.getDouble(i));
700
                        }
701
                }
702
                if(resampling) {
703
                        try {
704
                                Buffer result = null;
705
                                result = buf.getAdjustedWindow(rasterBuf.getWidth(), rasterBuf.getHeight(), Buffer.INTERPOLATION_NearestNeighbour);
706
                                if(result != buf)
707
                                        buf.dispose();
708
                                return result;
709
                        } catch (ProcessInterruptedException e) {
710
                                return buf;
711
                        }
712
                }
713
                return buf;
714
        }
715

    
716
        /**
717
         * Calculates the row and column number for the position i in the
718
         * array of data
719
         * @param i
720
         * @param buf
721
         * @return
722
         */
723
        private int[] getColAndRow(int i, Buffer buf) {
724
                int auxRow = (int)(i / buf.getWidth());
725
                return new int[]{
726
                                (int)buf.getHeight() - auxRow - 1,
727
                                i - (auxRow * buf.getWidth())
728
                                };
729
        }
730

    
731
        private void adjustPoints(Point2D ul, Point2D lr) {
732
                double a = (ul.getX() - (int)ul.getX());
733
                double b = (ul.getY() - (int)ul.getY());
734
                ul.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(ul.getX()) : ul.getX(),
735
                                                (b > 0.95 || b < 0.05) ? Math.round(ul.getY()) : ul.getY());
736
                lr.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(lr.getX()) : lr.getX(),
737
                                                (b > 0.95 || b < 0.05) ? Math.round(lr.getY()) : lr.getY());
738
        }
739

    
740
        public int getBlockSize(){
741
                return 0;
742
        }
743

    
744
        public ColorInterpretation getColorInterpretation() {
745
                if(super.getColorInterpretation() == null) {
746
                        setColorInterpretation(new DataStoreColorInterpretation(new String[]{ColorInterpretation.GRAY_BAND}));
747
                }
748
                return super.getColorInterpretation();
749
        }
750

    
751
        public DataStoreTransparency getTransparency() {
752
                if(fileTransparency == null)
753
                        fileTransparency = new DataStoreTransparency(getColorInterpretation());
754
                return fileTransparency;
755
        }
756

    
757
        /**
758
         * Informa de si el driver ha supersampleado en el �ltimo dibujado. Es el driver el que colocar�
759
         * el valor de esta variable cada vez que dibuja.
760
         * @return true si se ha supersampleado y false si no se ha hecho.
761
         */
762
        public boolean isSupersampling() {
763
                return false;
764
        }
765

    
766
        public void setAffineTransform(AffineTransform t){
767
                super.setAffineTransform(t);
768
        }
769

    
770
        public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
771
                if(band >= getBandCount())
772
                        throw new BandAccessException("Wrong band");
773
                return 0;
774
        }
775

    
776
        public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
777
                if (band >= getBandCount())
778
                        throw new BandAccessException("Wrong band");
779
                return 0;
780
        }
781

    
782
        public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
783
                if (band >= getBandCount())
784
                        throw new BandAccessException("Wrong band");
785
                return 0;
786
        }
787

    
788
        public boolean isOverviewsSupported() {
789
                return true;
790
        }
791

    
792
        public boolean isReproyectable() {
793
                return true;
794
        }
795

    
796
        public String getProviderName() {
797
                return NAME;
798
        }
799

    
800
        public void setStatus(RasterProvider provider) {
801
                if(provider instanceof NetCDFProvider) {
802
                        //Not implemented yet
803
                }
804
        }
805

    
806
        public boolean isTimeSupported() {
807
                return true;
808
        }
809

    
810
        public TileServer getTileServer() {
811
                if(tileServer == null) {
812
                        DefaultRasterStore store = new DefaultRasterStore();
813
                        store.setProvider(this);
814
                        tileServer = new FileTileServer(store);
815
                }
816
                return tileServer;
817
        }
818

    
819
    public void addFile(File file) throws InvalidSourceException {
820
        // Do nothing
821
    }
822

    
823
    public void removeFile(File file) {
824
        // Do nothing
825
    }
826
}