Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.symbology / org.gvsig.symbology.lib / org.gvsig.symbology.lib.impl / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / symbol / fill / impl / SimpleFillSymbol.java @ 45743

History | View | Annotate | Download (11.7 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.impl;
25

    
26
import java.awt.Color;
27
import java.awt.Graphics2D;
28
import java.awt.Rectangle;
29
import java.awt.geom.AffineTransform;
30

    
31
import org.gvsig.compat.print.PrintAttributes;
32
import org.gvsig.fmap.dal.feature.Feature;
33
import org.gvsig.fmap.geom.Geometry;
34
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
35
import org.gvsig.fmap.geom.GeometryLocator;
36
import org.gvsig.fmap.geom.GeometryManager;
37
import org.gvsig.fmap.geom.exception.CreateGeometryException;
38
import org.gvsig.fmap.geom.primitive.Envelope;
39
import org.gvsig.fmap.geom.primitive.GeneralPathX;
40
import org.gvsig.fmap.geom.primitive.Point;
41
import org.gvsig.fmap.mapcontext.MapContext;
42
import org.gvsig.fmap.mapcontext.MapContextLocator;
43
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
44
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
45
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
46
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
47
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.ISimpleFillSymbol;
48
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
49
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.impl.SimpleMarkerSymbol;
50
import org.gvsig.tools.ToolsLocator;
51
import org.gvsig.tools.dynobject.DynStruct;
52
import org.gvsig.tools.persistence.PersistenceManager;
53
import org.gvsig.tools.persistence.PersistentState;
54
import org.gvsig.tools.persistence.exception.PersistenceException;
55
import org.gvsig.tools.swing.api.TransparencySupport;
56
import org.gvsig.tools.task.Cancellable;
57
import org.gvsig.tools.util.Callable;
58
import org.slf4j.Logger;
59
import org.slf4j.LoggerFactory;
60

    
61
/**
62
 * Basic fill symbol. It will allow to paint a shape with its filling color (and
63
 * transparency) and the outline.
64
 *
65
 * @author 2005-2008 jaume dominguez faus - jaume.dominguez@iver.es
66
 * @author 2009-     <a href="cordinyana@gvsig.org">César Ordiñana</a> - gvSIG
67
 * team
68
 */
69
public class SimpleFillSymbol extends AbstractFillSymbol implements ISimpleFillSymbol, TransparencySupport {
70

    
71
    private static final String SIMPLE_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME = "SimpleFillSymbol";
72

    
73
    private static final Logger LOG = LoggerFactory.getLogger(SimpleFillSymbol.class);
74
    private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
75

    
76
    private static final String FIELD_SYMBOL_FOR_SELECTION = "symbolForSelection";
77

    
78
    private SimpleFillSymbol symbolForSelection;
79
    private SimpleMarkerSymbol tempSymbol = new SimpleMarkerSymbol();
80
    private transient double transparency;
81

    
82
    public SimpleFillSymbol() {
83
        super();
84
        this.transparency = 1.0;
85
    }
86

    
87
    @Override
88
    public ISymbol getSymbolForSelection() {
89
        if (symbolForSelection == null) {
90
            SimpleFillSymbol selectionSymbol = (SimpleFillSymbol) cloneForSelection();
91
            if (selectionSymbol != null) {
92
                selectionSymbol.setHasFill(true);
93
                setSymbolForSelection(selectionSymbol);
94
            }
95
        } else {
96
            symbolForSelection.setColor(MapContext.getSelectionColor());
97
        }
98
        if (symbolForSelection instanceof TransparencySupport) {
99
            symbolForSelection.setTransparency(this.transparency);
100
        }
101

    
102
        return symbolForSelection;
103
    }
104

    
105
    public void draw(Graphics2D g, AffineTransform affineTransform,
106
            Geometry geom, Feature feature, Cancellable cancel) {
107
        Color c = getFillColor();
108

    
109
        c = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int) (this.transparency * c.getAlpha()));
110

    
111
        if (true) {
112
            // Esto deberia ser para optimiza el pintado de 
113
            // geometrias grandes.
114
            try {
115
                Geometry env = geom.getEnvelope().getGeometry();
116
                env.transform(affineTransform);
117
                Envelope env2 = env.getEnvelope();
118
                if (env2.getLength(0) < 1.5 && env2.getLength(1) < 1.5) {
119
                    Point upperCorner = env2.getUpperCorner();
120
                    int y = (int) upperCorner.getY();
121
                    int x = (int) upperCorner.getX();
122
                    if (c != null && hasFill()) {
123
                        g.setColor(c);
124
                        g.drawLine(x, y, x, y);
125
                    }
126
                    if (getOutline() != null && hasOutline()) {
127
                        g.setColor(getOutline().getColor());
128
                        if (getOutline().getColor() != null) {
129

    
130
                        }
131
                        g.drawLine(x, y, x, y);
132
                    }
133
                    return;
134
                }
135
            } catch (Exception ex) {
136
                LOG.warn("Error optimizing the drawing of the geometry. Continues with normal drawing.", ex);
137
                // Do nothing, continue with the draw of the original geometry
138
            }
139

    
140
        }
141

    
142
        if (c != null && hasFill()) {
143
            g.setColor(c);
144
            g.fill(geom.getShape(affineTransform));
145
        }
146
        if (getOutline() != null && hasOutline()) {
147
            getOutline().draw(g, affineTransform, geom, feature, cancel);
148
        }
149
    }
150

    
151
    public int getSymbolType() {
152
        return Geometry.TYPES.SURFACE;
153
    }
154

    
155
    public void drawInsideRectangle(Graphics2D g,
156
            AffineTransform scaleInstance, Rectangle r, PrintAttributes properties) throws SymbolDrawingException {
157
        Rectangle rect = new Rectangle(r.x, r.y, r.width, r.height);
158
        rect.setFrame(((int) rect.getMinX()) + 1, ((int) rect.getMinY()) + 1, ((int) rect.getWidth()) - 2, ((int) rect.getHeight()) - 2);
159
        Geometry geom;
160
        try {
161
            geom = geomManager.createSurface(new GeneralPathX(rect.getPathIterator(null)), SUBTYPES.GEOM2D);
162
        } catch (CreateGeometryException e) {
163
            LOG.error("Creating a surface", e);
164
            throw new SymbolDrawingException(getSymbolType());
165
        }
166

    
167
        Color c = getFillColor();
168
        if (c != null && hasFill()) {
169
            g.setColor(c);
170
            g.fillRect(rect.x, rect.y, rect.width, rect.height);
171
        }
172

    
173
        if (getOutline() != null && hasOutline()) {
174
            if (properties == null) {
175
                getOutline().draw(g, scaleInstance, geom, null, null);
176
            } else {
177
                print(g, new AffineTransform(), geom, properties);
178
            }
179
        }
180
    }
181

    
182
    public String getClassName() {
183
        return getClass().getName();
184
    }
185

    
186
    public void print(Graphics2D g, AffineTransform at, Geometry geom, PrintAttributes properties) {
187
        Color c = getFillColor();
188
        if (c != null && hasFill()) {
189
            g.setColor(c);
190
            g.fill(geom.getShape(at));
191
        }
192
        if (getOutline() != null && hasOutline()) {
193
            getOutline().print(g, at, geom, properties);
194
        }
195
    }
196

    
197
    public Object clone() throws CloneNotSupportedException {
198
        SimpleFillSymbol copy = (SimpleFillSymbol) super.clone();
199

    
200
        // Clone selection
201
        if (symbolForSelection != null) {
202
            copy.symbolForSelection = (SimpleFillSymbol) symbolForSelection
203
                    .clone();
204
        }
205

    
206
        return copy;
207
    }
208

    
209
    private void setSymbolForSelection(SimpleFillSymbol symbolForSelection) {
210
        this.symbolForSelection = symbolForSelection;
211
    }
212

    
213
    public void loadFromState(PersistentState state)
214
            throws PersistenceException {
215
        // Set parent fill symbol properties
216
        super.loadFromState(state);
217
        setSymbolForSelection((SimpleFillSymbol) state.get(FIELD_SYMBOL_FOR_SELECTION));
218
    }
219

    
220
    public void saveToState(PersistentState state) throws PersistenceException {
221
        // Save parent fill symbol properties
222
        super.saveToState(state);
223

    
224
        // Don't use the getSymbolForSelection method, as it will create it
225
        // if it does not exist, and persistence will enter an infinite loop
226
        state.set(FIELD_SYMBOL_FOR_SELECTION, symbolForSelection);
227
    }
228

    
229
    @Override
230
    public void setTransparency(double transparency) {
231
        this.transparency = transparency;
232
        ILineSymbol theOutline = getOutline();
233
        if (theOutline != null && theOutline instanceof TransparencySupport) {
234
            ((TransparencySupport) theOutline).setTransparency(transparency);
235
        }
236
        ISymbol selectionSymbol = this.symbolForSelection;
237
        if (selectionSymbol != null && selectionSymbol instanceof TransparencySupport) {
238
            ((TransparencySupport) selectionSymbol).setTransparency(transparency);
239
        }
240
    }
241

    
242
    @Override
243
    public void setOutline(ILineSymbol outline) {
244
        super.setOutline(outline);
245
        if (outline != null && outline instanceof TransparencySupport) {
246
            ((TransparencySupport) outline).setTransparency(transparency);
247
        }
248
    }
249

    
250
    @Override
251
    public double getTransparency() {
252
        return this.transparency;
253
    }
254

    
255
    public static class RegisterPersistence implements Callable {
256

    
257
        public Object call() throws Exception {
258
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
259
            if (manager.getDefinition(SIMPLE_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
260
                DynStruct definition = manager.addDefinition(
261
                        SimpleFillSymbol.class,
262
                        SIMPLE_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME,
263
                        SIMPLE_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME + " Persistence definition",
264
                        null,
265
                        null
266
                );
267

    
268
                // Extend the FillSymbol base definition
269
                definition.extend(manager.getDefinition(FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME));
270

    
271
                // Selection Symbol
272
                definition.addDynFieldObject(FIELD_SYMBOL_FOR_SELECTION).setClassOfValue(SimpleFillSymbol.class).setMandatory(false);
273
            }
274
            return Boolean.TRUE;
275
        }
276

    
277
    }
278

    
279
    public static class RegisterSymbol implements Callable {
280

    
281
        public Object call() throws Exception {
282
            int[] shapeTypes;
283
            SymbolManager manager = MapContextLocator.getSymbolManager();
284

    
285
            shapeTypes
286
                    = new int[]{Geometry.TYPES.SURFACE, Geometry.TYPES.CIRCLE,
287
                        Geometry.TYPES.ELLIPSE, Geometry.TYPES.MULTISURFACE,
288
                        Geometry.TYPES.ELLIPTICARC, Geometry.TYPES.FILLEDSPLINE,
289
                        Geometry.TYPES.MULTIPOLYGON, Geometry.TYPES.POLYGON
290
                    };
291
            manager.registerSymbol(IFillSymbol.SYMBOL_NAME,
292
                    shapeTypes,
293
                    SimpleFillSymbol.class);
294

    
295
            return Boolean.TRUE;
296
        }
297

    
298
    }
299

    
300
}