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

History | View | Annotate | Download (11.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.image.BufferedImage;
27
import java.util.Observable;
28
import java.util.Observer;
29
import java.util.Set;
30
import java.util.TreeSet;
31

    
32
import org.cresques.cts.ICoordTrans;
33
import org.slf4j.LoggerFactory;
34

    
35
import org.gvsig.compat.print.PrintAttributes;
36
import org.gvsig.fmap.dal.DataStore;
37
import org.gvsig.fmap.dal.exception.DataException;
38
import org.gvsig.fmap.dal.exception.ReadException;
39
import org.gvsig.fmap.dal.raster.api.RasterQuery;
40
import org.gvsig.fmap.dal.raster.api.RasterSet;
41
import org.gvsig.fmap.dal.raster.api.RasterStore;
42
import org.gvsig.fmap.dal.raster.api.RasterStoreNotification;
43
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
44
import org.gvsig.fmap.geom.GeometryLocator;
45
import org.gvsig.fmap.geom.GeometryManager;
46
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
47
import org.gvsig.fmap.geom.primitive.Envelope;
48
import org.gvsig.fmap.mapcontext.ViewPort;
49
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
50
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
51
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
52
import org.gvsig.fmap.mapcontext.raster.api.RasterLayer;
53
import org.gvsig.fmap.mapcontext.raster.api.RasterLegendChangedListener;
54
import org.gvsig.metadata.exceptions.MetadataException;
55
import org.gvsig.raster.lib.legend.api.ColorInterpretation;
56
import org.gvsig.raster.lib.legend.api.RasterLegend;
57
import org.gvsig.tools.ToolsLocator;
58
import org.gvsig.tools.dispose.DisposeUtils;
59
import org.gvsig.tools.dynobject.exception.DynMethodException;
60
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
61
import org.gvsig.tools.exception.BaseException;
62
import org.gvsig.tools.task.Cancellable;
63
import org.gvsig.tools.task.SimpleTaskStatus;
64
import org.gvsig.tools.task.TaskStatusManager;
65

    
66
/**
67
 * Capa b?sica Raster.
68
 *
69
 */
70
public class DefaultRasterLayer extends FLyrDefault implements RasterLayer, RasterLegendChangedListener, Observer {
71

    
72
    final static private org.slf4j.Logger logger
73
    = LoggerFactory.getLogger(DefaultRasterLayer.class);
74

    
75
    private RasterStore store;
76
    private RasterLegend legend;
77
    //private Cancellable cancel;
78
    private RasterQuery baseQuery;
79

    
80
    /**
81
     * Creates a new DefaultRasterLayer
82
     * @throws LoadLayerException
83
     */
84
    public DefaultRasterLayer() throws LoadLayerException{
85
        super();
86
    }
87

    
88
    /**
89
     * Creates a new DefaultRasterLayer
90
     * @param store
91
     * @param legend
92
     */
93
    public DefaultRasterLayer(RasterStore store, RasterLegend legend) {
94
        super();
95
        ToolsLocator.getDisposableManager().bind(store);
96
        this.store = store;
97
        this.legend = legend;
98
    }
99

    
100
    public void setLegend(RasterLegend legend) throws LegendLayerException {
101
        if (this.legend == legend) {
102
            return;
103
        }
104
        if (this.legend != null && this.legend.equals(legend)) {
105
            return;
106
        }
107
        RasterLegend oldLegend = this.legend;
108
        this.legend = legend;
109
        if (oldLegend != null) {
110
            //oldLegend.removeLegendListener( this);
111
            //oldLegend.deleteDrawingObserver(this);
112
        }
113
        if (legend != null) {
114
            //this.legend.addDrawingObserver(this);
115
            //this.legend.addLegendListener( this);
116
        }
117
//        LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(oldLegend, this.legend);
118
//        e.setLayer(this);
119
        updateDrawVersion();
120
//        callLegendChanged(e);
121
    }
122

    
123

    
124
    /**
125
     * Devuelve la Leyenda de la capa.
126
     *
127
     * @return Leyenda.
128
     */
129
    public RasterLegend getLegend() {
130

    
131
        return legend;
132
    }
133

    
134
    @Override
135
    public DataStore getDataStore() {
136
        return this.store;
137
    }
138

    
139
    @Override
140
    public void setDataStore(DataStore dataStore) throws LoadLayerException {
141

    
142
        if (this.store != null) {
143
            ToolsLocator.getDisposableManager().release(this.store);
144
            DisposeUtils.disposeQuietly(this.store);
145
        }
146

    
147
        this.store = (RasterStore) dataStore;
148
        ToolsLocator.getDisposableManager().bind(dataStore);
149
        initLegend();
150
    }
151

    
152
    /**
153
     * Initializes the legend if it is not initalized yet
154
     * @throws LegendLayerException
155
     */
156
    private void initLegend() throws LegendLayerException {
157
        RasterLegend legend = null;
158
        if (this.legend == null) {
159
            // Should be done like this but must be corrected mapContextManager
160
            // MapContextManager mapContextManager = MapContextLocator.getMapContextManager();
161
            // Set the legend
162
            // IRasterLegend legend = (IRasterLegend) mapContextManager.getLegend(store);
163

    
164
            // Should be moved to mapContextManager when RasterLegend implements
165
            // ILegend
166
            if (legend == null) {
167
                try {
168
                    legend = (RasterLegend) store.invokeDynMethod(RasterStore.DYNMETHOD_GETLEGEND_NAME, null);
169
                } catch (DynMethodNotSupportedException e) {
170
                    logger.debug("This store {} does not provide a legend.", store.getName());
171
                } catch (DynMethodException e) {
172
                    logger.error("Can't load the specific legend provided for the store {}.", store.getName(), e);
173
                }
174
            }
175

    
176
            if (legend == null) {
177
                throw new LegendLayerException(this.getName());
178
            }
179

    
180
            this.setLegend(legend);
181
        }
182
    }
183

    
184
    @Override
185
    public Envelope getFullEnvelope() throws ReadException {
186
        Envelope rAux;
187
        try {
188
            rAux = getRasterStore().getEnvelope();
189
        } catch (BaseException e) {
190
            throw new ReadException(getName(), e);
191
        }
192

    
193
        // Esto es para cuando se crea una capa nueva con el fullExtent de ancho
194
        // y alto 0.
195
        if (rAux == null || rAux.isEmpty() || rAux.getMaximum(0) - rAux.getMinimum(0) == 0
196
                && rAux.getMaximum(1) - rAux.getMinimum(1) == 0) {
197
            try {
198
                GeometryManager geomManager = GeometryLocator.getGeometryManager();
199
                rAux = geomManager.createEnvelope(0, 0, 90, 90, SUBTYPES.GEOM2D);
200
            } catch (CreateEnvelopeException e) {
201
                logger.error("Error creating the envelope", e);
202
                e.printStackTrace();
203
            }
204
        }
205
        // Si existe reproyecci?n, reproyectar el extent
206
        ICoordTrans ct = getCoordTrans();
207
        if (ct != null) {
208
            rAux = rAux.convert(ct);
209
        }
210
        return rAux;
211
    }
212

    
213
    @Override
214
    public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
215
        Cancellable cancel, double scale) throws ReadException {
216
        if (legend == null) {
217
            return;
218
        }
219

    
220
        if (!this.isWithinScale(scale)) {
221
            return;
222
        }
223
        if (cancel.isCanceled()) {
224
            return;
225
        }
226

    
227
        RasterQuery rasterQuery = createRasterQuery();
228
        Envelope reprojectedViewPortEnvelope = (Envelope) viewPort.getEnvelope();
229
        ICoordTrans ct = getCoordTrans();
230
        if (ct != null) {
231
            try {
232
                reprojectedViewPortEnvelope = (Envelope) reprojectedViewPortEnvelope.clone();
233
                reprojectedViewPortEnvelope = reprojectedViewPortEnvelope.convert(ct.getInverted());
234
            } catch (CloneNotSupportedException e) {
235
                this.setAvailable(false);
236
                this.setError(e);
237
                throw new ReadException(getName(), e);
238
            }
239
        }
240

    
241
        double pixelSize = reprojectedViewPortEnvelope.getLength(0) / (double)viewPort.getImageWidth();
242

    
243
        rasterQuery.setPixelSize(pixelSize);
244

    
245

    
246
        ColorInterpretation colorInterpretation = legend.getColorInterpretation();
247
        String[] renderBands = colorInterpretation.getValues();//.buildRenderBands();
248
        for (int i = 0; i < renderBands.length; i++) {
249
            int band = colorInterpretation.getBand(renderBands[i]);
250
            rasterQuery.addBand(this.store.createBandQuery(band));
251
        }
252

    
253
        RasterSet rasterSet = null;
254
        try {
255

    
256
            long tini = System.currentTimeMillis();
257

    
258
            //TODO Task status should be used to cancel
259
            TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
260
            SimpleTaskStatus taskStatus = manager.createDefaultSimpleTaskStatus("Draw "+getDataStore().getName());
261

    
262
            rasterSet = getRasterStore().getRasterSet(rasterQuery);
263
            ((RasterLegend) legend).draw(g, rasterSet, viewPort, taskStatus);
264

    
265
            logger.debug("Layer " + this.getName() + " drawn in "
266
                    + (System.currentTimeMillis() - tini) + " milliseconds.");
267

    
268
        } catch (DataException e) {
269
            this.setAvailable(false);
270
            this.setError(e);
271
            throw new ReadException(getName(), e);
272
        } finally {
273
            if(rasterSet!=null){
274
                DisposeUtils.dispose(rasterSet);
275
                rasterSet = null;
276
            }
277
        }
278

    
279
    }
280

    
281
    @Override
282
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
283
        double scale, PrintAttributes properties) throws ReadException {
284

    
285
        //TODO legend doesn't have print method
286
        throw new UnsupportedOperationException();
287

    
288
    }
289

    
290
    @Override
291
    public Set<RasterStore> getMetadataChildren() throws MetadataException {
292
        Set<RasterStore> ret = new TreeSet<RasterStore>();
293
        ret.add(this.store);
294
        return ret;
295
    }
296

    
297
    @Override
298
    public Object getMetadataID() throws MetadataException {
299
        return "Layer(" + this.getName() + "):"
300
            + this.store.getMetadataID();
301
    }
302

    
303
    @Override
304
    public void update(Observable observable, Object notification) {
305
        if (observable.equals(this.store)) {
306
            if (notification instanceof RasterStoreNotification) {
307
                RasterStoreNotification event
308
                        = (RasterStoreNotification) notification;
309
                if (event.getType() == RasterStoreNotification.AFTER_REFRESH
310
                        || event.getType() == RasterStoreNotification.SELECTION_CHANGE
311
                        ) {
312
                    this.updateDrawVersion();
313
                } else if (event.getType() == RasterStoreNotification.RESOURCE_CHANGED) {
314
                    this.setAvailable(false);
315
                }
316
            }
317
        }
318
    }
319

    
320
    @Override
321
    public RasterStore getRasterStore() {
322
        return this.store;
323
    }
324

    
325
    @Override
326
    public void setBaseQuery(RasterQuery baseQuery) {
327
        this.baseQuery = baseQuery;
328
    }
329

    
330
    @Override
331
    public RasterQuery getBaseQuery() {
332
        return this.baseQuery;
333
    }
334

    
335
    @Override
336
    public RasterQuery createRasterQuery() {
337
        if( this.baseQuery==null ) {
338
            return this.getRasterStore().createRasterQuery();
339
        }
340
        try {
341
            return (RasterQuery) baseQuery.clone();
342
        } catch (CloneNotSupportedException ex) {
343
            throw new RuntimeException(ex);
344
        }
345
    }
346

    
347
    @Override
348
    protected void doDispose() throws BaseException {
349
        DisposeUtils.dispose(this.store);
350
        this.store = null;
351
        this.legend = null;
352
        this.baseQuery = null;
353
    }
354

    
355
}