Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.mapcontext / org.gvsig.fmap.mapcontext.api / src / main / java / org / gvsig / fmap / mapcontext / impl / DefaultMapContextDrawer.java @ 46909

History | View | Annotate | Download (29.3 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24 40435 jjdelcerro
package org.gvsig.fmap.mapcontext.impl;
25
26
import java.awt.Graphics2D;
27
import java.awt.geom.AffineTransform;
28
import java.awt.image.BufferedImage;
29
import java.util.ArrayList;
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.NoSuchElementException;
33
34
import org.gvsig.compat.CompatLocator;
35
import org.gvsig.compat.print.PrintAttributes;
36
import org.gvsig.fmap.dal.exception.ReadException;
37
import org.gvsig.fmap.geom.primitive.Envelope;
38
import org.gvsig.fmap.mapcontext.MapContext;
39
import org.gvsig.fmap.mapcontext.MapContextDrawer;
40 41840 jjdelcerro
import org.gvsig.fmap.mapcontext.MapContextException;
41
import org.gvsig.fmap.mapcontext.MapContextLocator;
42
import org.gvsig.fmap.mapcontext.MapContextManager;
43 40435 jjdelcerro
import org.gvsig.fmap.mapcontext.ViewPort;
44
import org.gvsig.fmap.mapcontext.layers.FLayer;
45
import org.gvsig.fmap.mapcontext.layers.FLayerHidesArea;
46
import org.gvsig.fmap.mapcontext.layers.FLayers;
47
import org.gvsig.fmap.mapcontext.layers.LayerDrawEvent;
48
import org.gvsig.fmap.mapcontext.layers.LayersIterator;
49
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
50
import org.gvsig.fmap.mapcontext.layers.operations.LayerCollection;
51
import org.gvsig.fmap.mapcontext.layers.vectorial.GraphicLayer;
52 44245 jjdelcerro
import org.gvsig.fmap.mapcontext.layers.vectorial.VectorLayer;
53 40435 jjdelcerro
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelable;
54
import org.gvsig.tools.task.Cancellable;
55 41840 jjdelcerro
import org.gvsig.tools.util.Callable;
56 40435 jjdelcerro
import org.slf4j.Logger;
57
import org.slf4j.LoggerFactory;
58
59
public class DefaultMapContextDrawer implements MapContextDrawer {
60
61 44453 omartinez
    private static final Logger LOG = LoggerFactory
62
            .getLogger(DefaultMapContextDrawer.class);
63 40435 jjdelcerro
64 44453 omartinez
    private MapContext mapContext = null;
65
    private ViewPort viewPort = null;
66
    private CachedImage cachedImage = null;
67
    private DrawList previousDrawList = null;
68 40435 jjdelcerro
69 44453 omartinez
    protected void checkInitialized() {
70
        if (mapContext == null || viewPort == null) {
71
            throw new IllegalStateException(
72
                    "MapContext and ViewPort must be set");
73
        }
74
    }
75 40435 jjdelcerro
76 44453 omartinez
    public void draw(FLayers root, BufferedImage image, Graphics2D g,
77
            Cancellable cancel, double scale) throws ReadException {
78 40435 jjdelcerro
79 44453 omartinez
        this.checkInitialized();
80 40435 jjdelcerro
81 44453 omartinez
        // With viewport changes all layers must be redrawn, discard cache
82 45384 fdiaz
        if (cachedImage != null && cachedImage.hasChangedViewPortDrawVersion()) {
83 44453 omartinez
            cachedImage = null;
84
        }
85 40435 jjdelcerro
86 44453 omartinez
        AffineTransform aux_at = null;
87 40435 jjdelcerro
88 44453 omartinez
        if (isValidFullCachedImage()) {
89 40435 jjdelcerro
90 44453 omartinez
            aux_at = g.getTransform();
91
            g.drawImage(
92
                    cachedImage.getFullDrawnImage(),
93
                    (int) -aux_at.getTranslateX(),
94
                    (int) -aux_at.getTranslateY(),
95
                    null);
96
            LOG.debug("Drawn full image from the cache, all layers cached");
97
            return;
98
        }
99 40435 jjdelcerro
100 44453 omartinez
        DrawList drawList = this.createDrawList(root, cancel, scale);
101
        if (drawList == null || drawList.size() == 0) {
102
            return;
103
        }
104 40435 jjdelcerro
105 44453 omartinez
        if (cancel.isCanceled()) {
106
            cachedImage = null;
107
            return;
108
        }
109 40435 jjdelcerro
110 44453 omartinez
        int firstLayerToDraw;
111
        int lastLayerToDraw;
112
        if (isValidPartialCachedImage(drawList)) {
113
            firstLayerToDraw = 0;
114
            lastLayerToDraw = cachedImage.getLastDrawnLayerPosition();
115 40435 jjdelcerro
116 44453 omartinez
            aux_at = g.getTransform();
117
            g.drawImage(
118
                    cachedImage.getPartialDrawnImage(),
119
                    (int) -aux_at.getTranslateX(),
120
                    (int) -aux_at.getTranslateY(),
121
                    null);
122 40435 jjdelcerro
123 44453 omartinez
            cachedImage.updateVersions(mapContext, viewPort);
124
            LOG.debug("Reused image of cached layers from 0 to {}",
125
                    new Integer(lastLayerToDraw));
126
        } else {
127
            if (cachedImage == null) {
128
                cachedImage = new CachedImage();
129
                // Draw all layers
130
                firstLayerToDraw = 0;
131
                //lastLayerToDraw = drawList.getLayerCount() - 1;
132
                lastLayerToDraw = drawList.getLastLayerVisible(viewPort);
133
            } else {
134
                // Draw the first group of layers without changes to be cached
135
                // next time
136
                firstLayerToDraw = 0;
137
                int firstChangedLayer = drawList.getFirstChangedLayer();
138
                // If negative nothing has changed, so draw all the layers
139
                lastLayerToDraw = firstChangedLayer < 0 ? drawList
140
                        .getLayerCount() - 1 : firstChangedLayer - 1;
141
            }
142
            drawList.drawLayers(image, g, firstLayerToDraw, lastLayerToDraw,
143
                    cancel, scale);
144
            cachedImage.setPartialDrawnImage(image, mapContext, viewPort,
145
                    lastLayerToDraw);
146
        }
147 40435 jjdelcerro
148 44453 omartinez
        if (cancel.isCanceled()) {
149
            cachedImage = null;
150
            return;
151
        }
152 40435 jjdelcerro
153 44453 omartinez
        // Draw the second group of layers not cached
154
        firstLayerToDraw = lastLayerToDraw + 1;
155
        lastLayerToDraw = drawList.getLayerCount() - 1;
156 46909 fdiaz
157 44453 omartinez
        drawList.drawLayers(image, g, firstLayerToDraw, lastLayerToDraw,
158
                cancel, scale);
159 46909 fdiaz
160
        if (cancel.isCanceled()) {
161
            this.clean();
162
        } else {
163
            cachedImage.setFullDrawnImage(image);
164
        }
165 40435 jjdelcerro
166 44453 omartinez
        this.previousDrawList = drawList;
167 46909 fdiaz
168 44453 omartinez
    }
169 40435 jjdelcerro
170 44453 omartinez
    private boolean isValidPartialCachedImage(DrawList drawList) {
171
        return cachedImage != null
172
                && cachedImage.isValidPartialDrawnImage(mapContext, drawList);
173
    }
174 40435 jjdelcerro
175 44453 omartinez
    private boolean isValidFullCachedImage() {
176
        return cachedImage != null
177
                && cachedImage.isValidFullDrawnImage(mapContext);
178
    }
179 40435 jjdelcerro
180 44453 omartinez
    private void print(Object layerOrComposed, Graphics2D g,
181
            Cancellable cancel, double scale, PrintAttributes properties)
182
            throws ReadException {
183
        ILabelable labelable = null;
184
        ILabelable tmp = null;
185
        if (layerOrComposed instanceof ILabelable) {
186 40435 jjdelcerro
187 44453 omartinez
            tmp = (ILabelable) layerOrComposed;
188 40435 jjdelcerro
189 44453 omartinez
            if (tmp.isLabeled() && tmp.getLabelingStrategy() != null
190
                    && tmp.getLabelingStrategy().shouldDrawLabels(scale)) {
191
                labelable = tmp;
192
            }
193
        }
194 40435 jjdelcerro
195 44453 omartinez
        if (layerOrComposed instanceof FLayer) {
196
            FLayer layer = (FLayer) layerOrComposed;
197
            layer.print(g, viewPort, cancel, scale, properties);
198
        } else {
199
            ComposedLayer composed = (ComposedLayer) layerOrComposed;
200
            composed.print(g, viewPort, cancel, scale, properties);
201
        }
202
        if (labelable != null) {
203
            labelable.printLabels(g, viewPort, cancel, scale, properties);
204
        }
205 40435 jjdelcerro
206 44453 omartinez
    }
207 40435 jjdelcerro
208 44453 omartinez
    public void setMapContext(MapContext mapContext) {
209
        if (this.mapContext == mapContext) {
210
            return;
211
        }
212
        this.clean();
213
        this.mapContext = mapContext;
214 40435 jjdelcerro
215 44453 omartinez
    }
216 40435 jjdelcerro
217 44453 omartinez
    public void setViewPort(ViewPort viewPort) {
218
        if (this.viewPort == viewPort) {
219
            return;
220
        }
221
        this.clean();
222
        this.viewPort = viewPort;
223 40435 jjdelcerro
224 44453 omartinez
    }
225 40435 jjdelcerro
226 44453 omartinez
    protected void clean() {
227
        this.cachedImage = null;
228
    }
229 40435 jjdelcerro
230 44453 omartinez
    public class CachedImage {
231 40435 jjdelcerro
232 44453 omartinez
        private BufferedImage partialDrawnImage;
233
        private BufferedImage fullDrawnImage;
234
        private long lastMapContextVersion;
235
        private long lastViewPortVersion;
236
        private int lastDrawnLayerPosition;
237 40435 jjdelcerro
238 44453 omartinez
        public void setPartialDrawnImage(BufferedImage partialDrawnImage,
239
                MapContext mapContext, ViewPort viewPort,
240
                int lastDrawnLayerPosition) {
241
            this.partialDrawnImage = CompatLocator.getGraphicsUtils()
242
                    .copyBufferedImage(partialDrawnImage);
243
            this.lastDrawnLayerPosition = lastDrawnLayerPosition;
244
            updateVersions(mapContext, viewPort);
245
        }
246 40435 jjdelcerro
247 44453 omartinez
        public void updateVersions(MapContext mapContext, ViewPort viewPort) {
248
            this.lastMapContextVersion = mapContext.getDrawVersion();
249
            this.lastViewPortVersion = viewPort.getDrawVersion();
250
        }
251 40435 jjdelcerro
252 44453 omartinez
        public void setFullDrawnImage(BufferedImage fullDrawnImage) {
253
            this.fullDrawnImage = CompatLocator.getGraphicsUtils()
254
                    .copyBufferedImage(fullDrawnImage);
255
        }
256 40435 jjdelcerro
257 44453 omartinez
        public BufferedImage getPartialDrawnImage() {
258
            return partialDrawnImage;
259
        }
260 40435 jjdelcerro
261 44453 omartinez
        public BufferedImage getFullDrawnImage() {
262
            return fullDrawnImage;
263
        }
264 40435 jjdelcerro
265 44453 omartinez
        public long getMapContextVersion() {
266
            return lastMapContextVersion;
267
        }
268 40435 jjdelcerro
269 44453 omartinez
        public int getLastDrawnLayerPosition() {
270
            return this.lastDrawnLayerPosition;
271
        }
272 40435 jjdelcerro
273 44453 omartinez
        public boolean isValidFullDrawnImage(MapContext context) {
274
            // If the MapContext version has not changed, there are not any
275
            // changes that require redrawing any of the layers.
276
            return fullDrawnImage != null && !hasChangedMapContextDrawVersion();
277
        }
278 40435 jjdelcerro
279 44453 omartinez
        public boolean hasChangedMapContextDrawVersion() {
280
            // This change detects changes in layers and the viewport also
281
            return mapContext.getDrawVersion() != this.lastMapContextVersion;
282
        }
283 40435 jjdelcerro
284 44453 omartinez
        public boolean hasChangedViewPortDrawVersion() {
285
            // This change detects changes in the viewport
286
            return viewPort.getDrawVersion() != this.lastViewPortVersion;
287
        }
288 40435 jjdelcerro
289 44453 omartinez
        public boolean isValidPartialDrawnImage(MapContext context,
290
                DrawList drawList) {
291
            if (!hasChangedMapContextDrawVersion()) {
292
                // Nothing has changed
293
                return true;
294
            }
295 40435 jjdelcerro
296 44453 omartinez
            if (partialDrawnImage == null || hasChangedViewPortDrawVersion()) {
297
                // No image available or changes in view port
298
                return false;
299
            }
300 40435 jjdelcerro
301 44453 omartinez
            if (drawList.size() < lastDrawnLayerPosition + 1) {
302
                // New list has fewer layers than before
303
                return false;
304
            }
305 40435 jjdelcerro
306 44453 omartinez
            // There is any change in the layers drawn in the partial drawn
307
            // image?
308
            return drawList.getFirstChangedLayer() > lastDrawnLayerPosition;
309
        }
310
    }
311 40435 jjdelcerro
312 44453 omartinez
    public class DrawList {
313 40435 jjdelcerro
314 44453 omartinez
        private List layers = new ArrayList();
315
        private List all = new ArrayList();
316
        private List versions = new ArrayList();
317
        private DrawList previosList = null;
318
        private int firstLayerChanged = -1;
319 40435 jjdelcerro
320 44453 omartinez
        public DrawList() {
321
        }
322 40435 jjdelcerro
323 44453 omartinez
        public DrawList(DrawList previousList) {
324
            if (previousList != null) {
325
                this.firstLayerChanged = previousList.getLayerCount();
326
                this.previosList = previousList;
327
            }
328
        }
329 40435 jjdelcerro
330 44453 omartinez
        public int getLayerCount() {
331
            return this.layers.size();
332
        }
333 40435 jjdelcerro
334 44453 omartinez
        public int getLastLayerVisible(ViewPort viewPort) {
335
            Envelope area = viewPort.getAdjustedEnvelope();
336
            for (int n = 0; n < this.layers.size() - 1; n++) {
337
                FLayer layer = (FLayer) this.layers.get(n);
338
                if (layer instanceof FLayerHidesArea) {
339
                    if (((FLayerHidesArea) (layer)).hidesThisArea(area)) {
340
                        return n;
341
                    }
342
                }
343
            }
344
            return this.layers.size() - 1;
345
        }
346 40435 jjdelcerro
347 44453 omartinez
        private boolean hasChanged(FLayer layer, int pos) {
348
            FLayer previous = (FLayer) this.previosList.layers.get(pos);
349
            // String previousName = previous.getName();
350
            // String layerName = layer.getName();
351
            if (previous != layer) {
352
                return true;
353
            }
354
            long previousVersion = ((Long) this.previosList.versions.get(pos))
355
                    .longValue();
356
            long layerVersion = layer.getDrawVersion();
357 40435 jjdelcerro
358 44453 omartinez
            return previousVersion != layerVersion;
359
        }
360 40435 jjdelcerro
361 44453 omartinez
        public void add(Object obj) {
362
            if (obj instanceof FLayer) {
363
                FLayer layer = (FLayer) obj;
364
                int curIndex = this.layers.size();
365
                if (this.firstLayerChanged >= curIndex) {
366
                    if (this.previosList.getLayerCount() > curIndex) {
367
                        if (this.hasChanged(layer, curIndex)) {
368
                            this.firstLayerChanged = curIndex;
369
                        }
370
                    } else if (this.previosList.getLayerCount() == curIndex) {
371
                        this.firstLayerChanged = curIndex;
372
                    }
373
                }
374
                this.layers.add(layer);
375
                this.versions.add(new Long(layer.getDrawVersion()));
376
            } else if (!(obj instanceof LayersGroupEvent)) {
377
                throw new UnsupportedOperationException();
378
            }
379 40435 jjdelcerro
380 44453 omartinez
            this.all.add(obj);
381
        }
382 40435 jjdelcerro
383 44453 omartinez
        public int size() {
384
            return this.all.size();
385
        }
386 40435 jjdelcerro
387 44453 omartinez
        public int getFirstChangedLayer() {
388
            if (this.firstLayerChanged > this.layers.size()) {
389
                this.firstLayerChanged = this.layers.size();
390
            }
391
            return this.firstLayerChanged;
392
        }
393 40435 jjdelcerro
394 44453 omartinez
        public FLayer getLayer(int pos) {
395
            return (FLayer) this.layers.get(pos);
396
        }
397 40435 jjdelcerro
398 44453 omartinez
        public Object get(int pos) {
399
            return this.all.get(pos);
400
        }
401 40435 jjdelcerro
402 44453 omartinez
        public void drawLayers(BufferedImage image, Graphics2D g,
403
                int firstLayerToDraw, int lastLayerToDraw, Cancellable cancel,
404
                double scale) throws ReadException {
405 40435 jjdelcerro
406 44453 omartinez
            if (firstLayerToDraw > lastLayerToDraw) {
407
                LOG.debug("Nothing to draw");
408
                return;
409
            }
410 40435 jjdelcerro
411 44453 omartinez
            // Find the real layer positions excluding LayersGroupEvents
412
            FLayer firstLayer = (FLayer) layers.get(firstLayerToDraw);
413
            int firstLayerPos = all.indexOf(firstLayer);
414
            // Look if it belongs to a group and start it
415
            if (firstLayerPos > 0) {
416
                for (int i = firstLayerPos - 1; i < all.size(); i++) {
417
                    // firstLayer
418
                    Object group = all.get(i);
419
                    if (group instanceof LayersGroupEvent) {
420
                        LayersGroupEvent event = (LayersGroupEvent) group;
421
                        if (event.type == LayersGroupEvent.IN_Event) {
422
                            event.group.beginDraw(g, viewPort);
423
                        }
424
                        break;
425
                    }
426
                }
427
            }
428
            FLayer lastLayer = (FLayer) layers.get(lastLayerToDraw);
429
            int lastLayerPos = all.indexOf(lastLayer);
430 40435 jjdelcerro
431 44453 omartinez
            LOG.debug("Drawing from layer {} in position (layers: {}, all: {})"
432
                    + " to layer {} in position (layers: {}, all: {})",
433
                    new Object[]{firstLayer, new Integer(firstLayerToDraw),
434
                        new Integer(firstLayerPos), lastLayer,
435
                        new Integer(lastLayerToDraw),
436
                        new Integer(lastLayerPos)});
437 40435 jjdelcerro
438 44453 omartinez
            ComposedLayer composed = null;
439
            for (int pos = firstLayerPos; pos <= lastLayerPos; pos++) {
440
                if (cancel.isCanceled()) {
441
                    return;
442
                }
443 40435 jjdelcerro
444 44453 omartinez
                Object layerOrGroup = get(pos);
445 40435 jjdelcerro
446 44453 omartinez
                // Group drawing events management
447
                if (layerOrGroup instanceof LayersGroupEvent) {
448
                    LayersGroupEvent event = (LayersGroupEvent) layerOrGroup;
449
                    if (event.type == LayersGroupEvent.IN_Event) {
450
                        event.group.beginDraw(g, viewPort);
451
                    } else {
452
                        event.group.endDraw(g, viewPort);
453
                    }
454
                } else {
455
                    FLayer layer = (FLayer) layerOrGroup;
456
                    if (composed != null && composed.canAdd(layer)) {
457
                        // Previous or current layer could be composed
458
                        // Add current layer
459
                        addToComposedLayer(composed, layer);
460
                    } else {
461
                        if (composed != null) {
462
                            // Current layer can't be composed on the previous
463
                            // composedlayer. Draw previous composed
464
                            LOG.debug("Drawing composed layer {} ", composed);
465
                            draw(composed, image, g, cancel, scale);
466
                            composed = null;
467
                        }
468 40435 jjdelcerro
469 44453 omartinez
                        // Try if the current layer can be composed
470
                        // Create new composed or draw current layer
471
                        composed = layer.newComposedLayer();
472
                        if (composed == null) {
473
                            LOG.debug("Drawing layer {} ", layer);
474
                            draw(layer, image, g, cancel, scale);
475
                        } else {
476
                            addToComposedLayer(composed, layer);
477
                        }
478
                    }
479
                }
480
            }
481
            if (composed != null) {
482
                // Draw the pending composed
483
                draw(composed, image, g, cancel, scale);
484
            }
485 40435 jjdelcerro
486 44453 omartinez
            // Check if the last layer is the last of a group and close it
487
            for (int i = lastLayerPos + 1; i < all.size(); i++) {
488
                Object group = all.get(i);
489
                if (group instanceof LayersGroupEvent) {
490
                    LayersGroupEvent event = (LayersGroupEvent) group;
491
                    if (event.type == LayersGroupEvent.OUT_Event) {
492
                        event.group.endDraw(g, viewPort);
493
                    }
494
                    break;
495
                }
496
            }
497
        }
498 40435 jjdelcerro
499 44453 omartinez
        private void addToComposedLayer(ComposedLayer composed, FLayer layer)
500
                throws ReadException {
501
            try {
502
                LOG.debug("Adding layer {} to composed layer ", layer, composed);
503
                composed.add(layer);
504
            } catch (Exception e) {
505
                throw new ReadException("DefalutMapContexDrawer exception", e);
506
            }
507
        }
508 40435 jjdelcerro
509 44453 omartinez
        private void draw(Object layerOrComposed, BufferedImage image,
510
                Graphics2D g, Cancellable cancel, double scale)
511
                throws ReadException {
512
            ILabelable labelable = null;
513
            ILabelable tmp = null;
514
            if (layerOrComposed instanceof ILabelable) {
515 40435 jjdelcerro
516 44453 omartinez
                tmp = (ILabelable) layerOrComposed;
517 40435 jjdelcerro
518 44453 omartinez
                if (tmp.isLabeled() && tmp.getLabelingStrategy() != null
519
                        && tmp.getLabelingStrategy().shouldDrawLabels(scale)) {
520
                    labelable = tmp;
521
                }
522
            }
523 40435 jjdelcerro
524 44453 omartinez
            if (layerOrComposed instanceof FLayer) {
525
                int beforeDrawEventType;
526
                int afterDrawEventType;
527
                if (layerOrComposed instanceof GraphicLayer) {
528
                    beforeDrawEventType = LayerDrawEvent.GRAPHICLAYER_BEFORE_DRAW;
529
                    afterDrawEventType = LayerDrawEvent.GRAPHICLAYER_AFTER_DRAW;
530
                } else {
531
                    beforeDrawEventType = LayerDrawEvent.LAYER_BEFORE_DRAW;
532
                    afterDrawEventType = LayerDrawEvent.LAYER_AFTER_DRAW;
533
                }
534
                FLayer layer = (FLayer) layerOrComposed;
535
                drawLayer(layer, image, g, cancel, scale, beforeDrawEventType,
536
                        afterDrawEventType);
537
            } else {
538
                ComposedLayer composed = (ComposedLayer) layerOrComposed;
539
                composed.draw(image, g, viewPort, cancel, scale);
540
            }
541
            if (labelable != null) {
542
                labelable.drawLabels(image, g, viewPort, cancel, scale,
543
                        mapContext.getViewPort().getDPI());
544
            }
545 40435 jjdelcerro
546 44453 omartinez
        }
547 40435 jjdelcerro
548 44453 omartinez
        protected void drawLayer(FLayer layer, BufferedImage image,
549
                Graphics2D g, Cancellable cancel, double scale,
550
                int beforeDrawEventType, int afterDrawEventType)
551
                throws ReadException {
552
            LayerDrawEvent event = new LayerDrawEvent(layer, g, viewPort, beforeDrawEventType);
553
            mapContext.fireLayerDrawingEvent(event);
554
            layer.draw(image, g, viewPort, cancel, scale);
555
            event = new LayerDrawEvent(layer, g, viewPort, afterDrawEventType);
556
            mapContext.fireLayerDrawingEvent(event);
557
        }
558 40435 jjdelcerro
559 44453 omartinez
    }
560 40435 jjdelcerro
561 44453 omartinez
    private class SimpleLayerIterator extends LayersIterator {
562 40435 jjdelcerro
563 44453 omartinez
        public SimpleLayerIterator(FLayer layer) {
564
            this.appendLayer(layer);
565
        }
566 40435 jjdelcerro
567 44453 omartinez
        public boolean evaluate(FLayer layer) {
568
            if (layer instanceof FLayers) {
569
                return false;
570
            }
571
            return layer.isAvailable() && layer.isVisible();
572
        }
573 40435 jjdelcerro
574 44453 omartinez
    }
575 40435 jjdelcerro
576 44453 omartinez
    public void dispose() {
577
        this.mapContext = null;
578
        this.viewPort = null;
579
        this.cachedImage = null;
580
        this.previousDrawList = null;
581
    }
582 40435 jjdelcerro
583 44453 omartinez
    public void print(FLayers root, Graphics2D g, Cancellable cancel,
584
            double scale, PrintAttributes properties) throws ReadException {
585
        this.checkInitialized();
586
587
        List printList = this.createPrintList(root, cancel);
588
        if (cancel.isCanceled()) {
589
            return;
590
        }
591
592
        ComposedLayer composed = null;
593
        int pos;
594
        FLayer layer;
595
        int layerPos = -1;
596
        Object obj;
597
        LayersGroupEvent event;
598
        for (pos = 0; pos < printList.size(); pos++) {
599
            if (cancel.isCanceled()) {
600
                return;
601
            }
602
603
            obj = printList.get(pos);
604
            if (obj instanceof LayersGroupEvent) {
605
                event = (LayersGroupEvent) obj;
606
                if (event.type == LayersGroupEvent.IN_Event) {
607
                    // System.out.println("=======Empiza a pintar grupo de capas "+
608
                    // ((FLayers)event.group).getName() +"============");
609
                    event.group.beginDraw(g, viewPort);
610
                } else {
611
                    event.group.endDraw(g, viewPort);
612
                    // System.out.println("=======Fin a pintar grupo de capas "+
613
                    // ((FLayers)event.group).getName() +"============");
614
615 44245 jjdelcerro
                }
616 44453 omartinez
                continue;
617
            }
618
            layerPos++;
619 40435 jjdelcerro
620 44453 omartinez
            layer = (FLayer) obj;
621 40435 jjdelcerro
622 44453 omartinez
            // *** Pintado de capa/composicion de capa ***
623
            if (composed == null) {
624
                composed = layer.newComposedLayer();
625
                if (composed != null) {
626
                    try {
627
                        composed.add(layer);
628
                        // System.out.println("=======Imprimiendo composicion de pintado "+
629
                        // (layerPos-1)+" ============");
630
                        continue;
631
                    } catch (Exception e) {
632
                        throw new ReadException(
633
                                "DefaultMapContexDrawer exception", e);
634
                    }
635
                }
636
            } else {
637
                if (composed.canAdd(layer)) {
638
                    try {
639
                        composed.add(layer);
640 45384 fdiaz
                        // System.out.println("=== a�adiendo a composicion de pintado "+
641 44453 omartinez
                        // layerPos+ " "+layer.getName());
642
                        continue;
643
                    } catch (Exception e) {
644
                        throw new ReadException(
645
                                "DefaultMapContexDrawer exception", e);
646
                    }
647
                } else {
648
                    // System.out.println("=======Imprimiendo composicion de pintado "+
649
                    // (layerPos-1)+" ============");
650
                    this.print(composed, g, cancel, scale, properties);
651
                    // composed.print( g, viewPort, cancel, scale,properties);
652
                    composed = layer.newComposedLayer();
653
                    if (composed != null) {
654
                        try {
655
                            composed.add(layer);
656 45384 fdiaz
                            // System.out.println("=== a�adiendo a composicion de pintado "+
657 44453 omartinez
                            // layerPos+ " "+layer.getName());
658
                            continue;
659
                        } catch (Exception e) {
660
                            throw new ReadException(
661
                                    "DefaultMapContexDrawer exception", e);
662
                        }
663
                    }
664
                }
665
            }
666
            // System.out.println("=== imprimiendo "+ layerPos+
667
            // " "+layer.getName());
668
            this.print(layer, g, cancel, scale, properties);
669
            // layer.print(g, viewPort, cancel, scale,properties);
670
            // *** Pintado de capa/composicion de capa ***
671
            if (composed != null) {
672
                // si la composicion no se ha pintado la pintamos
673
                // System.out.println("=======Imprimiendo composicion de pintado "+
674
                // (layerPos-1)+" (ultimo) ============");
675
                this.print(composed, g, cancel, scale, properties);
676
                // composed.print(g, viewPort, cancel, scale, properties);
677
                composed = null;
678
            }
679
        }
680 40435 jjdelcerro
681 44453 omartinez
    }
682 40435 jjdelcerro
683 44453 omartinez
    private DrawList createDrawList(FLayers root, Cancellable cancel,
684
            double scale) {
685
        DrawList result = new DrawList(this.previousDrawList);
686
        Iterator iter = new MyLayerIterator((FLayer) root, scale);
687
        while (iter.hasNext()) {
688
            if (cancel.isCanceled()) {
689
                return null;
690
            }
691
            result.add(iter.next());
692
        }
693
        if (cancel.isCanceled()) {
694
            return null;
695
        }
696
        // Take into account also the Graphic layer
697
        for (VectorLayer graphicsLayer : mapContext.getGraphicsLayers()) {
698
            if (graphicsLayer != null &&
699
                    graphicsLayer.isAvailable() &&
700
                    graphicsLayer.isVisible() &&
701
                    graphicsLayer.isWithinScale(scale)) {
702
                result.add(graphicsLayer);
703
            }
704
        }
705
        return result;
706
    }
707 40435 jjdelcerro
708 44453 omartinez
    private List createPrintList(FLayers root, Cancellable cancel) {
709
        List result = new ArrayList();
710
        Iterator iter = new SimpleLayerIterator((FLayer) root);
711
        while (iter.hasNext()) {
712
            if (cancel.isCanceled()) {
713
                return null;
714
            }
715
            result.add(iter.next());
716
        }
717
        return result;
718
    }
719 40435 jjdelcerro
720 44453 omartinez
    private class MyLayerIterator implements Iterator {
721 40435 jjdelcerro
722 44453 omartinez
        List layersList = new ArrayList();
723
        int index = 0;
724
        double scale = 0;
725 40435 jjdelcerro
726 44453 omartinez
        public MyLayerIterator(FLayer layer, double scale) {
727
            this.scale = scale;
728
            this.appendLayer(layer);
729
        }
730 40435 jjdelcerro
731 44453 omartinez
        protected void appendLayer(FLayer layer) {
732
            if (layer instanceof LayerCollection) {
733
                appendLayers((LayerCollection) layer);
734
            } else if (this.evaluate(layer)) {
735
                layersList.add(layer);
736
            }
737
        }
738 40435 jjdelcerro
739 44453 omartinez
        private void appendLayers(LayerCollection layers) {
740
            int i;
741
            layersList.add(new LayersGroupEvent(layers,
742
                    LayersGroupEvent.IN_Event));
743
            for (i = 0; i < layers.getLayersCount(); i++) {
744
                appendLayer(layers.getLayer(i));
745
            }
746
            layersList.add(new LayersGroupEvent(layers,
747
                    LayersGroupEvent.OUT_Event));
748
        }
749 40435 jjdelcerro
750 44453 omartinez
        public void remove() {
751
            throw new UnsupportedOperationException();
752
        }
753 40435 jjdelcerro
754 44453 omartinez
        public boolean hasNext() {
755
            return index < layersList.size();
756
        }
757 40435 jjdelcerro
758 44453 omartinez
        public Object next() {
759
            if (!this.hasNext()) {
760
                throw new NoSuchElementException();
761
            }
762
            Object aux = layersList.get(index);
763
            index++;
764
            return aux;
765
        }
766 40435 jjdelcerro
767 44453 omartinez
        public boolean evaluate(FLayer layer) {
768
            if (layer instanceof LayerCollection) {
769
                return false;
770
            }
771
            return layer.isAvailable() && layer.isVisible()
772
                    && layer.isWithinScale(this.scale);
773
        }
774 40435 jjdelcerro
775 44453 omartinez
    }
776 40435 jjdelcerro
777 44453 omartinez
    private class LayersGroupEvent {
778 41840 jjdelcerro
779 44453 omartinez
        public static final String IN_Event = "in";
780
        public static final String OUT_Event = "Out";
781
782
        private LayerCollection group = null;
783
        private String type = IN_Event;
784
785
        public LayersGroupEvent(LayerCollection group, String type) {
786
            this.group = group;
787
            this.type = type;
788
        }
789
790
        public String getType() {
791
            return type;
792
        }
793
794
        public LayerCollection getGroup() {
795
            return group;
796
        }
797
    }
798
799 41840 jjdelcerro
    public static class RegisterMapContextDrawer implements Callable {
800
801
        public Object call() {
802
            MapContextManager manager = MapContextLocator.getMapContextManager();
803
            try {
804 44453 omartinez
                manager.setDefaultMapContextDrawer(DefaultMapContextDrawer.class);
805 41840 jjdelcerro
            } catch (MapContextException ex) {
806 44453 omartinez
                throw new RuntimeException("Can't register the default MapContextDrawer", ex);
807 41840 jjdelcerro
            }
808
            return Boolean.TRUE;
809
        }
810
    }
811 40435 jjdelcerro
}