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 / marker / impl / AbstractMarkerSymbol.java @ 47593

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

    
26
import java.awt.Color;
27
import java.awt.Point;
28
import java.awt.Rectangle;
29
import java.awt.geom.Point2D;
30
import org.apache.commons.lang3.StringUtils;
31
import org.gvsig.expressionevaluator.ExpressionUtils;
32
import org.gvsig.expressionevaluator.SymbolTable;
33
import org.gvsig.fmap.dal.DALLocator;
34
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
35
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.geom.Geometry;
37
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
38
import org.gvsig.fmap.geom.GeometryLocator;
39
import org.gvsig.fmap.geom.GeometryManager;
40
import org.gvsig.fmap.geom.exception.CreateGeometryException;
41
import org.gvsig.fmap.mapcontext.MapContextLocator;
42
import org.gvsig.fmap.mapcontext.ViewPort;
43
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.AbstractSymbol;
44
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol_v2;
45
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.IMask;
46
import org.gvsig.tools.ToolsLocator;
47
import org.gvsig.tools.dynobject.DynStruct;
48
import org.gvsig.tools.persistence.PersistenceManager;
49
import org.gvsig.tools.persistence.PersistentState;
50
import org.gvsig.tools.persistence.exception.PersistenceException;
51
import org.gvsig.tools.util.Callable;
52

    
53
/**
54
 * Abstract class that any MARKER SYMBOL should extend.
55
 *
56
 * @author gvSIG team
57
 */
58
@SuppressWarnings("UseSpecificCatch")
59
public abstract class AbstractMarkerSymbol extends AbstractSymbol implements IMarkerSymbol_v2 {
60

    
61
    public static final String MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME = "MarkerSymbol";
62

    
63
    private static final String FIELD_COLOR = "color";
64
    private static final String FIELD_ROTATION = "rotation";
65
    private static final String FIELD_OFFSET = "offset";
66
    private static final String FIELD_SIZE = "size";
67
    private static final String FIELD_MASK = "mask";
68
    private static final String FIELD_LINETOOFFSETCOLOR = "lineToOffsetColor";
69
    private static final String FIELD_DRAWLINETOOFFSET = "drawLineToOffset";
70
    private static final String FIELD_SIZE_EXPRESSION = "sizeExpression";
71
    private static final String FIELD_OFFSETX_EXPRESSION = "offsetXExpression";
72
    private static final String FIELD_OFFSETY_EXPRESSION = "offsetYExpression";
73
    private static final String FIELD_ROTATION_EXPRESSION = "rotationExpression";
74
    private static final String FIELD_LINETOOFFSETCOLOR_EXPRESSION = "lineToOffsetColorExpression";
75

    
76
    private static final GeometryManager GEOMETRY_MANAGER = GeometryLocator.getGeometryManager();
77

    
78
    private Color color;
79
    private double rotationDegrees;
80
    private Point2D offset = new Point2D.Double();
81
    private double size = 4d;
82
    private IMask mask;
83

    
84
    private Color lineToOffsetColor;
85
    private boolean drawLineToOffset;
86

    
87
    private String sizeExpression;
88
    private String offsetXExpression;
89
    private String offsetYExpression;
90
    private String rotationExpression;
91
    private String lineToOffsetColorExpression;
92

    
93
    private transient org.gvsig.fmap.geom.primitive.Point point;
94

    
95
    public AbstractMarkerSymbol() {
96
        super();
97
        color = MapContextLocator.getSymbolManager()
98
                .getSymbolPreferences()
99
                .getDefaultSymbolFillColor();
100
        this.lineToOffsetColor = Color.BLACK;
101
        try {
102
            this.point = GEOMETRY_MANAGER.createPoint(0, 0, SUBTYPES.GEOM2D);
103
        } catch (CreateGeometryException ex) {
104

    
105
        }
106
    }
107

    
108
    protected org.gvsig.fmap.geom.primitive.Point getPoint(double x, double y) {
109
        this.point.setX(x);
110
        this.point.setY(y);
111
        return this.point;
112
    }
113

    
114
    @Override
115
    public final int getSymbolType() {
116
        return Geometry.TYPES.POINT;
117
    }
118

    
119
    @Override
120
    public double getRotation() {
121
        return this.getRotationInDegrees();
122
    }
123

    
124
    @Override
125
    public void setRotation(double r) {
126
        this.setRotationInDegrees(r);
127
    }
128

    
129
    public double getRotationInDegrees() {
130
        return rotationDegrees;
131
    }
132

    
133
    public void setRotationInDegrees(double r) {
134
        this.rotationDegrees = r;
135
        this.setRotationExpression(null);
136
    }
137

    
138
    public double getRotationInRadians() {
139
        return Math.toRadians(rotationDegrees);
140
    }
141

    
142
    public void setRotationInRadians(double r) {
143
        this.rotationDegrees = Math.toDegrees(r);
144
        this.setRotationExpression(null);
145
    }
146

    
147
    @Override
148
    public Point2D getOffset() {
149
        if (offset == null) {
150
            offset = new Point();
151
        }
152
        return offset;
153
    }
154

    
155
    @Override
156
    public void setOffset(Point2D offset) {
157
        this.offset = offset;
158
    }
159

    
160
    private FeatureSymbolTable symbolTable = null;
161

    
162
    protected SymbolTable getSymbolTable(Feature f) {
163
        if (symbolTable == null) {
164
            this.symbolTable = DALLocator.getManager().createFeatureSymbolTable();
165
            this.symbolTable.addSymbolTable(ExpressionUtils.createSymbolTable());
166
        }
167
        symbolTable.setFeature(f);
168
        return symbolTable;
169
    }
170

    
171
    @Override
172
    public Color getLineToOffsetColor() {
173
        return this.lineToOffsetColor;
174
    }
175

    
176
    @Override
177
    public void setLineToOffsetColor(Color color) {
178
        this.lineToOffsetColor = color;
179
    }
180

    
181
    @Override
182
    public boolean isDrawLineToOffset() {
183
        return this.drawLineToOffset;
184
    }
185

    
186
    @Override
187
    public void setDrawLineToOffset(boolean drawLineToOffset) {
188
        this.drawLineToOffset = drawLineToOffset;
189
    }
190

    
191
    @Override
192
    public String getOffsetXExpression() {
193
        return offsetXExpression;
194
    }
195

    
196
    @Override
197
    public void setOffsetXExpression(String offsetXExpression) {
198
        this.offsetXExpression = StringUtils.trimToNull(offsetXExpression);
199
    }
200

    
201
    @Override
202
    public String getOffsetYExpression() {
203
        return offsetYExpression;
204
    }
205

    
206
    @Override
207
    public void setOffsetYExpression(String offsetYExpression) {
208
        this.offsetYExpression = StringUtils.trimToNull(offsetYExpression);
209
    }
210

    
211
    @Override
212
    public String getRotationExpression() {
213
        return rotationExpression;
214
    }
215

    
216
    @Override
217
    public void setRotationExpression(String rotationExpression) {
218
        this.rotationExpression = StringUtils.trimToNull(rotationExpression);
219
    }
220

    
221
    @Override
222
    public String getSizeExpression() {
223
        return sizeExpression;
224
    }
225

    
226
    @Override
227
    public void setSizeExpression(String sizeExpression) {
228
        this.sizeExpression = StringUtils.trimToNull(sizeExpression);
229
    }
230

    
231
    @Override
232
    public String getLineToOffsetColorExpression() {
233
        return this.lineToOffsetColorExpression;
234
    }
235

    
236
    @Override
237
    public void setLineToOffsetColorExpression(String lineToOffsetColorExpression) {
238
        this.lineToOffsetColorExpression = StringUtils.trimToNull(lineToOffsetColorExpression);
239
    }
240

    
241
    @Override
242
    public Point2D getEfectiveOffset(Feature f) {
243
        if (f == null) {
244
            f = this.getFeature();
245
        }
246
        Point2D p;
247
        if (f == null || StringUtils.isBlank(this.offsetXExpression) || StringUtils.isBlank(this.offsetYExpression)) {
248
            p = this.getOffset();
249
            p = new Point2D.Double(
250
                    toCartographicUnits(p.getX()),
251
                    toCartographicUnits(p.getY())
252
            );
253
        } else {
254
            double offsetX = toCartographicUnits(ExpressionUtils.parseDouble(
255
                    this.getSymbolTable(f),
256
                    offsetXExpression,
257
                    (int) this.getOffset().getX()
258
            ));
259
            double offsetY = toCartographicUnits(ExpressionUtils.parseDouble(
260
                    this.getSymbolTable(f),
261
                    offsetYExpression,
262
                    (int) this.getOffset().getY()
263
            ));
264
            p = new Point2D.Double(offsetX, offsetY);
265
        }
266
        return p;
267
    }
268

    
269
    @Override
270
    public double getEfectiveRotationInDegres(Feature f) {
271
        if (StringUtils.isBlank(this.rotationExpression)) {
272
            return this.getRotationInDegrees();
273
        }
274
        // Por defecto vedra en grados.
275
        if (f == null) {
276
            f = this.getFeature();
277
        }
278
        if (f == null) {
279
            return this.getRotationInDegrees();
280
        }
281
        double r = ExpressionUtils.parseDouble(
282
                this.getSymbolTable(f),
283
                rotationExpression,
284
                this.getRotationInDegrees()
285
        );
286
        return r;
287
    }
288

    
289
    @Override
290
    public double getEfectiveRotationInRadians(Feature f) {
291
        // Pillamos el valor por defecto que es en grados y lo transformamos a radianes.
292
        if (StringUtils.isBlank(this.rotationExpression)) {
293
            return this.getRotationInRadians();
294
        }
295
        double r = this.getEfectiveRotationInDegres(f);
296
        if (r == 0) {
297
            return 0;
298
        }
299
        r = Math.toRadians(r);
300
        return r;
301
    }
302

    
303
    @Override
304
    public Color getEfectiveLineToOffsetColor(Feature f) {
305
        if (f == null) {
306
            f = this.getFeature();
307
        }
308
        if (f == null || StringUtils.isBlank(this.lineToOffsetColorExpression)) {
309
            return this.getLineToOffsetColor();
310
        }
311
        Color theColor = ExpressionUtils.parseColor(
312
                this.getSymbolTable(f),
313
                this.lineToOffsetColorExpression,
314
                this.getLineToOffsetColor()
315
        );
316
        return theColor;
317
    }
318

    
319
    @Override
320
    public double getEfectiveSize(Feature f) {
321
        if (StringUtils.isBlank(this.sizeExpression)) {
322
            return this.getCartographicSize();
323
        }
324
        if (f == null) {
325
            f = this.getFeature();
326
        }
327
        if (f == null) {
328
            return this.getCartographicSize();
329
        }
330
        double sz = ExpressionUtils.parseDouble(
331
                this.getSymbolTable(f),
332
                this.sizeExpression,
333
                -1
334
        );
335
        if (sz < 0) {
336
            return this.getCartographicSize();
337
        }
338
        return toCartographicUnits(sz);
339
    }
340

    
341
    @Override
342
    public boolean isSuitableFor(Geometry geom) {
343
        return geom.getType() == Geometry.TYPES.POINT;
344
    }
345

    
346
//    @Override
347
//    public int getOnePointRgb() {
348
//        return color.getRGB();
349
//    }
350

    
351
    @Override
352
    public double getSize() {
353
        return size;
354
    }
355

    
356
    @Override
357
    public void setSize(double size) {
358
        this.size = size;
359
        this.setSizeExpression(null);
360
    }
361

    
362
    @Override
363
    public Color getColor() {
364
        return color;
365
    }
366

    
367
    @Override
368
    public void setColor(Color color) {
369
        this.color = color;
370
    }
371

    
372
    @Override
373
    public void setAlpha(int outlineAlpha) {
374
        Color theColor = getColor();
375
        setColor(new Color(theColor.getRed(), theColor.getGreen(), theColor.getBlue(),
376
                outlineAlpha));
377
    }
378

    
379
//    @Override
380
//    public void getPixExtentPlus(Geometry geom, float[] distances, ViewPort viewPort, int dpi) {
381
//        setCartographicContext(viewPort, dpi, geom);
382
//        float cs = (float) getCartographicSize();
383
//        distances[0] = cs;
384
//        distances[1] = cs;
385
//    }
386

    
387
    @Override
388
    public final IMask getMask() {
389
        return mask;
390
    }
391

    
392
    @Override
393
    public final void setMask(IMask mask) {
394
        this.mask = mask;
395
    }
396

    
397
    protected double getCartographicSize() {
398
        return toCartographicUnits(getSize());
399
    }
400

    
401
    @Override
402
    public Object clone() throws CloneNotSupportedException {
403
        AbstractMarkerSymbol copy = (AbstractMarkerSymbol) super.clone();
404

    
405
        // Clone the offset
406
        if (offset != null) {
407
            copy.offset = (Point2D) offset.clone();
408
        }
409

    
410
        // clone the mask
411
        if (mask != null) {
412
            copy.mask = (IMask) mask.clone();
413
        }
414
        return copy;
415
    }
416

    
417
    @Override
418
    public void loadFromState(PersistentState state)
419
            throws PersistenceException {
420
        // Set parent symbol properties
421
        super.loadFromState(state);
422
        // Set own properties
423
        setColor((Color) state.get(FIELD_COLOR));
424
        setMask((IMask) state.get(FIELD_MASK));
425
        setOffset((Point2D) state.get(FIELD_OFFSET));
426
        setRotation(state.getDouble(FIELD_ROTATION));
427
        setSize(state.getDouble(FIELD_SIZE));
428
        setDrawLineToOffset(state.getBoolean(FIELD_DRAWLINETOOFFSET, false));
429
        setLineToOffsetColor((Color) state.get(FIELD_LINETOOFFSETCOLOR));
430

    
431
        setSizeExpression(state.getString(FIELD_SIZE_EXPRESSION));
432
        setOffsetXExpression(state.getString(FIELD_OFFSETX_EXPRESSION));
433
        setOffsetYExpression(state.getString(FIELD_OFFSETY_EXPRESSION));
434
        setRotationExpression(state.getString(FIELD_ROTATION_EXPRESSION));
435
        setLineToOffsetColorExpression(state.getString(FIELD_LINETOOFFSETCOLOR_EXPRESSION));
436
    }
437

    
438
    @Override
439
    public void saveToState(PersistentState state) throws PersistenceException {
440
        // Save parent symbol properties
441
        super.saveToState(state);
442
        // Save own properties
443
        state.set(FIELD_COLOR, getColor());
444
        state.set(FIELD_MASK, getMask());
445
        state.set(FIELD_OFFSET, getOffset());
446
        state.set(FIELD_ROTATION, getRotation());
447
        state.set(FIELD_SIZE, getSize());
448
        state.set(FIELD_LINETOOFFSETCOLOR, getLineToOffsetColor());
449
        state.set(FIELD_DRAWLINETOOFFSET, isDrawLineToOffset());
450

    
451
        state.set(FIELD_OFFSETX_EXPRESSION, getOffsetXExpression());
452
        state.set(FIELD_OFFSETY_EXPRESSION, getOffsetYExpression());
453
        state.set(FIELD_SIZE_EXPRESSION, getSizeExpression());
454
        state.set(FIELD_ROTATION_EXPRESSION, getRotationExpression());
455
        state.set(FIELD_LINETOOFFSETCOLOR_EXPRESSION, getLineToOffsetColorExpression());
456
    }
457

    
458
    public static class RegisterPersistence implements Callable {
459

    
460
        @Override
461
        public Object call() throws Exception {
462
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
463
            if (manager.getDefinition(MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
464
                DynStruct definition = manager.addDefinition(
465
                        AbstractMarkerSymbol.class,
466
                        MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME,
467
                        MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME + " Persistence definition",
468
                        null,
469
                        null
470
                );
471

    
472
                // Extend the Symbol base definition
473
                definition.extend(manager.getDefinition(SYMBOL_PERSISTENCE_DEFINITION_NAME));
474

    
475
                // Color
476
                definition.addDynFieldObject(FIELD_COLOR).setMandatory(false).setClassOfValue(Color.class);
477
                // Mask
478
                definition.addDynFieldObject(FIELD_MASK).setMandatory(false).setClassOfValue(IMask.class);
479

    
480
                // Offset
481
                definition.addDynFieldObject(FIELD_OFFSET).setMandatory(false).setClassOfValue(Point2D.class);
482

    
483
                // Rotation
484
                definition.addDynFieldDouble(FIELD_ROTATION).setMandatory(false);
485

    
486
                // Size
487
                definition.addDynFieldDouble(FIELD_SIZE).setMandatory(false);
488

    
489
                definition.addDynFieldBoolean(FIELD_DRAWLINETOOFFSET).setMandatory(false);
490
                definition.addDynFieldObject(FIELD_LINETOOFFSETCOLOR).setClassOfValue(Color.class).setMandatory(false);
491

    
492
                definition.addDynFieldString(FIELD_OFFSETX_EXPRESSION).setMandatory(false);
493
                definition.addDynFieldString(FIELD_OFFSETY_EXPRESSION).setMandatory(false);
494
                definition.addDynFieldString(FIELD_LINETOOFFSETCOLOR_EXPRESSION).setMandatory(false);
495
                definition.addDynFieldString(FIELD_ROTATION_EXPRESSION).setMandatory(false);
496
                definition.addDynFieldString(FIELD_SIZE_EXPRESSION).setMandatory(false);
497
            }
498
            return true;
499
        }
500

    
501
    }
502

    
503
    protected double getAdjustedSize(Rectangle r, double size) {
504
        if (r == null) {
505
            return size;
506
        }
507
        double min = Math.min(r.getHeight(), r.getWidth());
508
        if (size > min) {
509
            size = min;
510
        }
511
        return size;
512
    }
513

    
514
    protected Geometry getSampleGeometry(Rectangle r) {
515
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
516
        try {
517
            return geomManager.createEnvelope(
518
                    r.x + 1,
519
                    r.y + 1,
520
                    r.x + r.width - 2,
521
                    r.y + r.height - 2,
522
                    Geometry.SUBTYPES.GEOM2D).getGeometry();
523
        } catch (Exception e) {
524
            throw new RuntimeException("Can't create smple geometry.", e);
525
        }
526

    
527
    }
528

    
529
}