Statistics
| Revision:

root / org.gvsig.legend.urbanhorizontalsignage / trunk / org.gvsig.legend.urbanhorizontalsignage / org.gvsig.legend.urbanhorizontalsignage.lib / org.gvsig.legend.urbanhorizontalsignage.lib.impl / src / main / java / org / gvsig / legend / urbanhorizontalsignage / lib / impl / UrbanHorizontalSignageSymbol.java @ 5130

History | View | Annotate | Download (18.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.legend.urbanhorizontalsignage.lib.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 java.util.concurrent.Callable;
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.GeometryLocator;
35
import org.gvsig.fmap.geom.GeometryManager;
36
import org.gvsig.fmap.geom.GeometryUtils;
37
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
38
import org.gvsig.fmap.geom.primitive.Envelope;
39
import org.gvsig.fmap.geom.primitive.Line;
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.ViewPort;
44
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
45
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol_v2;
46
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
47
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
48
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData;
49
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_CONT_DISC;
50
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC;
51
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_CONT;
52
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_DISC;
53
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageLocator;
54
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageManager;
55
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.AbstractSymbol;
56
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.CartographicSupportToolkit;
57
import org.gvsig.tools.persistence.PersistentState;
58
import org.gvsig.tools.persistence.exception.PersistenceException;
59
import org.gvsig.tools.swing.api.TransparencySupport;
60
import org.gvsig.tools.task.Cancellable;
61
import org.slf4j.Logger;
62
import org.slf4j.LoggerFactory;
63

    
64
public class UrbanHorizontalSignageSymbol extends AbstractSymbol implements ISymbol_v2, TransparencySupport {
65

    
66
    private static final Logger LOG = LoggerFactory.getLogger(UrbanHorizontalSignageSymbol.class);
67
    private static final String SYMBOL_NAME = "UrbanHorizontalSignageSymbol";
68
    private static final String URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME = "UrbanHorizontalSignageSymbol";
69
    
70
    private static final String FIELD_WIDTH = "width";
71
    private static final String FIELD_CONTINUITY = "continuity";
72
    private static final String FIELD_SEGMENTS_COLOR = "segmentsColor";
73
    private static final String FIELD_SEGMENTS_LENGTH = "segmentsLength";
74
    private static final String FIELD_HOLES_COLOR = "holesColor";
75
    private static final String FIELD_HOLES_LENGTH = "holesLength";
76
    private static final String FIELD_PAINT_HOLES = "paintHoles";
77
    private static final String FIELD_GAP_WIDTH = "gapWidth";
78
    private static final String FIELD_ROUND_VERTEX = "roundVertex";
79
    private static final String FIELD_SEGMENTS_GEOMETRY = "segmentsGeometry";
80
    private static final String FIELD_HOLES_GEOMETRY = "holesGeometry";
81
    private static final String FIELD_TRANSPARENCY = "transparency";
82
    private static final String FIELD_MUST_DRAW_ORIGINAL_GEOMETRY = "mustDrawOriginalGeometry";
83
    private static final String FIELD_COLOR_FOR_ORIGINAL_GEOMETRY = "colorForOriginalGeometry";
84
    
85

    
86

    
87
//    private static final String FIELD_SYMBOL_FOR_SELECTION = "symbolForSelection";
88
    private UrbanHorizontalSignageData data;
89

    
90
    transient private UrbanHorizontalSignageSymbol symbolForSelection;
91
    
92
    private boolean mustDrawOriginalGeometry;
93
    private Color colorForOriginalGeometry;
94
    private double cartographicSize;
95
    private double transparency; //[0.0, 1.0]
96

    
97
    public UrbanHorizontalSignageSymbol() {
98
        super();
99
        this.mustDrawOriginalGeometry = false;
100
        this.transparency = 1.0;
101
    }
102

    
103
    public void setData(UrbanHorizontalSignageData data) {
104
        this.data = data;
105
    }
106

    
107
    public UrbanHorizontalSignageData getData() {
108
        return data;
109
    }
110

    
111
    /**
112
     * Sets the transparency for symbol. The valid values are in [0.0, 1.0]
113
     * 
114
     * @param transparency 
115
     */
116
    @Override
117
    public void setTransparency(double transparency) {
118
        if(transparency < 0 || transparency > 1.0){
119
            throw new IllegalArgumentException("Transparency value must be in [0.0, 1.0] ("+transparency+")");
120
        }
121
        this.transparency = transparency;
122
    }
123

    
124
    @Override
125
    public double getTransparency() {
126
        return transparency;
127
    }
128
    
129
    @Override
130
    public ISymbol getSymbolForSelection() {
131
        if (symbolForSelection == null) {
132
            symbolForSelection = (UrbanHorizontalSignageSymbol) cloneForSelection();
133
            symbolForSelection.mustDrawOriginalGeometry = true;
134
        } else {
135
            symbolForSelection.setColor(MapContext.getSelectionColor());
136
        }
137
        return symbolForSelection;
138
    }
139

    
140
    @Override
141
    public void draw(Graphics2D g, AffineTransform affineTransform,
142
            Geometry originalGeometry, Feature feature, Cancellable cancel) {
143
        
144
        if (true) {
145
            // Esto deberia ser para optimizar el pintado de 
146
            // geometrias grandes.
147
            try {
148
                Geometry env = originalGeometry.getEnvelope().getGeometry();
149
                env.transform(affineTransform);
150
                Envelope env2 = env.getEnvelope();
151
                if (env2.getLength(0) < 1.5 && env2.getLength(1) < 1.5) {
152
                    Color color = data.getSegmentsColor();
153
                    Color transparentColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int)(transparency*color.getAlpha()));
154
                    g.setColor(transparentColor);
155
                    Point upperCorner = env2.getUpperCorner();
156
                    int x = (int) upperCorner.getX();
157
                    int y = (int) upperCorner.getY();
158
                    g.drawLine(x, y, x, y);
159
                    return;
160
                }
161
            } catch (Exception ex) {
162
                LOG.warn("Error optimizing the drawing of the geometry. Continues with normal drawing.", ex);
163
                // Do nothing, continue with the draw of the original geometry
164
            }
165
        }
166

    
167
        UrbanHorizontalSignageManager uhsManager = UrbanHorizontalSignageLocator.getUrbanHorizontalSignageManager();
168
        uhsManager.calculateGeometries(originalGeometry, data);
169
        
170
        MultiPolygon geom = data.getSegmentsGeometry();
171
        if (geom != null && geom.getPrimitivesNumber() > 0) {
172
            Color color = data.getSegmentsColor();
173
            Color transparentColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int)(transparency*color.getAlpha()));
174
            g.setColor(transparentColor);
175
            g.fill(geom.getShape(affineTransform));
176
        }
177

    
178
        switch (data.getContinuity()) {
179
            case CONTINUITY_MODE_CONT_DISC:
180
            case CONTINUITY_MODE_DISC_CONT:
181
            case CONTINUITY_MODE_DISC:
182
            case CONTINUITY_MODE_DISC_DISC:
183
                if (data.isPaintHoles()) {
184
                    geom = data.getHolesGeometry();
185
                    if (geom != null && geom.getPrimitivesNumber() > 0) {
186
                        Color color = data.getHolesColor();
187
                        Color transparentColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int)(transparency*color.getAlpha()));
188
                        g.setColor(transparentColor);
189
                        g.fill(geom.getShape(affineTransform));
190
                    }
191
                }
192
        }
193

    
194
        //For debug purposse only
195
        if(mustDrawOriginalGeometry){
196
            g.setColor(getColor());
197
            g.draw(originalGeometry.getShape(affineTransform));
198
        }
199

    
200
    }
201

    
202
    @Override
203
    public int getOnePointRgb() {
204
        return data.getSegmentsColor().getRGB();
205
    }
206

    
207
    @Override
208
    public void drawInsideRectangle(Graphics2D g,
209
            AffineTransform scaleInstance, Rectangle r, PrintAttributes properties) throws SymbolDrawingException {
210
        
211
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
212
        
213
        final int hGap = (int) (r.getWidth() * 0.1); // the left and right margins
214
        final int vPos = 1;                                                  // the top and bottom margins
215
        final int splitCount = 3;                                          // number of lines
216
        final int splitHSize = (r.width - hGap - hGap) / splitCount;
217
        int hPos = hGap;
218
        boolean swap = false;
219

    
220
        Line geom = GeometryUtils.createLine(Geometry.SUBTYPES.GEOM2D);
221
        geom.addVertex(r.x + hPos, r.y + r.height - vPos);
222

    
223
        for (int i = 0; i < splitCount; i++) {
224
            swap = !swap;
225
            geom.addVertex(r.x + hPos + splitHSize, (swap ? vPos : r.height - vPos) + r.y);
226
            hPos += splitHSize;
227
        }
228

    
229
        try {
230
            if (properties == null) {
231
                draw(g, new AffineTransform(), geom, null, null);
232
            } else {
233
                print(g, new AffineTransform(), geom, properties);
234
            }
235
        } catch (Exception e) {
236
            throw new SymbolDrawingException(SymbolDrawingException.UNSUPPORTED_SET_OF_SETTINGS);
237
        }
238

    
239
    }
240

    
241
    @Override
242
    public Object clone() throws CloneNotSupportedException {
243
        UrbanHorizontalSignageSymbol copy = (UrbanHorizontalSignageSymbol) super.clone();
244

    
245
        if (symbolForSelection != null) {
246
            copy.symbolForSelection = (UrbanHorizontalSignageSymbol) symbolForSelection
247
                    .clone();
248
        }
249

    
250
        return copy;
251
    }
252

    
253
    @Override
254
    public void loadFromState(PersistentState state) throws PersistenceException {
255
        // Set parent style properties
256
        super.loadFromState(state);
257
        
258
        UrbanHorizontalSignageData data = new DefaultUrbanHorizontalSignageData();
259
        data.setWidth(state.getDouble(FIELD_WIDTH, UrbanHorizontalSignageData.DEFAULT_WIDTH_VALUE));
260
        data.setContinuity(state.getInt(FIELD_CONTINUITY, UrbanHorizontalSignageData.DEFAULT_CONTINUITY_VALUE));
261
        
262
        Color color = (Color) state.get(FIELD_SEGMENTS_COLOR);
263
        data.setSegmentsColor(color != null ? color : UrbanHorizontalSignageData.DEFAULT_SEGMENT_COLOR_VALUE);
264
        
265
        data.setSegmentsLength(state.getDouble(FIELD_SEGMENTS_LENGTH, UrbanHorizontalSignageData.DEFAULT_SEGMENT_LENGTH_VALUE));
266
        
267
        color = (Color) state.get(FIELD_HOLES_COLOR);
268
        data.setHolesColor(color != null ? color : UrbanHorizontalSignageData.DEFAULT_HOLES_COLOR_VALUE);
269
        
270
        data.setHolesLength(state.getDouble(FIELD_HOLES_LENGTH, UrbanHorizontalSignageData.DEFAULT_HOLES_LENGTH_VALUE));
271
        data.setGapWidth(state.getDouble(FIELD_GAP_WIDTH, UrbanHorizontalSignageData.DEFAULT_GAP_WIDTH_VALUE));
272
        data.setRoundVertex(state.getBoolean(FIELD_ROUND_VERTEX, UrbanHorizontalSignageData.DEFAULT_ROUND_VERTEX_VALUE));
273
        
274
        this.transparency = state.getDouble(FIELD_TRANSPARENCY, 1.0);
275
        this.mustDrawOriginalGeometry = state.getBoolean(FIELD_MUST_DRAW_ORIGINAL_GEOMETRY, false);
276
        color = (Color) state.get(FIELD_COLOR_FOR_ORIGINAL_GEOMETRY);
277
        this.colorForOriginalGeometry = color != null ? color : MapContext.getSelectionColor();
278
        this.data = data;
279

    
280
    }
281

    
282
    @Override
283
    public void saveToState(PersistentState state) throws PersistenceException {
284
        // Save parent fill symbol properties
285
        super.saveToState(state);
286

    
287
        // Save own properties
288
        
289
        if(data != null){
290
            state.set(FIELD_WIDTH, data.getWidth());
291
            state.set(FIELD_CONTINUITY, data.getContinuity());
292
            state.set(FIELD_SEGMENTS_COLOR, data.getSegmentsColor());
293
            state.set(FIELD_SEGMENTS_LENGTH, data.getSegmentsLength());
294
            state.set(FIELD_HOLES_COLOR, data.getHolesColor());
295
            state.set(FIELD_HOLES_LENGTH, data.getHolesLength());
296
            state.set(FIELD_PAINT_HOLES, data.isPaintHoles());
297
            state.set(FIELD_GAP_WIDTH, data.getGapWidth());
298
            state.set(FIELD_ROUND_VERTEX, data.isRoundVertex());
299
        }
300
        state.set(FIELD_MUST_DRAW_ORIGINAL_GEOMETRY, mustDrawOriginalGeometry);
301
        state.set(FIELD_COLOR_FOR_ORIGINAL_GEOMETRY, colorForOriginalGeometry);
302
        state.set(FIELD_TRANSPARENCY, this.getTransparency());
303
    }
304

    
305
    @Override
306
    public void getPixExtentPlus(Geometry geom, float[] distances, ViewPort viewPort, int dpi) {
307
        float cs = (float) getCartographicSize(viewPort, dpi, geom);
308
        // TODO and add the line offset
309
        distances[0] = cs;
310
        distances[1] = cs;
311
    }
312

    
313
    @Override
314
    public int getSymbolType() {
315
        return Geometry.TYPES.CURVE;
316
    }
317

    
318
    @Override
319
    public boolean isSuitableFor(Geometry geom) {
320
        return geom.getGeometryType().isTypeOf(Geometry.TYPES.CURVE);
321
    }
322

    
323
    @Override
324
    public Color getColor() {
325
        return this.colorForOriginalGeometry;
326
    }
327

    
328
    @Override
329
    public void setColor(Color color) {
330
        this.colorForOriginalGeometry = color;
331
    }
332

    
333
    @Override
334
    public void print(Graphics2D g, AffineTransform at, Geometry shape, PrintAttributes properties) {
335
        draw(g, at, shape, null, null);
336
//                double originalSize = getLineWidth();
337
//                double size=originalSize;
338
//                // scale it to size
339
//                int pq = properties.getPrintQuality();
340
//                if (pq == PrintAttributes.PRINT_QUALITY_NORMAL){
341
//                        size *= (double) 300/72;
342
//                }else if (pq == PrintAttributes.PRINT_QUALITY_HIGH){
343
//                        size *= (double) 600/72;
344
//                }else if (pq == PrintAttributes.PRINT_QUALITY_DRAFT){
345
//                        // size *= 72/72; // (which is the same than doing nothing)
346
//                }
347
//                setLineWidth(size);
348
//                draw(g,at,geom,null, null);
349
//                setLineWidth(originalSize);
350
    }
351

    
352
    @Override
353
    public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
354
        double oldSize = getData().getWidth();
355
        setCartographicSize(getCartographicSize(
356
                viewPort,
357
                dpi,
358
                geom),
359
                geom);
360
        return oldSize;
361

    
362
//        return 0;
363
    }
364

    
365
    @Override
366
    public void setCartographicSize(double cartographicSize, Geometry geom) {
367
        //DO NOTHING
368
        this.getData().setWidth(cartographicSize);
369
    }
370

    
371
    @Override
372
    public double getCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
373
        return CartographicSupportToolkit.getCartographicLength(
374
                this,
375
                getData().getWidth(),
376
                viewPort,
377
                dpi
378
        );
379

    
380
//        return 0;
381
    }
382

    
383
//    public static class RegisterPersistence implements Callable {
384
//
385
//        @Override
386
//        public Object call() throws Exception {
387
//            PersistenceManager manager = ToolsLocator.getPersistenceManager();
388
//            if (manager.getDefinition(URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
389
//                DynStruct definition = manager.addDefinition(
390
//                        UrbanHorizontalSignageSymbol.class,
391
//                        URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME,
392
//                        URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME + " Persistence definition",
393
//                        null,
394
//                        null
395
//                );
396
//                // Extend the LineSymbol base definition
397
//                definition.extend(manager.getDefinition(AbstractSymbol.SYMBOL_PERSISTENCE_DEFINITION_NAME));
398
//                
399
//                definition.addDynFieldDouble(FIELD_WIDTH).setMandatory(false);
400
//                definition.addDynFieldInt(FIELD_CONTINUITY).setMandatory(false);
401
//                definition.addDynFieldObject(FIELD_SEGMENTS_COLOR).setClassOfValue(Color.class).setMandatory(false);
402
//                definition.addDynFieldDouble(FIELD_SEGMENTS_LENGTH).setMandatory(false);
403
//                definition.addDynFieldObject(FIELD_HOLES_COLOR).setClassOfValue(Color.class).setMandatory(false);
404
//                definition.addDynFieldDouble(FIELD_HOLES_LENGTH).setMandatory(false);
405
//                definition.addDynFieldBoolean(FIELD_PAINT_HOLES).setMandatory(false);
406
//                definition.addDynFieldDouble(FIELD_GAP_WIDTH).setMandatory(false);
407
//                definition.addDynFieldBoolean(FIELD_ROUND_VERTEX).setMandatory(false);
408
//                definition.addDynFieldDouble(FIELD_TRANSPARENCY).setMandatory(false);
409
//                definition.addDynFieldBoolean(FIELD_MUST_DRAW_ORIGINAL_GEOMETRY).setMandatory(false);
410
//                definition.addDynFieldObject(FIELD_COLOR_FOR_ORIGINAL_GEOMETRY).setClassOfValue(Color.class).setMandatory(false);
411
//            }
412
//            return Boolean.TRUE;
413
//        }
414
//
415
//    }
416

    
417
    public static class RegisterSymbol implements Callable {
418

    
419
        @Override
420
        public Object call() throws Exception {
421
            int[] shapeTypes;
422
            SymbolManager manager = MapContextLocator.getSymbolManager();
423

    
424
            shapeTypes = new int[]{Geometry.TYPES.CURVE, Geometry.TYPES.ARC,
425
                Geometry.TYPES.MULTICURVE, Geometry.TYPES.CIRCUMFERENCE,
426
                Geometry.TYPES.PERIELLIPSE, Geometry.TYPES.SPLINE,
427
                Geometry.TYPES.LINE, Geometry.TYPES.MULTILINE};
428
            manager.registerSymbol(SYMBOL_NAME,
429
                    shapeTypes,
430
                    UrbanHorizontalSignageSymbol.class);
431

    
432
            return Boolean.TRUE;
433
        }
434

    
435
    }
436

    
437
}