Statistics
| Revision:

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

History | View | Annotate | Download (8.21 KB)

1 10679 jaume
/* 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$
45
* $Log$
46 10977 jaume
* Revision 1.5  2007-03-29 16:02:01  jaume
47
* *** empty log message ***
48
*
49
* Revision 1.4  2007/03/26 14:25:29  jaume
50 10902 jaume
* implemented Print
51
*
52
* Revision 1.3  2007/03/13 16:58:36  jaume
53 10739 jaume
* Added QuantityByCategory (Multivariable legend) and some bugfixes in symbols
54
*
55
* Revision 1.2  2007/03/09 11:20:57  jaume
56 10679 jaume
* Advanced symbology (start committing)
57
*
58
* Revision 1.1.2.3  2007/02/21 16:09:02  jaume
59
* *** empty log message ***
60
*
61
* Revision 1.1.2.2  2007/02/21 07:34:09  jaume
62
* labeling starts working
63
*
64
* Revision 1.1.2.1  2007/02/16 10:54:12  jaume
65
* multilayer splitted to multilayerline, multilayermarker,and  multilayerfill
66
*
67
*
68
*/
69
package com.iver.cit.gvsig.fmap.core.symbols;
70
71
import java.awt.Color;
72
import java.awt.Graphics2D;
73
import java.awt.Rectangle;
74
import java.awt.Shape;
75
import java.awt.geom.AffineTransform;
76
import java.util.ArrayList;
77
78
import javax.print.attribute.PrintRequestAttributeSet;
79
80
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
81
import com.iver.cit.gvsig.fmap.core.FShape;
82
import com.iver.cit.gvsig.fmap.core.IGeometry;
83
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
84
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
85
import com.iver.utiles.XMLEntity;
86
87
public class MultiLayerFillSymbol extends AbstractSymbol implements IFillSymbol, IMultiLayerSymbol{
88 10739 jaume
        private static final double OPACITY_SELECTION_FACTOR = .8;
89 10679 jaume
        private IFillSymbol[] layers = new IFillSymbol[0];
90
        private MultiLayerFillSymbol selectionSymbol;
91
        private Object symbolType;
92
93
        public Color getFillColor() {
94
                /*
95
                 * a multilayer symbol does not define any color, the color
96
                 * of each layer is defined by the layer itself
97
                 */
98
                return null;
99
        }
100
101
        public int getOnePointRgb() {
102
                // will paint only the last layer pixel
103
                return layers[layers.length-1].getOnePointRgb();
104
        }
105
106
        public ILineSymbol getOutline() {
107
                /*
108
                 * a multilayer symbol does not define any outline, the outline
109
                 * of each layer is defined by the layer it self
110
                 */
111
                return null;
112
        }
113
114
        public boolean isSuitableFor(IGeometry geom) {
115
                return geom.getGeometryType() == FShape.POLYGON;
116
        }
117
118
        public void setFillColor(Color color) {
119
                /*
120
                 * Will apply the color to each layer
121
                 */
122
                for (int i = 0; i < layers.length; i++) {
123
                        layers[i].setFillColor(color);
124
                }
125
        }
126
127
        public void setOutline(ILineSymbol outline) {
128
                for (int i = 0; i < layers.length; i++) {
129
                        layers[i].setOutline(null);
130
                }
131
                layers[layers.length-1].setOutline(outline);
132
        }
133
134
        public void draw(Graphics2D g, AffineTransform affineTransform, FShape shp) {
135
                for (int i = 0; i < layers.length; i++) {
136
                        layers[i].draw(g, affineTransform, shp);
137
                }
138
        }
139
140
        public void drawInsideRectangle(Graphics2D g,
141
                        AffineTransform scaleInstance, Rectangle r) {
142
                for (int i = 0; i < layers.length; i++) {
143
                        layers[i].drawInsideRectangle(g, scaleInstance, r);
144
                }
145
        }
146
147
        public int getPixExtentPlus(Graphics2D g, AffineTransform affineTransform,
148
                        Shape shp) {
149
                // TODO Implement it
150
                throw new Error("Not yet implemented!");
151
152
        }
153
154
        public ISymbol getSymbolForSelection() {
155
                if (selectionSymbol == null) {
156
                        selectionSymbol = new MultiLayerFillSymbol();
157
                        selectionSymbol.setDescription(getDescription());
158
                        selectionSymbol.symbolType = symbolType;
159
                        for (int i = 0; i < layers.length; i++) {
160
                                selectionSymbol.addLayer(layers[i].getSymbolForSelection());
161
                        }
162
                        SimpleFillSymbol selLayer = new SimpleFillSymbol();
163 10739 jaume
                        Color c = FSymbol.getSelectionColor();
164
                        c = new Color(
165
                                        c.getRed(),
166
                                        c.getGreen(),
167
                                        c.getBlue(),
168
                                        (int) (255*OPACITY_SELECTION_FACTOR));
169
                        selLayer.setFillColor(c);
170 10679 jaume
                        selLayer.setOutline(getOutline());
171
                        selectionSymbol.addLayer(selLayer);
172
                }
173
                return selectionSymbol;
174
175
        }
176
177
178
        public int getSymbolType() {
179
                return FShape.POLYGON;
180
        }
181
182
        public XMLEntity getXMLEntity() {
183
                XMLEntity xml = new XMLEntity();
184
                xml.putProperty("className", getClassName());
185
                xml.putProperty("desc", getDescription());
186
                xml.putProperty("isShapeVisible", isShapeVisible());
187
                for (int i = 0; i < layers.length; i++) {
188
                        xml.addChild(layers[i].getXMLEntity());
189
                }
190
                return xml;
191
        }
192
193
        public void setPrintingProperties(PrintRequestAttributeSet printProperties) {
194
                // TODO Implement it
195
                throw new Error("Not yet implemented!");
196
197
        }
198
199
        public String getClassName() {
200
                return getClass().getName();
201
        }
202
203
        public void setXMLEntity(XMLEntity xml) {
204
                setIsShapeVisible(xml.getBooleanProperty("isShapeVisible"));
205
                setDescription(xml.getStringProperty("desc"));
206
                layers = new IFillSymbol[xml.getChildrenCount()];
207
                for (int i = 0; i < layers.length; i++) {
208
                        layers[i] = (IFillSymbol) SymbologyFactory.createSymbolFromXML(xml.getChild(i), "layer" + i);
209
                }
210
        }
211
212 10902 jaume
        public void print(Graphics2D g, AffineTransform at, FShape shape, PrintRequestAttributeSet properties)
213 10679 jaume
                        throws ReadDriverException {
214 10902 jaume
                for (int i = 0; i < layers.length; i++) {
215
                        layers[i].print(g, at, shape, properties);
216
                }
217 10679 jaume
        }
218
219
        public void setLayer(int index, ISymbol layer) throws IndexOutOfBoundsException {
220
                layers[index] = (IFillSymbol) layer;
221
        }
222
223
        public void swapLayers(int index1, int index2) {
224
                ISymbol aux1 = getLayer(index1), aux2 = getLayer(index2);
225
                layers[index2] = (IFillSymbol) aux1;
226
                layers[index1] = (IFillSymbol) aux2;
227
        }
228
229
        public ISymbol getLayer(int layerIndex) {
230
                try{
231
                        return layers[layerIndex];
232
                } catch (Exception e) {
233
                        return null;
234
                }
235
        }
236
237
        public int getLayerCount() {
238
                return layers.length;
239
        }
240
241
        public void addLayer(ISymbol newLayer) {
242
                if (newLayer == null) return;
243
244
                selectionSymbol = null; /* forces the selection symbol to be re-created
245
                                                                 * next time it is required
246
                                                                 */
247
                int size = layers.length+1;
248
                IFillSymbol[] newLayers = new IFillSymbol[size];
249
                for (int i = 0; i < newLayers.length-1; i++) {
250
                        newLayers[i] = layers[i];
251
                }
252
                newLayers[size-1] = (IFillSymbol) newLayer;
253
                layers = newLayers;
254
        }
255
256
        public void addLayer(ISymbol newLayer, int layerIndex) throws IndexOutOfBoundsException {
257 10977 jaume
                if (newLayer == null )/*|| newLayer instanceof ILabelStyle)*/ return; // null or symbols that are styles are not allowed
258 10679 jaume
259
                selectionSymbol = null; /* forces the selection symbol to be re-created
260
                                                                  * next time it is required
261
                                                                  */
262
                if (layerIndex < 0 || layers.length < layerIndex)
263
                        throw new IndexOutOfBoundsException(layerIndex+" < 0 or "+layerIndex+" > "+layers.length);
264
                ArrayList newLayers = new ArrayList();
265
                for (int i = 0; i < layers.length; i++) {
266
                        newLayers.add(layers[i]);
267
                }
268
                newLayers.add(layerIndex, newLayer);
269
                layers = (IFillSymbol[]) newLayers.toArray(new IFillSymbol[0]);
270
        }
271
272
        public boolean removeLayer(ISymbol layer) {
273
274
                int capacity = 0;
275
                capacity = layers.length;
276
                ArrayList lst = new ArrayList(capacity);
277
                for (int i = 0; i < capacity; i++) {
278
                        lst.add(layers[i]);
279
                }
280
                boolean contains = lst.remove(layer);
281
                layers = (IFillSymbol[])lst.toArray(new IFillSymbol[0]);
282
                return contains;
283
        }
284
285
        public int getFillAlpha() {
286
                // will compute the acumulated opacity
287
                double myAlpha = 0;
288
                for (int i = 0; i < layers.length; i++) {
289
                        double layerAlpha = layers[i].getFillAlpha()/255D;
290
                        myAlpha += (1-myAlpha)*layerAlpha;
291
                }
292
                int result = (int) Math.round(myAlpha * 255);
293
                return (result>255) ? 255 : result;
294
        }
295
296
}