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

History | View | Annotate | Download (25.9 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, Graphics2D g, 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
            SimpleTaskStatus taskStatus = manager.createDefaultSimpleTaskStatus("Draw " + getDataStore().getName());
373

    
374
            rasterSet = getRasterStore().getRasterSet(rasterQuery);
375
            // BufferedImage img = rasterSet.getBufferedImage();
376
            // if (img != null) {
377
            // try {
378
            // ImageIO.write(rasterSet.getBufferedImage(), "png32", new
379
            // File("/tmp/"+rasterSet.getClass().getName()+".png"));
380
            // } catch (IOException e) {
381
            // // TODO Auto-generated catch block
382
            // e.printStackTrace();
383
            // }
384
            // }
385
            if (!rasterSet.isEmpty()) {
386
                ((RasterLegend) legend).draw(g, rasterSet, viewPort, taskStatus);
387

    
388
                logger.debug("Layer " + this.getName() + " drawn in " + (System.currentTimeMillis() - tini)
389
                    + " milliseconds.");
390
            }
391

    
392
        } catch (DataException e) {
393
            this.setAvailable(false);
394
            this.setError(e);
395
            throw new ReadException(getName(), e);
396
        } finally {
397
            if (rasterSet != null) {
398
                DisposeUtils.dispose(rasterSet);
399
                rasterSet = null;
400
            }
401
        }
402

    
403
    }
404

    
405
    @Override
406
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintAttributes properties)
407
        throws ReadException {
408

    
409
        // TODO legend doesn't have print method
410
        throw new UnsupportedOperationException();
411

    
412
    }
413

    
414
    @Override
415
    public Set<RasterStore> getMetadataChildren() throws MetadataException {
416
        Set<RasterStore> ret = new TreeSet<RasterStore>();
417
        ret.add(this.store);
418
        return ret;
419
    }
420

    
421
    @Override
422
    public Object getMetadataID() throws MetadataException {
423
        return "Layer(" + this.getName() + "):" + this.store.getMetadataID();
424
    }
425

    
426
    @Override
427
    public void update(Observable observable, Object notification) {
428
        if (observable.equals(this.store)) {
429
            if (notification instanceof RasterStoreNotification) {
430
                RasterStoreNotification event = (RasterStoreNotification) notification;
431
                if (event.getType() == RasterStoreNotification.AFTER_REFRESH
432
                    || event.getType() == RasterStoreNotification.SELECTION_CHANGE) {
433
                    this.updateDrawVersion();
434
                } else if (event.getType() == RasterStoreNotification.RESOURCE_CHANGED) {
435
                    this.setAvailable(false);
436
                }
437
            }
438
        }
439
    }
440

    
441
    @Override
442
    public RasterStore getRasterStore() {
443
        return this.store;
444
    }
445

    
446
    @Override
447
    public void setBaseQuery(RasterQuery baseQuery) {
448
        this.baseQuery = baseQuery;
449
    }
450

    
451
    @Override
452
    public RasterQuery getBaseQuery() {
453
        return this.baseQuery;
454
    }
455

    
456
    @Override
457
    public RasterQuery createRasterQuery() {
458
        if (this.baseQuery == null) {
459
            return this.getRasterStore().createRasterQuery();
460
        }
461
        try {
462
            return (RasterQuery) baseQuery.clone();
463
        } catch (CloneNotSupportedException ex) {
464
            throw new RuntimeException(ex);
465
        }
466
    }
467

    
468
    @Override
469
    protected void doDispose() throws BaseException {
470
        DisposeUtils.dispose(this.store);
471
        this.store = null;
472
        this.legend = null;
473
        this.baseQuery = null;
474
    }
475

    
476
    @Override
477
    public DynObjectSet getInfo(Point p, double tolerance, Cancellable cancel) throws LoadLayerException, DataException {
478

    
479
        return getInfo(p, tolerance, cancel, true);
480
    }
481

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

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

    
489
        // TODO:
490
        return null;
491
    }
492

    
493
    @Override
494
    public DynObjectSet getInfo(org.gvsig.fmap.geom.primitive.Point p, double tolerance) throws LoadLayerException,
495
        DataException {
496
        // TODO Auto-generated method stub
497
        return null;
498
    }
499

    
500
    public String getTocImageIcon() {
501
        return "layer-icon-raster";
502
    }
503

    
504
    @Override
505
    public void setLegend(ILegend legend) {
506
        if (legend instanceof RasterLegend) {
507
            setLegend((RasterLegend) legend);
508
        } else {
509
            throw new IllegalArgumentException("The legend isn't a RasterLegend.");
510
        }
511
    }
512

    
513
    @Override
514
    public String getInfoString() {
515
        RasterStore rasterStore = this.getRasterStore();
516
        Envelope envelope = null;
517
        try {
518
            envelope = rasterStore.getEnvelope();
519
        } catch (LocatorException | DataException | CreateEnvelopeException e) {
520
        }
521
        int bands = rasterStore.getBands();
522
        I18nManager i18nManager = ToolsLocator.getI18nManager();
523
        LayerInformationBuilder builder = MapContextLocator.getMapContextManager().createLayerInformationBuilder();
524

    
525
        builder.title().labelkey("Data_source");
526
        builder.property().labelkey("Source_type").value(store.getProviderName());
527
        builder.property().labelkey("origen").value(store.getFullName());
528
        if (store.getParameters() instanceof FilesystemStoreParameters) {
529
            File f = ((FilesystemStoreParameters) (store.getParameters())).getFile();
530
            if (f != null) {
531
                builder.property().labelkey("size").value("%d bytes", f.length());
532
            }
533
        }
534

    
535
        builder.property().labelkey("_bands").value("%d", bands);
536
        builder.property().labelkey("transparency").value("%d", this.getTransparency());
537

    
538
        builder.title().labelkey("_Coordenadas_geograficas");
539
        builder.envelope().value(envelope);
540

    
541
        builder.title().labelkey("_Projection");
542
        builder.property().value(this.getProjection());
543
        builder.text().asWKT(this.getProjection());
544

    
545
        for (int i = 0; i < bands; i++) {
546
            builder.title().labelkey(i18nManager.getTranslation("_band") + " " + i);
547

    
548
            BandDescriptor bandDescriptor = rasterStore.getBandDescriptor(i);
549

    
550
            builder.property().labelkey("_name").value(bandDescriptor.getName());
551
            builder.property().labelkey("_description").value(bandDescriptor.getDescription());
552
            builder.property().labelkey("_dataType")
553
                .value(BufferLocator.getBufferManager().getTypeName(bandDescriptor.getDataType()));
554

    
555
            if (bandDescriptor.getNoData() != null) {
556
                builder.property().labelkey("_noData").value(bandDescriptor.getNoData().toString());
557
            } else {
558
                builder.property().labelkey("_noData").value(i18nManager.getTranslation("_null"));
559
            }
560

    
561
            for (BandAttributeDescriptor bandAttributeDescriptor : bandDescriptor) {
562
                builder.property().labelkey("_name").value(bandAttributeDescriptor.getName());
563
                builder.property().labelkey("_description").value(bandAttributeDescriptor.getDescription());
564
                builder.property().labelkey("_units").value(bandAttributeDescriptor.getUnits());
565

    
566
                builder.title().labelkey("_values");
567

    
568
                List<Object> attributeValues = bandAttributeDescriptor.getAvailableValues();
569

    
570
                for (Object value : attributeValues) {
571
                    if (value != null) {
572
                        builder.property().labelkey("_units").value(bandAttributeDescriptor.getUnits());
573
                    } else {
574
                        builder.property().labelkey("_units").value(bandAttributeDescriptor.getUnits());
575
                    }
576
                }
577
            }
578
        }
579

    
580
        return builder.toString();
581
    }
582

    
583
    private String dataTypeString(int dataType) {
584

    
585
        // FIXME
586
        switch (dataType) {
587
        case BufferManager.TYPE_BYTE:
588
            return "Byte";
589
        case BufferManager.TYPE_USHORT:
590
            return "Unsigned short";
591
        case BufferManager.TYPE_SHORT:
592
            return "Short";
593
        case BufferManager.TYPE_INT:
594
            return "Integer";
595
        case BufferManager.TYPE_FLOAT:
596
            return "Float";
597
        case BufferManager.TYPE_DOUBLE:
598
            return "Double";
599
        default:
600
            throw new IllegalArgumentException();
601
        }
602
    }
603

    
604
    @Override
605
    public String getStatisticsString() {
606
        I18nManager i18nManager = ToolsLocator.getI18nManager();
607

    
608
        LayerInformationBuilder builder = MapContextLocator.getMapContextManager().createLayerInformationBuilder();
609

    
610
        this.statistics = getStatistics(null);
611

    
612
        int bandCounter = 0;
613
        for (StatisticsBand statisticsBand : this.statistics) {
614

    
615
            builder.title().labelkey(i18nManager.getTranslation("_band") + " " + bandCounter);
616

    
617
            int dataType = statisticsBand.getDataType();
618
            builder.property().labelkey("_dataType").value(dataTypeString(dataType));
619

    
620
            Long dataCount = statisticsBand.getBandLength();
621
            builder.property().labelkey("_dataCount").value(dataCount.toString());
622

    
623
            Long noDataValuesCount = statisticsBand.getNoDataValuesCount();
624
            builder.property().labelkey("_noDataValuesCount").value(noDataValuesCount.toString());
625

    
626
            Double minimum = statisticsBand.getMinimum();
627
            builder.property().labelkey("_minimum").value(minimum.toString());
628

    
629
            Double maximum = statisticsBand.getMaximum();
630
            builder.property().labelkey("_maximum").value(maximum.toString());
631

    
632
            Double mean = statisticsBand.getMean();
633
            builder.property().labelkey("_mean").value(mean.toString());
634

    
635
            Double median = statisticsBand.getMedian();
636
            builder.property().labelkey("_median").value(median.toString());
637

    
638
            Double secondMin = statisticsBand.getSecondMin();
639
            builder.property().labelkey("_secondMin").value(secondMin.toString());
640

    
641
            Double secondMax = statisticsBand.getSecondMax();
642
            builder.property().labelkey("_secondMax").value(secondMax.toString());
643

    
644
            Double variance = statisticsBand.getVariance();
645
            builder.property().labelkey("_variance").value(variance.toString());
646

    
647
            int bandCounter2 = 0;
648
            for (StatisticsBand statisticsBand2 : statistics) {
649
                if (bandCounter != bandCounter2) {
650
                    Double covariance = statisticsBand.getCovariance(statisticsBand2);
651
                    builder.property().label(i18nManager.getTranslation("_covariance_with_band") + " " + bandCounter2)
652
                        .value(covariance.toString());
653
                }
654
                bandCounter2++;
655
            }
656
            bandCounter++;
657
        }
658

    
659
        return builder.toString();
660
    }
661

    
662
    public Statistics getStatistics(SimpleTaskStatus status) {
663
        if (statistics == null) {
664
            try {
665
                statistics = getRasterStore().getRasterSet().getStatistics(status);
666
            } catch (DataException e) {
667
                logger.warn("Can't get layer's statistics", e);
668
            }
669
        }
670
        return statistics;
671
    }
672

    
673
    public void recalculateStatistics() {
674
        this.statistics = null;
675
    }
676

    
677
    @Override
678
    public FLayer cloneLayer() throws Exception {
679
        RasterLegend clonedLegend = (RasterLegend)this.legend.cloneLegend();
680
        DefaultRasterLayer cloned = new DefaultRasterLayer(this.store, clonedLegend);
681
        cloned.setName(this.getName());
682
        cloned.setProjection(this.getProjection());
683

    
684
        return cloned;
685
    }
686

    
687
    @Override
688
    public boolean symbolChanged(SymbolLegendEvent e) {
689
        //FIXME: Remove when fixed hierarchy of legend events
690
        throw new UnsupportedOperationException("There aren't any symbols in a raster legend.");
691
    }
692

    
693
    @Override
694
    public void legendCleared(LegendClearEvent event) {
695
        //FIXME: Remove when fixed hierarchy of legend events
696
        throw new UnsupportedOperationException("Can't clear a raster legend.");
697
    }
698

    
699
    @Override
700
    public boolean colorInterpretationChanged(RasterLegendEvent e) {
701
        this.updateDrawVersion();
702

    
703
        LegendChangedEvent ev = LegendChangedEvent.createLegendChangedEvent(legend, e);
704
        this.callLegendChanged(ev);
705
        return true;
706
    }
707
}