Statistics
| Revision:

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

History | View | Annotate | Download (10.4 KB)

1 12728 jaume
/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
2 10679 jaume
 *
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 12728 jaume
 *   Av. Blasco Ib��ez, 50
24 10679 jaume
 *   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 13953 jaume
* Revision 1.12  2007-09-21 12:25:32  jaume
47
* cancellation support extended down to the IGeometry and ISymbol level
48
*
49
* Revision 1.11  2007/09/19 16:20:45  jaume
50 13881 jaume
* removed unnecessary imports
51
*
52
* Revision 1.10  2007/08/13 11:36:50  jvidal
53 12985 jvidal
* javadoc
54
*
55 13032 jvidal
* Revision 1.9  2007/08/08 12:04:15  jvidal
56
* javadoc
57
*
58 12985 jvidal
* Revision 1.8  2007/07/23 06:52:25  jaume
59 12728 jaume
* default selection color refactored, moved to MapContext
60
*
61
* Revision 1.7  2007/07/03 10:58:29  jaume
62 12467 jaume
* first refactor on CartographicSupport
63
*
64
* Revision 1.6  2007/06/29 13:07:01  jaume
65 12427 jaume
* +PictureLineSymbol
66
*
67
* Revision 1.5  2007/03/29 16:02:01  jaume
68 10977 jaume
* *** empty log message ***
69
*
70
* Revision 1.4  2007/03/26 14:25:29  jaume
71 10902 jaume
* implemented Print
72
*
73
* Revision 1.3  2007/03/13 16:58:36  jaume
74 10739 jaume
* Added QuantityByCategory (Multivariable legend) and some bugfixes in symbols
75
*
76
* Revision 1.2  2007/03/09 11:20:57  jaume
77 10679 jaume
* Advanced symbology (start committing)
78
*
79
* Revision 1.1.2.3  2007/02/21 16:09:02  jaume
80
* *** empty log message ***
81
*
82
* Revision 1.1.2.2  2007/02/21 07:34:09  jaume
83
* labeling starts working
84
*
85
* Revision 1.1.2.1  2007/02/16 10:54:12  jaume
86
* multilayer splitted to multilayerline, multilayermarker,and  multilayerfill
87
*
88
*
89
*/
90
package com.iver.cit.gvsig.fmap.core.symbols;
91
92
import java.awt.Color;
93
import java.awt.Graphics2D;
94
import java.awt.Rectangle;
95
import java.awt.geom.AffineTransform;
96
import java.util.ArrayList;
97
98
import javax.print.attribute.PrintRequestAttributeSet;
99
100 12728 jaume
import com.iver.cit.gvsig.fmap.MapContext;
101 18621 jdominguez
import com.iver.cit.gvsig.fmap.ViewPort;
102 10679 jaume
import com.iver.cit.gvsig.fmap.core.FShape;
103
import com.iver.cit.gvsig.fmap.core.IGeometry;
104
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
105
import com.iver.utiles.XMLEntity;
106 13953 jaume
import com.iver.utiles.swing.threads.Cancellable;
107 10679 jaume
108 12985 jvidal
/**
109
 * MultiLayerFillSymbol is a symbol which allows to group several kind of fill symbols
110
 * (xxxFillSymbol implementing IFillSymbol)in one and treats it like single symbol.
111
 */
112
113 12467 jaume
public class MultiLayerFillSymbol extends AbstractFillSymbol implements IFillSymbol, IMultiLayerSymbol{
114 10739 jaume
        private static final double OPACITY_SELECTION_FACTOR = .8;
115 10679 jaume
        private IFillSymbol[] layers = new IFillSymbol[0];
116
        private MultiLayerFillSymbol selectionSymbol;
117
        private Object symbolType;
118 29810 vcaballero
        private double[] sizes=null;
119 10679 jaume
        public Color getFillColor() {
120
                /*
121
                 * a multilayer symbol does not define any color, the color
122
                 * of each layer is defined by the layer itself
123
                 */
124
                return null;
125
        }
126
127
        public int getOnePointRgb() {
128
                // will paint only the last layer pixel
129
                return layers[layers.length-1].getOnePointRgb();
130
        }
131
132
        public ILineSymbol getOutline() {
133
                /*
134
                 * a multilayer symbol does not define any outline, the outline
135
                 * of each layer is defined by the layer it self
136
                 */
137
                return null;
138
        }
139
140
        public boolean isSuitableFor(IGeometry geom) {
141 29132 vcaballero
                return (geom.getGeometryType() % FShape.Z) == FShape.POLYGON;
142 10679 jaume
        }
143
144
        public void setFillColor(Color color) {
145
                /*
146
                 * Will apply the color to each layer
147
                 */
148
                for (int i = 0; i < layers.length; i++) {
149
                        layers[i].setFillColor(color);
150
                }
151
        }
152
153
        public void setOutline(ILineSymbol outline) {
154
                for (int i = 0; i < layers.length; i++) {
155
                        layers[i].setOutline(null);
156
                }
157
                layers[layers.length-1].setOutline(outline);
158
        }
159
160 13953 jaume
        public void draw(Graphics2D g, AffineTransform affineTransform, FShape shp, Cancellable cancel) {
161
                for (int i = 0; (cancel==null || !cancel.isCanceled()) && i < layers.length; i++) {
162
                        layers[i].draw(g, affineTransform, shp, cancel);
163 10679 jaume
                }
164
        }
165
166
        public void drawInsideRectangle(Graphics2D g,
167 28367 vcaballero
                        AffineTransform scaleInstance, Rectangle r, PrintRequestAttributeSet properties) throws SymbolDrawingException {
168 10679 jaume
                for (int i = 0; i < layers.length; i++) {
169 28367 vcaballero
                        layers[i].drawInsideRectangle(g, scaleInstance, r, properties);
170 10679 jaume
                }
171
        }
172
173 18621 jdominguez
        public void getPixExtentPlus(FShape shp, float[] distances,
174
                        ViewPort viewPort, int dpi) {
175
                float[] myDistances = new float[] {0,0};
176
                distances[0] = 0;
177
                distances[1] = 0;
178
                for (int i = 0; i < layers.length; i++) {
179
                        layers[i].getPixExtentPlus(shp, myDistances, viewPort, dpi);
180
                        distances[0] = Math.max(myDistances[0], distances[0]);
181
                        distances[1] = Math.max(myDistances[1], distances[1]);
182
                }
183 10679 jaume
        }
184
185
        public ISymbol getSymbolForSelection() {
186
                if (selectionSymbol == null) {
187
                        selectionSymbol = new MultiLayerFillSymbol();
188
                        selectionSymbol.setDescription(getDescription());
189
                        selectionSymbol.symbolType = symbolType;
190
                        for (int i = 0; i < layers.length; i++) {
191
                                selectionSymbol.addLayer(layers[i].getSymbolForSelection());
192
                        }
193
                        SimpleFillSymbol selLayer = new SimpleFillSymbol();
194 12728 jaume
                        Color c = MapContext.getSelectionColor();
195 10739 jaume
                        c = new Color(
196
                                        c.getRed(),
197
                                        c.getGreen(),
198
                                        c.getBlue(),
199
                                        (int) (255*OPACITY_SELECTION_FACTOR));
200
                        selLayer.setFillColor(c);
201 10679 jaume
                        selLayer.setOutline(getOutline());
202
                        selectionSymbol.addLayer(selLayer);
203
                }
204
                return selectionSymbol;
205
206
        }
207
208
209
        public int getSymbolType() {
210
                return FShape.POLYGON;
211
        }
212
213
        public XMLEntity getXMLEntity() {
214
                XMLEntity xml = new XMLEntity();
215
                xml.putProperty("className", getClassName());
216
                xml.putProperty("desc", getDescription());
217
                xml.putProperty("isShapeVisible", isShapeVisible());
218 18621 jdominguez
                xml.putProperty("referenceSystem", getReferenceSystem());
219
                xml.putProperty("unit", getUnit());
220 29132 vcaballero
221 10679 jaume
                for (int i = 0; i < layers.length; i++) {
222
                        xml.addChild(layers[i].getXMLEntity());
223
                }
224
                return xml;
225
        }
226
227
        public void setPrintingProperties(PrintRequestAttributeSet printProperties) {
228
                // TODO Implement it
229
                throw new Error("Not yet implemented!");
230
231
        }
232
233
        public String getClassName() {
234
                return getClass().getName();
235
        }
236
237
        public void setXMLEntity(XMLEntity xml) {
238
                setIsShapeVisible(xml.getBooleanProperty("isShapeVisible"));
239
                setDescription(xml.getStringProperty("desc"));
240 14461 jdominguez
                for (int i = 0; i < xml.getChildrenCount(); i++) {
241
                        addLayer((IFillSymbol) SymbologyFactory.createSymbolFromXML(xml.getChild(i), "layer" + i));
242 10679 jaume
                }
243 29132 vcaballero
244 18621 jdominguez
                if (xml.contains("unit")) { // remove this line when done
245
                // measure unit (for outline)
246
                setUnit(xml.getIntProperty("unit"));
247 29132 vcaballero
248 18621 jdominguez
                // reference system (for outline)
249
                setReferenceSystem(xml.getIntProperty("referenceSystem"));
250
                }
251 10679 jaume
        }
252
253 28367 vcaballero
        public void print(Graphics2D g, AffineTransform at, FShape shape, PrintRequestAttributeSet properties) {
254 10902 jaume
                for (int i = 0; i < layers.length; i++) {
255
                        layers[i].print(g, at, shape, properties);
256
                }
257 10679 jaume
        }
258
259
        public void setLayer(int index, ISymbol layer) throws IndexOutOfBoundsException {
260
                layers[index] = (IFillSymbol) layer;
261
        }
262
263
        public void swapLayers(int index1, int index2) {
264
                ISymbol aux1 = getLayer(index1), aux2 = getLayer(index2);
265
                layers[index2] = (IFillSymbol) aux1;
266
                layers[index1] = (IFillSymbol) aux2;
267
        }
268
269
        public ISymbol getLayer(int layerIndex) {
270 12427 jaume
//                try{
271 10679 jaume
                        return layers[layerIndex];
272 12427 jaume
//                } catch (Exception e) {
273
//                        return null;
274
//                }
275 10679 jaume
        }
276
277
        public int getLayerCount() {
278
                return layers.length;
279
        }
280
281
        public void addLayer(ISymbol newLayer) {
282 18621 jdominguez
                addLayer(newLayer, layers.length);
283 10679 jaume
        }
284
285
        public void addLayer(ISymbol newLayer, int layerIndex) throws IndexOutOfBoundsException {
286 10977 jaume
                if (newLayer == null )/*|| newLayer instanceof ILabelStyle)*/ return; // null or symbols that are styles are not allowed
287 10679 jaume
288
                selectionSymbol = null; /* forces the selection symbol to be re-created
289
                                                                  * next time it is required
290
                                                                  */
291
                if (layerIndex < 0 || layers.length < layerIndex)
292
                        throw new IndexOutOfBoundsException(layerIndex+" < 0 or "+layerIndex+" > "+layers.length);
293 18621 jdominguez
                ArrayList<ISymbol> newLayers = new ArrayList<ISymbol>();
294 10679 jaume
                for (int i = 0; i < layers.length; i++) {
295
                        newLayers.add(layers[i]);
296
                }
297 20778 vcaballero
                try {
298
                        newLayers.add(layerIndex, newLayer);
299
                        layers = (IFillSymbol[]) newLayers.toArray(new IFillSymbol[0]);
300
                } catch (ArrayStoreException asEx) {
301
                        throw new ClassCastException(newLayer.getClassName()+" is not an IFillSymbol");
302
                }
303 10679 jaume
        }
304
305
        public boolean removeLayer(ISymbol layer) {
306
307
                int capacity = 0;
308
                capacity = layers.length;
309 18621 jdominguez
                ArrayList<IFillSymbol> lst = new ArrayList<IFillSymbol>(capacity);
310 10679 jaume
                for (int i = 0; i < capacity; i++) {
311
                        lst.add(layers[i]);
312
                }
313
                boolean contains = lst.remove(layer);
314
                layers = (IFillSymbol[])lst.toArray(new IFillSymbol[0]);
315
                return contains;
316
        }
317 18621 jdominguez
318
        @Override
319
        public void setUnit(int unitIndex) {
320
                super.setUnit(unitIndex);
321
                for (int i = 0; i < layers.length; i++) {
322
                        layers[i].setUnit(unitIndex);
323
                }
324
        }
325 29132 vcaballero
326 18621 jdominguez
        @Override
327
        public void setReferenceSystem(int system) {
328
                super.setReferenceSystem(system);
329
                for (int i = 0; i < layers.length; i++) {
330
                        layers[i].setReferenceSystem(system);
331
                }
332
        }
333 29132 vcaballero
334 13032 jvidal
        /**
335
         *Returns the transparency of the multi layer fill symbol created
336
         */
337 10679 jaume
        public int getFillAlpha() {
338
                // will compute the acumulated opacity
339
                double myAlpha = 0;
340
                for (int i = 0; i < layers.length; i++) {
341
                        double layerAlpha = layers[i].getFillAlpha()/255D;
342
                        myAlpha += (1-myAlpha)*layerAlpha;
343
                }
344
                int result = (int) Math.round(myAlpha * 255);
345
                return (result>255) ? 255 : result;
346
        }
347
348 29810 vcaballero
        public void setCartographicSize(double previousSize,FShape shp){
349
                for (int i = 0; i < layers.length; i++) {
350
                        layers[i].setCartographicSize(sizes[i], shp);
351
                }
352
        }
353 18621 jdominguez
354
        public double toCartographicSize(ViewPort viewPort, double dpi, FShape shp) {
355
                double size = 0;
356 29810 vcaballero
                sizes=new double[layers.length];
357 18621 jdominguez
                for (int i = 0; i < layers.length; i++) {
358 29810 vcaballero
                        double previousSize=layers[i].toCartographicSize(viewPort, dpi, shp);
359
                        sizes[i]=previousSize;
360
                        size = Math.max(size, previousSize);
361
//                        layers[i].setCartographicSize(previousSize, shp);
362 18621 jdominguez
                }
363
                return size;
364
        }
365 10679 jaume
}