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

History | View | Annotate | Download (23.4 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.geom.Rectangle2D;
29
import java.awt.image.BufferedImage;
30
import java.util.ArrayList;
31
import java.util.Iterator;
32
import java.util.List;
33
import java.util.NoSuchElementException;
34

    
35
import org.gvsig.compat.CompatLocator;
36
import org.gvsig.compat.print.PrintAttributes;
37
import org.gvsig.fmap.dal.exception.ReadException;
38
import org.gvsig.fmap.geom.primitive.Envelope;
39
import org.gvsig.fmap.mapcontext.ExtentHistory;
40
import org.gvsig.fmap.mapcontext.MapContext;
41
import org.gvsig.fmap.mapcontext.MapContextDrawer;
42
import org.gvsig.fmap.mapcontext.MapContextException;
43
import org.gvsig.fmap.mapcontext.MapContextLocator;
44
import org.gvsig.fmap.mapcontext.MapContextManager;
45
import org.gvsig.fmap.mapcontext.ViewPort;
46
import org.gvsig.fmap.mapcontext.layers.FLayer;
47
import org.gvsig.fmap.mapcontext.layers.FLayerHidesArea;
48
import org.gvsig.fmap.mapcontext.layers.FLayers;
49
import org.gvsig.fmap.mapcontext.layers.LayerDrawEvent;
50
import org.gvsig.fmap.mapcontext.layers.LayersIterator;
51
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
52
import org.gvsig.fmap.mapcontext.layers.operations.LayerCollection;
53
import org.gvsig.fmap.mapcontext.layers.vectorial.GraphicLayer;
54
import org.gvsig.fmap.mapcontext.layers.vectorial.VectorLayer;
55
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelable;
56
import org.gvsig.tools.ToolsLocator;
57
import org.gvsig.tools.dynobject.DynStruct;
58
import org.gvsig.tools.library.LibraryException;
59
import org.gvsig.tools.persistence.PersistenceManager;
60
import org.gvsig.tools.task.Cancellable;
61
import org.gvsig.tools.util.Callable;
62
import org.slf4j.Logger;
63
import org.slf4j.LoggerFactory;
64

    
65
public class DefaultMapContextDrawer implements MapContextDrawer {
66

    
67
        private static final Logger LOG = LoggerFactory
68
                        .getLogger(DefaultMapContextDrawer.class);
69

    
70
        private MapContext mapContext = null;
71
        private ViewPort viewPort = null;
72
        private CachedImage cachedImage = null;
73
        private DrawList previousDrawList = null;
74

    
75
        protected void checkInitialized() {
76
                if (mapContext == null || viewPort == null) {
77
                        throw new IllegalStateException(
78
                                        "MapContext and ViewPort must be set");
79
                }
80
        }
81

    
82
        public void draw(FLayers root, BufferedImage image, Graphics2D g,
83
                        Cancellable cancel, double scale) throws ReadException {
84

    
85
                this.checkInitialized();
86

    
87
                // With viewport changes all layers must be redrawn, discard cache
88
                if (cachedImage != null && cachedImage.hasChangedViewPortDrawVersion()) {
89
                        cachedImage = null;
90
                }
91

    
92
                AffineTransform aux_at = null;
93
                
94
                if (isValidFullCachedImage()) {
95
                    
96
                    aux_at = g.getTransform();
97
                        g.drawImage(
98
                            cachedImage.getFullDrawnImage(),
99
                            (int) -aux_at.getTranslateX(),
100
                            (int) -aux_at.getTranslateY(),
101
                            null);
102
                        LOG.debug("Drawn full image from the cache, all layers cached");
103
                        return;
104
                }
105

    
106
                DrawList drawList = this.createDrawList(root, cancel, scale);
107
                if (drawList == null || drawList.size() == 0) {
108
                        return;
109
                }
110

    
111
                if (cancel.isCanceled()) {
112
                        cachedImage = null;
113
                        return;
114
                }
115

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

    
154
                if (cancel.isCanceled()) {
155
                        cachedImage = null;
156
                        return;
157
                }
158

    
159
                // Draw the second group of layers not cached
160
                firstLayerToDraw = lastLayerToDraw + 1;
161
                lastLayerToDraw = drawList.getLayerCount() - 1;
162
                drawList.drawLayers(image, g, firstLayerToDraw, lastLayerToDraw,
163
                                cancel, scale);
164
                cachedImage.setFullDrawnImage(image);
165

    
166
                this.previousDrawList = drawList;
167
        }
168

    
169
        private boolean isValidPartialCachedImage(DrawList drawList) {
170
                return cachedImage != null
171
                                && cachedImage.isValidPartialDrawnImage(mapContext, drawList);
172
        }
173

    
174
        private boolean isValidFullCachedImage() {
175
                return cachedImage != null
176
                                && cachedImage.isValidFullDrawnImage(mapContext);
177
        }
178

    
179
        private void print(Object layerOrComposed, Graphics2D g,
180
                        Cancellable cancel, double scale, PrintAttributes properties)
181
                        throws ReadException {
182
                ILabelable labelable = null;
183
                ILabelable tmp = null;
184
                if (layerOrComposed instanceof ILabelable) {
185

    
186
                        tmp = (ILabelable) layerOrComposed;
187

    
188
                        if (tmp.isLabeled() && tmp.getLabelingStrategy() != null
189
                                        && tmp.getLabelingStrategy().shouldDrawLabels(scale)) {
190
                                labelable = tmp;
191
                        }
192
                }
193

    
194
                if (layerOrComposed instanceof FLayer) {
195
                        FLayer layer = (FLayer) layerOrComposed;
196
                        layer.print(g, viewPort, cancel, scale, properties);
197
                } else {
198
                        ComposedLayer composed = (ComposedLayer) layerOrComposed;
199
                        composed.print(g, viewPort, cancel, scale, properties);
200
                }
201
                if (labelable != null) {
202
                        labelable.printLabels(g, viewPort, cancel, scale, properties);
203
                }
204

    
205
        }
206

    
207
        public void setMapContext(MapContext mapContext) {
208
                if (this.mapContext == mapContext) {
209
                        return;
210
                }
211
                this.clean();
212
                this.mapContext = mapContext;
213

    
214
        }
215

    
216
        public void setViewPort(ViewPort viewPort) {
217
                if (this.viewPort == viewPort) {
218
                        return;
219
                }
220
                this.clean();
221
                this.viewPort = viewPort;
222

    
223
        }
224

    
225
        protected void clean() {
226
                this.cachedImage = null;
227
        }
228

    
229
        public class CachedImage {
230
                private BufferedImage partialDrawnImage;
231
                private BufferedImage fullDrawnImage;
232
                private long lastMapContextVersion;
233
                private long lastViewPortVersion;
234
                private int lastDrawnLayerPosition;
235

    
236
                public void setPartialDrawnImage(BufferedImage partialDrawnImage,
237
                                MapContext mapContext, ViewPort viewPort,
238
                                int lastDrawnLayerPosition) {
239
                        this.partialDrawnImage = CompatLocator.getGraphicsUtils()
240
                                        .copyBufferedImage(partialDrawnImage);
241
                        this.lastDrawnLayerPosition = lastDrawnLayerPosition;
242
                        updateVersions(mapContext, viewPort);
243
                }
244
                
245
                public void updateVersions(MapContext mapContext, ViewPort viewPort) {
246
                        this.lastMapContextVersion = mapContext.getDrawVersion();
247
                        this.lastViewPortVersion = viewPort.getDrawVersion();                        
248
                }
249

    
250
                public void setFullDrawnImage(BufferedImage fullDrawnImage) {
251
                        this.fullDrawnImage = CompatLocator.getGraphicsUtils()
252
                                        .copyBufferedImage(fullDrawnImage);
253
                }
254

    
255
                public BufferedImage getPartialDrawnImage() {
256
                        return partialDrawnImage;
257
                }
258

    
259
                public BufferedImage getFullDrawnImage() {
260
                        return fullDrawnImage;
261
                }
262

    
263
                public long getMapContextVersion() {
264
                        return lastMapContextVersion;
265
                }
266

    
267
                public int getLastDrawnLayerPosition() {
268
                        return this.lastDrawnLayerPosition;
269
                }
270

    
271
                public boolean isValidFullDrawnImage(MapContext context) {
272
                        // If the MapContext version has not changed, there are not any
273
                        // changes that require redrawing any of the layers.
274
                        return fullDrawnImage != null && !hasChangedMapContextDrawVersion();
275
                }
276

    
277
                public boolean hasChangedMapContextDrawVersion() {
278
                        // This change detects changes in layers and the viewport also
279
                        return mapContext.getDrawVersion() != this.lastMapContextVersion;
280
                }
281

    
282
                public boolean hasChangedViewPortDrawVersion() {
283
                        // This change detects changes in the viewport
284
                        return viewPort.getDrawVersion() != this.lastViewPortVersion;
285
                }
286

    
287
                public boolean isValidPartialDrawnImage(MapContext context,
288
                                DrawList drawList) {
289
                        if (!hasChangedMapContextDrawVersion()) {
290
                                // Nothing has changed
291
                                return true;
292
                        }
293

    
294
                        if (partialDrawnImage == null || hasChangedViewPortDrawVersion()) {
295
                                // No image available or changes in view port
296
                                return false;
297
                        }
298

    
299
                        if (drawList.size() < lastDrawnLayerPosition + 1) {
300
                                // New list has fewer layers than before
301
                                return false;
302
                        }
303

    
304
                        // There is any change in the layers drawn in the partial drawn
305
                        // image?
306
                        return drawList.getFirstChangedLayer() > lastDrawnLayerPosition;
307
                }
308
        }
309

    
310
        public class DrawList {
311
                private List layers = new ArrayList();
312
                private List all = new ArrayList();
313
                private List versions = new ArrayList();
314
                private DrawList previosList = null;
315
                private int firstLayerChanged = -1;
316

    
317
                public DrawList() {
318
                }
319

    
320
                public DrawList(DrawList previousList) {
321
                        if (previousList != null) {
322
                                this.firstLayerChanged = previousList.getLayerCount();
323
                                this.previosList = previousList;
324
                        }
325
                }
326

    
327
                public int getLayerCount() {
328
                        return this.layers.size();
329
                }
330

    
331
                public int getLastLayerVisible(ViewPort viewPort) {
332
                        Envelope area = viewPort.getAdjustedEnvelope();
333
                        for( int n=0; n<this.layers.size()-1; n++ ) {
334
                                FLayer layer = (FLayer) this.layers.get(n);
335
                                if( layer instanceof FLayerHidesArea ) {
336
                                        if( ((FLayerHidesArea)(layer)).hidesThisArea(area) ) {
337
                                                return n;
338
                                        }
339
                                }
340
                        }
341
                        return this.layers.size()-1;
342
                }
343

    
344
                private boolean hasChanged(FLayer layer, int pos) {
345
                        FLayer previous = (FLayer) this.previosList.layers.get(pos);
346
                        // String previousName = previous.getName();
347
                        // String layerName = layer.getName();
348
                        if (previous != layer) {
349
                                return true;
350
                        }
351
                        long previousVersion = ((Long) this.previosList.versions.get(pos))
352
                                        .longValue();
353
                        long layerVersion = layer.getDrawVersion();
354

    
355
                        return previousVersion != layerVersion;
356
                }
357

    
358
                public void add(Object obj) {
359
                        if (obj instanceof FLayer) {
360
                                FLayer layer = (FLayer) obj;
361
                                int curIndex = this.layers.size();
362
                                if (this.firstLayerChanged >= curIndex) {
363
                                        if (this.previosList.getLayerCount() > curIndex) {
364
                                                if (this.hasChanged(layer, curIndex)) {
365
                                                        this.firstLayerChanged = curIndex;
366
                                                }
367
                                        } else if (this.previosList.getLayerCount() == curIndex) {
368
                                                this.firstLayerChanged = curIndex;
369
                                        }
370
                                }
371
                                this.layers.add(layer);
372
                                this.versions.add(new Long(layer.getDrawVersion()));
373
                        } else if (!(obj instanceof LayersGroupEvent)) {
374
                                throw new UnsupportedOperationException();
375
                        }
376

    
377
                        this.all.add(obj);
378
                }
379

    
380
                public int size() {
381
                        return this.all.size();
382
                }
383

    
384
                public int getFirstChangedLayer() {
385
                        if (this.firstLayerChanged > this.layers.size()) {
386
                                this.firstLayerChanged = this.layers.size();
387
                        }
388
                        return this.firstLayerChanged;
389
                }
390

    
391
                public FLayer getLayer(int pos) {
392
                        return (FLayer) this.layers.get(pos);
393
                }
394

    
395
                public Object get(int pos) {
396
                        return this.all.get(pos);
397
                }
398

    
399
                public void drawLayers(BufferedImage image, Graphics2D g,
400
                                int firstLayerToDraw, int lastLayerToDraw, Cancellable cancel,
401
                                double scale) throws ReadException {
402

    
403
                        if (firstLayerToDraw > lastLayerToDraw) {
404
                                LOG.debug("Nothing to draw");
405
                                return;
406
                        }
407

    
408
                        // Find the real layer positions excluding LayersGroupEvents
409
                        FLayer firstLayer = (FLayer) layers.get(firstLayerToDraw);
410
                        int firstLayerPos = all.indexOf(firstLayer);
411
                        // Look if it belongs to a group and start it
412
                        if (firstLayerPos > 0) {
413
                                for (int i = firstLayerPos - 1; i < all.size(); i++) {
414
                                        // firstLayer
415
                                        Object group = all.get(i);
416
                                        if (group instanceof LayersGroupEvent) {
417
                                                LayersGroupEvent event = (LayersGroupEvent) group;
418
                                                if (event.type == LayersGroupEvent.IN_Event) {
419
                                                        event.group.beginDraw(g, viewPort);
420
                                                }
421
                                                break;
422
                                        }
423
                                }
424
                        }
425
                        FLayer lastLayer = (FLayer) layers.get(lastLayerToDraw);
426
                        int lastLayerPos = all.indexOf(lastLayer);
427

    
428
                        LOG.debug("Drawing from layer {} in position (layers: {}, all: {})"
429
                                        + " to layer {} in position (layers: {}, all: {})",
430
                                        new Object[] { firstLayer, new Integer(firstLayerToDraw),
431
                                                        new Integer(firstLayerPos), lastLayer,
432
                                                        new Integer(lastLayerToDraw),
433
                                                        new Integer(lastLayerPos) });
434

    
435
                        ComposedLayer composed = null;
436
                        for (int pos = firstLayerPos; pos <= lastLayerPos; pos++) {
437
                                if (cancel.isCanceled()) {
438
                                        return;
439
                                }
440

    
441
                                Object layerOrGroup = get(pos);
442

    
443
                                // Group drawing events management
444
                                if (layerOrGroup instanceof LayersGroupEvent) {
445
                                        LayersGroupEvent event = (LayersGroupEvent) layerOrGroup;
446
                                        if (event.type == LayersGroupEvent.IN_Event) {
447
                                                event.group.beginDraw(g, viewPort);
448
                                        } else {
449
                                                event.group.endDraw(g, viewPort);
450
                                        }
451
                                } else {
452
                                        FLayer layer = (FLayer) layerOrGroup;
453
                                        if (composed != null && composed.canAdd(layer)) {
454
                                                // Previous or current layer could be composed
455
                                                // Add current layer
456
                                                addToComposedLayer(composed, layer);
457
                                        } else {
458
                                                if (composed != null) {
459
                                                        // Current layer can't be composed on the previous
460
                                                        // composedlayer. Draw previous composed
461
                                                        LOG.debug("Drawing composed layer {} ", composed);
462
                                                        draw(composed, image, g, cancel, scale);
463
                                                        composed = null;
464
                                                }
465

    
466
                                                // Try if the current layer can be composed
467
                                                // Create new composed or draw current layer
468
                                                composed = layer.newComposedLayer();
469
                                                if (composed == null) {
470
                                                        LOG.debug("Drawing layer {} ", layer);
471
                                                        draw(layer, image, g, cancel, scale);
472
                                                } else {
473
                                                        addToComposedLayer(composed, layer);
474
                                                }
475
                                        }
476
                                }
477
                        }
478
                        if (composed != null) {
479
                                // Draw the pending composed
480
                                draw(composed, image, g, cancel, scale);
481
                        }
482

    
483
                        // Check if the last layer is the last of a group and close it
484
                        for (int i = lastLayerPos + 1; i < all.size(); i++) {
485
                                Object group = all.get(i);
486
                                if (group instanceof LayersGroupEvent) {
487
                                        LayersGroupEvent event = (LayersGroupEvent) group;
488
                                        if (event.type == LayersGroupEvent.OUT_Event) {
489
                                                event.group.endDraw(g, viewPort);
490
                                        }
491
                                        break;
492
                                }
493
                        }
494
                }
495

    
496
                private void addToComposedLayer(ComposedLayer composed, FLayer layer)
497
                                throws ReadException {
498
                        try {
499
                                LOG.debug("Adding layer {} to composed layer ", layer, composed);
500
                                composed.add(layer);
501
                        } catch (Exception e) {
502
                                throw new ReadException("DefalutMapContexDrawer exception", e);
503
                        }
504
                }
505

    
506
                private void draw(Object layerOrComposed, BufferedImage image,
507
                                Graphics2D g, Cancellable cancel, double scale)
508
                                throws ReadException {
509
                        ILabelable labelable = null;
510
                        ILabelable tmp = null;
511
                        if (layerOrComposed instanceof ILabelable) {
512

    
513
                                tmp = (ILabelable) layerOrComposed;
514

    
515
                                if (tmp.isLabeled() && tmp.getLabelingStrategy() != null
516
                                                && tmp.getLabelingStrategy().shouldDrawLabels(scale)) {
517
                                        labelable = tmp;
518
                                }
519
                        }
520
                                
521
                        if (layerOrComposed instanceof FLayer) {
522
                                int beforeDrawEventType;
523
                                int afterDrawEventType;
524
                                if (layerOrComposed instanceof GraphicLayer) {
525
                                        beforeDrawEventType = LayerDrawEvent.GRAPHICLAYER_BEFORE_DRAW;
526
                                        afterDrawEventType = LayerDrawEvent.GRAPHICLAYER_AFTER_DRAW;
527
                                } else {
528
                                        beforeDrawEventType = LayerDrawEvent.LAYER_BEFORE_DRAW;
529
                                        afterDrawEventType = LayerDrawEvent.LAYER_AFTER_DRAW;
530
                                }
531
                                FLayer layer = (FLayer) layerOrComposed;
532
                                drawLayer(layer, image, g, cancel, scale, beforeDrawEventType,
533
                                                afterDrawEventType);
534
                        } else {
535
                                ComposedLayer composed = (ComposedLayer) layerOrComposed;
536
                                composed.draw(image, g, viewPort, cancel, scale);
537
                        }
538
                        if (labelable != null) {
539
                                labelable.drawLabels(image, g, viewPort, cancel, scale,
540
                                                mapContext.getViewPort().getDPI());
541
                        }
542

    
543
                }
544

    
545
                protected void drawLayer(FLayer layer, BufferedImage image,
546
                                Graphics2D g, Cancellable cancel, double scale,
547
                                int beforeDrawEventType, int afterDrawEventType)
548
                                throws ReadException {
549
                        LayerDrawEvent event = new LayerDrawEvent(layer, g, viewPort, beforeDrawEventType);
550
                        mapContext.fireLayerDrawingEvent(event);
551
                        layer.draw(image, g, viewPort, cancel, scale);
552
                        event = new LayerDrawEvent(layer, g, viewPort, afterDrawEventType);
553
                        mapContext.fireLayerDrawingEvent(event);
554
                }
555

    
556
        }
557

    
558
        private class SimpleLayerIterator extends LayersIterator {
559

    
560
                public SimpleLayerIterator(FLayer layer) {
561
                        this.appendLayer(layer);
562
                }
563

    
564
                public boolean evaluate(FLayer layer) {
565
                        if (layer instanceof FLayers) {
566
                                return false;
567
                        }
568
                        return layer.isAvailable() && layer.isVisible();
569
                }
570

    
571
        }
572

    
573
        public void dispose() {
574
                this.mapContext = null;
575
                this.viewPort = null;
576
                this.cachedImage = null;
577
                this.previousDrawList = null;
578
        }
579

    
580
        public void print(FLayers root, Graphics2D g, Cancellable cancel,
581
                        double scale, PrintAttributes properties) throws ReadException {
582
                this.checkInitialized();
583

    
584
                List printList = this.createPrintList(root, cancel);
585
                if (cancel.isCanceled()) {
586
                        return;
587
                }
588

    
589
                ComposedLayer composed = null;
590
                int pos;
591
                FLayer layer;
592
                int layerPos = -1;
593
                Object obj;
594
                LayersGroupEvent event;
595
                for (pos = 0; pos < printList.size(); pos++) {
596
                        if (cancel.isCanceled()) {
597
                                return;
598
                        }
599

    
600
                        obj = printList.get(pos);
601
                        if (obj instanceof LayersGroupEvent) {
602
                                event = (LayersGroupEvent) obj;
603
                                if (event.type == LayersGroupEvent.IN_Event) {
604
                                        // System.out.println("=======Empiza a pintar grupo de capas "+
605
                                        // ((FLayers)event.group).getName() +"============");
606
                                        event.group.beginDraw(g, viewPort);
607
                                } else {
608
                                        event.group.endDraw(g, viewPort);
609
                                        // System.out.println("=======Fin a pintar grupo de capas "+
610
                                        // ((FLayers)event.group).getName() +"============");
611

    
612
                                }
613
                                continue;
614
                        }
615
                        layerPos++;
616

    
617
                        layer = (FLayer) obj;
618

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

    
678
        }
679

    
680
        private DrawList createDrawList(FLayers root, Cancellable cancel,
681
                        double scale) {
682
                DrawList result = new DrawList(this.previousDrawList);
683
                Iterator iter = new MyLayerIterator((FLayer) root, scale);
684
                while (iter.hasNext()) {
685
                        if (cancel.isCanceled()) {
686
                                return null;
687
                        }
688
                        result.add(iter.next());
689
                }
690
                if (cancel.isCanceled()) {
691
                        return null;
692
                }
693
                // Take into account also the Graphic layer
694
                for (VectorLayer graphicsLayer : mapContext.getGraphicsLayers()) {
695
                    result.add(graphicsLayer);
696
                }
697
                return result;
698
        }
699

    
700
        private List createPrintList(FLayers root, Cancellable cancel) {
701
                List result = new ArrayList();
702
                Iterator iter = new SimpleLayerIterator((FLayer) root);
703
                while (iter.hasNext()) {
704
                        if (cancel.isCanceled()) {
705
                                return null;
706
                        }
707
                        result.add(iter.next());
708
                }
709
                return result;
710
        }
711

    
712
        private class MyLayerIterator implements Iterator {
713
                List layersList = new ArrayList();
714
                int index = 0;
715
                double scale = 0;
716

    
717
                public MyLayerIterator(FLayer layer, double scale) {
718
                        this.scale = scale;
719
                        this.appendLayer(layer);
720
                }
721

    
722
                protected void appendLayer(FLayer layer) {
723
                        if (layer instanceof LayerCollection) {
724
                                appendLayers((LayerCollection) layer);
725
                        } else if (this.evaluate(layer)) {
726
                                layersList.add(layer);
727
                        }
728
                }
729

    
730
                private void appendLayers(LayerCollection layers) {
731
                        int i;
732
                        layersList.add(new LayersGroupEvent(layers,
733
                                        LayersGroupEvent.IN_Event));
734
                        for (i = 0; i < layers.getLayersCount(); i++) {
735
                                appendLayer(layers.getLayer(i));
736
                        }
737
                        layersList.add(new LayersGroupEvent(layers,
738
                                        LayersGroupEvent.OUT_Event));
739
                }
740

    
741
                public void remove() {
742
                        throw new UnsupportedOperationException();
743
                }
744

    
745
                public boolean hasNext() {
746
                        return index < layersList.size();
747
                }
748

    
749
                public Object next() {
750
                        if (!this.hasNext()) {
751
                                throw new NoSuchElementException();
752
                        }
753
                        Object aux = layersList.get(index);
754
                        index++;
755
                        return aux;
756
                }
757

    
758
                public boolean evaluate(FLayer layer) {
759
                        if (layer instanceof LayerCollection) {
760
                                return false;
761
                        }
762
                        return layer.isAvailable() && layer.isVisible()
763
                                        && layer.isWithinScale(this.scale);
764
                }
765

    
766
        }
767

    
768
        private class LayersGroupEvent {
769
                public static final String IN_Event = "in";
770
                public static final String OUT_Event = "Out";
771

    
772
                private LayerCollection group = null;
773
                private String type = IN_Event;
774

    
775
                public LayersGroupEvent(LayerCollection group, String type) {
776
                        this.group = group;
777
                        this.type = type;
778
                }
779

    
780
                public String getType() {
781
                        return type;
782
                }
783

    
784
                public LayerCollection getGroup() {
785
                        return group;
786
                }
787
        }
788

    
789

    
790
    public static class RegisterMapContextDrawer implements Callable {
791

    
792
        public Object call() {
793
            MapContextManager manager = MapContextLocator.getMapContextManager();
794
            try {
795
                    manager.setDefaultMapContextDrawer(DefaultMapContextDrawer.class);
796
            } catch (MapContextException ex) {
797
                    throw new RuntimeException("Can't register the default MapContextDrawer", ex);
798
            }
799
            return Boolean.TRUE;
800
        }
801
    }
802
}