Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster / org.gvsig.fmap.mapcontext.raster / org.gvsig.fmap.mapcontext.raster.impl / src / main / java / org / gvsig / fmap / mapcontext / raster / impl / DefaultRasterLayer.java @ 8800

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

    
25
import java.awt.Graphics2D;
26
import java.awt.Point;
27
import java.awt.geom.Point2D;
28
import java.awt.image.BufferedImage;
29
import java.io.File;
30
import java.util.List;
31
import java.util.Observable;
32
import java.util.Observer;
33
import java.util.Set;
34
import java.util.TreeSet;
35

    
36
import org.cresques.cts.ICoordTrans;
37
import org.slf4j.LoggerFactory;
38

    
39
import org.gvsig.compat.print.PrintAttributes;
40
import org.gvsig.fmap.dal.DataStore;
41
import org.gvsig.fmap.dal.exception.DataException;
42
import org.gvsig.fmap.dal.exception.ReadException;
43
import org.gvsig.fmap.dal.raster.api.BandAttributeDescriptor;
44
import org.gvsig.fmap.dal.raster.api.BandDescriptor;
45
import org.gvsig.fmap.dal.raster.api.RasterQuery;
46
import org.gvsig.fmap.dal.raster.api.RasterSet;
47
import org.gvsig.fmap.dal.raster.api.RasterStore;
48
import org.gvsig.fmap.dal.raster.api.RasterStoreNotification;
49
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemStoreParameters;
50
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
51
import org.gvsig.fmap.geom.GeometryLocator;
52
import org.gvsig.fmap.geom.GeometryManager;
53
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
54
import org.gvsig.fmap.geom.primitive.Envelope;
55
import org.gvsig.fmap.mapcontext.MapContextLocator;
56
import org.gvsig.fmap.mapcontext.ViewPort;
57
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
58
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
59
import org.gvsig.fmap.mapcontext.layers.FLayer;
60
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
61
import org.gvsig.fmap.mapcontext.layers.LayerInformationBuilder;
62
import org.gvsig.fmap.mapcontext.raster.api.RasterLayer;
63
import org.gvsig.fmap.mapcontext.raster.api.legend.RasterLegendEvent;
64
import org.gvsig.fmap.mapcontext.raster.api.legend.listeners.RasterLegendChangedListener;
65
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
66
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
67
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
68
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent;
69
import org.gvsig.metadata.exceptions.MetadataException;
70
import org.gvsig.raster.lib.buffer.api.BufferLocator;
71
import org.gvsig.raster.lib.buffer.api.BufferManager;
72
import org.gvsig.raster.lib.buffer.api.statistics.Statistics;
73
import org.gvsig.raster.lib.buffer.api.statistics.StatisticsBand;
74
import org.gvsig.raster.lib.legend.api.RasterLegend;
75
import org.gvsig.raster.lib.legend.api.colorinterpretation.ColorInterpretation;
76
import org.gvsig.tools.ToolsLocator;
77
import org.gvsig.tools.dispose.DisposeUtils;
78
import org.gvsig.tools.dynobject.DynObjectSet;
79
import org.gvsig.tools.dynobject.DynStruct;
80
import org.gvsig.tools.dynobject.exception.DynMethodException;
81
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
82
import org.gvsig.tools.exception.BaseException;
83
import org.gvsig.tools.i18n.I18nManager;
84
import org.gvsig.tools.locator.LocatorException;
85
import org.gvsig.tools.persistence.PersistenceManager;
86
import org.gvsig.tools.persistence.Persistent;
87
import org.gvsig.tools.persistence.PersistentState;
88
import org.gvsig.tools.persistence.exception.PersistenceException;
89
import org.gvsig.tools.task.Cancellable;
90
import org.gvsig.tools.task.SimpleTaskStatus;
91
import org.gvsig.tools.task.TaskStatusManager;
92
import org.gvsig.tools.util.Callable;
93

    
94
/**
95
 * Capa b?sica Raster.
96
 *
97
 */
98
public class DefaultRasterLayer extends FLyrDefault implements RasterLayer, RasterLegendChangedListener, Observer {
99

    
100
    final static private org.slf4j.Logger logger = LoggerFactory.getLogger(DefaultRasterLayer.class);
101

    
102
    private RasterStore store;
103
    private RasterLegend legend;
104
    // private Cancellable cancel;
105
    private RasterQuery baseQuery;
106
    private Statistics statistics;
107

    
108
    public static class RegisterPersistence implements Callable {
109

    
110
        public Object call() {
111
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
112
            DynStruct definition =
113
                manager.addDefinition(DefaultRasterLayer.class, "DefaultRasterLayer",
114
                    "DefaultRasterLayer Persistence definition", null, null);
115
            definition.extend(PersistenceManager.PERSISTENCE_NAMESPACE, "FLyrDefault");
116
            definition.addDynFieldObject("legend").setClassOfValue(RasterLegend.class).setMandatory(true);
117
            definition.addDynFieldObject("store").setClassOfValue(RasterStore.class).setMandatory(true);
118
            definition.addDynFieldObject("baseQuery").setClassOfValue(RasterQuery.class).setMandatory(false);
119

    
120
            return Boolean.TRUE;
121
        }
122
    }
123

    
124
    /**
125
     * Creates a new DefaultRasterLayer
126
     *
127
     * @throws LoadLayerException
128
     */
129
    public DefaultRasterLayer() throws LoadLayerException {
130
        super();
131
    }
132

    
133
    /**
134
     * Creates a new DefaultRasterLayer
135
     *
136
     * @param store
137
     * @param legend
138
     */
139
    public DefaultRasterLayer(RasterStore store, RasterLegend legend) {
140
        super();
141
        ToolsLocator.getDisposableManager().bind(store);
142
        this.store = store;
143
        this.setLegend(legend);
144
    }
145

    
146
    public void saveToState(PersistentState state) throws PersistenceException {
147
        try {
148
            super.saveToState(state);
149

    
150
            state.set("store", (Persistent) this.store);
151
            state.set("legend", (Persistent) this.legend);
152
            state.set("baseQuery", (Persistent) this.baseQuery);
153

    
154
        } catch (PersistenceException ex) {
155
            logger.warn("Can't save to persistent state the layer '" + this.getName() + "'.");
156
            throw ex;
157
        } catch (RuntimeException ex) {
158
            logger.warn("Can't save to persistent state the layer '" + this.getName() + "'.");
159
            throw ex;
160
        }
161
    }
162

    
163
    public void loadFromState(PersistentState state) throws PersistenceException {
164

    
165
        try {
166
            super.loadFromState(state);
167

    
168
            this.store = (RasterStore) state.get("store");
169
            this.legend = (RasterLegend) state.get("legend");
170
            this.baseQuery = (RasterQuery) state.get("baseQuery");
171

    
172
        } catch (PersistenceException ex) {
173
            logger.warn("Can't load from persietent state the layer '" + this.getName() + "'.");
174
            throw ex;
175
        } catch (RuntimeException ex) {
176
            logger.warn("Can't load from persietent state the layer '" + this.getName() + "'.");
177
            throw ex;
178
        }
179

    
180
    }
181

    
182
    private void setLegend(RasterLegend legend) {
183
        if (this.legend == legend) {
184
            return;
185
        }
186
        if (this.legend != null && this.legend.equals(legend)) {
187
            return;
188
        }
189
        RasterLegend oldLegend = this.legend;
190
        if (oldLegend != null) {
191
             oldLegend.removeLegendListener( this);
192
//             oldLegend.deleteDrawingObserver(this);
193
        }
194
        this.legend = legend;
195
//        if (this.legend != null) {
196
//             this.legend.addDrawingObserver(this);
197
//             this.legend.addLegendListener( this);
198
//        }
199

    
200
        ColorInterpretation colorInterpretation = legend.getColorInterpretation();
201
        if (colorInterpretation.isPalette()) {
202
            legend.addColorTableOperation(colorInterpretation, 0);
203
        } else {
204
            legend.addLinearStretchEnhancementOperationIfNeeded(colorInterpretation, getRasterStore(), 0);
205
        }
206

    
207
        this.legend.addLegendListener(this);
208

    
209
        LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(oldLegend, this.legend);
210
        // FIXME: cuando se arregle LegendChangeEvent para que admita capas
211
        // raster (y no solo las ClassifiableVectorial) descomentarizar la siguiente l?nea
212
        // e.setLayer(this);
213
        updateDrawVersion();
214
        callLegendChanged(e);
215
    }
216

    
217
    /**
218
     * Devuelve la Leyenda de la capa.
219
     *
220
     * @return Leyenda.
221
     */
222
    public RasterLegend getLegend(){
223
        if (legend == null) {
224
            try {
225
                initLegend();
226
            } catch (LegendLayerException e) {
227
                throw new RuntimeException("Can't initialize legend.", e);
228
            }
229
        }
230
        return legend;
231
    }
232

    
233
    @Override
234
    public DataStore getDataStore() {
235
        return this.store;
236
    }
237

    
238
    @Override
239
    public void setDataStore(DataStore dataStore) throws LoadLayerException {
240

    
241
        if (this.store != null) {
242
            ToolsLocator.getDisposableManager().release(this.store);
243
            DisposeUtils.disposeQuietly(this.store);
244
        }
245

    
246
        this.store = (RasterStore) dataStore;
247
        ToolsLocator.getDisposableManager().bind(dataStore);
248
        initLegend();
249
    }
250

    
251
    /**
252
     * Initializes the legend if it is not initalized yet
253
     *
254
     * @throws LegendLayerException
255
     */
256
    private void initLegend() throws LegendLayerException {
257
        RasterLegend legend = null;
258
        if (this.legend == null) {
259
            // Should be done like this but must be corrected mapContextManager
260
            // MapContextManager mapContextManager =
261
            // MapContextLocator.getMapContextManager();
262
            // Set the legend
263
            // IRasterLegend legend = (IRasterLegend)
264
            // mapContextManager.getLegend(store);
265

    
266
            // Should be moved to mapContextManager when RasterLegend implements
267
            // ILegend
268
            if (legend == null) {
269
                try {
270
                    legend = (RasterLegend) store.invokeDynMethod(RasterStore.DYNMETHOD_GETLEGEND_NAME, null);
271
                } catch (DynMethodNotSupportedException e) {
272
                    logger.debug("This store {} does not provide a legend.", store.getName());
273
                } catch (DynMethodException e) {
274
                    logger.error("Can't load the specific legend provided for the store {}.", store.getName(), e);
275
                }
276
            }
277

    
278
            if (legend == null) {
279
                throw new LegendLayerException(this.getName());
280
            }
281

    
282
            this.setLegend(legend);
283
        }
284
    }
285

    
286
    @Override
287
    public Envelope getFullEnvelope() throws ReadException {
288
        Envelope rAux;
289
        try {
290
            rAux = getRasterStore().getEnvelope();
291
        } catch (BaseException e) {
292
            throw new ReadException(getName(), e);
293
        }
294

    
295
        // Esto es para cuando se crea una capa nueva con el fullExtent de ancho
296
        // y alto 0.
297
        if (rAux == null || rAux.isEmpty() || rAux.getMaximum(0) - rAux.getMinimum(0) == 0
298
            && rAux.getMaximum(1) - rAux.getMinimum(1) == 0) {
299
            try {
300
                GeometryManager geomManager = GeometryLocator.getGeometryManager();
301
                rAux = geomManager.createEnvelope(0, 0, 90, 90, SUBTYPES.GEOM2D);
302
            } catch (CreateEnvelopeException e) {
303
                logger.error("Error creating the envelope", e);
304
                e.printStackTrace();
305
            }
306
        }
307
        // Si existe reproyecci?n, reproyectar el extent
308
        ICoordTrans ct = getCoordTrans();
309
        if (ct != null) {
310
            rAux = rAux.convert(ct);
311
        }
312
        return rAux;
313
    }
314

    
315
    @Override
316
    public void draw(BufferedImage image, final Graphics2D g, final ViewPort viewPort, Cancellable cancel, double scale)
317
        throws ReadException {
318
        if (legend == null) {
319
            try {
320
                initLegend();
321
            } catch (LegendLayerException e) {
322
                logger.warn("Can't initialize the legend", e);
323
                return;
324
            }
325
            return;
326
        }
327

    
328
        if (!this.isWithinScale(scale)) {
329
            return;
330
        }
331
        if (cancel.isCanceled()) {
332
            return;
333
        }
334

    
335
        RasterQuery rasterQuery = createRasterQuery();
336
        Envelope reprojectedViewPortEnvelope = (Envelope) viewPort.getAdjustedEnvelope(); // .getEnvelope();
337
        ICoordTrans ct = getCoordTrans();
338
        if (ct != null) {
339
            try {
340
                reprojectedViewPortEnvelope = (Envelope) reprojectedViewPortEnvelope.clone();
341
                reprojectedViewPortEnvelope = reprojectedViewPortEnvelope.convert(ct.getInverted());
342
            } catch (CloneNotSupportedException e) {
343
                this.setAvailable(false);
344
                this.setError(e);
345
                throw new ReadException(getName(), e);
346
            }
347
        }
348

    
349
        double pixelSize = reprojectedViewPortEnvelope.getLength(0) / (double) viewPort.getImageWidth();
350

    
351
        rasterQuery.setPixelSize(pixelSize);
352
        rasterQuery.setClip(reprojectedViewPortEnvelope);
353

    
354
        // ColorInterpretation colorInterpretation =
355
        // legend.getColorInterpretation();
356
        // String[] renderBands =
357
        // colorInterpretation.getValues();//.buildRenderBands();
358
        // for (int i = 0; i < renderBands.length; i++) {
359
        // int band = colorInterpretation.getBand(renderBands[i]);
360
        // if(band>=0){
361
        // rasterQuery.addBand(this.store.createBandQuery(band));
362
        // }
363
        // }
364

    
365
        RasterSet rasterSet = null;
366
        try {
367

    
368
            long tini = System.currentTimeMillis();
369

    
370
            // TODO Task status should be used to cancel
371
            TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
372
            final SimpleTaskStatus taskStatus = manager.createDefaultSimpleTaskStatus("Draw " + getDataStore().getName());
373

    
374
//            getRasterStore().getRasterSet(rasterQuery, new org.gvsig.tools.observer.Observer() {
375
//
376
//                @Override
377
//                public void update(org.gvsig.tools.observer.Observable buffer, Object notification) {
378
//                    ((RasterLegend) legend).draw(g, buffer, viewPort, taskStatus);
379
//                }
380
//            });
381

    
382
            rasterSet = getRasterStore().getRasterSet(rasterQuery);
383
            // BufferedImage img = rasterSet.getBufferedImage();
384
            // if (img != null) {
385
            // try {
386
            // ImageIO.write(rasterSet.getBufferedImage(), "png32", new
387
            // File("/tmp/"+rasterSet.getClass().getName()+".png"));
388
            // } catch (IOException e) {
389
            // // TODO Auto-generated catch block
390
            // e.printStackTrace();
391
            // }
392
            // }
393
            if (!rasterSet.isEmpty()) {
394
                ((RasterLegend) legend).draw(g, rasterSet, viewPort, taskStatus);
395

    
396
                logger.debug("Layer " + this.getName() + " drawn in " + (System.currentTimeMillis() - tini)
397
                    + " milliseconds.");
398
            }
399

    
400
        } catch (DataException e) {
401
            this.setAvailable(false);
402
            this.setError(e);
403
            throw new ReadException(getName(), e);
404
        } finally {
405
            if (rasterSet != null) {
406
                DisposeUtils.dispose(rasterSet);
407
                rasterSet = null;
408
            }
409
        }
410

    
411
    }
412

    
413
    @Override
414
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintAttributes properties)
415
        throws ReadException {
416

    
417
        // TODO legend doesn't have print method
418
        throw new UnsupportedOperationException();
419

    
420
    }
421

    
422
    @Override
423
    public Set<RasterStore> getMetadataChildren() throws MetadataException {
424
        Set<RasterStore> ret = new TreeSet<RasterStore>();
425
        ret.add(this.store);
426
        return ret;
427
    }
428

    
429
    @Override
430
    public Object getMetadataID() throws MetadataException {
431
        return "Layer(" + this.getName() + "):" + this.store.getMetadataID();
432
    }
433

    
434
    @Override
435
    public void update(Observable observable, Object notification) {
436
        if (observable.equals(this.store)) {
437
            if (notification instanceof RasterStoreNotification) {
438
                RasterStoreNotification event = (RasterStoreNotification) notification;
439
                if (event.getType() == RasterStoreNotification.AFTER_REFRESH
440
                    || event.getType() == RasterStoreNotification.SELECTION_CHANGE) {
441
                    this.updateDrawVersion();
442
                } else if (event.getType() == RasterStoreNotification.RESOURCE_CHANGED) {
443
                    this.setAvailable(false);
444
                }
445
            }
446
        }
447
    }
448

    
449
    @Override
450
    public RasterStore getRasterStore() {
451
        return this.store;
452
    }
453

    
454
    @Override
455
    public void setBaseQuery(RasterQuery baseQuery) {
456
        this.baseQuery = baseQuery;
457
    }
458

    
459
    @Override
460
    public RasterQuery getBaseQuery() {
461
        return this.baseQuery;
462
    }
463

    
464
    @Override
465
    public RasterQuery createRasterQuery() {
466
        if (this.baseQuery == null) {
467
            return this.getRasterStore().createRasterQuery();
468
        }
469
        try {
470
            return (RasterQuery) baseQuery.clone();
471
        } catch (CloneNotSupportedException ex) {
472
            throw new RuntimeException(ex);
473
        }
474
    }
475

    
476
    @Override
477
    protected void doDispose() throws BaseException {
478
        DisposeUtils.dispose(this.store);
479
        this.store = null;
480
        this.legend = null;
481
        this.baseQuery = null;
482
    }
483

    
484
    @Override
485
    public DynObjectSet getInfo(Point p, double tolerance, Cancellable cancel) throws LoadLayerException, DataException {
486

    
487
        return getInfo(p, tolerance, cancel, true);
488
    }
489

    
490
    @Override
491
    public DynObjectSet getInfo(Point p, double tolerance, Cancellable cancel, boolean fast) throws LoadLayerException,
492
        DataException {
493

    
494
        Point2D infop = new Point2D.Double(p.x, p.y);
495
        org.gvsig.fmap.geom.primitive.Point pReal = this.getMapContext().getViewPort().convertToMapPoint(infop);
496

    
497
        // TODO:
498
        return null;
499
    }
500

    
501
    @Override
502
    public DynObjectSet getInfo(org.gvsig.fmap.geom.primitive.Point p, double tolerance) throws LoadLayerException,
503
        DataException {
504
        // TODO Auto-generated method stub
505
        return null;
506
    }
507

    
508
    public String getTocImageIcon() {
509
        //FIXME: Subir esto a la clase abstracta
510
        return MapContextLocator.getMapContextManager().getIconLayer(this.getDataStore());
511
    }
512

    
513
    @Override
514
    public void setLegend(ILegend legend) {
515
        if (legend instanceof RasterLegend) {
516
            setLegend((RasterLegend) legend);
517
        } else {
518
            throw new IllegalArgumentException("The legend isn't a RasterLegend.");
519
        }
520
    }
521

    
522
    @Override
523
    public String getInfoString() {
524
        RasterStore rasterStore = this.getRasterStore();
525
        Envelope envelope = null;
526
        try {
527
            envelope = rasterStore.getEnvelope();
528
        } catch (LocatorException | DataException | CreateEnvelopeException e) {
529
        }
530
        int bands = rasterStore.getBands();
531
        I18nManager i18nManager = ToolsLocator.getI18nManager();
532
        LayerInformationBuilder builder = MapContextLocator.getMapContextManager().createLayerInformationBuilder();
533

    
534
        builder.title().labelkey("Data_source");
535
        builder.property().labelkey("Source_type").value(store.getProviderName());
536
        builder.property().labelkey("origen").value(store.getFullName());
537
        if (store.getParameters() instanceof FilesystemStoreParameters) {
538
            File f = ((FilesystemStoreParameters) (store.getParameters())).getFile();
539
            if (f != null) {
540
                builder.property().labelkey("size").value("%d bytes", f.length());
541
            }
542
        }
543

    
544
        builder.property().labelkey("_bands").value("%d", bands);
545
        builder.property().labelkey("transparency").value("%d", this.getTransparency());
546

    
547
        builder.title().labelkey("_Coordenadas_geograficas");
548
        builder.envelope().value(envelope);
549

    
550
        builder.title().labelkey("_Projection");
551
        builder.property().value(this.getProjection());
552
        builder.text().asWKT(this.getProjection());
553

    
554
        for (int i = 0; i < bands; i++) {
555
            builder.title().labelkey(i18nManager.getTranslation("_band") + " " + i);
556

    
557
            BandDescriptor bandDescriptor = rasterStore.getBandDescriptor(i);
558

    
559
            builder.property().labelkey("_name").value(bandDescriptor.getName());
560
            builder.property().labelkey("_description").value(bandDescriptor.getDescription());
561
            builder.property().labelkey("_dataType")
562
                .value(BufferLocator.getBufferManager().getTypeName(bandDescriptor.getDataType()));
563

    
564
            if (bandDescriptor.getNoData() != null) {
565
                builder.property().labelkey("_noData").value(bandDescriptor.getNoData().toString());
566
            } else {
567
                builder.property().labelkey("_noData").value(i18nManager.getTranslation("_null"));
568
            }
569

    
570
            for (BandAttributeDescriptor bandAttributeDescriptor : bandDescriptor) {
571
                builder.property().labelkey("_name").value(bandAttributeDescriptor.getName());
572
                builder.property().labelkey("_description").value(bandAttributeDescriptor.getDescription());
573
                builder.property().labelkey("_units").value(bandAttributeDescriptor.getUnits());
574

    
575
                builder.title().labelkey("_values");
576

    
577
                List<Object> attributeValues = bandAttributeDescriptor.getAvailableValues();
578

    
579
                for (Object value : attributeValues) {
580
                    if (value != null) {
581
                        builder.property().labelkey("_units").value(bandAttributeDescriptor.getUnits());
582
                    } else {
583
                        builder.property().labelkey("_units").value(bandAttributeDescriptor.getUnits());
584
                    }
585
                }
586
            }
587
        }
588

    
589
        return builder.toString();
590
    }
591

    
592
    private String dataTypeString(int dataType) {
593

    
594
        // FIXME
595
        switch (dataType) {
596
        case BufferManager.TYPE_BYTE:
597
            return "Byte";
598
        case BufferManager.TYPE_USHORT:
599
            return "Unsigned short";
600
        case BufferManager.TYPE_SHORT:
601
            return "Short";
602
        case BufferManager.TYPE_INT:
603
            return "Integer";
604
        case BufferManager.TYPE_FLOAT:
605
            return "Float";
606
        case BufferManager.TYPE_DOUBLE:
607
            return "Double";
608
        default:
609
            throw new IllegalArgumentException();
610
        }
611
    }
612

    
613
    @Override
614
    public String getStatisticsString() {
615
        I18nManager i18nManager = ToolsLocator.getI18nManager();
616

    
617
        LayerInformationBuilder builder = MapContextLocator.getMapContextManager().createLayerInformationBuilder();
618

    
619
        this.statistics = getStatistics(null);
620

    
621
        int bandCounter = 0;
622
        for (StatisticsBand statisticsBand : this.statistics) {
623

    
624
            builder.title().labelkey(i18nManager.getTranslation("_band") + " " + bandCounter);
625

    
626
            int dataType = statisticsBand.getDataType();
627
            builder.property().labelkey("_dataType").value(dataTypeString(dataType));
628

    
629
            Long dataCount = statisticsBand.getBandLength();
630
            builder.property().labelkey("_dataCount").value(dataCount.toString());
631

    
632
            Long noDataValuesCount = statisticsBand.getNoDataValuesCount();
633
            builder.property().labelkey("_noDataValuesCount").value(noDataValuesCount.toString());
634

    
635
            Double minimum = statisticsBand.getMinimum();
636
            builder.property().labelkey("_minimum").value(minimum.toString());
637

    
638
            Double maximum = statisticsBand.getMaximum();
639
            builder.property().labelkey("_maximum").value(maximum.toString());
640

    
641
            Double mean = statisticsBand.getMean();
642
            builder.property().labelkey("_mean").value(mean.toString());
643

    
644
            Double median = statisticsBand.getMedian();
645
            builder.property().labelkey("_median").value(median.toString());
646

    
647
            Double secondMin = statisticsBand.getSecondMin();
648
            builder.property().labelkey("_secondMin").value(secondMin.toString());
649

    
650
            Double secondMax = statisticsBand.getSecondMax();
651
            builder.property().labelkey("_secondMax").value(secondMax.toString());
652

    
653
            Double variance = statisticsBand.getVariance();
654
            builder.property().labelkey("_variance").value(variance.toString());
655

    
656
            int bandCounter2 = 0;
657
            for (StatisticsBand statisticsBand2 : statistics) {
658
                if (bandCounter != bandCounter2) {
659
                    Double covariance = statisticsBand.getCovariance(statisticsBand2);
660
                    builder.property().label(i18nManager.getTranslation("_covariance_with_band") + " " + bandCounter2)
661
                        .value(covariance.toString());
662
                }
663
                bandCounter2++;
664
            }
665
            bandCounter++;
666
        }
667

    
668
        return builder.toString();
669
    }
670

    
671
    public Statistics getStatistics(SimpleTaskStatus status) {
672
        if (statistics == null) {
673
            try {
674
                statistics = getRasterStore().getRasterSet().getStatistics(status);
675
            } catch (DataException e) {
676
                logger.warn("Can't get layer's statistics", e);
677
            }
678
        }
679
        return statistics;
680
    }
681

    
682
    public void recalculateStatistics() {
683
        this.statistics = null;
684
    }
685

    
686
    @Override
687
    public FLayer cloneLayer() throws Exception {
688
        RasterLegend clonedLegend = (RasterLegend)this.legend.cloneLegend();
689
        DefaultRasterLayer cloned = new DefaultRasterLayer(this.store, clonedLegend);
690
        cloned.setName(this.getName());
691
        cloned.setProjection(this.getProjection());
692

    
693
        return cloned;
694
    }
695

    
696
    @Override
697
    public boolean symbolChanged(SymbolLegendEvent e) {
698
        //FIXME: Remove when fixed hierarchy of legend events
699
        throw new UnsupportedOperationException("There aren't any symbols in a raster legend.");
700
    }
701

    
702
    @Override
703
    public void legendCleared(LegendClearEvent event) {
704
        //FIXME: Remove when fixed hierarchy of legend events
705
        throw new UnsupportedOperationException("Can't clear a raster legend.");
706
    }
707

    
708
    @Override
709
    public boolean colorInterpretationChanged(RasterLegendEvent e) {
710
        this.updateDrawVersion();
711

    
712
        LegendChangedEvent ev = LegendChangedEvent.createLegendChangedEvent(legend, e);
713
        this.callLegendChanged(ev);
714
        return true;
715
    }
716

    
717
    @Override
718
    public boolean operationListChanged(RasterLegendEvent e) {
719
        this.updateDrawVersion();
720

    
721
        LegendChangedEvent ev = LegendChangedEvent.createLegendChangedEvent(legend, e);
722
        this.callLegendChanged(ev);
723
        return true;
724
    }
725
}