Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2021 / extensions / org.gvsig.symbology / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / symbol / impl / MultiShapeSymbol.java @ 34111

History | View | Annotate | Download (17.6 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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 2
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
 */
22
package org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl;
23

    
24
import java.awt.Color;
25
import java.awt.Graphics2D;
26
import java.awt.Rectangle;
27
import java.awt.geom.AffineTransform;
28
import java.awt.geom.Point2D;
29

    
30
import org.gvsig.compat.print.PrintAttributes;
31
import org.gvsig.fmap.dal.feature.Feature;
32
import org.gvsig.fmap.geom.Geometry;
33
import org.gvsig.fmap.geom.aggregate.Aggregate;
34
import org.gvsig.fmap.mapcontext.MapContextLocator;
35
import org.gvsig.fmap.mapcontext.ViewPort;
36
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
37
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
38
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
39
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
40
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
41
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
42
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.ILineStyle;
43
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.IMask;
44
import org.gvsig.tools.ToolsLocator;
45
import org.gvsig.tools.dynobject.DynStruct;
46
import org.gvsig.tools.persistence.PersistenceManager;
47
import org.gvsig.tools.persistence.PersistentState;
48
import org.gvsig.tools.persistence.exception.PersistenceException;
49
import org.gvsig.tools.task.Cancellable;
50
import org.gvsig.tools.util.Callable;
51
import org.slf4j.Logger;
52
import org.slf4j.LoggerFactory;
53

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

    
64
        private static final Logger LOG = LoggerFactory.getLogger(MultiShapeSymbol.class); 
65

    
66
        public static final String MULTI_SHAPE_SYMBOL_PERSISTENCE_DEFINITION_NAME = "MultiShapeSymbol";
67
        
68
        private static final String FIELD_MARKER = "marker";
69
        private static final String FIELD_LINE = "line";
70
        private static final String FIELD_FILL = "fill";
71
        private static final String FIELD_DESCRIPTION = "description";
72

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

    
96
        public Color getLineColor() {
97
                return line.getColor();
98
        }
99

    
100
        public void setLineColor(Color color) {
101
                line.setLineColor(color);
102
        }
103

    
104
        public ILineStyle getLineStyle() {
105
                return line.getLineStyle();
106
        }
107

    
108
        public void setLineStyle(ILineStyle lineStyle) {
109
                line.setLineStyle(lineStyle);
110
        }
111

    
112
        public void setLineWidth(double width) {
113
                line.setLineWidth(width);
114
        }
115

    
116
        public double getLineWidth() {
117
                return line.getLineWidth();
118
        }
119

    
120
        public int getAlpha() {
121
                return line.getAlpha();
122
        }
123

    
124
        public void setAlpha(int outlineAlpha) {
125
                line.setAlpha(outlineAlpha);
126
        }
127

    
128
        public ISymbol getSymbolForSelection() {
129
                if (symSelect == null) {
130
                        symSelect = new MultiShapeSymbol();
131
                }
132

    
133
                if (marker!=null){
134
                        symSelect.setMarkerSymbol((IMarkerSymbol) marker.getSymbolForSelection());
135
                }
136

    
137
                if (line!=null){
138
                        symSelect.setLineSymbol((ILineSymbol) line.getSymbolForSelection());
139
                }
140

    
141
                if (fill!=null ){
142
                        symSelect.setFillSymbol((IFillSymbol) fill.getSymbolForSelection());
143
                }
144

    
145
                return symSelect;
146

    
147
        }
148

    
149
        public void draw(Graphics2D g, AffineTransform affineTransform,
150
                        Geometry geom, Feature feature, Cancellable cancel) {
151
                switch (geom.getType()) {
152
                case Geometry.TYPES.POINT: //Tipo punto
153
                   if (marker != null) {
154
                                marker.draw(g, affineTransform, geom, feature, cancel);
155
                        }
156
                        break;
157
                case Geometry.TYPES.CURVE:
158
                case Geometry.TYPES.ARC:
159
                case Geometry.TYPES.SPLINE:
160
                if (line != null) {
161
                                line.draw(g, affineTransform, geom, feature, cancel);
162
                        }
163
                        break;
164

    
165
                case Geometry.TYPES.SURFACE:
166
        case Geometry.TYPES.ELLIPSE:
167
                case Geometry.TYPES.CIRCLE:
168
                        if (fill != null) {
169
                                fill.draw(g, affineTransform, geom, feature, cancel);
170
                        }
171
                        break;
172
                }
173

    
174

    
175
        }
176
        
177
        public boolean isOneDotOrPixel(Geometry geom,
178
                        double[] positionOfDotOrPixel, ViewPort viewPort, int dpi) {
179
                switch (geom.getType()) {
180
                case Geometry.TYPES.POINT: //Tipo punto
181
                   if (marker != null) {
182
                                return marker.isOneDotOrPixel(geom, positionOfDotOrPixel, viewPort, dpi);
183
                        }
184
                        break;
185
                case Geometry.TYPES.CURVE:
186
                case Geometry.TYPES.ARC:
187
                case Geometry.TYPES.SPLINE:
188
                if (line != null) {
189
                                return line.isOneDotOrPixel(geom, positionOfDotOrPixel, viewPort, dpi);
190
                        }
191
                        break;
192

    
193
                case Geometry.TYPES.SURFACE:
194
        case Geometry.TYPES.ELLIPSE:
195
                case Geometry.TYPES.CIRCLE:
196
                        if (fill != null) {
197
                                return fill.isOneDotOrPixel(geom, positionOfDotOrPixel, viewPort, dpi);
198
                        }
199
                        break;
200
                }
201
                if (!geom.isSimple()){
202
                        Aggregate aggregate = (Aggregate)geom;                        
203
                        for (int i=0 ; i<aggregate.getPrimitivesNumber() ; i++){
204
                                if (!isOneDotOrPixel(aggregate.getPrimitiveAt(i), positionOfDotOrPixel, viewPort, dpi)){
205
                                        return false;
206
                                }
207
                        }
208
                        return true;
209
                }
210
                return true;
211
        }
212

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

    
218
        }
219

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

    
223
                int rMarker = 0;
224
                int gMarker = 0;
225
                int bMarker = 0;
226
                int aMarker = 0;
227

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

    
235
                int rLine = 0;
236
                int gLine = 0;
237
                int bLine = 0;
238
                int aLine = 0;
239

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

    
247
                int rFill = 0;
248
                int gFill = 0;
249
                int bFill = 0;
250
                int aFill = 0;
251

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

    
265
                        }
266
                }
267

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

    
273
                return (alpha) << 24 + (red << 16) + (green << 8) + blue;
274
        }
275

    
276
        public String getDescription() {
277
                return desc;
278
        }
279

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

    
285
                if (line != null) {
286
                        return line.isShapeVisible();
287
                }
288

    
289
                if (fill != null) {
290
                        fill.isShapeVisible();
291
                }
292

    
293
                return false;
294
        }
295

    
296
        public void setDescription(String desc) {
297
                this.desc = desc ;
298
        }
299

    
300
        public int getSymbolType() {
301
                return Geometry.TYPES.GEOMETRY;
302
        }
303

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

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

    
313
                Rectangle rect = new Rectangle(0, r.y, (int) myWidth, r.height);
314

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

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

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

    
332
                }
333
        }
334

    
335
        public String getClassName() {
336
                return getClass().getName();
337
        }
338

    
339
        public void print(Graphics2D g, AffineTransform at, Geometry geom, PrintAttributes properties) {
340
                switch (geom.getType()) {
341
                case Geometry.TYPES.POINT: //Tipo punto
342
                   if (marker != null) {
343
                                marker.print(g, at, geom, properties);
344
                        }
345
                        break;
346
                case Geometry.TYPES.CURVE:
347
                case Geometry.TYPES.ARC:
348
                        if (line != null) {
349
                                line.print(g, at, geom, properties);
350
                        }
351
                        break;
352

    
353
                case Geometry.TYPES.SURFACE:
354
                case Geometry.TYPES.ELLIPSE:
355
        case Geometry.TYPES.CIRCLE:
356
                        if (fill != null) {
357
                                fill.print(g, at, geom, properties);
358
                        }
359
                        break;
360
                }
361
        }
362

    
363
        public double getRotation() {
364
                if (marker != null) {
365
                        return marker.getRotation();
366
                }
367
                return 0;
368
        }
369

    
370
        public void setRotation(double rotation) {
371
                if (marker != null) {
372
                        marker.setRotation(rotation);
373
                }
374
        }
375

    
376
        public Point2D getOffset() {
377
                if (marker != null) {
378
                        return marker.getOffset();
379
                }
380
                return new Point2D.Double();
381
        }
382

    
383
        public void setOffset(Point2D offset) {
384
                if (marker != null) {
385
                        marker.setOffset(offset);
386
                }
387
        }
388

    
389
        public double getSize() {
390
                if (marker != null) {
391
                        return marker.getSize();
392
                }
393
                return 0;
394
        }
395

    
396
        public void setSize(double size) {
397
                if (marker != null) {
398
                        marker.setSize(size);
399
                }
400

    
401
        }
402

    
403
        public Color getColor() {
404
                if (marker != null) {
405
                        return marker.getColor();
406
                }
407
                return null;
408
        }
409

    
410
        public void setColor(Color color) {
411
                if (marker != null) {
412
                        marker.setColor(color);
413
                }
414
        }
415

    
416
        public void setFillColor(Color color) {
417
                if (fill != null) {
418
                        fill.setFillColor(color);
419
                }
420
        }
421

    
422
        public void setOutline(ILineSymbol outline) {
423
                if (fill != null) {
424
                        fill.setOutline(outline);
425
                }
426
        }
427

    
428
        public Color getFillColor() {
429
                if (fill != null) {
430
                        return fill.getFillColor();
431
                }
432
                return null;
433
        }
434

    
435
        public ILineSymbol getOutline() {
436
                if (fill != null) {
437
                        return fill.getOutline();
438
                }
439
                return null;
440
        }
441

    
442
        public int getFillAlpha() {
443
                if (fill != null) {
444
                        return fill.getFillAlpha();
445
                }
446
                return 255;
447
        }
448

    
449
        public IMask getMask() {
450
                return mask;
451
        }
452

    
453
        public void setUnit(int unitIndex) {
454
                if (marker != null) {
455
                        marker.setUnit(unitIndex);
456
                }
457
                if (line != null) {
458
                        line.setUnit(unitIndex);
459
                }
460
        }
461

    
462
        public int getUnit() {
463
                if (marker != null) {
464
                        return marker.getUnit();
465
                }
466
                if (line != null) {
467
                        return line.getUnit();
468
                }
469
                return -1;
470
        }
471

    
472
        public void setMask(IMask mask) {
473
                // TODO Implement it
474
                throw new Error("Not yet implemented!");
475

    
476
        }
477

    
478
        public int getReferenceSystem() {
479
                return this.referenceSystem;
480
        }
481

    
482
        public void setReferenceSystem(int system) {
483
                this.referenceSystem = system;
484

    
485
        }
486

    
487
        public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
488
                switch (geom.getType()) {
489
                case Geometry.TYPES.POINT: //Tipo punto
490
                if (marker != null) {
491
                                return marker.toCartographicSize(viewPort, dpi, geom);
492
                        }
493
                case Geometry.TYPES.CURVE:
494
                case Geometry.TYPES.ARC:
495
                        if (line != null) {
496
                                return line.toCartographicSize(viewPort, dpi, geom);
497
                        }
498
                case Geometry.TYPES.SURFACE:
499
                case Geometry.TYPES.ELLIPSE:
500
                case Geometry.TYPES.CIRCLE:
501
                        LOG.warn("Cartographic size does not have any sense for fill symbols");
502

    
503
                }
504
                return -1;
505
        }
506

    
507
        public void setCartographicSize(double cartographicSize, Geometry geom) {
508
                switch (geom.getType()) {
509
                case Geometry.TYPES.POINT: //Tipo punto
510
                if (marker != null) {
511
                                marker.setCartographicSize(cartographicSize, null);
512
                        }
513
                break;
514
                case Geometry.TYPES.CURVE:
515
                case Geometry.TYPES.ARC:
516
                        if (line != null) {
517
                                line.setCartographicSize(cartographicSize, null);
518
                        }
519
                break;
520
                case Geometry.TYPES.SURFACE:
521
                case Geometry.TYPES.ELLIPSE:
522
            case Geometry.TYPES.CIRCLE:
523
                    LOG.warn("Cartographic size does not have any sense for fill symbols");
524
                }
525
        }
526

    
527

    
528
        public double getCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
529
                switch (geom.getType()) {
530
                case Geometry.TYPES.POINT: //Tipo punto
531
                return CartographicSupportToolkit.
532
                        getCartographicLength(marker,
533
                                                                  getSize(),
534
                                                                  viewPort,
535
                                                                  dpi);
536
                case Geometry.TYPES.CURVE:
537
                case Geometry.TYPES.ARC:
538
                        return CartographicSupportToolkit.
539
                        getCartographicLength(line,
540
                                                                  getSize(),
541
                                                                  viewPort,
542
                                                                  dpi);
543
                case Geometry.TYPES.SURFACE:
544
             case Geometry.TYPES.ELLIPSE:
545
            case Geometry.TYPES.CIRCLE:
546
                    LOG.warn("Cartographic size does not have any sense for fill symbols");
547
                }
548
                return -1;
549
        }
550

    
551
        public IMarkerSymbol getMarkerSymbol() {
552
                return marker;
553
        }
554

    
555
        public ILineSymbol getLineSymbol() {
556
                return line;
557
        }
558

    
559
        public IFillSymbol getFillSymbol() {
560
                return fill;
561
        }
562

    
563
        public void setMarkerSymbol(IMarkerSymbol markerSymbol) {
564
                this.marker = markerSymbol;
565
        }
566

    
567
        public void setLineSymbol(ILineSymbol lineSymbol) {
568
                this.line = lineSymbol;
569
        }
570

    
571
        public void setFillSymbol(IFillSymbol fillFillSymbol) {
572
                this.fill = fillFillSymbol;
573
        }
574

    
575
        public boolean hasFill() {
576
        if (fill == null) {
577
                return false;
578
        }
579
        return fill.hasFill();
580
        }
581

    
582
        public void setHasFill(boolean hasFill) {
583
                if (fill != null) {
584
                        fill.setHasFill(hasFill);
585
//                        this.hasFill = hasFill;
586
                }
587
        }
588

    
589
        public boolean hasOutline() {
590
                // TODO Auto-generated method stub
591
                return false;
592
        }
593

    
594
        public void setHasOutline(boolean hasOutline) {
595
                // TODO Auto-generated method stub
596

    
597
        }
598

    
599
        public Object clone() throws CloneNotSupportedException {
600
                MultiShapeSymbol copy = (MultiShapeSymbol) super.clone();
601

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

    
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
        public void saveToState(PersistentState state) throws PersistenceException {
634
                state.set(FIELD_DESCRIPTION, getDescription());
635
                state.set(FIELD_FILL, getFillSymbol());
636
                state.set(FIELD_MARKER, getMarkerSymbol());
637
                state.set(FIELD_LINE, getLineSymbol());
638
        }
639

    
640
        public static class RegisterPersistence implements Callable {
641

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

    
666
        public static class RegisterSymbol implements Callable {
667

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