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 @ 47470

History | View | Annotate | Download (11.8 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
import org.gvsig.compat.print.PrintAttributes;
31
import org.gvsig.fmap.dal.feature.Feature;
32
import org.gvsig.fmap.geom.Geometry;
33
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
34
import org.gvsig.fmap.geom.GeometryLocator;
35
import org.gvsig.fmap.geom.GeometryManager;
36
import org.gvsig.fmap.geom.exception.CreateGeometryException;
37
import org.gvsig.fmap.geom.primitive.Envelope;
38
import org.gvsig.fmap.geom.primitive.GeneralPathX;
39
import org.gvsig.fmap.geom.primitive.Point;
40
import org.gvsig.fmap.mapcontext.MapContext;
41
import org.gvsig.fmap.mapcontext.MapContextLocator;
42
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
43
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
44
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
45
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
46
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.ISimpleFillSymbol;
47
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
48
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.impl.SimpleMarkerSymbol;
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.swing.api.TransparencySupport;
55
import org.gvsig.tools.task.Cancellable;
56
import org.gvsig.tools.util.Callable;
57
import org.slf4j.Logger;
58
import org.slf4j.LoggerFactory;
59

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

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

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

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

    
77
    private SimpleFillSymbol symbolForSelection;
78
    private SimpleMarkerSymbol tempSymbol = new SimpleMarkerSymbol();
79

    
80
    public SimpleFillSymbol() {
81
        super();
82
    }
83

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

    
99
        return symbolForSelection;
100
    }
101

    
102
    public void draw(Graphics2D g, AffineTransform affineTransform,
103
            Geometry geom, Feature feature, Cancellable cancel) {
104
        Color c = getFillColor();
105

    
106
        if (true) {
107
            // Esto deberia ser para optimiza el pintado de 
108
            // geometrias grandes.
109
            try {
110
                Geometry env = geom.getEnvelope().getGeometry();
111
                env.transform(affineTransform);
112
                Envelope env2 = env.getEnvelope();
113
                if (env2.getLength(0) < 1.5 && env2.getLength(1) < 1.5) {
114
                    Point upperCorner = env2.getUpperCorner();
115
                    int y = (int) upperCorner.getY();
116
                    int x = (int) upperCorner.getX();
117
                    if (c != null && hasFill()) {
118
                        g.setColor(c);
119
                        g.drawLine(x, y, x, y);
120
                    }
121
                    if (getOutline() != null && hasOutline()) {
122
                        g.setColor(getOutline().getColor());
123
//                        if (getOutline().getColor() != null) {
124
//
125
//                        }
126
                        g.drawLine(x, y, x, y);
127
                    }
128
                    return;
129
                }
130
            } catch (Exception ex) {
131
                LOG.warn("Error optimizing the drawing of the geometry. Continues with normal drawing.", ex);
132
                // Do nothing, continue with the draw of the original geometry
133
            }
134

    
135
        }
136

    
137
        if (c != null && hasFill()) {
138
            g.setColor(c);
139
            g.fill(geom.getShape(affineTransform));
140
        }
141
        if (getOutline() != null && hasOutline()) {
142
            getOutline().draw(g, affineTransform, geom, feature, cancel);
143
        }
144
    }
145

    
146
    @Override
147
    public int getSymbolType() {
148
        return Geometry.TYPES.SURFACE;
149
    }
150

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

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

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

    
179
    public String getClassName() {
180
        return getClass().getName();
181
    }
182

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

    
195
    @Override
196
    public Object clone() throws CloneNotSupportedException {
197
        SimpleFillSymbol copy = (SimpleFillSymbol) super.clone();
198

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

    
205
        return copy;
206
    }
207

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

    
212
    @Override
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
    @Override
221
    public void saveToState(PersistentState state) throws PersistenceException {
222
        // Save parent fill symbol properties
223
        super.saveToState(state);
224

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

    
230
    @Override
231
    public void setTransparency(double transparency) {
232
        Color c = getFillColor();
233
        c = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int) (transparency * 255));
234
        setFillColor(c);
235
        
236
        ILineSymbol theOutline = getOutline();
237
        if (theOutline != null && theOutline instanceof TransparencySupport) {
238
            ((TransparencySupport) theOutline).setTransparency(transparency);
239
        }
240
        ISymbol selectionSymbol = this.symbolForSelection;
241
        if (selectionSymbol != null && selectionSymbol instanceof TransparencySupport) {
242
            ((TransparencySupport) selectionSymbol).setTransparency(transparency);
243
        }
244
    }
245

    
246
    @Override
247
    public void setOutline(ILineSymbol outline) {
248
        super.setOutline(outline);
249
//        if (outline != null && outline instanceof TransparencySupport) {
250
//            ((TransparencySupport) outline).setTransparency(this.getTransparency());
251
//        }
252
    }
253

    
254
    @Override
255
    public double getTransparency() {
256
        return ((double)getFillAlpha())/255;
257
    }
258

    
259
    public static class RegisterPersistence implements Callable {
260

    
261
        @Override
262
        public Object call() throws Exception {
263
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
264
            if (manager.getDefinition(SIMPLE_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
265
                DynStruct definition = manager.addDefinition(
266
                        SimpleFillSymbol.class,
267
                        SIMPLE_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME,
268
                        SIMPLE_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME + " Persistence definition",
269
                        null,
270
                        null
271
                );
272

    
273
                // Extend the FillSymbol base definition
274
                definition.extend(manager.getDefinition(FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME));
275

    
276
                // Selection Symbol
277
                definition.addDynFieldObject(FIELD_SYMBOL_FOR_SELECTION).setClassOfValue(SimpleFillSymbol.class).setMandatory(false);
278
            }
279
            return Boolean.TRUE;
280
        }
281

    
282
    }
283

    
284
    public static class RegisterSymbol implements Callable {
285

    
286
        @Override
287
        public Object call() throws Exception {
288
            int[] shapeTypes;
289
            SymbolManager manager = MapContextLocator.getSymbolManager();
290

    
291
            shapeTypes
292
                    = new int[]{Geometry.TYPES.SURFACE, Geometry.TYPES.CIRCLE,
293
                        Geometry.TYPES.ELLIPSE, Geometry.TYPES.MULTISURFACE,
294
                        Geometry.TYPES.ELLIPTICARC, Geometry.TYPES.FILLEDSPLINE,
295
                        Geometry.TYPES.MULTIPOLYGON, Geometry.TYPES.POLYGON
296
                    };
297
            manager.registerSymbol(IFillSymbol.SYMBOL_NAME,
298
                    shapeTypes,
299
                    SimpleFillSymbol.class);
300

    
301
            return Boolean.TRUE;
302
        }
303

    
304
    }
305

    
306
}