Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / core / symbols / MultiLayerFillSymbol.java @ 13881

History | View | Annotate | Download (8.91 KB)

1
/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib��ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41

    
42
/* CVS MESSAGES:
43
*
44
* $Id: MultiLayerFillSymbol.java 13881 2007-09-19 16:22:04Z jaume $
45
* $Log$
46
* Revision 1.11  2007-09-19 16:20:45  jaume
47
* removed unnecessary imports
48
*
49
* Revision 1.10  2007/08/13 11:36:50  jvidal
50
* javadoc
51
*
52
* Revision 1.9  2007/08/08 12:04:15  jvidal
53
* javadoc
54
*
55
* Revision 1.8  2007/07/23 06:52:25  jaume
56
* default selection color refactored, moved to MapContext
57
*
58
* Revision 1.7  2007/07/03 10:58:29  jaume
59
* first refactor on CartographicSupport
60
*
61
* Revision 1.6  2007/06/29 13:07:01  jaume
62
* +PictureLineSymbol
63
*
64
* Revision 1.5  2007/03/29 16:02:01  jaume
65
* *** empty log message ***
66
*
67
* Revision 1.4  2007/03/26 14:25:29  jaume
68
* implemented Print
69
*
70
* Revision 1.3  2007/03/13 16:58:36  jaume
71
* Added QuantityByCategory (Multivariable legend) and some bugfixes in symbols
72
*
73
* Revision 1.2  2007/03/09 11:20:57  jaume
74
* Advanced symbology (start committing)
75
*
76
* Revision 1.1.2.3  2007/02/21 16:09:02  jaume
77
* *** empty log message ***
78
*
79
* Revision 1.1.2.2  2007/02/21 07:34:09  jaume
80
* labeling starts working
81
*
82
* Revision 1.1.2.1  2007/02/16 10:54:12  jaume
83
* multilayer splitted to multilayerline, multilayermarker,and  multilayerfill
84
*
85
*
86
*/
87
package com.iver.cit.gvsig.fmap.core.symbols;
88

    
89
import java.awt.Color;
90
import java.awt.Graphics2D;
91
import java.awt.Rectangle;
92
import java.awt.Shape;
93
import java.awt.geom.AffineTransform;
94
import java.util.ArrayList;
95

    
96
import javax.print.attribute.PrintRequestAttributeSet;
97

    
98
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
99
import com.iver.cit.gvsig.fmap.MapContext;
100
import com.iver.cit.gvsig.fmap.core.FShape;
101
import com.iver.cit.gvsig.fmap.core.IGeometry;
102
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
103
import com.iver.utiles.XMLEntity;
104

    
105
/**
106
 * MultiLayerFillSymbol is a symbol which allows to group several kind of fill symbols
107
 * (xxxFillSymbol implementing IFillSymbol)in one and treats it like single symbol.
108
 */
109

    
110
public class MultiLayerFillSymbol extends AbstractFillSymbol implements IFillSymbol, IMultiLayerSymbol{
111
        private static final double OPACITY_SELECTION_FACTOR = .8;
112
        private IFillSymbol[] layers = new IFillSymbol[0];
113
        private MultiLayerFillSymbol selectionSymbol;
114
        private Object symbolType;
115

    
116
        public Color getFillColor() {
117
                /*
118
                 * a multilayer symbol does not define any color, the color
119
                 * of each layer is defined by the layer itself
120
                 */
121
                return null;
122
        }
123

    
124
        public int getOnePointRgb() {
125
                // will paint only the last layer pixel
126
                return layers[layers.length-1].getOnePointRgb();
127
        }
128

    
129
        public ILineSymbol getOutline() {
130
                /*
131
                 * a multilayer symbol does not define any outline, the outline
132
                 * of each layer is defined by the layer it self
133
                 */
134
                return null;
135
        }
136

    
137
        public boolean isSuitableFor(IGeometry geom) {
138
                return geom.getGeometryType() == FShape.POLYGON;
139
        }
140

    
141
        public void setFillColor(Color color) {
142
                /*
143
                 * Will apply the color to each layer
144
                 */
145
                for (int i = 0; i < layers.length; i++) {
146
                        layers[i].setFillColor(color);
147
                }
148
        }
149

    
150
        public void setOutline(ILineSymbol outline) {
151
                for (int i = 0; i < layers.length; i++) {
152
                        layers[i].setOutline(null);
153
                }
154
                layers[layers.length-1].setOutline(outline);
155
        }
156

    
157
        public void draw(Graphics2D g, AffineTransform affineTransform, FShape shp) {
158
                for (int i = 0; i < layers.length; i++) {
159
                        layers[i].draw(g, affineTransform, shp);
160
                }
161
        }
162

    
163
        public void drawInsideRectangle(Graphics2D g,
164
                        AffineTransform scaleInstance, Rectangle r) {
165
                for (int i = 0; i < layers.length; i++) {
166
                        layers[i].drawInsideRectangle(g, scaleInstance, r);
167
                }
168
        }
169

    
170
        public int getPixExtentPlus(Graphics2D g, AffineTransform affineTransform,
171
                        Shape shp) {
172
                // TODO Implement it
173
                throw new Error("Not yet implemented!");
174

    
175
        }
176

    
177
        public ISymbol getSymbolForSelection() {
178
                if (selectionSymbol == null) {
179
                        selectionSymbol = new MultiLayerFillSymbol();
180
                        selectionSymbol.setDescription(getDescription());
181
                        selectionSymbol.symbolType = symbolType;
182
                        for (int i = 0; i < layers.length; i++) {
183
                                selectionSymbol.addLayer(layers[i].getSymbolForSelection());
184
                        }
185
                        SimpleFillSymbol selLayer = new SimpleFillSymbol();
186
                        Color c = MapContext.getSelectionColor();
187
                        c = new Color(
188
                                        c.getRed(),
189
                                        c.getGreen(),
190
                                        c.getBlue(),
191
                                        (int) (255*OPACITY_SELECTION_FACTOR));
192
                        selLayer.setFillColor(c);
193
                        selLayer.setOutline(getOutline());
194
                        selectionSymbol.addLayer(selLayer);
195
                }
196
                return selectionSymbol;
197

    
198
        }
199

    
200

    
201
        public int getSymbolType() {
202
                return FShape.POLYGON;
203
        }
204

    
205
        public XMLEntity getXMLEntity() {
206
                XMLEntity xml = new XMLEntity();
207
                xml.putProperty("className", getClassName());
208
                xml.putProperty("desc", getDescription());
209
                xml.putProperty("isShapeVisible", isShapeVisible());
210
                for (int i = 0; i < layers.length; i++) {
211
                        xml.addChild(layers[i].getXMLEntity());
212
                }
213
                return xml;
214
        }
215

    
216
        public void setPrintingProperties(PrintRequestAttributeSet printProperties) {
217
                // TODO Implement it
218
                throw new Error("Not yet implemented!");
219

    
220
        }
221

    
222
        public String getClassName() {
223
                return getClass().getName();
224
        }
225

    
226
        public void setXMLEntity(XMLEntity xml) {
227
                setIsShapeVisible(xml.getBooleanProperty("isShapeVisible"));
228
                setDescription(xml.getStringProperty("desc"));
229
                layers = new IFillSymbol[xml.getChildrenCount()];
230
                for (int i = 0; i < layers.length; i++) {
231
                        layers[i] = (IFillSymbol) SymbologyFactory.createSymbolFromXML(xml.getChild(i), "layer" + i);
232
                }
233
        }
234

    
235
        public void print(Graphics2D g, AffineTransform at, FShape shape, PrintRequestAttributeSet properties)
236
                        throws ReadDriverException {
237
                for (int i = 0; i < layers.length; i++) {
238
                        layers[i].print(g, at, shape, properties);
239
                }
240
        }
241

    
242
        public void setLayer(int index, ISymbol layer) throws IndexOutOfBoundsException {
243
                layers[index] = (IFillSymbol) layer;
244
        }
245

    
246
        public void swapLayers(int index1, int index2) {
247
                ISymbol aux1 = getLayer(index1), aux2 = getLayer(index2);
248
                layers[index2] = (IFillSymbol) aux1;
249
                layers[index1] = (IFillSymbol) aux2;
250
        }
251

    
252
        public ISymbol getLayer(int layerIndex) {
253
//                try{
254
                        return layers[layerIndex];
255
//                } catch (Exception e) {
256
//                        return null;
257
//                }
258
        }
259

    
260
        public int getLayerCount() {
261
                return layers.length;
262
        }
263

    
264
        public void addLayer(ISymbol newLayer) {
265
                if (newLayer == null) return;
266

    
267
                selectionSymbol = null; /* forces the selection symbol to be re-created
268
                                                                 * next time it is required
269
                                                                 */
270
                int size = layers.length+1;
271
                IFillSymbol[] newLayers = new IFillSymbol[size];
272
                for (int i = 0; i < newLayers.length-1; i++) {
273
                        newLayers[i] = layers[i];
274
                }
275
                newLayers[size-1] = (IFillSymbol) newLayer;
276
                layers = newLayers;
277
        }
278

    
279
        public void addLayer(ISymbol newLayer, int layerIndex) throws IndexOutOfBoundsException {
280
                if (newLayer == null )/*|| newLayer instanceof ILabelStyle)*/ return; // null or symbols that are styles are not allowed
281

    
282
                selectionSymbol = null; /* forces the selection symbol to be re-created
283
                                                                  * next time it is required
284
                                                                  */
285
                if (layerIndex < 0 || layers.length < layerIndex)
286
                        throw new IndexOutOfBoundsException(layerIndex+" < 0 or "+layerIndex+" > "+layers.length);
287
                ArrayList newLayers = new ArrayList();
288
                for (int i = 0; i < layers.length; i++) {
289
                        newLayers.add(layers[i]);
290
                }
291
                newLayers.add(layerIndex, newLayer);
292
                layers = (IFillSymbol[]) newLayers.toArray(new IFillSymbol[0]);
293
        }
294

    
295
        public boolean removeLayer(ISymbol layer) {
296

    
297
                int capacity = 0;
298
                capacity = layers.length;
299
                ArrayList lst = new ArrayList(capacity);
300
                for (int i = 0; i < capacity; i++) {
301
                        lst.add(layers[i]);
302
                }
303
                boolean contains = lst.remove(layer);
304
                layers = (IFillSymbol[])lst.toArray(new IFillSymbol[0]);
305
                return contains;
306
        }
307
        /**
308
         *Returns the transparency of the multi layer fill symbol created
309
         */
310
        public int getFillAlpha() {
311
                // will compute the acumulated opacity
312
                double myAlpha = 0;
313
                for (int i = 0; i < layers.length; i++) {
314
                        double layerAlpha = layers[i].getFillAlpha()/255D;
315
                        myAlpha += (1-myAlpha)*layerAlpha;
316
                }
317
                int result = (int) Math.round(myAlpha * 255);
318
                return (result>255) ? 255 : result;
319
        }
320

    
321
}