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 / line / impl / SimpleLineSymbol.java @ 47476

History | View | Annotate | Download (12.4 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.line.impl;
25

    
26
import java.awt.Color;
27
import java.awt.Graphics2D;
28
import java.awt.Rectangle;
29
import java.awt.Shape;
30
import java.awt.geom.AffineTransform;
31
import org.gvsig.fmap.dal.feature.Feature;
32
import org.gvsig.fmap.geom.Geometry;
33
import org.gvsig.fmap.geom.GeometryLocator;
34
import org.gvsig.fmap.geom.GeometryManager;
35
import org.gvsig.fmap.geom.aggregate.MultiCurve;
36
import org.gvsig.fmap.geom.exception.CreateGeometryException;
37
import org.gvsig.fmap.geom.primitive.Envelope;
38
import org.gvsig.fmap.geom.primitive.Point;
39
import org.gvsig.fmap.mapcontext.MapContext;
40
import org.gvsig.fmap.mapcontext.MapContextLocator;
41
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
42
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
43
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
44
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
45
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ISimpleLineSymbol;
46
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
47
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.ArrowDecoratorStyle;
48
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.IArrowDecoratorStyle;
49
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.ILineStyle;
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
 * SimpleLineSymbol is the most basic symbol for the representation of line
63
 * objects. Allows to define the width of the line, the color and the drawn
64
 * pattern.
65
 *
66
 * @author 2005-2008 jaume dominguez faus - jaume.dominguez@iver.es
67
 * @author 2009-     <a href="cordinyana@gvsig.org">C?sar Ordi?ana</a> - gvSIG team
68
 */
69
public class SimpleLineSymbol extends AbstractLineSymbol implements ISimpleLineSymbol, TransparencySupport {
70

    
71
    private static final Logger LOG = LoggerFactory.getLogger(SimpleLineSymbol.class);
72
    public static final String SIMPLE_LINE_SYMBOL_PERSISTENCE_DEFINITION_NAME = "SimpleLineSymbol";
73

    
74
    private static final String SELECTION_SYMBOL = "symbolForSelection";
75

    
76
    SimpleLineSymbol symbolForSelection;
77
    private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
78

    
79
    public SimpleLineSymbol() {
80
        super();
81
        setLineWidth(1d);
82
   }
83

    
84
    @Override
85
    public ISymbol getSymbolForSelection() {
86
        if (symbolForSelection == null) {
87
            symbolForSelection = (SimpleLineSymbol) cloneForSelection();
88
        } else {
89
            symbolForSelection.setColor(MapContext.getSelectionColor());
90
        }
91
        if (symbolForSelection instanceof TransparencySupport) {
92
            symbolForSelection.setTransparency(this.getTransparency());
93
        }
94
        return symbolForSelection;
95
    }
96

    
97
    @Override
98
    public void draw(Graphics2D g, AffineTransform affineTransform, Geometry geom, Feature f, Cancellable cancel, Rectangle r) {
99
        if(r != null){
100
            geom = this.getSampleGeometry(r);
101
        }
102

    
103
        Color c = getColor();
104

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

    
125
        Geometry geomToDraw;
126
//        try {
127
//            geomToDraw = geom.toLines();
128
//        } catch (Exception ex) {
129
            geomToDraw = geom.cloneGeometry();
130
//        }
131
        ILineStyle lineStyle = getLineStyle();
132
        
133
        if (lineStyle != null) {
134
            if(lineStyle instanceof CartographicSupport && r == null){
135
                ((CartographicSupport)lineStyle).setCartographicContext(this.getCartographicContext());
136
                g.setStroke(lineStyle.getCartographicStroke());
137
            } else {
138
                g.setStroke(lineStyle.getStroke());
139
            }
140

    
141
        }
142
        if(geomToDraw != null) {
143
            g.setColor(c);
144
            Shape shape = null;
145
            geomToDraw.transform(affineTransform);
146
            double offset = lineStyle.getOffset();
147
            if(offset != 0) {
148
                geomToDraw = applyOffset(this.toCartographicUnits(offset), r, geomToDraw);
149
            }
150
            if(geomToDraw != null){
151
                shape = geomToDraw.getShape();
152

    
153
                if (shape != null) {
154
                    g.draw(shape);
155
                    if (lineStyle != null) {
156
                        ArrowDecoratorStyle arrowDecorator = (ArrowDecoratorStyle) lineStyle.getArrowDecorator();
157

    
158
                        if (arrowDecorator != null) {
159
                            try {
160
                                if(arrowDecorator instanceof CartographicSupport){
161
                                    if(r == null){
162
                                        arrowDecorator.setCartographicContext(this.getCartographicContext());
163
                                    } else {
164
                                        arrowDecorator.setCartographicContext((CartographicContext)null);
165
                                    }
166
                                }
167
                                //Pasamos una transformaci?n afin identidad porque la geometr?a ya viene transformada
168
                                arrowDecorator.draw(g, null, geomToDraw, f);
169
                            } catch (CreateGeometryException e) {
170
                                LOG.warn("Error drawing geometry.", e);
171
                            }
172
                        }
173
                    }
174
                }
175
            }
176
        }
177
    }
178

    
179
    private Geometry applyOffset(double offset, Rectangle r, Geometry geomToDraw) {
180
        if (offset != 0) {
181
            try {
182
                geomToDraw = geomToDraw.offset(offset);
183
//                if(offset > 0 ){
184
//                    geomToDraw.flip();
185
//                }
186
            } catch (Exception e) {
187
                LOG.warn("Error creating a polygon with an offset", e);
188
            }
189
        }
190
        return geomToDraw;
191
    }
192

    
193
//    @Override
194
//    public int getOnePointRgb() {
195
//        return getColor().getRGB();
196
//    }
197

    
198
    @Override
199
    public void setLineWidth(double width) {
200
        getLineStyle().setLineWidth((float) width);
201
    }
202

    
203
    @Override
204
    public double getLineWidth() {
205
        return getLineStyle().getLineWidth();
206
    }
207

    
208
    @Override
209
    public Object clone() throws CloneNotSupportedException {
210
        SimpleLineSymbol copy = (SimpleLineSymbol) super.clone();
211

    
212
        if (symbolForSelection != null) {
213
            copy.symbolForSelection = (SimpleLineSymbol) symbolForSelection
214
                    .clone();
215
        }
216

    
217
        return copy;
218
    }
219

    
220
    @Override
221
    public void loadFromState(PersistentState state) throws PersistenceException {
222
        // Set parent style properties
223
        super.loadFromState(state);
224

    
225
        this.symbolForSelection = (SimpleLineSymbol) state.get(SELECTION_SYMBOL);
226
    }
227

    
228
    @Override
229
    public void saveToState(PersistentState state) throws PersistenceException {
230
        // Save parent fill symbol properties
231
        super.saveToState(state);
232

    
233
        // Save own properties
234
        if (this.symbolForSelection != null) {
235
            state.set(SELECTION_SYMBOL, this.getSymbolForSelection());
236
        }
237
    }
238

    
239
    @Override
240
    public void setTransparency(double transparency) {
241
        Color c = getColor();
242
        c = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int) (transparency * 255));
243
        setColor(c);
244
        
245
        ISymbol selectionSymbol = this.symbolForSelection;
246
        if (selectionSymbol != null && selectionSymbol instanceof TransparencySupport) {
247
            ((TransparencySupport) selectionSymbol).setTransparency(transparency);
248
        }
249
    }
250

    
251
    @Override
252
    public double getTransparency() {
253
        return ((double)this.getAlpha())/255;
254
    }
255

    
256
    public static class RegisterPersistence implements Callable {
257

    
258
        @Override
259
        public Object call() throws Exception {
260
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
261
            if (manager.getDefinition(SIMPLE_LINE_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
262
                DynStruct definition = manager.addDefinition(
263
                        SimpleLineSymbol.class,
264
                        SIMPLE_LINE_SYMBOL_PERSISTENCE_DEFINITION_NAME,
265
                        SIMPLE_LINE_SYMBOL_PERSISTENCE_DEFINITION_NAME + " Persistence definition",
266
                        null,
267
                        null
268
                );
269
                // Extend the LineSymbol base definition
270
                definition.extend(manager.getDefinition(LINE_SYMBOL_PERSISTENCE_DEFINITION_NAME));
271

    
272
                definition.addDynFieldObject(SELECTION_SYMBOL).setClassOfValue(SimpleLineSymbol.class);
273

    
274
            }
275
            return Boolean.TRUE;
276
        }
277

    
278
    }
279

    
280
    public static class RegisterSymbol implements Callable {
281

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

    
287
            shapeTypes = new int[]{Geometry.TYPES.CURVE, Geometry.TYPES.ARC,
288
                Geometry.TYPES.MULTICURVE, Geometry.TYPES.CIRCUMFERENCE,
289
                Geometry.TYPES.PERIELLIPSE, Geometry.TYPES.SPLINE,
290
                Geometry.TYPES.LINE, Geometry.TYPES.MULTILINE};
291
            manager.registerSymbol(ILineSymbol.SYMBOL_NAME,
292
                    shapeTypes,
293
                    SimpleLineSymbol.class);
294

    
295
            return Boolean.TRUE;
296
        }
297

    
298
    }
299

    
300
    @Override
301
    public void setCartographicContext(CartographicContext ctx) {
302
        super.setCartographicContext(ctx);
303
        if (getLineStyle() != null
304
                && getLineStyle().getArrowDecorator() != null) {
305
            IArrowDecoratorStyle arrowDecorator = getLineStyle().getArrowDecorator();
306
            if(arrowDecorator != null){
307
                if (arrowDecorator instanceof CartographicSupport) {
308
                    ((CartographicSupport) arrowDecorator).setCartographicContext(ctx);
309
                }
310
                if (arrowDecorator.getMarker() != null) {
311
                    IMarkerSymbol marker = arrowDecorator.getMarker();
312
                    if (marker instanceof CartographicSupport) {
313
                        ((CartographicSupport) marker).setCartographicContext(ctx);
314
                    }
315
                }
316
            }
317
        }
318
    }
319
}