Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster / org.gvsig.fmap.dal.file.jimi / src / main / java / org / gvsig / fmap / dal / file / jimi / JimiRasterStoreProvider.java @ 6302

History | View | Annotate | Download (17.7 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2016 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.dal.file.jimi;
24

    
25
import java.awt.Canvas;
26
import java.awt.Image;
27
import java.awt.MediaTracker;
28
import java.awt.image.ColorModel;
29
import java.awt.image.ImageConsumer;
30
import java.awt.image.ImageProducer;
31
import java.io.ByteArrayInputStream;
32
import java.io.File;
33
import java.util.ArrayList;
34
import java.util.Hashtable;
35
import java.util.List;
36
import java.util.Map;
37

    
38
import org.apache.commons.io.FileUtils;
39
import org.apache.commons.io.FilenameUtils;
40
import org.cresques.cts.IProjection;
41
import org.gvsig.fmap.dal.DALLocator;
42
import org.gvsig.fmap.dal.DataManager;
43
import org.gvsig.fmap.dal.DataServerExplorer;
44
import org.gvsig.fmap.dal.DataStore;
45
import org.gvsig.fmap.dal.DataStoreNotification;
46
import org.gvsig.fmap.dal.FileHelper;
47
import org.gvsig.fmap.dal.exception.CloseException;
48
import org.gvsig.fmap.dal.exception.DataException;
49
import org.gvsig.fmap.dal.exception.InitializeException;
50
import org.gvsig.fmap.dal.exception.OpenException;
51
import org.gvsig.fmap.dal.exception.ReadException;
52
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
53
import org.gvsig.fmap.dal.raster.api.BandAttributeDescriptor;
54
import org.gvsig.fmap.dal.raster.api.BandDescriptor;
55
import org.gvsig.fmap.dal.raster.api.BandQuery;
56
import org.gvsig.fmap.dal.raster.api.RasterQuery;
57
import org.gvsig.fmap.dal.raster.spi.AbstractRasterStoreProvider;
58
import org.gvsig.fmap.dal.resource.ResourceAction;
59
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
60
import org.gvsig.fmap.dal.resource.file.FileResource;
61
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
62
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
63
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
64
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
65
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
66
import org.gvsig.fmap.geom.Geometry;
67
import org.gvsig.fmap.geom.GeometryLocator;
68
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
69
import org.gvsig.fmap.geom.primitive.Envelope;
70
import org.gvsig.metadata.MetadataLocator;
71
import org.gvsig.metadata.MetadataManager;
72
import org.gvsig.metadata.exceptions.MetadataException;
73
import org.gvsig.raster.lib.buffer.api.BandInfo;
74
import org.gvsig.raster.lib.buffer.api.Buffer;
75
import org.gvsig.raster.lib.buffer.api.BufferLocator;
76
import org.gvsig.raster.lib.buffer.api.BufferManager;
77
import org.gvsig.raster.lib.buffer.api.NoData;
78
import org.gvsig.raster.lib.buffer.api.PageManager;
79
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException;
80
import org.gvsig.tools.ToolsLocator;
81
import org.gvsig.tools.dynobject.DynObject;
82
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
83
import org.gvsig.tools.exception.BaseException;
84
import org.gvsig.tools.locator.LocatorException;
85
import org.gvsig.tools.task.SimpleTaskStatus;
86
import org.gvsig.tools.task.TaskStatusManager;
87
import org.slf4j.Logger;
88
import org.slf4j.LoggerFactory;
89

    
90
import com.sun.jimi.core.Jimi;
91
import com.sun.jimi.core.JimiReader;
92
import com.sun.jimi.core.raster.JimiRasterImage;
93
import com.sun.jimi.core.util.ProgressListener;
94

    
95
/**
96
 * Provider for JIMI files
97
 * @author dmartinezizquierdo
98
 *
99
 */
100
public class JimiRasterStoreProvider extends AbstractRasterStoreProvider implements
101
ResourceConsumer{
102

    
103
    private static final Logger logger =
104
        LoggerFactory.getLogger(JimiRasterStoreProvider.class);
105

    
106
    public static String NAME = "JIMI";
107
    public static String DESCRIPTION = "JIMI file";
108
    public static final String METADATA_DEFINITION_NAME = NAME;
109

    
110
    private ResourceProvider resource;
111
    private final SimpleTaskStatus taskStatus;
112

    
113
    private MemoryImage image = null;
114
    private Envelope envelope = null;
115
    private IProjection projection= null;
116
    private Canvas waitComponent = null;
117

    
118
    protected static void registerMetadataDefinition()
119
        throws MetadataException {
120
        MetadataManager manager = MetadataLocator.getMetadataManager();
121
        if (manager.getDefinition(METADATA_DEFINITION_NAME) == null) {
122
            manager.addDefinition(METADATA_DEFINITION_NAME,
123
                JimiRasterStoreProviderParameters.class
124
                    .getResourceAsStream("JimiMetadata.xml"),
125
                JimiRasterStoreProviderParameters.class.getClassLoader());
126
        }
127
    }
128

    
129
    public JimiRasterStoreProvider(JimiRasterStoreProviderParameters params,
130
        DataStoreProviderServices storeServices)
131
        throws InitializeException {
132
        super(
133
                params,
134
                storeServices,
135
                FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
136
        );
137
        TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
138
        this.taskStatus = manager.createDefaultSimpleTaskStatus("Jimi");
139
        this.init(params, storeServices);
140
    }
141

    
142
    protected JimiRasterStoreProvider(JimiRasterStoreProviderParameters params,
143
            DataStoreProviderServices storeServices, DynObject metadata)
144
            throws InitializeException {
145
        super(params, storeServices, metadata);
146
        TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
147
        this.taskStatus = manager.createDefaultSimpleTaskStatus("Jimi");
148
        this.init(params, storeServices);
149
    }
150

    
151
    protected void init(JimiRasterStoreProviderParameters params,
152
        DataStoreProviderServices storeServices) throws InitializeException {
153
        if (params == null) {
154
            throw new InitializeException(
155
                new NullPointerException("params is null"));
156
        }
157
        File file = getJimiParameters().getFile();
158
        if (file == null) {
159
            throw new InitializeException(
160
                new NullPointerException("Jimi file is null"));
161
        }
162

    
163
        this.projection=params.getCRS();
164

    
165
        resource = this.createResource(
166
            FileResource.NAME,
167
            new Object[] { file.getAbsolutePath() }
168
        );
169

    
170
        resource.addConsumer(this);
171

    
172
    }
173

    
174
    private JimiRasterStoreProviderParameters getJimiParameters() {
175
        return (JimiRasterStoreProviderParameters) this.getParameters();
176
    }
177
    
178
    @Override
179
    public BandDescriptor getBandDescriptor(int band) {
180
        if(band > this.getBands()){
181
            throw new IllegalArgumentException("Invalid band");
182
        }
183
        return getStoreServices().createBandDescriptor(band,
184
            new ArrayList<BandAttributeDescriptor>());
185
    }
186
    
187
    @Override
188
    public int getBands() {
189
        return image.bands;
190
    }
191

    
192
    @Override
193
    public Buffer createBuffer(RasterQuery rasterQuery) throws BufferException {
194
        
195
        BufferManager bufferManager = BufferLocator.getBufferManager();
196
        List<BandQuery> bands = rasterQuery.getBands();
197
        int[] bandDataTypes = new int[bands.size()];
198
        NoData[] bandNoData = new NoData[bands.size()];
199
        
200
        List<PageManager> pageManagers = new ArrayList<PageManager>();
201
        for (BandQuery bandQuery : bands) {
202
            int band = bandQuery.getBand();
203
            bandDataTypes[band] = image.dataType;
204
            bandNoData[band] = null;
205
            pageManagers.add(new MemoryImageBandPageManager(image, band));
206
        }
207

    
208
        Buffer buffer =
209
            bufferManager.createBuffer(image.rows, image.columns, bandDataTypes, bandNoData,
210
                projection, envelope, pageManagers);
211

    
212
        return buffer;
213
    }
214
    
215
    @Override
216
    public BandInfo getBandInfo(int band) {
217
        return null;
218
    }
219

    
220
    @Override
221
    public DataServerExplorer getExplorer()
222
        throws ReadException, ValidateDataParametersException {
223
        DataManager manager = DALLocator.getDataManager();
224
        FilesystemServerExplorerParameters params;
225
        try {
226
            params = (FilesystemServerExplorerParameters) manager
227
            .createServerExplorerParameters(FilesystemServerExplorer.NAME);
228
            params.setRoot(this.getJimiParameters().getFile().getParent());
229
            return manager.openServerExplorer(FilesystemServerExplorer.NAME,params);
230
        } catch (DataException e) {
231
            throw new ReadException(this.getProviderName(), e);
232
        } catch (ValidateDataParametersException e) {
233
            throw new ReadException(this.getProviderName(), e);
234
        }
235

    
236
    }
237

    
238
    public void open() throws OpenException {
239
        if (this.image != null) {
240
            return;
241
        }
242
        openEver();
243
    }
244

    
245
    private void openEver() throws OpenException {
246
        try {
247
            getResource().execute(new ResourceAction() {
248

    
249
                public Object run() throws Exception {
250

    
251
                    JimiReader reader = null;
252
                    try {
253
                        File file = (File) resource.get();
254
                        resource.notifyOpen();
255
                        reader = Jimi.createJimiReader(file.toURI().toURL(),Jimi.SYNCHRONOUS);
256
                        reader.setProgressListener(new ProgressListener() {
257
                            @Override
258
                            public void setStarted() {
259
                                taskStatus.add();
260
                                taskStatus.setRangeOfValues(0, 100);
261
                            }
262
                            @Override
263
                            public void setProgressLevel(int arg0) {
264
                                taskStatus.setCurValue(arg0);
265
                            }
266
                            @Override
267
                            public void setFinished() {
268
                                taskStatus.terminate();
269
                            }
270
                            @Override
271
                            public void setAbort(String arg0) {
272
                                taskStatus.abort();
273
                            }
274
                            @Override
275
                            public void setAbort() {
276
                                taskStatus.abort();
277
                            }
278
                        });
279
                        ByteArrayInputStream is = new ByteArrayInputStream(FileUtils.readFileToByteArray(file));
280

    
281
                        JimiRasterImage jimiRasterImage = Jimi.getRasterImage(is, Jimi.SYNCHRONOUS);
282
                        NewImageConsumer imageConsumer = new NewImageConsumer();
283
                        imageConsumer.addImage(jimiRasterImage);
284
                        imageConsumer.waitFor();
285
                        image = new MemoryImage(jimiRasterImage);
286

    
287
                        if (getJimiParameters().getWldParams()!=null){
288
                            envelope=createWLDEnvelope(getJimiParameters().getWldParams());
289
                        }else{
290
                        envelope =
291
                            GeometryLocator.getGeometryManager().createEnvelope(0, 0,
292
                                image.columns, image.rows, Geometry.SUBTYPES.GEOM2D);
293
                        }
294

    
295
                        resource.notifyClose();
296

    
297
                        resource.setData(image);
298
                    } finally  {
299
                        if( reader != null ) {
300
                            reader.close();
301
                        }
302
                    }
303
                    return null;
304
                }
305

    
306
            });
307
        } catch (Exception e) {
308
            this.image = null;
309
            try {
310
                throw new OpenException(resource.getName(), e);
311
            } catch (AccessResourceException e1) {
312
                throw new OpenException(getProviderName(), e);
313
            }
314
        } finally {
315
            this.taskStatus.remove();
316
        }
317
    }
318

    
319
    private Envelope createWLDEnvelope(List<String> wldParams){
320
        double pixelSizeX=Double.valueOf(wldParams.get(0));
321
        double rotationAxisY = Double.valueOf(wldParams.get(1));
322
        double rotationAxisX = Double.valueOf(wldParams.get(2));
323
        double pixelSizeY = Double.valueOf(wldParams.get(3));
324
        double upperLeftPixelCenterCoordX = Double.valueOf(wldParams.get(4));
325
        double upperLeftPixelCenterCoordY = Double.valueOf(wldParams.get(5));
326

    
327
        if (0.0 != rotationAxisX || 0.0 != rotationAxisY) {
328
            logger.warn(
329
                "Rotation in wld file not implemented yet. It will be ignored");
330
        }
331

    
332
        double leftMostX = upperLeftPixelCenterCoordX - (pixelSizeX * 0.5);
333
        double upperMostY = upperLeftPixelCenterCoordY - (pixelSizeY * 0.5);
334
        double height=image.rows*pixelSizeY;
335
        double width=image.columns*pixelSizeX;
336

    
337
        // double minX, double minY, double maxX, double maxY, int subType
338
        try {
339
            envelope = GeometryLocator.getGeometryManager().createEnvelope(
340
                Math.min(leftMostX,leftMostX + width),
341
                Math.min(upperMostY,upperMostY + height),
342
                Math.max(leftMostX,leftMostX + width),
343
                Math.max(upperMostY,upperMostY + height),
344
                Geometry.SUBTYPES.GEOM2D);
345
        } catch (LocatorException | CreateEnvelopeException e) {
346
            logger.warn(
347
                "Failed to create envelope from wld file with coords: minx:"+leftMostX+
348
                ", miny:"+upperMostY+", maxX: "+leftMostX + width+", maxY: "+upperMostY + height);
349
            e.printStackTrace();
350
        }
351

    
352
        return envelope;
353
    }
354

    
355
    @Override
356
    public Object getDynValue(String name) throws DynFieldNotFoundException {
357
        if( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
358
            return this.envelope;
359
        } else if( DataStore.METADATA_CRS.equalsIgnoreCase(name) ) {
360
            IProjection pro = this.getJimiParameters().getCRS();
361
            if (pro != null) {
362
                return pro;
363
            }
364
        }
365
        return super.getDynValue(name);
366
    }
367

    
368
    @Override
369
    public void close() throws CloseException {
370
        this.image = null;
371
    }
372

    
373
    @Override
374
    public ResourceProvider getResource() {
375
        return this.resource;
376
    }
377

    
378

    
379
    @Override
380
    public Object getSourceId() {
381
        return this.getJimiParameters().getFile();
382
    }
383

    
384
    @Override
385
    public String getProviderName() {
386
        return NAME;
387
    }
388

    
389
    @Override
390
    public String getName() {
391
        String name = this.getJimiParameters().getFile().getName();
392
        return FilenameUtils.getBaseName(name);
393
    }
394

    
395
    @Override
396
    public String getFullName() {
397
        return this.getJimiParameters().getFile().getAbsolutePath();
398
    }
399

    
400
    @Override
401
    public boolean closeResourceRequested(ResourceProvider resource) {
402
        return true;
403
    }
404

    
405
    @Override
406
    /*
407
     * (non-Javadoc)
408
     *
409
     * @see
410
     * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
411
     * gvsig.fmap.dal.resource.spi.ResourceProvider)
412
     */
413
    public void resourceChanged(ResourceProvider resource) {
414
        this.getStoreServices().notifyChange(
415
            DataStoreNotification.RESOURCE_CHANGED,
416
            resource);
417
    }
418

    
419
    @Override
420
    /* (non-Javadoc)
421
     * @see org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider#doDispose()
422
     */
423
    protected void doDispose() throws BaseException {
424
        super.doDispose();
425
        resource.removeConsumer(this);
426
    }
427

    
428
    private void waitImage(Image image)
429
    {
430

    
431
        if (waitComponent == null)
432
        {
433
            waitComponent = new Canvas();
434
        }
435
        MediaTracker tracker = new MediaTracker(waitComponent);
436
        tracker.addImage(image, 0);
437
        try
438
        {
439
            tracker.waitForAll();
440
        }
441
        catch (InterruptedException e)
442
        {
443
            // do nothing
444
        }
445
    }
446

    
447
    public class NewImageConsumer implements ImageConsumer, Runnable
448
    {
449
       private ImageProducer _ip;
450

    
451
       private Thread _thr;
452

    
453
       private boolean _f;
454

    
455
       private int _n;
456

    
457
       public void addImage(JimiRasterImage i)
458
       {
459
          _ip = i.getImageProducer();
460

    
461
          _ip.addConsumer(this);
462

    
463
          _thr = Thread.currentThread();
464

    
465
          _f = false;
466

    
467
          _n = -1;
468
       }
469

    
470
       public int waitFor()
471
       {
472
          new Thread(this).start();
473

    
474
          while (_f == false) _thr.suspend();
475

    
476
          return _n;
477
       }
478

    
479
       public void imageComplete(int nStatus)
480
       {
481
          _f = true;
482

    
483
          _n = nStatus;
484

    
485
          _ip.removeConsumer(this);
486

    
487
          _thr.resume();
488
       }
489

    
490
       public void run()
491
       {
492
          _ip.startProduction(this);
493
       }
494

    
495
       public void setColorModel(ColorModel cm)
496
       {
497
          ;
498
       }
499

    
500
       public void setDimensions(int w, int h)
501
       {
502
          ;
503
       }
504

    
505
       public void setHints(int nHints)
506
       {
507
          ;
508
       }
509

    
510
       public void setProperties(Hashtable htProperties)
511
       {
512
          ;
513
       }
514

    
515
       public void setPixels(int x, int y, int w, int h,
516
                             ColorModel cm, byte rgb[],
517
                             int nOffset, int nScansize)
518
       {
519
          ;
520
       }
521

    
522
       public void setPixels(int x, int y, int w, int h,
523
                             ColorModel cm, int rgn[],
524
                             int nOffset, int nScansize)
525
       {
526
          ;
527
       }
528
    }
529

    
530
    public MemoryImage getMemoryImage(){
531
        return image;
532
    }
533
}