Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2060 / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / impl / DefaultMapContextDrawer.java @ 39366

History | View | Annotate | Download (21.3 KB)

1
package org.gvsig.fmap.mapcontext.impl;
2

    
3
import java.awt.Graphics2D;
4
import java.awt.geom.AffineTransform;
5
import java.awt.image.BufferedImage;
6
import java.util.ArrayList;
7
import java.util.Iterator;
8
import java.util.List;
9
import java.util.NoSuchElementException;
10

    
11
import org.gvsig.compat.CompatLocator;
12
import org.gvsig.compat.print.PrintAttributes;
13
import org.gvsig.fmap.dal.exception.ReadException;
14
import org.gvsig.fmap.geom.primitive.Envelope;
15
import org.gvsig.fmap.mapcontext.MapContext;
16
import org.gvsig.fmap.mapcontext.MapContextDrawer;
17
import org.gvsig.fmap.mapcontext.ViewPort;
18
import org.gvsig.fmap.mapcontext.layers.FLayer;
19
import org.gvsig.fmap.mapcontext.layers.FLayerHidesArea;
20
import org.gvsig.fmap.mapcontext.layers.FLayers;
21
import org.gvsig.fmap.mapcontext.layers.LayerDrawEvent;
22
import org.gvsig.fmap.mapcontext.layers.LayersIterator;
23
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
24
import org.gvsig.fmap.mapcontext.layers.operations.LayerCollection;
25
import org.gvsig.fmap.mapcontext.layers.vectorial.GraphicLayer;
26
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelable;
27
import org.gvsig.tools.task.Cancellable;
28
import org.slf4j.Logger;
29
import org.slf4j.LoggerFactory;
30

    
31
public class DefaultMapContextDrawer implements MapContextDrawer {
32

    
33
        private static final Logger LOG = LoggerFactory
34
                        .getLogger(DefaultMapContextDrawer.class);
35

    
36
        private MapContext mapContext = null;
37
        private ViewPort viewPort = null;
38
        private CachedImage cachedImage = null;
39
        private DrawList previousDrawList = null;
40

    
41
        protected void checkInitialized() {
42
                if (mapContext == null || viewPort == null) {
43
                        throw new IllegalStateException(
44
                                        "MapContext and ViewPort must be set");
45
                }
46
        }
47

    
48
        public void draw(FLayers root, BufferedImage image, Graphics2D g,
49
                        Cancellable cancel, double scale) throws ReadException {
50

    
51
                this.checkInitialized();
52

    
53
                // With viewport changes all layers must be redrawn, discard cache
54
                if (cachedImage != null && cachedImage.hasChangedViewPortDrawVersion()) {
55
                        cachedImage = null;
56
                }
57

    
58
                AffineTransform aux_at = null;
59
                
60
                if (isValidFullCachedImage()) {
61
                    
62
                    aux_at = g.getTransform();
63
                        g.drawImage(
64
                            cachedImage.getFullDrawnImage(),
65
                            (int) -aux_at.getTranslateX(),
66
                            (int) -aux_at.getTranslateY(),
67
                            null);
68
                        LOG.debug("Drawn full image from the cache, all layers cached");
69
                        return;
70
                }
71

    
72
                DrawList drawList = this.createDrawList(root, cancel, scale);
73
                if (drawList == null || drawList.size() == 0) {
74
                        return;
75
                }
76

    
77
                if (cancel.isCanceled()) {
78
                        cachedImage = null;
79
                        return;
80
                }
81

    
82
                int firstLayerToDraw;
83
                int lastLayerToDraw;
84
                if (isValidPartialCachedImage(drawList)) {
85
                        firstLayerToDraw = 0;
86
                        lastLayerToDraw = cachedImage.getLastDrawnLayerPosition();
87
                        
88
                        aux_at = g.getTransform();
89
                        g.drawImage(
90
                        cachedImage.getPartialDrawnImage(),
91
                        (int) -aux_at.getTranslateX(),
92
                        (int) -aux_at.getTranslateY(),
93
                        null);
94
                        
95
                        cachedImage.updateVersions(mapContext, viewPort);
96
                        LOG.debug("Reused image of cached layers from 0 to {}",
97
                                        new Integer(lastLayerToDraw));
98
                } else {
99
                        if (cachedImage == null) {
100
                                cachedImage = new CachedImage();
101
                                // Draw all layers
102
                                firstLayerToDraw = 0;
103
                                //lastLayerToDraw = drawList.getLayerCount() - 1;
104
                                lastLayerToDraw = drawList.getLastLayerVisible(viewPort);
105
                        } else {
106
                                // Draw the first group of layers without changes to be cached
107
                                // next time
108
                                firstLayerToDraw = 0;
109
                                int firstChangedLayer = drawList.getFirstChangedLayer();
110
                                // If negative nothing has changed, so draw all the layers
111
                                lastLayerToDraw = firstChangedLayer < 0 ? drawList
112
                                                .getLayerCount() - 1 : firstChangedLayer - 1;
113
                        }
114
                        drawList.drawLayers(image, g, firstLayerToDraw, lastLayerToDraw,
115
                                        cancel, scale);
116
                        cachedImage.setPartialDrawnImage(image, mapContext, viewPort,
117
                                        lastLayerToDraw);
118
                }
119

    
120
                if (cancel.isCanceled()) {
121
                        cachedImage = null;
122
                        return;
123
                }
124

    
125
                // Draw the second group of layers not cached
126
                firstLayerToDraw = lastLayerToDraw + 1;
127
                lastLayerToDraw = drawList.getLayerCount() - 1;
128
                drawList.drawLayers(image, g, firstLayerToDraw, lastLayerToDraw,
129
                                cancel, scale);
130
                cachedImage.setFullDrawnImage(image);
131

    
132
                this.previousDrawList = drawList;
133
        }
134

    
135
        private boolean isValidPartialCachedImage(DrawList drawList) {
136
                return cachedImage != null
137
                                && cachedImage.isValidPartialDrawnImage(mapContext, drawList);
138
        }
139

    
140
        private boolean isValidFullCachedImage() {
141
                return cachedImage != null
142
                                && cachedImage.isValidFullDrawnImage(mapContext);
143
        }
144

    
145
        private void print(Object layerOrComposed, Graphics2D g,
146
                        Cancellable cancel, double scale, PrintAttributes properties)
147
                        throws ReadException {
148
                ILabelable labelable = null;
149
                ILabelable tmp = null;
150
                if (layerOrComposed instanceof ILabelable) {
151

    
152
                        tmp = (ILabelable) layerOrComposed;
153

    
154
                        if (tmp.isLabeled() && tmp.getLabelingStrategy() != null
155
                                        && tmp.getLabelingStrategy().shouldDrawLabels(scale)) {
156
                                labelable = tmp;
157
                        }
158
                }
159

    
160
                if (layerOrComposed instanceof FLayer) {
161
                        FLayer layer = (FLayer) layerOrComposed;
162
                        layer.print(g, viewPort, cancel, scale, properties);
163
                } else {
164
                        ComposedLayer composed = (ComposedLayer) layerOrComposed;
165
                        composed.print(g, viewPort, cancel, scale, properties);
166
                }
167
                if (labelable != null) {
168
                        labelable.printLabels(g, viewPort, cancel, scale, properties);
169
                }
170

    
171
        }
172

    
173
        public void setMapContext(MapContext mapContext) {
174
                if (this.mapContext == mapContext) {
175
                        return;
176
                }
177
                this.clean();
178
                this.mapContext = mapContext;
179

    
180
        }
181

    
182
        public void setViewPort(ViewPort viewPort) {
183
                if (this.viewPort == viewPort) {
184
                        return;
185
                }
186
                this.clean();
187
                this.viewPort = viewPort;
188

    
189
        }
190

    
191
        protected void clean() {
192
                this.cachedImage = null;
193
        }
194

    
195
        public class CachedImage {
196
                private BufferedImage partialDrawnImage;
197
                private BufferedImage fullDrawnImage;
198
                private long lastMapContextVersion;
199
                private long lastViewPortVersion;
200
                private int lastDrawnLayerPosition;
201

    
202
                public void setPartialDrawnImage(BufferedImage partialDrawnImage,
203
                                MapContext mapContext, ViewPort viewPort,
204
                                int lastDrawnLayerPosition) {
205
                        this.partialDrawnImage = CompatLocator.getGraphicsUtils()
206
                                        .copyBufferedImage(partialDrawnImage);
207
                        this.lastDrawnLayerPosition = lastDrawnLayerPosition;
208
                        updateVersions(mapContext, viewPort);
209
                }
210
                
211
                public void updateVersions(MapContext mapContext, ViewPort viewPort) {
212
                        this.lastMapContextVersion = mapContext.getDrawVersion();
213
                        this.lastViewPortVersion = viewPort.getDrawVersion();                        
214
                }
215

    
216
                public void setFullDrawnImage(BufferedImage fullDrawnImage) {
217
                        this.fullDrawnImage = CompatLocator.getGraphicsUtils()
218
                                        .copyBufferedImage(fullDrawnImage);
219
                }
220

    
221
                public BufferedImage getPartialDrawnImage() {
222
                        return partialDrawnImage;
223
                }
224

    
225
                public BufferedImage getFullDrawnImage() {
226
                        return fullDrawnImage;
227
                }
228

    
229
                public long getMapContextVersion() {
230
                        return lastMapContextVersion;
231
                }
232

    
233
                public int getLastDrawnLayerPosition() {
234
                        return this.lastDrawnLayerPosition;
235
                }
236

    
237
                public boolean isValidFullDrawnImage(MapContext context) {
238
                        // If the MapContext version has not changed, there are not any
239
                        // changes that require redrawing any of the layers.
240
                        return fullDrawnImage != null && !hasChangedMapContextDrawVersion();
241
                }
242

    
243
                public boolean hasChangedMapContextDrawVersion() {
244
                        // This change detects changes in layers and the viewport also
245
                        return mapContext.getDrawVersion() != this.lastMapContextVersion;
246
                }
247

    
248
                public boolean hasChangedViewPortDrawVersion() {
249
                        // This change detects changes in the viewport
250
                        return viewPort.getDrawVersion() != this.lastViewPortVersion;
251
                }
252

    
253
                public boolean isValidPartialDrawnImage(MapContext context,
254
                                DrawList drawList) {
255
                        if (!hasChangedMapContextDrawVersion()) {
256
                                // Nothing has changed
257
                                return true;
258
                        }
259

    
260
                        if (partialDrawnImage == null || hasChangedViewPortDrawVersion()) {
261
                                // No image available or changes in view port
262
                                return false;
263
                        }
264

    
265
                        if (drawList.size() < lastDrawnLayerPosition + 1) {
266
                                // New list has fewer layers than before
267
                                return false;
268
                        }
269

    
270
                        // There is any change in the layers drawn in the partial drawn
271
                        // image?
272
                        return drawList.getFirstChangedLayer() > lastDrawnLayerPosition;
273
                }
274
        }
275

    
276
        public class DrawList {
277
                private List layers = new ArrayList();
278
                private List all = new ArrayList();
279
                private List versions = new ArrayList();
280
                private DrawList previosList = null;
281
                private int firstLayerChanged = -1;
282

    
283
                public DrawList() {
284
                }
285

    
286
                public DrawList(DrawList previousList) {
287
                        if (previousList != null) {
288
                                this.firstLayerChanged = previousList.getLayerCount();
289
                                this.previosList = previousList;
290
                        }
291
                }
292

    
293
                public int getLayerCount() {
294
                        return this.layers.size();
295
                }
296

    
297
                public int getLastLayerVisible(ViewPort viewPort) {
298
                        Envelope area = viewPort.getAdjustedEnvelope();
299
                        for( int n=0; n<this.layers.size()-1; n++ ) {
300
                                FLayer layer = (FLayer) this.layers.get(n);
301
                                if( layer instanceof FLayerHidesArea ) {
302
                                        if( ((FLayerHidesArea)(layer)).hidesThisArea(area) ) {
303
                                                return n;
304
                                        }
305
                                }
306
                        }
307
                        return this.layers.size()-1;
308
                }
309

    
310
                private boolean hasChanged(FLayer layer, int pos) {
311
                        FLayer previous = (FLayer) this.previosList.layers.get(pos);
312
                        // String previousName = previous.getName();
313
                        // String layerName = layer.getName();
314
                        if (previous != layer) {
315
                                return true;
316
                        }
317
                        long previousVersion = ((Long) this.previosList.versions.get(pos))
318
                                        .longValue();
319
                        long layerVersion = layer.getDrawVersion();
320

    
321
                        return previousVersion != layerVersion;
322
                }
323

    
324
                public void add(Object obj) {
325
                        if (obj instanceof FLayer) {
326
                                FLayer layer = (FLayer) obj;
327
                                int curIndex = this.layers.size();
328
                                if (this.firstLayerChanged >= curIndex) {
329
                                        if (this.previosList.getLayerCount() > curIndex) {
330
                                                if (this.hasChanged(layer, curIndex)) {
331
                                                        this.firstLayerChanged = curIndex;
332
                                                }
333
                                        } else if (this.previosList.getLayerCount() == curIndex) {
334
                                                this.firstLayerChanged = curIndex;
335
                                        }
336
                                }
337
                                this.layers.add(layer);
338
                                this.versions.add(new Long(layer.getDrawVersion()));
339
                        } else if (!(obj instanceof LayersGroupEvent)) {
340
                                throw new UnsupportedOperationException();
341
                        }
342

    
343
                        this.all.add(obj);
344
                }
345

    
346
                public int size() {
347
                        return this.all.size();
348
                }
349

    
350
                public int getFirstChangedLayer() {
351
                        if (this.firstLayerChanged > this.layers.size()) {
352
                                this.firstLayerChanged = this.layers.size();
353
                        }
354
                        return this.firstLayerChanged;
355
                }
356

    
357
                public FLayer getLayer(int pos) {
358
                        return (FLayer) this.layers.get(pos);
359
                }
360

    
361
                public Object get(int pos) {
362
                        return this.all.get(pos);
363
                }
364

    
365
                public void drawLayers(BufferedImage image, Graphics2D g,
366
                                int firstLayerToDraw, int lastLayerToDraw, Cancellable cancel,
367
                                double scale) throws ReadException {
368

    
369
                        if (firstLayerToDraw > lastLayerToDraw) {
370
                                LOG.debug("Nothing to draw");
371
                                return;
372
                        }
373

    
374
                        // Find the real layer positions excluding LayersGroupEvents
375
                        FLayer firstLayer = (FLayer) layers.get(firstLayerToDraw);
376
                        int firstLayerPos = all.indexOf(firstLayer);
377
                        // Look if it belongs to a group and start it
378
                        if (firstLayerPos > 0) {
379
                                for (int i = firstLayerPos - 1; i > 0; i++) {
380
                                        Object group = all.get(i);
381
                                        if (group instanceof LayersGroupEvent) {
382
                                                LayersGroupEvent event = (LayersGroupEvent) group;
383
                                                if (event.type == LayersGroupEvent.IN_Event) {
384
                                                        event.group.beginDraw(g, viewPort);
385
                                                }
386
                                                break;
387
                                        }
388
                                }
389
                        }
390
                        FLayer lastLayer = (FLayer) layers.get(lastLayerToDraw);
391
                        int lastLayerPos = all.indexOf(lastLayer);
392

    
393
                        LOG.debug("Drawing from layer {} in position (layers: {}, all: {})"
394
                                        + " to layer {} in position (layers: {}, all: {})",
395
                                        new Object[] { firstLayer, new Integer(firstLayerToDraw),
396
                                                        new Integer(firstLayerPos), lastLayer,
397
                                                        new Integer(lastLayerToDraw),
398
                                                        new Integer(lastLayerPos) });
399

    
400
                        ComposedLayer composed = null;
401
                        for (int pos = firstLayerPos; pos <= lastLayerPos; pos++) {
402
                                if (cancel.isCanceled()) {
403
                                        return;
404
                                }
405

    
406
                                Object layerOrGroup = get(pos);
407

    
408
                                // Group drawing events management
409
                                if (layerOrGroup instanceof LayersGroupEvent) {
410
                                        LayersGroupEvent event = (LayersGroupEvent) layerOrGroup;
411
                                        if (event.type == LayersGroupEvent.IN_Event) {
412
                                                event.group.beginDraw(g, viewPort);
413
                                        } else {
414
                                                event.group.endDraw(g, viewPort);
415
                                        }
416
                                } else {
417
                                        FLayer layer = (FLayer) layerOrGroup;
418
                                        if (composed != null && composed.canAdd(layer)) {
419
                                                // Previous or current layer could be composed
420
                                                // Add current layer
421
                                                addToComposedLayer(composed, layer);
422
                                        } else {
423
                                                if (composed != null) {
424
                                                        // Current layer can't be composed on the previous
425
                                                        // composedlayer. Draw previous composed
426
                                                        LOG.debug("Drawing composed layer {} ", composed);
427
                                                        draw(composed, image, g, cancel, scale);
428
                                                        composed = null;
429
                                                }
430

    
431
                                                // Try if the current layer can be composed
432
                                                // Create new composed or draw current layer
433
                                                composed = layer.newComposedLayer();
434
                                                if (composed == null) {
435
                                                        LOG.debug("Drawing layer {} ", layer);
436
                                                        draw(layer, image, g, cancel, scale);
437
                                                } else {
438
                                                        addToComposedLayer(composed, layer);
439
                                                }
440
                                        }
441
                                }
442
                        }
443
                        if (composed != null) {
444
                                // Draw the pending composed
445
                                draw(composed, image, g, cancel, scale);
446
                        }
447

    
448
                        // Check if the last layer is the last of a group and close it
449
                        for (int i = lastLayerPos + 1; i < all.size(); i++) {
450
                                Object group = all.get(i);
451
                                if (group instanceof LayersGroupEvent) {
452
                                        LayersGroupEvent event = (LayersGroupEvent) group;
453
                                        if (event.type == LayersGroupEvent.OUT_Event) {
454
                                                event.group.endDraw(g, viewPort);
455
                                        }
456
                                        break;
457
                                }
458
                        }
459
                }
460

    
461
                private void addToComposedLayer(ComposedLayer composed, FLayer layer)
462
                                throws ReadException {
463
                        try {
464
                                LOG.debug("Adding layer {} to composed layer ", layer, composed);
465
                                composed.add(layer);
466
                        } catch (Exception e) {
467
                                throw new ReadException("DefalutMapContexDrawer exception", e);
468
                        }
469
                }
470

    
471
                private void draw(Object layerOrComposed, BufferedImage image,
472
                                Graphics2D g, Cancellable cancel, double scale)
473
                                throws ReadException {
474
                        ILabelable labelable = null;
475
                        ILabelable tmp = null;
476
                        if (layerOrComposed instanceof ILabelable) {
477

    
478
                                tmp = (ILabelable) layerOrComposed;
479

    
480
                                if (tmp.isLabeled() && tmp.getLabelingStrategy() != null
481
                                                && tmp.getLabelingStrategy().shouldDrawLabels(scale)) {
482
                                        labelable = tmp;
483
                                }
484
                        }
485
                                
486
                        if (layerOrComposed instanceof FLayer) {
487
                                int beforeDrawEventType;
488
                                int afterDrawEventType;
489
                                if (layerOrComposed instanceof GraphicLayer) {
490
                                        beforeDrawEventType = LayerDrawEvent.GRAPHICLAYER_BEFORE_DRAW;
491
                                        afterDrawEventType = LayerDrawEvent.GRAPHICLAYER_AFTER_DRAW;
492
                                } else {
493
                                        beforeDrawEventType = LayerDrawEvent.LAYER_BEFORE_DRAW;
494
                                        afterDrawEventType = LayerDrawEvent.LAYER_AFTER_DRAW;
495
                                }
496
                                FLayer layer = (FLayer) layerOrComposed;
497
                                drawLayer(layer, image, g, cancel, scale, beforeDrawEventType,
498
                                                afterDrawEventType);
499
                        } else {
500
                                ComposedLayer composed = (ComposedLayer) layerOrComposed;
501
                                composed.draw(image, g, viewPort, cancel, scale);
502
                        }
503
                        if (labelable != null) {
504
                                labelable.drawLabels(image, g, viewPort, cancel, scale,
505
                                                MapContext.getScreenDPI());
506
                        }
507

    
508
                }
509

    
510
                protected void drawLayer(FLayer layer, BufferedImage image,
511
                                Graphics2D g, Cancellable cancel, double scale,
512
                                int beforeDrawEventType, int afterDrawEventType)
513
                                throws ReadException {
514
                        LayerDrawEvent event = new LayerDrawEvent(layer, g, viewPort, beforeDrawEventType);
515
                        mapContext.fireLayerDrawingEvent(event);
516
                        layer.draw(image, g, viewPort, cancel, scale);
517
                        event = new LayerDrawEvent(layer, g, viewPort, afterDrawEventType);
518
                        mapContext.fireLayerDrawingEvent(event);
519
                }
520

    
521
        }
522

    
523
        private class SimpleLayerIterator extends LayersIterator {
524

    
525
                public SimpleLayerIterator(FLayer layer) {
526
                        this.appendLayer(layer);
527
                }
528

    
529
                public boolean evaluate(FLayer layer) {
530
                        if (layer instanceof FLayers) {
531
                                return false;
532
                        }
533
                        return layer.isAvailable() && layer.isVisible();
534
                }
535

    
536
        }
537

    
538
        public void dispose() {
539
                this.mapContext = null;
540
                this.viewPort = null;
541
                this.cachedImage = null;
542
                this.previousDrawList = null;
543
        }
544

    
545
        public void print(FLayers root, Graphics2D g, Cancellable cancel,
546
                        double scale, PrintAttributes properties) throws ReadException {
547
                this.checkInitialized();
548

    
549
                List printList = this.createPrintList(root, cancel);
550
                if (cancel.isCanceled()) {
551
                        return;
552
                }
553

    
554
                ComposedLayer composed = null;
555
                int pos;
556
                FLayer layer;
557
                int layerPos = -1;
558
                Object obj;
559
                LayersGroupEvent event;
560
                for (pos = 0; pos < printList.size(); pos++) {
561
                        if (cancel.isCanceled()) {
562
                                return;
563
                        }
564

    
565
                        obj = printList.get(pos);
566
                        if (obj instanceof LayersGroupEvent) {
567
                                event = (LayersGroupEvent) obj;
568
                                if (event.type == LayersGroupEvent.IN_Event) {
569
                                        // System.out.println("=======Empiza a pintar grupo de capas "+
570
                                        // ((FLayers)event.group).getName() +"============");
571
                                        event.group.beginDraw(g, viewPort);
572
                                } else {
573
                                        event.group.endDraw(g, viewPort);
574
                                        // System.out.println("=======Fin a pintar grupo de capas "+
575
                                        // ((FLayers)event.group).getName() +"============");
576

    
577
                                }
578
                                continue;
579
                        }
580
                        layerPos++;
581

    
582
                        layer = (FLayer) obj;
583

    
584
                        // *** Pintado de capa/composicion de capa ***
585
                        if (composed == null) {
586
                                composed = layer.newComposedLayer();
587
                                if (composed != null) {
588
                                        try {
589
                                                composed.add(layer);
590
                                                // System.out.println("=======Imprimiendo composicion de pintado "+
591
                                                // (layerPos-1)+" ============");
592
                                                continue;
593
                                        } catch (Exception e) {
594
                                                throw new ReadException(
595
                                                                "DefaultMapContexDrawer exception", e);
596
                                        }
597
                                }
598
                        } else {
599
                                if (composed.canAdd(layer)) {
600
                                        try {
601
                                                composed.add(layer);
602
                                                // System.out.println("=== a?adiendo a composicion de pintado "+
603
                                                // layerPos+ " "+layer.getName());
604
                                                continue;
605
                                        } catch (Exception e) {
606
                                                throw new ReadException(
607
                                                                "DefaultMapContexDrawer exception", e);
608
                                        }
609
                                } else {
610
                                        // System.out.println("=======Imprimiendo composicion de pintado "+
611
                                        // (layerPos-1)+" ============");
612
                                        this.print(composed, g, cancel, scale, properties);
613
                                        // composed.print( g, viewPort, cancel, scale,properties);
614
                                        composed = layer.newComposedLayer();
615
                                        if (composed != null) {
616
                                                try {
617
                                                        composed.add(layer);
618
                                                        // System.out.println("=== a?adiendo a composicion de pintado "+
619
                                                        // layerPos+ " "+layer.getName());
620
                                                        continue;
621
                                                } catch (Exception e) {
622
                                                        throw new ReadException(
623
                                                                        "DefaultMapContexDrawer exception", e);
624
                                                }
625
                                        }
626
                                }
627
                        }
628
                        // System.out.println("=== imprimiendo "+ layerPos+
629
                        // " "+layer.getName());
630
                        this.print(layer, g, cancel, scale, properties);
631
                        // layer.print(g, viewPort, cancel, scale,properties);
632
                        // *** Pintado de capa/composicion de capa ***
633
                        if (composed != null) {
634
                                // si la composicion no se ha pintado la pintamos
635
                                // System.out.println("=======Imprimiendo composicion de pintado "+
636
                                // (layerPos-1)+" (ultimo) ============");
637
                                this.print(composed, g, cancel, scale, properties);
638
                                // composed.print(g, viewPort, cancel, scale, properties);
639
                                composed = null;
640
                        }
641
                }
642

    
643
        }
644

    
645
        private DrawList createDrawList(FLayers root, Cancellable cancel,
646
                        double scale) {
647
                DrawList result = new DrawList(this.previousDrawList);
648
                Iterator iter = new MyLayerIterator((FLayer) root, scale);
649
                while (iter.hasNext()) {
650
                        if (cancel.isCanceled()) {
651
                                return null;
652
                        }
653
                        result.add(iter.next());
654
                }
655
                if (cancel.isCanceled()) {
656
                        return null;
657
                }
658
                // Take into account also the Graphic layer
659
                result.add(mapContext.getGraphicsLayer());
660
                return result;
661
        }
662

    
663
        private List createPrintList(FLayers root, Cancellable cancel) {
664
                List result = new ArrayList();
665
                Iterator iter = new SimpleLayerIterator((FLayer) root);
666
                while (iter.hasNext()) {
667
                        if (cancel.isCanceled()) {
668
                                return null;
669
                        }
670
                        result.add(iter.next());
671
                }
672
                return result;
673
        }
674

    
675
        private class MyLayerIterator implements Iterator {
676
                List layersList = new ArrayList();
677
                int index = 0;
678
                double scale = 0;
679

    
680
                public MyLayerIterator(FLayer layer, double scale) {
681
                        this.scale = scale;
682
                        this.appendLayer(layer);
683
                }
684

    
685
                protected void appendLayer(FLayer layer) {
686
                        if (layer instanceof LayerCollection) {
687
                                appendLayers((LayerCollection) layer);
688
                        } else if (this.evaluate(layer)) {
689
                                layersList.add(layer);
690
                        }
691
                }
692

    
693
                private void appendLayers(LayerCollection layers) {
694
                        int i;
695
                        layersList.add(new LayersGroupEvent(layers,
696
                                        LayersGroupEvent.IN_Event));
697
                        for (i = 0; i < layers.getLayersCount(); i++) {
698
                                appendLayer(layers.getLayer(i));
699
                        }
700
                        layersList.add(new LayersGroupEvent(layers,
701
                                        LayersGroupEvent.OUT_Event));
702
                }
703

    
704
                public void remove() {
705
                        throw new UnsupportedOperationException();
706
                }
707

    
708
                public boolean hasNext() {
709
                        return index < layersList.size();
710
                }
711

    
712
                public Object next() {
713
                        if (!this.hasNext()) {
714
                                throw new NoSuchElementException();
715
                        }
716
                        Object aux = layersList.get(index);
717
                        index++;
718
                        return aux;
719
                }
720

    
721
                public boolean evaluate(FLayer layer) {
722
                        if (layer instanceof LayerCollection) {
723
                                return false;
724
                        }
725
                        return layer.isAvailable() && layer.isVisible()
726
                                        && layer.isWithinScale(this.scale);
727
                }
728

    
729
        }
730

    
731
        private class LayersGroupEvent {
732
                public static final String IN_Event = "in";
733
                public static final String OUT_Event = "Out";
734

    
735
                private LayerCollection group = null;
736
                private String type = IN_Event;
737

    
738
                public LayersGroupEvent(LayerCollection group, String type) {
739
                        this.group = group;
740
                        this.type = type;
741
                }
742

    
743
                public String getType() {
744
                        return type;
745
                }
746

    
747
                public LayerCollection getGroup() {
748
                        return group;
749
                }
750
        }
751

    
752
}