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

History | View | Annotate | Download (22.3 KB)

1
/**
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
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
import org.gvsig.fmap.mapcontext.ViewPort;
41
import org.gvsig.fmap.mapcontext.layers.FLayer;
42
import org.gvsig.fmap.mapcontext.layers.FLayerHidesArea;
43
import org.gvsig.fmap.mapcontext.layers.FLayers;
44
import org.gvsig.fmap.mapcontext.layers.LayerDrawEvent;
45
import org.gvsig.fmap.mapcontext.layers.LayersIterator;
46
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
47
import org.gvsig.fmap.mapcontext.layers.operations.LayerCollection;
48
import org.gvsig.fmap.mapcontext.layers.vectorial.GraphicLayer;
49
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelable;
50
import org.gvsig.tools.task.Cancellable;
51
import org.slf4j.Logger;
52
import org.slf4j.LoggerFactory;
53

    
54
public class DefaultMapContextDrawer implements MapContextDrawer {
55

    
56
        private static final Logger LOG = LoggerFactory
57
                        .getLogger(DefaultMapContextDrawer.class);
58

    
59
        private MapContext mapContext = null;
60
        private ViewPort viewPort = null;
61
        private CachedImage cachedImage = null;
62
        private DrawList previousDrawList = null;
63

    
64
        protected void checkInitialized() {
65
                if (mapContext == null || viewPort == null) {
66
                        throw new IllegalStateException(
67
                                        "MapContext and ViewPort must be set");
68
                }
69
        }
70

    
71
        public void draw(FLayers root, BufferedImage image, Graphics2D g,
72
                        Cancellable cancel, double scale) throws ReadException {
73

    
74
                this.checkInitialized();
75

    
76
                // With viewport changes all layers must be redrawn, discard cache
77
                if (cachedImage != null && cachedImage.hasChangedViewPortDrawVersion()) {
78
                        cachedImage = null;
79
                }
80

    
81
                AffineTransform aux_at = null;
82
                
83
                if (isValidFullCachedImage()) {
84
                    
85
                    aux_at = g.getTransform();
86
                        g.drawImage(
87
                            cachedImage.getFullDrawnImage(),
88
                            (int) -aux_at.getTranslateX(),
89
                            (int) -aux_at.getTranslateY(),
90
                            null);
91
                        LOG.debug("Drawn full image from the cache, all layers cached");
92
                        return;
93
                }
94

    
95
                DrawList drawList = this.createDrawList(root, cancel, scale);
96
                if (drawList == null || drawList.size() == 0) {
97
                        return;
98
                }
99

    
100
                if (cancel.isCanceled()) {
101
                        cachedImage = null;
102
                        return;
103
                }
104

    
105
                int firstLayerToDraw;
106
                int lastLayerToDraw;
107
                if (isValidPartialCachedImage(drawList)) {
108
                        firstLayerToDraw = 0;
109
                        lastLayerToDraw = cachedImage.getLastDrawnLayerPosition();
110
                        
111
                        aux_at = g.getTransform();
112
                        g.drawImage(
113
                        cachedImage.getPartialDrawnImage(),
114
                        (int) -aux_at.getTranslateX(),
115
                        (int) -aux_at.getTranslateY(),
116
                        null);
117
                        
118
                        cachedImage.updateVersions(mapContext, viewPort);
119
                        LOG.debug("Reused image of cached layers from 0 to {}",
120
                                        new Integer(lastLayerToDraw));
121
                } else {
122
                        if (cachedImage == null) {
123
                                cachedImage = new CachedImage();
124
                                // Draw all layers
125
                                firstLayerToDraw = 0;
126
                                //lastLayerToDraw = drawList.getLayerCount() - 1;
127
                                lastLayerToDraw = drawList.getLastLayerVisible(viewPort);
128
                        } else {
129
                                // Draw the first group of layers without changes to be cached
130
                                // next time
131
                                firstLayerToDraw = 0;
132
                                int firstChangedLayer = drawList.getFirstChangedLayer();
133
                                // If negative nothing has changed, so draw all the layers
134
                                lastLayerToDraw = firstChangedLayer < 0 ? drawList
135
                                                .getLayerCount() - 1 : firstChangedLayer - 1;
136
                        }
137
                        drawList.drawLayers(image, g, firstLayerToDraw, lastLayerToDraw,
138
                                        cancel, scale);
139
                        cachedImage.setPartialDrawnImage(image, mapContext, viewPort,
140
                                        lastLayerToDraw);
141
                }
142

    
143
                if (cancel.isCanceled()) {
144
                        cachedImage = null;
145
                        return;
146
                }
147

    
148
                // Draw the second group of layers not cached
149
                firstLayerToDraw = lastLayerToDraw + 1;
150
                lastLayerToDraw = drawList.getLayerCount() - 1;
151
                drawList.drawLayers(image, g, firstLayerToDraw, lastLayerToDraw,
152
                                cancel, scale);
153
                cachedImage.setFullDrawnImage(image);
154

    
155
                this.previousDrawList = drawList;
156
        }
157

    
158
        private boolean isValidPartialCachedImage(DrawList drawList) {
159
                return cachedImage != null
160
                                && cachedImage.isValidPartialDrawnImage(mapContext, drawList);
161
        }
162

    
163
        private boolean isValidFullCachedImage() {
164
                return cachedImage != null
165
                                && cachedImage.isValidFullDrawnImage(mapContext);
166
        }
167

    
168
        private void print(Object layerOrComposed, Graphics2D g,
169
                        Cancellable cancel, double scale, PrintAttributes properties)
170
                        throws ReadException {
171
                ILabelable labelable = null;
172
                ILabelable tmp = null;
173
                if (layerOrComposed instanceof ILabelable) {
174

    
175
                        tmp = (ILabelable) layerOrComposed;
176

    
177
                        if (tmp.isLabeled() && tmp.getLabelingStrategy() != null
178
                                        && tmp.getLabelingStrategy().shouldDrawLabels(scale)) {
179
                                labelable = tmp;
180
                        }
181
                }
182

    
183
                if (layerOrComposed instanceof FLayer) {
184
                        FLayer layer = (FLayer) layerOrComposed;
185
                        layer.print(g, viewPort, cancel, scale, properties);
186
                } else {
187
                        ComposedLayer composed = (ComposedLayer) layerOrComposed;
188
                        composed.print(g, viewPort, cancel, scale, properties);
189
                }
190
                if (labelable != null) {
191
                        labelable.printLabels(g, viewPort, cancel, scale, properties);
192
                }
193

    
194
        }
195

    
196
        public void setMapContext(MapContext mapContext) {
197
                if (this.mapContext == mapContext) {
198
                        return;
199
                }
200
                this.clean();
201
                this.mapContext = mapContext;
202

    
203
        }
204

    
205
        public void setViewPort(ViewPort viewPort) {
206
                if (this.viewPort == viewPort) {
207
                        return;
208
                }
209
                this.clean();
210
                this.viewPort = viewPort;
211

    
212
        }
213

    
214
        protected void clean() {
215
                this.cachedImage = null;
216
        }
217

    
218
        public class CachedImage {
219
                private BufferedImage partialDrawnImage;
220
                private BufferedImage fullDrawnImage;
221
                private long lastMapContextVersion;
222
                private long lastViewPortVersion;
223
                private int lastDrawnLayerPosition;
224

    
225
                public void setPartialDrawnImage(BufferedImage partialDrawnImage,
226
                                MapContext mapContext, ViewPort viewPort,
227
                                int lastDrawnLayerPosition) {
228
                        this.partialDrawnImage = CompatLocator.getGraphicsUtils()
229
                                        .copyBufferedImage(partialDrawnImage);
230
                        this.lastDrawnLayerPosition = lastDrawnLayerPosition;
231
                        updateVersions(mapContext, viewPort);
232
                }
233
                
234
                public void updateVersions(MapContext mapContext, ViewPort viewPort) {
235
                        this.lastMapContextVersion = mapContext.getDrawVersion();
236
                        this.lastViewPortVersion = viewPort.getDrawVersion();                        
237
                }
238

    
239
                public void setFullDrawnImage(BufferedImage fullDrawnImage) {
240
                        this.fullDrawnImage = CompatLocator.getGraphicsUtils()
241
                                        .copyBufferedImage(fullDrawnImage);
242
                }
243

    
244
                public BufferedImage getPartialDrawnImage() {
245
                        return partialDrawnImage;
246
                }
247

    
248
                public BufferedImage getFullDrawnImage() {
249
                        return fullDrawnImage;
250
                }
251

    
252
                public long getMapContextVersion() {
253
                        return lastMapContextVersion;
254
                }
255

    
256
                public int getLastDrawnLayerPosition() {
257
                        return this.lastDrawnLayerPosition;
258
                }
259

    
260
                public boolean isValidFullDrawnImage(MapContext context) {
261
                        // If the MapContext version has not changed, there are not any
262
                        // changes that require redrawing any of the layers.
263
                        return fullDrawnImage != null && !hasChangedMapContextDrawVersion();
264
                }
265

    
266
                public boolean hasChangedMapContextDrawVersion() {
267
                        // This change detects changes in layers and the viewport also
268
                        return mapContext.getDrawVersion() != this.lastMapContextVersion;
269
                }
270

    
271
                public boolean hasChangedViewPortDrawVersion() {
272
                        // This change detects changes in the viewport
273
                        return viewPort.getDrawVersion() != this.lastViewPortVersion;
274
                }
275

    
276
                public boolean isValidPartialDrawnImage(MapContext context,
277
                                DrawList drawList) {
278
                        if (!hasChangedMapContextDrawVersion()) {
279
                                // Nothing has changed
280
                                return true;
281
                        }
282

    
283
                        if (partialDrawnImage == null || hasChangedViewPortDrawVersion()) {
284
                                // No image available or changes in view port
285
                                return false;
286
                        }
287

    
288
                        if (drawList.size() < lastDrawnLayerPosition + 1) {
289
                                // New list has fewer layers than before
290
                                return false;
291
                        }
292

    
293
                        // There is any change in the layers drawn in the partial drawn
294
                        // image?
295
                        return drawList.getFirstChangedLayer() > lastDrawnLayerPosition;
296
                }
297
        }
298

    
299
        public class DrawList {
300
                private List layers = new ArrayList();
301
                private List all = new ArrayList();
302
                private List versions = new ArrayList();
303
                private DrawList previosList = null;
304
                private int firstLayerChanged = -1;
305

    
306
                public DrawList() {
307
                }
308

    
309
                public DrawList(DrawList previousList) {
310
                        if (previousList != null) {
311
                                this.firstLayerChanged = previousList.getLayerCount();
312
                                this.previosList = previousList;
313
                        }
314
                }
315

    
316
                public int getLayerCount() {
317
                        return this.layers.size();
318
                }
319

    
320
                public int getLastLayerVisible(ViewPort viewPort) {
321
                        Envelope area = viewPort.getAdjustedEnvelope();
322
                        for( int n=0; n<this.layers.size()-1; n++ ) {
323
                                FLayer layer = (FLayer) this.layers.get(n);
324
                                if( layer instanceof FLayerHidesArea ) {
325
                                        if( ((FLayerHidesArea)(layer)).hidesThisArea(area) ) {
326
                                                return n;
327
                                        }
328
                                }
329
                        }
330
                        return this.layers.size()-1;
331
                }
332

    
333
                private boolean hasChanged(FLayer layer, int pos) {
334
                        FLayer previous = (FLayer) this.previosList.layers.get(pos);
335
                        // String previousName = previous.getName();
336
                        // String layerName = layer.getName();
337
                        if (previous != layer) {
338
                                return true;
339
                        }
340
                        long previousVersion = ((Long) this.previosList.versions.get(pos))
341
                                        .longValue();
342
                        long layerVersion = layer.getDrawVersion();
343

    
344
                        return previousVersion != layerVersion;
345
                }
346

    
347
                public void add(Object obj) {
348
                        if (obj instanceof FLayer) {
349
                                FLayer layer = (FLayer) obj;
350
                                int curIndex = this.layers.size();
351
                                if (this.firstLayerChanged >= curIndex) {
352
                                        if (this.previosList.getLayerCount() > curIndex) {
353
                                                if (this.hasChanged(layer, curIndex)) {
354
                                                        this.firstLayerChanged = curIndex;
355
                                                }
356
                                        } else if (this.previosList.getLayerCount() == curIndex) {
357
                                                this.firstLayerChanged = curIndex;
358
                                        }
359
                                }
360
                                this.layers.add(layer);
361
                                this.versions.add(new Long(layer.getDrawVersion()));
362
                        } else if (!(obj instanceof LayersGroupEvent)) {
363
                                throw new UnsupportedOperationException();
364
                        }
365

    
366
                        this.all.add(obj);
367
                }
368

    
369
                public int size() {
370
                        return this.all.size();
371
                }
372

    
373
                public int getFirstChangedLayer() {
374
                        if (this.firstLayerChanged > this.layers.size()) {
375
                                this.firstLayerChanged = this.layers.size();
376
                        }
377
                        return this.firstLayerChanged;
378
                }
379

    
380
                public FLayer getLayer(int pos) {
381
                        return (FLayer) this.layers.get(pos);
382
                }
383

    
384
                public Object get(int pos) {
385
                        return this.all.get(pos);
386
                }
387

    
388
                public void drawLayers(BufferedImage image, Graphics2D g,
389
                                int firstLayerToDraw, int lastLayerToDraw, Cancellable cancel,
390
                                double scale) throws ReadException {
391

    
392
                        if (firstLayerToDraw > lastLayerToDraw) {
393
                                LOG.debug("Nothing to draw");
394
                                return;
395
                        }
396

    
397
                        // Find the real layer positions excluding LayersGroupEvents
398
                        FLayer firstLayer = (FLayer) layers.get(firstLayerToDraw);
399
                        int firstLayerPos = all.indexOf(firstLayer);
400
                        // Look if it belongs to a group and start it
401
                        if (firstLayerPos > 0) {
402
                                for (int i = firstLayerPos - 1; i > 0; i++) {
403
                                        Object group = all.get(i);
404
                                        if (group instanceof LayersGroupEvent) {
405
                                                LayersGroupEvent event = (LayersGroupEvent) group;
406
                                                if (event.type == LayersGroupEvent.IN_Event) {
407
                                                        event.group.beginDraw(g, viewPort);
408
                                                }
409
                                                break;
410
                                        }
411
                                }
412
                        }
413
                        FLayer lastLayer = (FLayer) layers.get(lastLayerToDraw);
414
                        int lastLayerPos = all.indexOf(lastLayer);
415

    
416
                        LOG.debug("Drawing from layer {} in position (layers: {}, all: {})"
417
                                        + " to layer {} in position (layers: {}, all: {})",
418
                                        new Object[] { firstLayer, new Integer(firstLayerToDraw),
419
                                                        new Integer(firstLayerPos), lastLayer,
420
                                                        new Integer(lastLayerToDraw),
421
                                                        new Integer(lastLayerPos) });
422

    
423
                        ComposedLayer composed = null;
424
                        for (int pos = firstLayerPos; pos <= lastLayerPos; pos++) {
425
                                if (cancel.isCanceled()) {
426
                                        return;
427
                                }
428

    
429
                                Object layerOrGroup = get(pos);
430

    
431
                                // Group drawing events management
432
                                if (layerOrGroup instanceof LayersGroupEvent) {
433
                                        LayersGroupEvent event = (LayersGroupEvent) layerOrGroup;
434
                                        if (event.type == LayersGroupEvent.IN_Event) {
435
                                                event.group.beginDraw(g, viewPort);
436
                                        } else {
437
                                                event.group.endDraw(g, viewPort);
438
                                        }
439
                                } else {
440
                                        FLayer layer = (FLayer) layerOrGroup;
441
                                        if (composed != null && composed.canAdd(layer)) {
442
                                                // Previous or current layer could be composed
443
                                                // Add current layer
444
                                                addToComposedLayer(composed, layer);
445
                                        } else {
446
                                                if (composed != null) {
447
                                                        // Current layer can't be composed on the previous
448
                                                        // composedlayer. Draw previous composed
449
                                                        LOG.debug("Drawing composed layer {} ", composed);
450
                                                        draw(composed, image, g, cancel, scale);
451
                                                        composed = null;
452
                                                }
453

    
454
                                                // Try if the current layer can be composed
455
                                                // Create new composed or draw current layer
456
                                                composed = layer.newComposedLayer();
457
                                                if (composed == null) {
458
                                                        LOG.debug("Drawing layer {} ", layer);
459
                                                        draw(layer, image, g, cancel, scale);
460
                                                } else {
461
                                                        addToComposedLayer(composed, layer);
462
                                                }
463
                                        }
464
                                }
465
                        }
466
                        if (composed != null) {
467
                                // Draw the pending composed
468
                                draw(composed, image, g, cancel, scale);
469
                        }
470

    
471
                        // Check if the last layer is the last of a group and close it
472
                        for (int i = lastLayerPos + 1; i < all.size(); i++) {
473
                                Object group = all.get(i);
474
                                if (group instanceof LayersGroupEvent) {
475
                                        LayersGroupEvent event = (LayersGroupEvent) group;
476
                                        if (event.type == LayersGroupEvent.OUT_Event) {
477
                                                event.group.endDraw(g, viewPort);
478
                                        }
479
                                        break;
480
                                }
481
                        }
482
                }
483

    
484
                private void addToComposedLayer(ComposedLayer composed, FLayer layer)
485
                                throws ReadException {
486
                        try {
487
                                LOG.debug("Adding layer {} to composed layer ", layer, composed);
488
                                composed.add(layer);
489
                        } catch (Exception e) {
490
                                throw new ReadException("DefalutMapContexDrawer exception", e);
491
                        }
492
                }
493

    
494
                private void draw(Object layerOrComposed, BufferedImage image,
495
                                Graphics2D g, Cancellable cancel, double scale)
496
                                throws ReadException {
497
                        ILabelable labelable = null;
498
                        ILabelable tmp = null;
499
                        if (layerOrComposed instanceof ILabelable) {
500

    
501
                                tmp = (ILabelable) layerOrComposed;
502

    
503
                                if (tmp.isLabeled() && tmp.getLabelingStrategy() != null
504
                                                && tmp.getLabelingStrategy().shouldDrawLabels(scale)) {
505
                                        labelable = tmp;
506
                                }
507
                        }
508
                                
509
                        if (layerOrComposed instanceof FLayer) {
510
                                int beforeDrawEventType;
511
                                int afterDrawEventType;
512
                                if (layerOrComposed instanceof GraphicLayer) {
513
                                        beforeDrawEventType = LayerDrawEvent.GRAPHICLAYER_BEFORE_DRAW;
514
                                        afterDrawEventType = LayerDrawEvent.GRAPHICLAYER_AFTER_DRAW;
515
                                } else {
516
                                        beforeDrawEventType = LayerDrawEvent.LAYER_BEFORE_DRAW;
517
                                        afterDrawEventType = LayerDrawEvent.LAYER_AFTER_DRAW;
518
                                }
519
                                FLayer layer = (FLayer) layerOrComposed;
520
                                drawLayer(layer, image, g, cancel, scale, beforeDrawEventType,
521
                                                afterDrawEventType);
522
                        } else {
523
                                ComposedLayer composed = (ComposedLayer) layerOrComposed;
524
                                composed.draw(image, g, viewPort, cancel, scale);
525
                        }
526
                        if (labelable != null) {
527
                                labelable.drawLabels(image, g, viewPort, cancel, scale,
528
                                                MapContext.getScreenDPI());
529
                        }
530

    
531
                }
532

    
533
                protected void drawLayer(FLayer layer, BufferedImage image,
534
                                Graphics2D g, Cancellable cancel, double scale,
535
                                int beforeDrawEventType, int afterDrawEventType)
536
                                throws ReadException {
537
                        LayerDrawEvent event = new LayerDrawEvent(layer, g, viewPort, beforeDrawEventType);
538
                        mapContext.fireLayerDrawingEvent(event);
539
                        layer.draw(image, g, viewPort, cancel, scale);
540
                        event = new LayerDrawEvent(layer, g, viewPort, afterDrawEventType);
541
                        mapContext.fireLayerDrawingEvent(event);
542
                }
543

    
544
        }
545

    
546
        private class SimpleLayerIterator extends LayersIterator {
547

    
548
                public SimpleLayerIterator(FLayer layer) {
549
                        this.appendLayer(layer);
550
                }
551

    
552
                public boolean evaluate(FLayer layer) {
553
                        if (layer instanceof FLayers) {
554
                                return false;
555
                        }
556
                        return layer.isAvailable() && layer.isVisible();
557
                }
558

    
559
        }
560

    
561
        public void dispose() {
562
                this.mapContext = null;
563
                this.viewPort = null;
564
                this.cachedImage = null;
565
                this.previousDrawList = null;
566
        }
567

    
568
        public void print(FLayers root, Graphics2D g, Cancellable cancel,
569
                        double scale, PrintAttributes properties) throws ReadException {
570
                this.checkInitialized();
571

    
572
                List printList = this.createPrintList(root, cancel);
573
                if (cancel.isCanceled()) {
574
                        return;
575
                }
576

    
577
                ComposedLayer composed = null;
578
                int pos;
579
                FLayer layer;
580
                int layerPos = -1;
581
                Object obj;
582
                LayersGroupEvent event;
583
                for (pos = 0; pos < printList.size(); pos++) {
584
                        if (cancel.isCanceled()) {
585
                                return;
586
                        }
587

    
588
                        obj = printList.get(pos);
589
                        if (obj instanceof LayersGroupEvent) {
590
                                event = (LayersGroupEvent) obj;
591
                                if (event.type == LayersGroupEvent.IN_Event) {
592
                                        // System.out.println("=======Empiza a pintar grupo de capas "+
593
                                        // ((FLayers)event.group).getName() +"============");
594
                                        event.group.beginDraw(g, viewPort);
595
                                } else {
596
                                        event.group.endDraw(g, viewPort);
597
                                        // System.out.println("=======Fin a pintar grupo de capas "+
598
                                        // ((FLayers)event.group).getName() +"============");
599

    
600
                                }
601
                                continue;
602
                        }
603
                        layerPos++;
604

    
605
                        layer = (FLayer) obj;
606

    
607
                        // *** Pintado de capa/composicion de capa ***
608
                        if (composed == null) {
609
                                composed = layer.newComposedLayer();
610
                                if (composed != null) {
611
                                        try {
612
                                                composed.add(layer);
613
                                                // System.out.println("=======Imprimiendo composicion de pintado "+
614
                                                // (layerPos-1)+" ============");
615
                                                continue;
616
                                        } catch (Exception e) {
617
                                                throw new ReadException(
618
                                                                "DefaultMapContexDrawer exception", e);
619
                                        }
620
                                }
621
                        } else {
622
                                if (composed.canAdd(layer)) {
623
                                        try {
624
                                                composed.add(layer);
625
                                                // System.out.println("=== a?adiendo a composicion de pintado "+
626
                                                // layerPos+ " "+layer.getName());
627
                                                continue;
628
                                        } catch (Exception e) {
629
                                                throw new ReadException(
630
                                                                "DefaultMapContexDrawer exception", e);
631
                                        }
632
                                } else {
633
                                        // System.out.println("=======Imprimiendo composicion de pintado "+
634
                                        // (layerPos-1)+" ============");
635
                                        this.print(composed, g, cancel, scale, properties);
636
                                        // composed.print( g, viewPort, cancel, scale,properties);
637
                                        composed = layer.newComposedLayer();
638
                                        if (composed != null) {
639
                                                try {
640
                                                        composed.add(layer);
641
                                                        // System.out.println("=== a?adiendo a composicion de pintado "+
642
                                                        // layerPos+ " "+layer.getName());
643
                                                        continue;
644
                                                } catch (Exception e) {
645
                                                        throw new ReadException(
646
                                                                        "DefaultMapContexDrawer exception", e);
647
                                                }
648
                                        }
649
                                }
650
                        }
651
                        // System.out.println("=== imprimiendo "+ layerPos+
652
                        // " "+layer.getName());
653
                        this.print(layer, g, cancel, scale, properties);
654
                        // layer.print(g, viewPort, cancel, scale,properties);
655
                        // *** Pintado de capa/composicion de capa ***
656
                        if (composed != null) {
657
                                // si la composicion no se ha pintado la pintamos
658
                                // System.out.println("=======Imprimiendo composicion de pintado "+
659
                                // (layerPos-1)+" (ultimo) ============");
660
                                this.print(composed, g, cancel, scale, properties);
661
                                // composed.print(g, viewPort, cancel, scale, properties);
662
                                composed = null;
663
                        }
664
                }
665

    
666
        }
667

    
668
        private DrawList createDrawList(FLayers root, Cancellable cancel,
669
                        double scale) {
670
                DrawList result = new DrawList(this.previousDrawList);
671
                Iterator iter = new MyLayerIterator((FLayer) root, scale);
672
                while (iter.hasNext()) {
673
                        if (cancel.isCanceled()) {
674
                                return null;
675
                        }
676
                        result.add(iter.next());
677
                }
678
                if (cancel.isCanceled()) {
679
                        return null;
680
                }
681
                // Take into account also the Graphic layer
682
                result.add(mapContext.getGraphicsLayer());
683
                return result;
684
        }
685

    
686
        private List createPrintList(FLayers root, Cancellable cancel) {
687
                List result = new ArrayList();
688
                Iterator iter = new SimpleLayerIterator((FLayer) root);
689
                while (iter.hasNext()) {
690
                        if (cancel.isCanceled()) {
691
                                return null;
692
                        }
693
                        result.add(iter.next());
694
                }
695
                return result;
696
        }
697

    
698
        private class MyLayerIterator implements Iterator {
699
                List layersList = new ArrayList();
700
                int index = 0;
701
                double scale = 0;
702

    
703
                public MyLayerIterator(FLayer layer, double scale) {
704
                        this.scale = scale;
705
                        this.appendLayer(layer);
706
                }
707

    
708
                protected void appendLayer(FLayer layer) {
709
                        if (layer instanceof LayerCollection) {
710
                                appendLayers((LayerCollection) layer);
711
                        } else if (this.evaluate(layer)) {
712
                                layersList.add(layer);
713
                        }
714
                }
715

    
716
                private void appendLayers(LayerCollection layers) {
717
                        int i;
718
                        layersList.add(new LayersGroupEvent(layers,
719
                                        LayersGroupEvent.IN_Event));
720
                        for (i = 0; i < layers.getLayersCount(); i++) {
721
                                appendLayer(layers.getLayer(i));
722
                        }
723
                        layersList.add(new LayersGroupEvent(layers,
724
                                        LayersGroupEvent.OUT_Event));
725
                }
726

    
727
                public void remove() {
728
                        throw new UnsupportedOperationException();
729
                }
730

    
731
                public boolean hasNext() {
732
                        return index < layersList.size();
733
                }
734

    
735
                public Object next() {
736
                        if (!this.hasNext()) {
737
                                throw new NoSuchElementException();
738
                        }
739
                        Object aux = layersList.get(index);
740
                        index++;
741
                        return aux;
742
                }
743

    
744
                public boolean evaluate(FLayer layer) {
745
                        if (layer instanceof LayerCollection) {
746
                                return false;
747
                        }
748
                        return layer.isAvailable() && layer.isVisible()
749
                                        && layer.isWithinScale(this.scale);
750
                }
751

    
752
        }
753

    
754
        private class LayersGroupEvent {
755
                public static final String IN_Event = "in";
756
                public static final String OUT_Event = "Out";
757

    
758
                private LayerCollection group = null;
759
                private String type = IN_Event;
760

    
761
                public LayersGroupEvent(LayerCollection group, String type) {
762
                        this.group = group;
763
                        this.type = type;
764
                }
765

    
766
                public String getType() {
767
                        return type;
768
                }
769

    
770
                public LayerCollection getGroup() {
771
                        return group;
772
                }
773
        }
774

    
775
}