Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.symbology / org.gvsig.symbology.lib / org.gvsig.symbology.lib.impl / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / symbol / impl / MultiShapeSymbol.java @ 43510

History | View | Annotate | Download (18.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.symbology.fmap.mapcontext.rendering.symbol.impl;
25

    
26
import java.awt.Color;
27
import java.awt.Graphics2D;
28
import java.awt.Rectangle;
29
import java.awt.geom.AffineTransform;
30
import java.awt.geom.Point2D;
31

    
32
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34

    
35
import org.gvsig.compat.print.PrintAttributes;
36
import org.gvsig.fmap.dal.feature.Feature;
37
import org.gvsig.fmap.geom.Geometry;
38
import org.gvsig.fmap.geom.aggregate.Aggregate;
39
import org.gvsig.fmap.geom.type.GeometryType;
40
import org.gvsig.fmap.mapcontext.MapContextLocator;
41
import org.gvsig.fmap.mapcontext.ViewPort;
42
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
43
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
44
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
45
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.IMultiShapeSymbol;
46
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
47
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
48
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
49
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.ILineStyle;
50
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.IMask;
51
import org.gvsig.tools.ToolsLocator;
52
import org.gvsig.tools.dynobject.DynStruct;
53
import org.gvsig.tools.exception.NotYetImplemented;
54
import org.gvsig.tools.persistence.PersistenceManager;
55
import org.gvsig.tools.persistence.PersistentState;
56
import org.gvsig.tools.persistence.exception.PersistenceException;
57
import org.gvsig.tools.task.Cancellable;
58
import org.gvsig.tools.util.Callable;
59

    
60
/**
61
 * MultiShapeSymbol class allows to create a composition of several symbols with
62
 * different shapes and be treated as a single symbol.These shapes can be
63
 * marker,line or fill.
64
 * 
65
 * @author 2005-2008 jaume dominguez faus - jaume.dominguez@iver.es
66
 * @author 2009- <a href="cordinyana@gvsig.org">C?sar Ordi?ana</a> - gvSIG team
67
 */
68
public class MultiShapeSymbol implements ILineSymbol, IMarkerSymbol, IFillSymbol, IMultiShapeSymbol {
69

    
70
        private static final Logger LOG = LoggerFactory.getLogger(MultiShapeSymbol.class); 
71

    
72
        public static final String MULTI_SHAPE_SYMBOL_PERSISTENCE_DEFINITION_NAME = "MultiShapeSymbol";
73
        
74
        private static final String FIELD_MARKER = "marker";
75
        private static final String FIELD_LINE = "line";
76
        private static final String FIELD_FILL = "fill";
77
        private static final String FIELD_DESCRIPTION = "description";
78

    
79
        public static final String SYMBOL_NAME = "multiShape";
80
        
81
        private SymbolManager manager = MapContextLocator.getSymbolManager();
82
        
83
        private IMarkerSymbol marker;
84
        private ILineSymbol line;
85
        private IFillSymbol fill;
86
        private IMask mask;
87
        private String desc;
88
        private int referenceSystem;
89
        private MultiShapeSymbol symSelect;
90
        
91
        public MultiShapeSymbol() {
92
                super();
93
                marker = (IMarkerSymbol) createSymbol(IMarkerSymbol.SYMBOL_NAME);
94
                line = (ILineSymbol) createSymbol(ILineSymbol.SYMBOL_NAME);
95
                fill = (IFillSymbol) createSymbol(IFillSymbol.SYMBOL_NAME);
96
        }
97
        
98
        private ISymbol createSymbol(String symbolName) {
99
                return manager.createSymbol(symbolName);
100
        }
101

    
102
        public Color getLineColor() {
103
                return line.getColor();
104
        }
105

    
106
        public void setLineColor(Color color) {
107
                line.setLineColor(color);
108
        }
109

    
110
        public ILineStyle getLineStyle() {
111
                return line.getLineStyle();
112
        }
113

    
114
        public void setLineStyle(ILineStyle lineStyle) {
115
                line.setLineStyle(lineStyle);
116
        }
117

    
118
        public void setLineWidth(double width) {
119
                line.setLineWidth(width);
120
        }
121

    
122
        public double getLineWidth() {
123
                return line.getLineWidth();
124
        }
125

    
126
        public int getAlpha() {
127
                return line.getAlpha();
128
        }
129

    
130
        public void setAlpha(int outlineAlpha) {
131
                line.setAlpha(outlineAlpha);
132
        }
133

    
134
        public ISymbol getSymbolForSelection() {
135
                if (symSelect == null) {
136
                        symSelect = new MultiShapeSymbol();
137
                }
138

    
139
                if (marker!=null){
140
                        symSelect.setMarkerSymbol((IMarkerSymbol) marker.getSymbolForSelection());
141
                }
142

    
143
                if (line!=null){
144
                        symSelect.setLineSymbol((ILineSymbol) line.getSymbolForSelection());
145
                }
146

    
147
                if (fill!=null ){
148
                        symSelect.setFillSymbol((IFillSymbol) fill.getSymbolForSelection());
149
                }
150

    
151
                return symSelect;
152

    
153
        }
154

    
155
        public void draw(Graphics2D g, AffineTransform affineTransform,
156
                        Geometry geom, Feature feature, Cancellable cancel) {
157
            GeometryType geometryType = geom.getGeometryType();
158
            if (geometryType.isTypeOf(Geometry.TYPES.POINT)){
159
                if (marker != null) {
160
                    marker.draw(g, affineTransform, geom, feature, cancel);
161
                }
162
            }else if (geometryType.isTypeOf(Geometry.TYPES.CURVE)){
163
                if (line != null) {
164
                    line.draw(g, affineTransform, geom, feature, cancel);
165
                }
166
            }else if (geometryType.isTypeOf(Geometry.TYPES.SURFACE)){
167
                if (fill != null) {
168
                    fill.draw(g, affineTransform, geom, feature, cancel);
169
                }                        
170
            }else if (geometryType.isTypeOf(Geometry.TYPES.AGGREGATE)){
171
                Aggregate aggregate = (Aggregate)geom;
172
                for (int i=0 ; i<aggregate.getPrimitivesNumber() ; i++){
173
                    draw(g, affineTransform, aggregate.getPrimitiveAt(i), feature, cancel);
174
                }
175
            }
176
        }
177
        
178
    @Override
179
        public boolean isOneDotOrPixel(Geometry geom,
180
                        double[] positionOfDotOrPixel, ViewPort viewPort, int dpi) {
181
                
182
        GeometryType geomType = geom.getGeometryType();
183
        if( geomType.isSubTypeOf(Geometry.TYPES.POINT) ) {
184
                   if (marker != null) {
185
                                return marker.isOneDotOrPixel(geom, positionOfDotOrPixel, viewPort, dpi);
186
                        }
187

    
188
        } else if( geomType.isSubTypeOf(Geometry.TYPES.CURVE) ) {
189
            if (line != null) {
190
                return line.isOneDotOrPixel(geom, positionOfDotOrPixel, viewPort, dpi);
191
                        }
192
            
193
        } else if( geomType.isSubTypeOf(Geometry.TYPES.SURFACE) ) {
194
                        if (fill != null) {
195
                                return fill.isOneDotOrPixel(geom, positionOfDotOrPixel, viewPort, dpi);
196
                        }
197
            
198
        }
199
                if (!geom.isSimple()){
200
                        Aggregate aggregate = (Aggregate)geom;                        
201
                        for (int i=0 ; i<aggregate.getPrimitivesNumber() ; i++){
202
                                if (!isOneDotOrPixel(aggregate.getPrimitiveAt(i), positionOfDotOrPixel, viewPort, dpi)){
203
                                        return false;
204
                                }
205
                        }
206
                        return true;
207
                }
208
                return true;
209
        }
210

    
211
        public void getPixExtentPlus(Geometry geom, float[] distances,
212
                        ViewPort viewPort, int dpi) {
213
                // TODO Implement it
214
                throw new Error("Not yet implemented!");
215

    
216
        }
217

    
218
        public int getOnePointRgb() {
219
                // will return a mixture of all symbol's getOnePointRgb() value
220

    
221
                int rMarker = 0;
222
                int gMarker = 0;
223
                int bMarker = 0;
224
                int aMarker = 0;
225

    
226
                if (marker!=null && marker.getColor() != null) {
227
                        rMarker = marker.getColor().getRed();
228
                        gMarker = marker.getColor().getGreen();
229
                        bMarker = marker.getColor().getBlue();
230
                        aMarker = marker.getColor().getAlpha();
231
                }
232

    
233
                int rLine = 0;
234
                int gLine = 0;
235
                int bLine = 0;
236
                int aLine = 0;
237

    
238
                if (line != null  && line.getColor() != null) {
239
                        rLine = line.getColor().getRed();
240
                        gLine = line.getColor().getGreen();
241
                        bLine = line.getColor().getBlue();
242
                        aLine = line.getColor().getAlpha();
243
                }
244

    
245
                int rFill = 0;
246
                int gFill = 0;
247
                int bFill = 0;
248
                int aFill = 0;
249

    
250
                if (fill != null ) {
251
                        Color colorOfFill = null;
252
                        if (fill.getOutline()!=null) {
253
                                colorOfFill = fill.getOutline().getColor();
254
                        } else if (fill.getFillColor()!=null) {
255
                                colorOfFill = fill.getFillColor();
256
                        }
257
                        if (colorOfFill != null) {
258
                                rFill = colorOfFill.getRed();
259
                                gFill = colorOfFill.getGreen();
260
                                bFill = colorOfFill.getBlue();
261
                                aFill = colorOfFill.getAlpha();
262

    
263
                        }
264
                }
265

    
266
                int red = (rMarker + rLine + rFill) / 3;
267
                int green = (gMarker + gLine + gFill) / 3;
268
                int blue = (bMarker + bLine + bFill) / 3;
269
                int alpha = (aMarker + aLine + aFill) / 3;
270

    
271
                return (alpha) << 24 + (red << 16) + (green << 8) + blue;
272
        }
273

    
274
        public String getDescription() {
275
                return desc;
276
        }
277

    
278
        public boolean isShapeVisible() {
279
                if (marker!=null) {
280
                        return marker.isShapeVisible();
281
                }
282

    
283
                if (line != null) {
284
                        return line.isShapeVisible();
285
                }
286

    
287
                if (fill != null) {
288
                        fill.isShapeVisible();
289
                }
290

    
291
                return false;
292
        }
293

    
294
        public void setDescription(String desc) {
295
                this.desc = desc ;
296
        }
297

    
298
        public int getSymbolType() {
299
                return Geometry.TYPES.GEOMETRY;
300
        }
301

    
302
        public boolean isSuitableFor(Geometry geom) {
303
                // suitable for everything (why else does it exist?)
304
                return true;
305
        }
306

    
307
        public void drawInsideRectangle(Graphics2D g,
308
                        AffineTransform scaleInstance, Rectangle r, PrintAttributes properties) throws SymbolDrawingException {
309
                double myWidth =  (r.getWidth()/3);
310

    
311
                Rectangle rect = new Rectangle(0, 0, (int) myWidth, r.height);
312

    
313
                if (marker != null) {
314
                        g.translate(r.x, r.y);
315
                        marker.drawInsideRectangle(g, scaleInstance, rect, properties);
316
                        g.translate(-(r.x), -(r.y));
317
                }
318

    
319
                if (line != null) {
320
                        g.translate(r.x+myWidth, r.y);
321
                        line.drawInsideRectangle(g, scaleInstance, rect, properties);
322
                        g.translate(-(r.x+myWidth), -(r.y));
323
                }
324

    
325
                if (fill != null) {
326
                        g.translate(r.x+myWidth+myWidth, r.y);
327
                        fill.drawInsideRectangle(g, scaleInstance, rect, properties);
328
                        g.translate(-(r.x+myWidth+myWidth), -(r.y));
329

    
330
                }
331
        }
332

    
333
    @Override
334
        public void print(Graphics2D g, AffineTransform at, Geometry geom, PrintAttributes properties) {
335
        GeometryType geomType = geom.getGeometryType();
336
        if( geomType.isTypeOf(Geometry.TYPES.POINT) ) {
337
                   if (marker != null) {
338
                                marker.print(g, at, geom, properties);
339
                        }
340

    
341
        } else if( geomType.isTypeOf(Geometry.TYPES.CURVE) ) {
342
                        if (line != null) {
343
                                line.print(g, at, geom, properties);
344
                        }
345

    
346
        } else if( geomType.isTypeOf(Geometry.TYPES.SURFACE) ) {
347
                        if (fill != null) {
348
                                fill.print(g, at, geom, properties);
349
                        }
350

    
351
        }
352
        }
353

    
354
    @Override
355
        public double getRotation() {
356
                if (marker != null) {
357
                        return marker.getRotation();
358
                }
359
                return 0;
360
        }
361

    
362
        public void setRotation(double rotation) {
363
                if (marker != null) {
364
                        marker.setRotation(rotation);
365
                }
366
        }
367

    
368
        public Point2D getOffset() {
369
                if (marker != null) {
370
                        return marker.getOffset();
371
                }
372
                return new Point2D.Double();
373
        }
374

    
375
        public void setOffset(Point2D offset) {
376
                if (marker != null) {
377
                        marker.setOffset(offset);
378
                }
379
        }
380

    
381
        public double getSize() {
382
                if (marker != null) {
383
                        return marker.getSize();
384
                }
385
                return 0;
386
        }
387

    
388
        public void setSize(double size) {
389
                if (marker != null) {
390
                        marker.setSize(size);
391
                }
392

    
393
        }
394

    
395
        public Color getColor() {
396
                if (marker != null) {
397
                        return marker.getColor();
398
                }
399
                return null;
400
        }
401

    
402
        public void setColor(Color color) {
403
                if (marker != null) {
404
                        marker.setColor(color);
405
                }
406
        }
407

    
408
        public void setFillColor(Color color) {
409
                if (fill != null) {
410
                        fill.setFillColor(color);
411
                }
412
        }
413

    
414
        public void setOutline(ILineSymbol outline) {
415
                if (fill != null) {
416
                        fill.setOutline(outline);
417
                }
418
        }
419

    
420
        public Color getFillColor() {
421
                if (fill != null) {
422
                        return fill.getFillColor();
423
                }
424
                return null;
425
        }
426

    
427
        public ILineSymbol getOutline() {
428
                if (fill != null) {
429
                        return fill.getOutline();
430
                }
431
                return null;
432
        }
433

    
434
        public int getFillAlpha() {
435
                if (fill != null) {
436
                        return fill.getFillAlpha();
437
                }
438
                return 255;
439
        }
440

    
441
        public IMask getMask() {
442
                return mask;
443
        }
444

    
445
        public void setUnit(int unitIndex) {
446
                if (marker != null) {
447
                        marker.setUnit(unitIndex);
448
                }
449
                if (line != null) {
450
                        line.setUnit(unitIndex);
451
                }
452
        }
453

    
454
    @Override
455
        public int getUnit() {
456
                if (marker != null) {
457
                        return marker.getUnit();
458
                }
459
                if (line != null) {
460
                        return line.getUnit();
461
                }
462
                return -1;
463
        }
464

    
465
    @Override
466
        public void setMask(IMask mask) {
467
                throw new NotYetImplemented();
468

    
469
        }
470

    
471
    @Override
472
        public int getReferenceSystem() {
473
                return this.referenceSystem;
474
        }
475

    
476
    @Override
477
        public void setReferenceSystem(int system) {
478
                this.referenceSystem = system;
479

    
480
        }
481

    
482
    @Override
483
        public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
484
        GeometryType geomType = geom.getGeometryType();
485
        if( geomType.isTypeOf(Geometry.TYPES.POINT) ) {
486
                if (marker != null) {
487
                                return marker.toCartographicSize(viewPort, dpi, geom);
488
                        }
489

    
490
        } else if( geomType.isTypeOf(Geometry.TYPES.CURVE) ) {
491
                        if (line != null) {
492
                                return line.toCartographicSize(viewPort, dpi, geom);
493
                        }
494

    
495
        } else if( geomType.isTypeOf(Geometry.TYPES.SURFACE) ) {
496
                        LOG.warn("Cartographic size does not have any sense for fill symbols");
497

    
498
        }
499
                return -1;
500
        }
501

    
502
    @Override
503
        public void setCartographicSize(double cartographicSize, Geometry geom) {
504
        GeometryType geomType = geom.getGeometryType();
505
        if( geomType.isTypeOf(Geometry.TYPES.POINT) ) {
506
                if (marker != null) {
507
                                marker.setCartographicSize(cartographicSize, null);
508
                        }
509

    
510
        } else if( geomType.isTypeOf(Geometry.TYPES.CURVE) ) {
511
                        if (line != null) {
512
                                line.setCartographicSize(cartographicSize, null);
513
                        }
514

    
515
        } else if( geomType.isTypeOf(Geometry.TYPES.SURFACE) ) {
516
                    LOG.warn("Cartographic size does not have any sense for fill symbols");
517

    
518
        }
519
        }
520

    
521

    
522
    @Override
523
        public double getCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
524
        GeometryType geomType = geom.getGeometryType();
525
        if( geomType.isTypeOf(Geometry.TYPES.POINT) ) {
526
                return CartographicSupportToolkit.getCartographicLength(
527
                marker, getSize(), viewPort, dpi
528
            );
529

    
530
        } else if( geomType.isTypeOf(Geometry.TYPES.CURVE) ) {
531
                        return CartographicSupportToolkit.getCartographicLength(
532
                line, getSize(), viewPort, dpi
533
            );
534

    
535
        } else if( geomType.isTypeOf(Geometry.TYPES.SURFACE) ) {
536
                    LOG.warn("Cartographic size does not have any sense for fill symbols");
537

    
538
        }
539
                return -1;
540
        }
541

    
542
    @Override
543
        public IMarkerSymbol getMarkerSymbol() {
544
                return marker;
545
        }
546

    
547
    @Override
548
        public ILineSymbol getLineSymbol() {
549
                return line;
550
        }
551

    
552
    @Override
553
        public IFillSymbol getFillSymbol() {
554
                return fill;
555
        }
556

    
557
    @Override
558
        public void setMarkerSymbol(IMarkerSymbol markerSymbol) {
559
                this.marker = markerSymbol;
560
        }
561

    
562
    @Override
563
        public void setLineSymbol(ILineSymbol lineSymbol) {
564
                this.line = lineSymbol;
565
        }
566

    
567
    @Override
568
        public void setFillSymbol(IFillSymbol fillFillSymbol) {
569
                this.fill = fillFillSymbol;
570
        }
571

    
572
    @Override
573
        public boolean hasFill() {
574
        if (fill == null) {
575
                return false;
576
        }
577
        return fill.hasFill();
578
        }
579

    
580
    @Override
581
        public void setHasFill(boolean hasFill) {
582
                if (fill != null) {
583
                        fill.setHasFill(hasFill);
584
                }
585
        }
586

    
587
    @Override
588
        public boolean hasOutline() {
589
                return false;
590
        }
591

    
592
    @Override
593
        public void setHasOutline(boolean hasOutline) {
594

    
595
        }
596

    
597
    @Override
598
        public Object clone() throws CloneNotSupportedException {
599
                MultiShapeSymbol copy = (MultiShapeSymbol) super.clone();
600

    
601
                // Clone inner symbols
602
                if (marker != null) {
603
                        copy.marker = (IMarkerSymbol) marker.clone();
604
                }
605
                if (line != null) {
606
                        copy.line = (ILineSymbol) line.clone();
607
                }
608
                if (fill != null) {
609
                        copy.fill = (IFillSymbol) fill.clone();
610
                }
611
                
612
                if (mask != null) {
613
                        copy.mask = (IMask) mask.clone();
614
                }
615
                
616
                // Clone selection symbol
617
                if (symSelect != null) {
618
                        copy.symSelect = (MultiShapeSymbol) symSelect.clone();
619
                }
620
                
621
                return copy;
622
        }
623

    
624
    @Override
625
        public void loadFromState(PersistentState state)
626
                        throws PersistenceException {
627
                setDescription(state.getString(FIELD_DESCRIPTION));
628
                setFillSymbol((IFillSymbol) state.get(FIELD_FILL));
629
                setMarkerSymbol((IMarkerSymbol) state.get(FIELD_MARKER));
630
                setLineSymbol((ILineSymbol) state.get(FIELD_LINE));
631
        }
632

    
633
    @Override
634
        public void saveToState(PersistentState state) throws PersistenceException {
635
                state.set(FIELD_DESCRIPTION, getDescription());
636
                state.set(FIELD_FILL, getFillSymbol());
637
                state.set(FIELD_MARKER, getMarkerSymbol());
638
                state.set(FIELD_LINE, getLineSymbol());
639
        }
640

    
641
        public static class RegisterPersistence implements Callable {
642

    
643
        @Override
644
                public Object call() throws Exception {
645
                        PersistenceManager manager = ToolsLocator.getPersistenceManager();
646
                        if( manager.getDefinition(MULTI_SHAPE_SYMBOL_PERSISTENCE_DEFINITION_NAME)==null ) {
647
                                DynStruct definition = manager.addDefinition(
648
                                                MultiShapeSymbol.class,
649
                                                MULTI_SHAPE_SYMBOL_PERSISTENCE_DEFINITION_NAME,
650
                                                MULTI_SHAPE_SYMBOL_PERSISTENCE_DEFINITION_NAME+" Persistence definition",
651
                                                null, 
652
                                                null
653
                                );
654
                                // Description
655
                                definition.addDynFieldString(FIELD_DESCRIPTION).setMandatory(false);
656
                                // Fill symbol
657
                                definition.addDynFieldObject(FIELD_FILL).setClassOfValue(IFillSymbol.class).setMandatory(true);
658
                                // Line symbol
659
                                definition.addDynFieldObject(FIELD_LINE).setClassOfValue(ILineSymbol.class).setMandatory(true);
660
                                // Marker symbol
661
                                definition.addDynFieldObject(FIELD_MARKER).setClassOfValue(IMarkerSymbol.class).setMandatory(true);
662
                        }
663
                        return Boolean.TRUE;
664
                }
665
                
666
        }
667

    
668
        public static class RegisterSymbol implements Callable {
669

    
670
        @Override
671
                public Object call() throws Exception {
672
                int[] shapeTypes;
673
                SymbolManager manager = MapContextLocator.getSymbolManager();
674
                
675
                shapeTypes = new int[] { Geometry.TYPES.GEOMETRY };
676
                manager.registerSymbol(MultiShapeSymbol.SYMBOL_NAME,
677
                    shapeTypes,
678
                    MultiShapeSymbol.class
679
                );
680
                        return Boolean.TRUE;
681
                }
682
                
683
        }
684
        
685
}