Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster / org.gvsig.fmap.dal.raster / org.gvsig.fmap.dal.raster.impl / src / main / java / org / gvsig / fmap / dal / raster / impl / DefaultRasterStore.java @ 8691

History | View | Annotate | Download (34 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.raster.impl;
24

    
25
import java.util.ArrayList;
26
import java.util.Collection;
27
import java.util.HashMap;
28
import java.util.Iterator;
29
import java.util.List;
30
import java.util.Map;
31
import java.util.Map.Entry;
32
import java.util.Set;
33

    
34
import org.cresques.cts.IProjection;
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

    
38
import org.gvsig.fmap.dal.DALLocator;
39
import org.gvsig.fmap.dal.DataManager;
40
import org.gvsig.fmap.dal.DataParameters;
41
import org.gvsig.fmap.dal.DataQuery;
42
import org.gvsig.fmap.dal.DataServerExplorer;
43
import org.gvsig.fmap.dal.DataSet;
44
import org.gvsig.fmap.dal.DataStore;
45
import org.gvsig.fmap.dal.DataStoreNotification;
46
import org.gvsig.fmap.dal.DataStoreParameters;
47
import org.gvsig.fmap.dal.DataStoreProviderFactory;
48
import org.gvsig.fmap.dal.exception.CloneException;
49
import org.gvsig.fmap.dal.exception.DataException;
50
import org.gvsig.fmap.dal.exception.InitializeException;
51
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
52
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
53
import org.gvsig.fmap.dal.feature.exception.PersistenceStoreAlreadyLoadedException;
54
import org.gvsig.fmap.dal.impl.DefaultDataManager;
55
import org.gvsig.fmap.dal.raster.RasterStoreProviderFactory;
56
import org.gvsig.fmap.dal.raster.api.BandAttributeDescriptor;
57
import org.gvsig.fmap.dal.raster.api.BandDescriptor;
58
import org.gvsig.fmap.dal.raster.api.BandQuery;
59
import org.gvsig.fmap.dal.raster.api.RasterCache;
60
import org.gvsig.fmap.dal.raster.api.RasterQuery;
61
import org.gvsig.fmap.dal.raster.api.RasterSet;
62
import org.gvsig.fmap.dal.raster.api.RasterStore;
63
import org.gvsig.fmap.dal.raster.api.RasterStoreNotification;
64
import org.gvsig.fmap.dal.raster.api.exceptions.RasterQueryCloneException;
65
import org.gvsig.fmap.dal.raster.impl.exceptions.AddingBandsException;
66
import org.gvsig.fmap.dal.raster.spi.RasterCacheStoreProvider;
67
import org.gvsig.fmap.dal.raster.spi.RasterStoreProvider;
68
import org.gvsig.fmap.dal.raster.spi.RasterStoreProviderServices;
69
import org.gvsig.fmap.dal.resource.Resource;
70
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
71
import org.gvsig.fmap.dal.spi.DALSPILocator;
72
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
73
import org.gvsig.fmap.dal.spi.DataStoreInitializer2;
74
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
75
import org.gvsig.fmap.geom.primitive.Envelope;
76
import org.gvsig.metadata.MetadataLocator;
77
import org.gvsig.metadata.MetadataManager;
78
import org.gvsig.metadata.exceptions.MetadataException;
79
import org.gvsig.raster.lib.buffer.api.Band;
80
import org.gvsig.raster.lib.buffer.api.Buffer;
81
import org.gvsig.raster.lib.buffer.api.BufferDimensions;
82
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException;
83
import org.gvsig.timesupport.Interval;
84
import org.gvsig.tools.ToolsLocator;
85
import org.gvsig.tools.dispose.DisposeUtils;
86
import org.gvsig.tools.dispose.impl.AbstractDisposable;
87
import org.gvsig.tools.dynobject.DelegatedDynObject;
88
import org.gvsig.tools.dynobject.DynClass;
89
import org.gvsig.tools.dynobject.DynObject;
90
import org.gvsig.tools.dynobject.DynObjectManager;
91
import org.gvsig.tools.dynobject.DynObject_v2;
92
import org.gvsig.tools.dynobject.DynStruct;
93
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
94
import org.gvsig.tools.dynobject.exception.DynMethodException;
95
import org.gvsig.tools.exception.BaseException;
96
import org.gvsig.tools.locator.LocatorException;
97
import org.gvsig.tools.observer.Observable;
98
import org.gvsig.tools.observer.Observer;
99
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
100
import org.gvsig.tools.persistence.PersistenceManager;
101
import org.gvsig.tools.persistence.PersistentState;
102
import org.gvsig.tools.persistence.exception.PersistenceException;
103
import org.gvsig.tools.visitor.Visitor;
104

    
105
/**
106
 * Implements RasterStore
107
 *
108
 * @author dmartinezizquierdo
109
 *
110
 */
111
public class DefaultRasterStore extends AbstractDisposable implements DataStoreInitializer2,
112
    RasterStoreProviderServices, RasterStore, Observer {
113

    
114
    private static final Logger LOG = LoggerFactory.getLogger(DefaultRasterStore.class);
115

    
116
    private static final String PERSISTENCE_DEFINITION_NAME = "RasterStore";
117
    private static final String METADATA_DEFINITION_NAME = "RasterStore";
118

    
119
    private DataStoreParameters parameters = null;
120
    private RasterStoreProvider provider = null;
121
    private DelegatedDynObject metadata;
122
    private DefaultDataManager dataManager = null;
123
    private List<BandsFromStore> additionalBands = null;
124

    
125
    private DelegateWeakReferencingObservable delegateObservable = new DelegateWeakReferencingObservable(this);
126

    
127
    /**
128
     * Registers persistence
129
     */
130
    public static void registerPersistenceDefinition() {
131
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
132
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
133
            DynStruct definition =
134
                manager.addDefinition(DefaultRasterStore.class, PERSISTENCE_DEFINITION_NAME,
135
                    PERSISTENCE_DEFINITION_NAME + " Persistent definition", null, null);
136
            definition.addDynFieldString("dataStoreName").setMandatory(true).setPersistent(true);
137

    
138
            definition.addDynFieldObject("parameters").setClassOfValue(DynObject.class).setMandatory(true)
139
                .setPersistent(true);
140
        }
141
    }
142

    
143
    /**
144
     * Registers metadata
145
     *
146
     * @throws MetadataException
147
     */
148
    public static void registerMetadataDefinition() throws MetadataException {
149
        MetadataManager manager = MetadataLocator.getMetadataManager();
150
        if (manager.getDefinition(METADATA_DEFINITION_NAME) == null) {
151
            DynStruct metadataDefinition = manager.addDefinition(METADATA_DEFINITION_NAME, null);
152
            metadataDefinition.extend(manager.getDefinition(DataStore.METADATA_DEFINITION_NAME));
153
        }
154
    }
155

    
156
    /**
157
     * @return dataManager
158
     */
159
    public DataManager getManager() {
160
        return this.dataManager;
161
    }
162

    
163
    @Override
164
    public String getName() {
165
        return this.provider.getName();
166
    }
167

    
168
    @Override
169
    public String getFullName() {
170
        return this.provider.getFullName();
171
    }
172

    
173
    @Override
174
    public DataStoreParameters getParameters() {
175
        return parameters;
176
    }
177

    
178
    @Override
179
    public String getProviderName() {
180
        return this.provider.getProviderName();
181
    }
182

    
183
    @Override
184
    public void refresh() throws DataException {
185
        this.notifyChange(RasterStoreNotification.BEFORE_REFRESH);
186
        this.provider.refresh();
187
        this.notifyChange(RasterStoreNotification.AFTER_REFRESH);
188
    }
189

    
190
    @Override
191
    public DataSet getDataSet() throws DataException {
192
        return this.getRasterSet();
193
    }
194

    
195
    @Override
196
    public DataSet getDataSet(DataQuery dataQuery) throws DataException {
197
        return this.getRasterSet((RasterQuery) dataQuery);
198
    }
199

    
200
    @Override
201
    public void getDataSet(Observer observer) throws DataException {
202
        this.getRasterSet(null, observer);
203
    }
204

    
205
    @Override
206
    public void getDataSet(DataQuery dataQuery, Observer observer) throws DataException {
207
        this.getRasterSet((RasterQuery) dataQuery, observer);
208
    }
209

    
210
    @Override
211
    public RasterSet getRasterSet(RasterQuery rasterQuery) throws DataException {
212

    
213
        try {
214
            if (rasterQuery != null) {
215
                List<BandQuery> queryBands = rasterQuery.getBands();
216
                if (!queryBands.isEmpty()) {
217
                    RasterQuery mainRasterQuery = (RasterQuery) rasterQuery.clone();
218
                    mainRasterQuery.clearBands();
219
                    Map<RasterStore, RasterQuery> rasterQueries = new HashMap<RasterStore, RasterQuery>();
220

    
221
                    for (BandQuery bandQuery : queryBands) {
222
                        int band = bandQuery.getBand();
223
                        if(band<getProvider().getBands()){
224
                            mainRasterQuery.addBand(bandQuery);
225
                        } else {
226
                            int bandCounter = getProvider().getBands();
227
                            boolean bandFound = false;
228
                            if(additionalBands!=null){
229
                                for (BandsFromStore bandsFromStore : additionalBands) {
230
                                    RasterStore store = bandsFromStore.getStore();
231

    
232
                                    if (band < bandCounter + bandsFromStore.size()) {
233
                                        BandQuery storeBandQuery =
234
                                            store.createBandQuery(bandsFromStore.get(band - bandCounter));
235
                                        if (rasterQueries.containsKey(store)) {
236
                                            rasterQueries.get(store).addBand(storeBandQuery);
237
                                        } else {
238
                                            RasterQuery storeRasterQuery = (RasterQuery) rasterQuery.clone();
239
                                            storeRasterQuery.clearBands();
240
                                            storeRasterQuery.addBand(storeBandQuery);
241
                                            rasterQueries.put(store, storeRasterQuery);
242
                                            bandFound = true;
243
                                        }
244
                                    }
245
                                    bandCounter += bandsFromStore.size();
246
                                    if (bandFound) {
247
                                        break;
248
                                    }
249
                                }
250
                            }
251
                        }
252
                    }
253

    
254
                    RasterSet mainRasterSet = new DefaultRasterSet(this, mainRasterQuery);
255
                    for (Entry<RasterStore, RasterQuery> entry : rasterQueries.entrySet()) {
256
                        RasterStore store = entry.getKey();
257
                        RasterQuery query = entry.getValue();
258
                        RasterSet subRasterSet = store.getRasterSet(query);
259
                        for (Band band : subRasterSet) {
260
                            mainRasterSet.addBand(band);
261
                        }
262
                    }
263
                    return mainRasterSet;
264
                }
265
            }
266
            RasterSet mainRasterSet = new DefaultRasterSet(this, rasterQuery);
267
            if (additionalBands != null) {
268
                for (BandsFromStore bandsFromStore : additionalBands) {
269
                    RasterStore store = bandsFromStore.getStore();
270
                    RasterQuery subRasterQuery = store.createRasterQuery();
271
                    subRasterQuery.setClip(rasterQuery.getClip());
272
                    subRasterQuery.setPixelSize(mainRasterSet.getPixelSizeX()); //rasterQuery.getPixelSize()); //
273
                    subRasterQuery.setScale(rasterQuery.getScale());
274
                    for (int i = 0; i < bandsFromStore.size(); i++) {
275
                        BandQuery bandQuery = store.createBandQuery(bandsFromStore.get(i));
276
                        subRasterQuery.addBand(bandQuery);
277
                    }
278
                    DefaultRasterSet subRasterSet = new DefaultRasterSet(store, subRasterQuery);
279
                    if(subRasterSet.getColumns()!=mainRasterSet.getColumns() || subRasterSet.getRows()!=mainRasterSet.getRows()){
280
                        Buffer subBuffer = subRasterSet.createInterpolated(mainRasterSet.getRows(), mainRasterSet.getColumns(), Buffer.INTERPOLATION_NearestNeighbour, null);
281
                        for (Band band : subBuffer) {
282
                            mainRasterSet.addBand(band);
283
                        }
284
                    } else {
285
                        for (Band band : subRasterSet) {
286
                            mainRasterSet.addBand(band);
287
                        }
288
                    }
289
                }
290
            }
291
            return mainRasterSet;
292
        } catch (CloneNotSupportedException | LocatorException | BufferException e) {
293
            throw new RasterQueryCloneException(e);
294
        }
295
    }
296

    
297
    @Override
298
    public RasterSet getRasterSet() throws DataException {
299
        return getRasterSet(createRasterQuery());
300
    }
301

    
302
    /**
303
     * Adds an observer to the DataSet
304
     *
305
     * @param observer
306
     * @throws DataException
307
     */
308
    public void getRasterSet(Observer observer) throws DataException {
309
        RasterSet set = this.getRasterSet();
310
        set.addObserver(observer);
311
    }
312

    
313
    /**
314
     * Adds an observer to the queried DataSet
315
     *
316
     * @param rasterQuery
317
     * @param observer
318
     * @throws DataException
319
     */
320
    public void getRasterSet(RasterQuery rasterQuery, Observer observer) throws DataException {
321
        RasterSet set = this.getRasterSet(rasterQuery);
322
        set.addObserver(observer);
323
    }
324

    
325
    @Override
326
    public void accept(Visitor visitor) throws BaseException {
327
        RasterSet set = getRasterSet();
328
        try {
329
            set.accept(visitor);
330
        } finally {
331
            set.dispose();
332
        }
333
    }
334

    
335
    @Override
336
    public void accept(Visitor visitor, DataQuery dataQuery) throws BaseException {
337
        RasterSet set = getRasterSet((RasterQuery) dataQuery);
338
        try {
339
            set.accept(visitor);
340
        } finally {
341
            set.dispose();
342
        }
343

    
344
    }
345

    
346
    @Override
347
    public DataSet getSelection() throws DataException {
348
        // TODO Auto-generated method stub
349
        return null;
350
    }
351

    
352
    @Override
353
    public void setSelection(DataSet selection) throws DataException {
354
        // TODO Auto-generated method stub
355

    
356
    }
357

    
358
    @Override
359
    public DataSet createSelection() throws DataException {
360
        // TODO Auto-generated method stub
361
        return null;
362
    }
363

    
364
    @Override
365
    public Iterator<?> getChildren() {
366
        return this.provider.getChilds();
367
    }
368

    
369
    @Override
370
    public DataServerExplorer getExplorer() throws DataException, ValidateDataParametersException {
371
        return this.provider.getExplorer();
372
    }
373

    
374
    @Override
375
    public DataQuery createQuery() {
376
        return createRasterQuery();
377
    }
378

    
379
    @Override
380
    public Interval getInterval() {
381
        return this.provider.getInterval();
382
    }
383

    
384
    @Override
385
    public Collection<?> getTimes() {
386
        return this.provider.getTimes();
387
    }
388

    
389
    @Override
390
    public Collection<?> getTimes(Interval interval) {
391
        return this.provider.getTimes(interval);
392
    }
393

    
394
    @Override
395
    public void disableNotifications() {
396
        this.delegateObservable.disableNotifications();
397
    }
398

    
399
    @Override
400
    public void enableNotifications() {
401
        this.delegateObservable.enableNotifications();
402

    
403
    }
404

    
405
    @Override
406
    public void beginComplexNotification() {
407
        this.delegateObservable.beginComplexNotification();
408

    
409
    }
410

    
411
    @Override
412
    public void endComplexNotification() {
413
        this.delegateObservable.endComplexNotification();
414
    }
415

    
416
    @Override
417
    public void addObserver(Observer observer) {
418
        if (delegateObservable != null) {
419
            this.delegateObservable.addObserver(observer);
420
        }
421
    }
422

    
423
    @Override
424
    public void deleteObserver(Observer observer) {
425
        if (delegateObservable != null) {
426
            this.delegateObservable.deleteObserver(observer);
427
        }
428

    
429
    }
430

    
431
    @Override
432
    public void deleteObservers() {
433
        this.delegateObservable.deleteObservers();
434
    }
435

    
436
    @Override
437
    public void saveToState(PersistentState state) throws PersistenceException {
438

    
439
        state.set("dataStoreName", this.getName());
440
        state.set("parameters", this.parameters);
441
    }
442

    
443
    @Override
444
    public void loadFromState(PersistentState state) throws PersistenceException {
445
        if (this.provider != null) {
446
            throw new PersistenceStoreAlreadyLoadedException(this.getName());
447
        }
448
        if (this.getManager() == null) {
449
            this.dataManager = (DefaultDataManager) DALLocator.getDataManager();
450
        }
451

    
452
        DataStoreParameters params = (DataStoreParameters) state.get("parameters");
453

    
454
        try {
455

    
456
            this.intialize(this.dataManager, params);
457
            this.setProvider(this.provider);
458

    
459
        } catch (InitializeException e) {
460
            throw new PersistenceException(e);
461
        } catch (DataException e) {
462
            throw new PersistenceException(e);
463
        }
464

    
465
    }
466

    
467
    //
468
    // ====================================================================
469
    // Metadata related methods
470
    //
471

    
472
    @Override
473
    public Set<?> getMetadataChildren() throws MetadataException {
474
        // TODO Auto-generated method stub
475
        return null;
476
    }
477

    
478
    @Override
479
    public Object getMetadataID() throws MetadataException {
480
        return this.provider.getSourceId();
481
    }
482

    
483
    @Override
484
    public String getMetadataName() throws MetadataException {
485
        return this.provider.getProviderName();
486
    }
487

    
488
    @Override
489
    public DynClass getDynClass() {
490
        return this.metadata.getDynClass();
491
    }
492

    
493
    @Override
494
    public void implement(DynClass dynClass) {
495
        this.metadata.implement(dynClass);
496
    }
497

    
498
    @Override
499
    public void delegate(DynObject dynObject) {
500
        this.metadata.delegate(dynObject);
501
    }
502

    
503
    @Override
504
    public Object getDynValue(String name) throws DynFieldNotFoundException {
505
        if (this.metadata.hasDynValue(name)) {
506
            return this.metadata.getDynValue(name);
507
        }
508
        if (METADATA_PROVIDER.equalsIgnoreCase(name)) {
509
            return this.provider.getProviderName();
510
        } else if (METADATA_CONTAINERNAME.equalsIgnoreCase(name)) {
511
            return this.provider.getSourceId();
512
        }
513
        return this.metadata.getDynValue(name);
514
    }
515

    
516
    @Override
517
    public void setDynValue(String name, Object value) throws DynFieldNotFoundException {
518

    
519
        this.metadata.setDynValue(name, value);
520

    
521
    }
522

    
523
    @Override
524
    public boolean hasDynValue(String name) {
525
        return this.metadata.hasDynValue(name);
526
    }
527

    
528
    @Override
529
    public Object invokeDynMethod(String name, Object[] args) throws DynMethodException {
530
        return this.metadata.invokeDynMethod(this, name, args);
531
    }
532

    
533
    @Override
534
    public Object invokeDynMethod(int code, Object[] args) throws DynMethodException {
535
        return this.metadata.invokeDynMethod(this, code, args);
536
    }
537

    
538
    @Override
539
    public void clear() {
540
        if (metadata != null) {
541
            metadata.clear();
542
        }
543
    }
544

    
545
    @Override
546
    public RasterQuery createRasterQuery() {
547
        return new DefaultRasterQuery();
548
    }
549

    
550
    @Override
551
    public DataStore getStore() {
552
        return this;
553
    }
554

    
555
    @Override
556
    public void update(Observable observable, Object notification) {
557
        if (observable instanceof DataSet) {
558
            this.notifyChange(RasterStoreNotification.DATASET_CHANGED);
559

    
560
        } else {
561
            if (observable instanceof RasterStoreProvider) {
562
                if (observable == this.provider) {
563
                    this.notifyChange(RasterStoreNotification.STORE_PROVIDER_CHANGED);
564
                }
565
            }
566
        }
567
    }
568

    
569
    @Override
570
    protected void doDispose() throws BaseException {
571

    
572
        this.notifyChange(DataStoreNotification.BEFORE_DISPOSE);
573
        this.provider.dispose();
574
        this.parameters = null;
575
        if(additionalBands!=null){
576
            for (Iterator iterator = additionalBands.iterator(); iterator.hasNext();) {
577
                BandsFromStore bandsFromStore = (BandsFromStore) iterator.next();
578
                bandsFromStore.getStore().dispose();
579
            }
580
            this.additionalBands = null;
581
        }
582

    
583
        this.notifyChange(DataStoreNotification.AFTER_DISPOSE);
584
        if (delegateObservable != null) {
585
            this.delegateObservable.deleteObservers();
586
            this.delegateObservable = null;
587
        }
588
    }
589

    
590
    @Override
591
    public Object clone() throws CloneNotSupportedException {
592
        DataStoreParameters dsp = getParameters();
593

    
594
        DefaultRasterStore cloned_store = null;
595

    
596
        try {
597
            cloned_store = (DefaultRasterStore) DALLocator.getDataManager().openStore(this.getProviderName(), dsp);
598
            cloned_store.additionalBands = new ArrayList<DefaultRasterStore.BandsFromStore>(additionalBands);
599
        } catch (Exception e) {
600
            throw new CloneException(e);
601
        }
602
        return cloned_store;
603

    
604
    }
605

    
606
    /**
607
     * Notifies change
608
     *
609
     * @param notification
610
     */
611
    public void notifyChange(String notification) {
612
        if (delegateObservable != null) {
613
            notifyChange(new DefaultRasterStoreNotification(this, notification));
614
        }
615

    
616
    }
617

    
618
    @Override
619
    public void notifyChange(String notification, ResourceProvider data) {
620
        notifyChange(new DefaultRasterStoreNotification(this, DataStoreNotification.RESOURCE_CHANGED));
621
    }
622

    
623
    /**
624
     * Notifies change
625
     *
626
     * @param storeNotification
627
     */
628
    public void notifyChange(DefaultRasterStoreNotification storeNotification) {
629
        try {
630
            delegateObservable.notifyObservers(storeNotification);
631
        } catch (Exception e) {
632
            LOG.warn("Problems notifying changes in store '"+getName()+"'.", e);
633
        }
634
    }
635

    
636
    /**
637
     * Gets this provider
638
     *
639
     * @return RasterStoreProvider
640
     */
641
    public RasterStoreProvider getProvider() {
642
        return this.provider;
643
    }
644

    
645
    @Override
646
    public Envelope getEnvelope() throws DataException, LocatorException, CreateEnvelopeException {
647
        return getDimensions().getEnvelope();
648
    }
649

    
650
//    @Override
651
//    public BandInfo getBandInfo(int band) {
652
//        int bands = this.provider.getBands();
653
//        if(band<bands){
654
//            return this.provider.getBandInfo(band);
655
//        }
656
//
657
//        if(additionalBands!=null){
658
//            for (BandsFromStore bandsFromStore : additionalBands) {
659
//                if((band-bands)<bandsFromStore.bands.size()){
660
//                    RasterStore store = bandsFromStore.getStore();
661
//                    int storeBand = bandsFromStore.get(band-bands);
662
//                    return store.getBandInfo(storeBand);
663
//                }
664
//                bands+=bandsFromStore.size();
665
//            }
666
//        }
667
//        return null;
668
//    }
669

    
670
    @Override
671
    public BandDescriptor getBandDescriptor(int band) {
672
        int bandsCounter = this.provider.getBands();
673
        if(band<bandsCounter){
674
            return this.provider.getBandDescriptor(band);
675
        }
676

    
677
        if(additionalBands!=null){
678
            for (BandsFromStore bandsFromStore : additionalBands) {
679
                if((band-bandsCounter)<bandsFromStore.bands.size()){
680
                    return bandsFromStore.getBandDescriptor(band-bandsCounter);
681
                }
682
                bandsCounter+=bandsFromStore.size();
683
            }
684
        }
685
        return null;
686
    }
687

    
688
    @Override
689
    public BandQuery createBandQuery(int band) {
690
        return new DefaultBandQuery(band, getBandDescriptor(band));
691
    }
692

    
693
    @Override
694
    public int getBands() {
695
        int bands = this.provider.getBands();
696
        if(additionalBands!=null){
697
            for (BandsFromStore bandsFromStore : additionalBands) {
698
                bands+=bandsFromStore.size();
699
            }
700
        }
701
        return bands;
702
    }
703

    
704
    @Override
705
    public BandDescriptor createBandDescriptor(int band, List<BandAttributeDescriptor> attributes) {
706
        return new DefaultBandDescriptor(this, band, attributes);
707
    }
708

    
709
    @Override
710
    public BandAttributeDescriptor createBandAttributeDescriptor(int band, String name, String description,
711
        List<Object> values, String units) {
712
        return new DefaultBandAttributeDescriptor(band, name, description, values, units);
713
    }
714

    
715
    @Override
716
    public BandAttributeDescriptor createBandAttributeDescriptor(int band, String name, Object value, String description,
717
        List<Object> values, String units) {
718
        return new DefaultBandAttributeDescriptor(band, name, value, description, values, units);
719
    }
720

    
721
    @Override
722
    public BandAttributeDescriptor createBandAttributeDescriptor(int band, String name, String description,
723
        List<Object> values) {
724
        return new DefaultBandAttributeDescriptor(band, name, description, values);
725
    }
726

    
727
    @Override
728
    public void notifyChange(String notification, Resource resource) {
729
        notifyChange(new DefaultRasterStoreNotification(this, DataStoreNotification.RESOURCE_CHANGED));
730
    }
731

    
732
    @Override
733
    public RasterStore getRasterStore() {
734
        return this;
735
    }
736

    
737
    @Override
738
    public void useCache(String providerName, DynObject parameters) throws DataException {
739

    
740
        if (providerName == null) {
741
            throw new InitializeException("It is necessary to provide a cache name", null);
742
        }
743
        if (parameters == null) {
744
            throw new InitializeException("It is necessary to provide parameters to create the explorer", null);
745
        }
746

    
747
        DataManagerProviderServices manager = DALSPILocator.getDataManagerProviderServices();
748
        RasterStoreProviderFactory providerFactory =
749
            (RasterStoreProviderFactory) manager.getStoreProviderFactory(providerName);
750

    
751
        if (providerFactory == null) {
752
            throw new ProviderNotRegisteredException(providerName);
753
        }
754

    
755
        RasterCacheStoreProvider cache =
756
            (RasterCacheStoreProvider) providerFactory.createProvider((DataParameters) parameters, this);
757

    
758
        RasterQuery rasterQuery = this.createRasterQuery();
759
        cache.apply(provider,
760
            (IProjection) this.getParameters().getDynValue(DataStore.METADATA_CRS), rasterQuery);
761
        this.provider = cache;
762
    }
763

    
764
    @Override
765
    public RasterCache getCache() {
766
        if(this.provider instanceof RasterCache){
767
            return (RasterCache) this.provider;
768
        }
769
        return null;
770
    }
771

    
772
    @Override
773
    public void intialize(DataManager dataManager, DataStoreParameters parameters) throws InitializeException {
774

    
775
        DynObjectManager dynManager = ToolsLocator.getDynObjectManager();
776

    
777
        this.metadata =
778
            (DelegatedDynObject) dynManager.createDynObject(METADATA_DEFINITION_NAME,
779
                MetadataManager.METADATA_NAMESPACE);
780

    
781
        this.dataManager = (DefaultDataManager) dataManager;
782

    
783
        this.parameters = parameters;
784

    
785
    }
786

    
787
    @Override
788
    public void setProvider(org.gvsig.fmap.dal.DataStoreProvider provider) {
789
        this.provider = (RasterStoreProvider) provider;
790
        this.delegate(this.provider);
791
    }
792

    
793
    @Override
794
    public void addBand(RasterStore store, int band) throws DataException {
795
        if(store.equals(this)){
796
            LOG.warn("Can't add bands that belong to this same store.");
797
            throw new IllegalArgumentException("Can't add bands that belong to this same store.");
798
        }
799

    
800
        try {
801
            if(!store.getEnvelope().equals(this.getEnvelope())){
802
                LOG.warn("The envelopes are differents.");
803
                throw new AddingBandsException(store.getName(), this.getName(), "The envelopes are differents.", null);
804
            }
805
        } catch (LocatorException | DataException | CreateEnvelopeException e) {
806
            LOG.warn("Can't compare the envelopes.",e);
807
            throw new AddingBandsException(store.getName(), this.getName(), "Can't compare the envelopes.", e);
808
        }
809

    
810
        if(!store.getParameters().getDynValue(METADATA_CRS).equals(this.getParameters().getDynValue(METADATA_CRS))){
811
            throw new AddingBandsException(store.getName(), this.getName(), "The projections are differents.", null);
812
        }
813

    
814
        if(additionalBands==null){
815
            this.additionalBands = new ArrayList<BandsFromStore>();
816
        }
817

    
818
        boolean found = false;
819
        for (Iterator iterator = additionalBands.iterator(); iterator.hasNext();) {
820
            BandsFromStore bandsFromStore = (BandsFromStore) iterator.next();
821
            if(bandsFromStore.getStore().equals(store)){
822
                found = true;
823
                if(bandsFromStore.contains(band)){
824
                    LOG.warn("The band '"+band+"' of the store '"+store.getName()+"' is already added to the additional bands.");
825
                } else {
826
                    bandsFromStore.add(band);
827
                }
828
                break;
829
            }
830
        }
831
        if(!found){
832
            BandsFromStore bandsFromStore = new BandsFromStore(store);
833
            bandsFromStore.add(band);
834
            this.additionalBands.add(bandsFromStore);
835
        }
836
    }
837

    
838
    @Override
839
    public void addBands(RasterStore store, List<Integer> bands) throws DataException {
840
        if(store.equals(this)){
841
            LOG.warn("Can't add bands that belong to this same store.");
842
            throw new IllegalArgumentException("Can't add bands that belong to this same store.");
843
        }
844

    
845
        try {
846
            if(!store.getEnvelope().equals(this.getEnvelope())){
847
                LOG.warn("The envelopes are differents.");
848
                throw new AddingBandsException(store.getName(), this.getName(), "The envelopes are differents.", null);
849
            }
850
        } catch (LocatorException | DataException | CreateEnvelopeException e) {
851
            LOG.warn("Can't compare the envelopes.",e);
852
            throw new AddingBandsException(store.getName(), this.getName(), "Can't compare the envelopes.", e);
853
        }
854

    
855
        if(!store.getParameters().getDynValue(METADATA_CRS).equals(this.getParameters().getDynValue(METADATA_CRS))){
856
            throw new AddingBandsException(store.getName(), this.getName(), "The projections are differents.", null);
857
        }
858

    
859
        if(additionalBands==null){
860
            this.additionalBands = new ArrayList<BandsFromStore>();
861
        }
862

    
863
        boolean found = false;
864
        for (BandsFromStore bandsFromStore : additionalBands) {
865
            if(bandsFromStore.getStore().equals(store)){
866
                found = true;
867
                for (Iterator<Integer> bandIterator = bands.iterator(); bandIterator.hasNext();) {
868
                    Integer band = (Integer) bandIterator.next();
869
                    bandsFromStore.add(band);
870
                }
871
            }
872
        }
873
        if(!found){
874
            BandsFromStore bandsFromStore = new BandsFromStore(store, bands);
875
            this.additionalBands.add(bandsFromStore);
876
        }
877
    }
878

    
879
    public void clearAdditionalBands(){
880
        //FIXME: recorrer todos y dispose de los stores
881
        this.additionalBands = null;
882
    }
883

    
884
    @Override
885
    public void removeBand(int band) {
886
        if(band<getProvider().getBands()){
887
            throw new IllegalArgumentException("Can't remove bands of main store.");
888
        }
889
        int bandCounter = getProvider().getBands();
890
        int storeCounter = 0;
891
        while(bandCounter < band){
892
            BandsFromStore additionalStore = this.additionalBands.get(storeCounter);
893
            if( (band-bandCounter) < additionalStore.size()){
894
                additionalStore.remove(band-bandCounter);
895
                if(additionalStore.size()==0){
896
                    DisposeUtils.disposeQuietly(additionalStore.getStore());
897
                    this.additionalBands.remove(additionalStore);
898
                }
899
                return;
900
            }
901
            bandCounter += additionalStore.size();
902
        }
903
    }
904

    
905
    private static class BandsFromStore{
906
        RasterStore store;
907
        List<Integer> bands;
908

    
909
        public BandsFromStore(RasterStore store){
910
            this.store = store;
911
            ToolsLocator.getDisposableManager().bind(store);
912
            this.bands = new ArrayList<Integer>();
913
        }
914

    
915
        public BandsFromStore(RasterStore store, List<Integer> bands){
916
            this.store = store;
917
            ToolsLocator.getDisposableManager().bind(store);
918
            this.bands = bands;
919
        }
920

    
921
        /**
922
         * Add the band to the list
923
         *
924
         * @param band
925
         */
926
        public void add(int band){
927
            if(bands.contains(band)){
928
                throw new IllegalArgumentException("The band "+band+" is already added.");
929
            }
930
            this.bands.add(band);
931
        }
932

    
933
        /**
934
         * Remove the band from the list
935
         * @param band
936
         */
937
        public void remove(int band){
938
            if(!bands.contains(band)){
939
                throw new IllegalArgumentException("The band "+band+" isn't previously added.");
940
            }
941
            this.bands.remove(band);
942
        }
943

    
944
        public boolean contains(int band){
945
            return (bands.contains(band));
946
        }
947

    
948
        /**
949
         * Return the band from the store in the index position
950
         *
951
         * @param index
952
         * @return
953
         */
954
        public int get(int index){
955
            return this.bands.get(index).intValue();
956
        }
957

    
958
        public RasterStore getStore() {
959
            return store;
960
        }
961

    
962
        public int size() {
963
            return bands.size();
964
        }
965

    
966
        /**
967
         * Return the BandDescriptor of the band in the index position.
968
         * @param index
969
         * @return
970
         */
971
        public BandDescriptor getBandDescriptor(int index) {
972
            return store.getBandDescriptor(bands.get(index));
973
        }
974

    
975
    }
976

    
977
    @Override
978
    public boolean isOwnBand(int band) {
979
        if(band < this.getProvider().getBands()){
980
            return true;
981
        }
982
        return false;
983
    }
984

    
985
    public DataStoreProviderFactory getProviderFactory() {
986
        DataStoreProviderFactory factory = dataManager.getStoreProviderFactory(parameters.getDataStoreName());
987
        return factory;
988
    }
989

    
990
    @Override
991
    public BufferDimensions getDimensions() throws InitializeException {
992
        return this.getProvider().getDimensions();
993
    }
994

    
995
    @Override
996
    public boolean isTiled() {
997
        return this.provider.isTiled();
998
    }
999

    
1000
    @Override
1001
    public boolean hasDynMethod(String name) {
1002
        return ((DynObject_v2)this.metadata).hasDynMethod(name);
1003
    }
1004
}