Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / 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 @ 37499

History | View | Annotate | Download (18 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.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

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

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

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

    
69
        public static final String MULTI_SHAPE_SYMBOL_PERSISTENCE_DEFINITION_NAME = "MultiShapeSymbol";
70
        
71
        private static final String FIELD_MARKER = "marker";
72
        private static final String FIELD_LINE = "line";
73
        private static final String FIELD_FILL = "fill";
74
        private static final String FIELD_DESCRIPTION = "description";
75

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

    
99
        public Color getLineColor() {
100
                return line.getColor();
101
        }
102

    
103
        public void setLineColor(Color color) {
104
                line.setLineColor(color);
105
        }
106

    
107
        public ILineStyle getLineStyle() {
108
                return line.getLineStyle();
109
        }
110

    
111
        public void setLineStyle(ILineStyle lineStyle) {
112
                line.setLineStyle(lineStyle);
113
        }
114

    
115
        public void setLineWidth(double width) {
116
                line.setLineWidth(width);
117
        }
118

    
119
        public double getLineWidth() {
120
                return line.getLineWidth();
121
        }
122

    
123
        public int getAlpha() {
124
                return line.getAlpha();
125
        }
126

    
127
        public void setAlpha(int outlineAlpha) {
128
                line.setAlpha(outlineAlpha);
129
        }
130

    
131
        public ISymbol getSymbolForSelection() {
132
                if (symSelect == null) {
133
                        symSelect = new MultiShapeSymbol();
134
                }
135

    
136
                if (marker!=null){
137
                        symSelect.setMarkerSymbol((IMarkerSymbol) marker.getSymbolForSelection());
138
                }
139

    
140
                if (line!=null){
141
                        symSelect.setLineSymbol((ILineSymbol) line.getSymbolForSelection());
142
                }
143

    
144
                if (fill!=null ){
145
                        symSelect.setFillSymbol((IFillSymbol) fill.getSymbolForSelection());
146
                }
147

    
148
                return symSelect;
149

    
150
        }
151

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

    
191
                case Geometry.TYPES.SURFACE:
192
        case Geometry.TYPES.ELLIPSE:
193
                case Geometry.TYPES.CIRCLE:
194
                        if (fill != null) {
195
                                return fill.isOneDotOrPixel(geom, positionOfDotOrPixel, viewPort, dpi);
196
                        }
197
                        break;
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, r.y, (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
//        public String getClassName() {
334
//                return getClass().getName();
335
//        }
336

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

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

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

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

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

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

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

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

    
399
        }
400

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

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

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

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

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

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

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

    
447
        public IMask getMask() {
448
                return mask;
449
        }
450

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

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

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

    
474
        }
475

    
476
        public int getReferenceSystem() {
477
                return this.referenceSystem;
478
        }
479

    
480
        public void setReferenceSystem(int system) {
481
                this.referenceSystem = system;
482

    
483
        }
484

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

    
501
                }
502
                return -1;
503
        }
504

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

    
525

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

    
549
        public IMarkerSymbol getMarkerSymbol() {
550
                return marker;
551
        }
552

    
553
        public ILineSymbol getLineSymbol() {
554
                return line;
555
        }
556

    
557
        public IFillSymbol getFillSymbol() {
558
                return fill;
559
        }
560

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

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

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

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

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

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

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

    
595
        }
596

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

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

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

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

    
638
        public static class RegisterPersistence implements Callable {
639

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

    
664
        public static class RegisterSymbol implements Callable {
665

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