Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / org.gvsig.symbology / org.gvsig.symbology.lib / org.gvsig.symbology.lib.impl / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / legend / styling / AttrInTableLabelingStrategy.java @ 34978

History | View | Annotate | Download (17.3 KB)

1
package org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling;
2

    
3
import java.awt.Color;
4
import java.awt.Font;
5
import java.awt.Graphics2D;
6
import java.awt.image.BufferedImage;
7
import java.util.ArrayList;
8
import java.util.List;
9

    
10
import org.gvsig.compat.print.PrintAttributes;
11
import org.gvsig.fmap.dal.exception.DataException;
12
import org.gvsig.fmap.dal.exception.ReadException;
13
import org.gvsig.fmap.dal.feature.Feature;
14
import org.gvsig.fmap.dal.feature.FeatureQuery;
15
import org.gvsig.fmap.dal.feature.FeatureSet;
16
import org.gvsig.fmap.dal.feature.FeatureStore;
17
import org.gvsig.fmap.dal.feature.FeatureType;
18
import org.gvsig.fmap.geom.Geometry;
19
import org.gvsig.fmap.geom.exception.CreateGeometryException;
20
import org.gvsig.fmap.geom.operation.GeometryOperationException;
21
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
22
import org.gvsig.fmap.geom.primitive.Point;
23
import org.gvsig.fmap.mapcontext.MapContext;
24
import org.gvsig.fmap.mapcontext.ViewPort;
25
import org.gvsig.fmap.mapcontext.layers.FLayer;
26
import org.gvsig.fmap.mapcontext.layers.vectorial.ContainsEnvelopeEvaluator;
27
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
28
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingMethod;
29
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IPlacementConstraints;
30
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IZoomConstraints;
31
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.CartographicSupportToolkit;
32
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.impl.SimpleTextSymbol;
33
import org.gvsig.tools.ToolsLocator;
34
import org.gvsig.tools.dispose.DisposableIterator;
35
import org.gvsig.tools.dynobject.DynStruct;
36
import org.gvsig.tools.exception.BaseException;
37
import org.gvsig.tools.persistence.PersistenceManager;
38
import org.gvsig.tools.persistence.PersistentState;
39
import org.gvsig.tools.persistence.exception.PersistenceException;
40
import org.gvsig.tools.task.Cancellable;
41
import org.gvsig.tools.util.Callable;
42
import org.slf4j.LoggerFactory;
43

    
44

    
45

    
46
/**
47
 * LabelingStrategy used when the user wants to use label sizes, rotations, etc. from
48
 * the values included in fields of the datasource's table
49
 *
50
 * @author jaume dominguez faus - jaume.dominguez@iver.es
51
 *
52
 */
53
public class AttrInTableLabelingStrategy implements IAttrInTableLabelingStrategy {
54
        private static final String FIELD_LABELING_METHOD = "labelingMethod";
55
        private static final String FIELD_ZOOM_CONSTRAINTS = "zoomConstraints";
56
        private static final String FIELD_COLOR_FONT = "colorFont";
57
        private static final String FIELD_LAYER = "layer";
58
        private static final String FIELD_REFERENCE_SYSTEM = "referenceSystem";
59
        private static final String FIELD_FIXED_COLOR = "fixedColor";
60
        private static final String FIELD_USE_FIXED_COLOR = "useFixedColor";
61
        private static final String FIELD_FIXED_SIZE = "fixedSize";
62
        private static final String FIELD_USE_FIXED_SIZE = "useFixedSize";
63
        private static final String FIELD_FONT = "font";
64
        private static final String FIELD_UNIT = "Unit";
65
        private static final String FIELD_ROTATION = "RotationField";
66
        private static final String FIELD_COLOR = "ColorField";
67
        private static final String FIELD_HEIGHT = "HeightField";
68
        private static final String FIELD_TEXT = "TextField";
69
        private static final org.slf4j.Logger logger = LoggerFactory.getLogger(AttrInTableLabelingStrategy.class);
70
        public static final double MIN_TEXT_SIZE = 3;
71
        private static final String ATTR_IN_TABLE_LABELING_STRATEGY_PERSISTENCE_DEFINITION_NAME =
72
                        "AttrInTableLabelingStrategy";
73
        private ILabelingMethod method = new DefaultLabelingMethod();
74
        private IZoomConstraints zoom;
75
        private FLyrVect layer;
76
//        private double unitFactor = 1D;
77
        private double fixedSize=10;
78
        private Color fixedColor;
79
        private int unit = -1; //(pixel)
80
        private boolean useFixedSize;
81
        private boolean useFixedColor;
82
        private int referenceSystem;
83
//        private boolean isPrinting;
84
        private String[] usedFields = null;
85
        private Font font;
86
        private Color colorFont;
87
        private String textFieldName;
88
        private String rotationFieldName;
89
        private String heightFieldName;
90
        private String colorFieldName;
91

    
92
        public ILabelingMethod getLabelingMethod() {
93
                return this.method;
94
        }
95

    
96
        public void setLabelingMethod(ILabelingMethod method) {
97
                this.method = method;
98
        }
99

    
100
        public IPlacementConstraints getPlacementConstraints() {
101
                return null; // (automatically handled by the driver)
102
        }
103

    
104
        public void setPlacementConstraints(IPlacementConstraints constraints) {
105
                // nothing
106
        }
107

    
108
        public IZoomConstraints getZoomConstraints() {
109
                return zoom;
110
        }
111

    
112
        public void setZoomConstraints(IZoomConstraints constraints) {
113
                this.zoom = constraints;
114
        }
115

    
116
        private void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
117
                        Cancellable cancel, PrintAttributes props) throws ReadException {
118
                double scale = viewPort.getScale();
119

    
120
                SimpleTextSymbol sym = new SimpleTextSymbol();
121

    
122
                sym.setFont(getFont());
123

    
124
                sym.setUnit(unit);
125
                sym.setReferenceSystem(referenceSystem);
126
                if (zoom==null ||
127
                        ( zoom.isUserDefined() && (scale >= zoom.getMaxScale())
128
                        && (scale <= zoom.getMinScale()) ) ) {
129
                        FeatureSet set = null;
130
                        DisposableIterator iterator = null;
131
                        try {
132
                                // limit the labeling to the visible extent
133
                                List<String> fields = new ArrayList<String>();
134
                                int heightPos =-1;
135
                                int rotationPos =-1;
136
                                int textPos = -1;
137
                                int colorPos = -1;
138

    
139
                                if (!this.usesFixedSize()) {
140
                                        if (getHeightField() != null) {
141
                                                heightPos = fields.size();
142
                                                fields.add(getHeightField());
143
                                        }
144
                                }
145
                                if (getRotationField() != null) {
146
                                        rotationPos = fields.size();
147
                                        fields.add(getRotationField());
148
                                }
149
                                if (getTextField() != null) {
150
                                        textPos = fields.size();
151
                                        fields.add(getTextField());
152
                                }
153

    
154
                                if (!this.usesFixedColor() && getColorField() != null) {
155
                                        colorPos = fields.size();
156
                                        fields.add(getColorField());
157
                                }
158

    
159
                                FeatureStore featureStore=layer.getFeatureStore();
160

    
161
                                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
162
                                fields.add(geomName);
163

    
164
                                FeatureQuery featureQuery=featureStore.createFeatureQuery();
165

    
166
                                featureQuery.setAttributeNames((String[]) fields.toArray(new String[fields.size()]));
167
                                // TODO no set filter y layer is contained totaly in viewPort
168
                                ContainsEnvelopeEvaluator iee=new ContainsEnvelopeEvaluator(viewPort.getAdjustedEnvelope(),viewPort.getProjection(),featureStore.getDefaultFeatureType(),geomName);
169
                                featureQuery.setFilter(iee);
170

    
171

    
172

    
173
                                set = featureStore
174
                                                .getFeatureSet(featureQuery);
175

    
176
                                iterator = set.fastIterator();
177
                                while(iterator.hasNext()){
178
                                        if (cancel.isCanceled()){
179
                                                return;
180
                                        }
181
                                        Feature feature=(Feature)iterator.next();
182
                                        double size = 0;
183
                                        Color color = null;
184
                                        if (useFixedSize){
185
                                                // uses fixed size
186
                                                size = fixedSize;// * fontScaleFactor;
187
                                        } else if (heightFieldName != null) {
188
                                                // text size is defined in the table
189
                                                try {
190
                                                        size = feature.getDouble(fields.get(heightPos));
191
                                                } catch (Exception e) {
192
                                                        logger.
193
                                                                warn("Null text height value for text '{}'", feature.getString(fields.get(textPos)));
194

    
195
                                                        continue;
196
                                                }
197
                                        } else {
198
                                                // otherwise will use the size in the symbol
199
                                                size = sym.getFont().getSize();
200
                                        }
201

    
202
                                        size = CartographicSupportToolkit.
203
                                                                getCartographicLength(this,
204
                                                                                                          size,
205
                                                                                                          viewPort,
206
                                                                                                          MapContext.getScreenDPI());
207
                                        if (size <= MIN_TEXT_SIZE) {
208
                                                // label is too small to be readable, will be skipped
209
                                                // this speeds up the rendering in wider zooms
210
                                                continue;
211
                                        }
212

    
213
                                        sym.setFontSize(size);
214

    
215
                                        if (useFixedColor){
216
                                                color = fixedColor;
217
                                        } else if (colorFieldName != null) {
218
                                                // text size is defined in the table
219
                                                try {
220
                                                        color = new Color(feature.getInt(fields.get(colorPos)));
221
                                                } catch (ClassCastException ccEx) {
222
                                                        if (feature.get(fields.get(colorPos)) != null) {
223
                                                                throw new ReadException("Unknown", ccEx);
224
                                                        }
225
                                                        logger.warn(
226
                                                                        "Null color value for text '{}'", 
227
                                                                        feature.getString(textFieldName));
228

    
229
                                                        continue;
230
                                                }
231
                                        } else {
232
                                                color = sym.getTextColor();
233
                                        }
234

    
235
                                        sym.setTextColor(color);
236

    
237
                                        double rotation = 0D;
238
                                        if (rotationFieldName != null) {
239
                                                // text rotation is defined in the table
240
                                                rotation = -Math.toRadians(((Number) feature.get(fields.get(rotationPos))).doubleValue());
241
                                        }
242

    
243
                                        Geometry geom = feature.getDefaultGeometry();
244
                                        sym.setText(feature.getString(fields.get(textPos)));
245
                                        sym.setRotation(rotation);
246
                        
247
                    Point p = createLabelPoint(geom);
248
                    if( p!=null ) {
249
                            p.transform(viewPort.getAffineTransform());
250
                                                if (props == null) {
251
                                sym.draw(g, null, p, feature, cancel);
252
                            } else {
253
                                                        sym.print(g, null, p, props);
254
                            }
255
                    }
256
                                }
257

    
258
                        } catch (BaseException e) {
259
                                throw new ReadException(
260
                                                "Could not draw annotation in the layer.", e);
261
                        } finally {
262
                                if (iterator != null) {
263
                                        iterator.dispose();
264
                                }
265
                                if (set != null) {
266
                                        set.dispose();
267
                                }
268

    
269
                        }
270

    
271
                }
272
        }
273
        
274
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
275
                        Cancellable cancel, double dpi) throws ReadException {
276
                draw(image, g, viewPort, cancel, null);
277
        }
278

    
279
        private org.gvsig.fmap.geom.primitive.Point createLabelPoint(org.gvsig.fmap.geom.Geometry geom)
280
                        throws CreateGeometryException {
281
                
282
                try {
283
                        return geom.centroid();
284
                } catch (GeometryOperationNotSupportedException e) {
285
                        return null;
286
                } catch (GeometryOperationException e) {
287
                        return null;
288
                }
289
        }
290

    
291
//        public String getClassName() {
292
//                return getClass().getName();
293
//        }
294

    
295
        public String getRotationField()  {
296
                return this.rotationFieldName;
297
        }
298

    
299
        public String getTextField()  {
300
                return this.textFieldName;
301
        }
302

    
303
        public String getHeightField() {
304
                return this.heightFieldName;
305
        }
306

    
307
        public String getColorField()  {
308
                return this.colorFieldName;
309
        }
310

    
311
        public void setTextField(String textFieldName) {
312
                this.textFieldName=textFieldName;
313
                this.usedFields = null;
314
        }
315

    
316
        public void setRotationField(String rotationFieldName) {
317
                this.rotationFieldName = rotationFieldName;
318
                this.usedFields = null;
319
        }
320

    
321
        /**
322
         * Sets the field that contains the size of the text. The size is computed
323
         * in meters. To use any other unit, call setUnit(int) with the scale factor from meters
324
         * (for centimeters, call <b>setUnitFactor(0.01))</b>.
325
         * @param heightFieldName
326
         */
327
        public void setHeightField(String heightFieldName) {
328
                this.heightFieldName = heightFieldName;
329
                this.usedFields = null;
330
        }
331

    
332

    
333
        public void setColorField(String colorFieldName) {
334
                this.colorFieldName = colorFieldName;
335
        }
336

    
337
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
338
                        PrintAttributes props) throws ReadException {
339
                draw(null, g, viewPort, cancel, props);
340
        }
341

    
342
        public void setUsesFixedSize(boolean b) {
343
                useFixedSize = b;
344
                this.usedFields = null;
345
        }
346

    
347
        public boolean usesFixedSize() {
348
                return useFixedSize;
349
        }
350

    
351
        public double getFixedSize() {
352
                return fixedSize;
353
        }
354

    
355
        public void setFixedSize(double fixedSize) {
356
                this.fixedSize = fixedSize;
357
                this.usedFields = null;
358
        }
359

    
360
        public void setUsesFixedColor(boolean b) {
361
                useFixedColor = b;
362
                this.usedFields = null;
363
        }
364

    
365
        public boolean usesFixedColor() {
366
                return useFixedColor;
367
        }
368

    
369
        public Color getFixedColor() {
370
                return fixedColor;
371
        }
372

    
373
        public void setFixedColor(Color fixedColor) {
374
                this.fixedColor = fixedColor;
375
        }
376

    
377

    
378
        public void setUnit(int unitIndex) {
379
                unit = unitIndex;
380

    
381
        }
382

    
383
        public int getUnit() {
384
                return unit;
385
        }
386

    
387
        public String[] getUsedFields() {
388
                if (this.usedFields == null) {
389
                        List<String> v = new ArrayList<String>(4);
390
                        if (!this.usesFixedSize()) {
391
                                if (getHeightField() != null) {
392
                                        v.add(getHeightField());
393
                                }
394
                        }
395
                        if (getRotationField() != null) {
396
                                v.add(getRotationField());
397
                        }
398
                        if (getTextField() != null) {
399
                                v.add(getTextField());
400
                        }
401

    
402
                        if (!this.usesFixedColor() && getColorField() != null) {
403
                                v.add(getColorField());
404
                        }
405
                        this.usedFields = (String[]) v.toArray(new String[v.size()]);
406
                }
407
                return this.usedFields;
408
        }
409

    
410
        public int getReferenceSystem() {
411
                return referenceSystem;
412
        }
413

    
414
        public void setReferenceSystem(int referenceSystem) {
415
                this.referenceSystem = referenceSystem;
416
        }
417

    
418
        public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
419
                // not required here
420
                throw new Error("Undefined in this context");
421
        }
422

    
423
        public void setCartographicSize(double cartographicSize, Geometry geom) {
424
                // not required here
425
                throw new Error("Undefined in this context");
426
        }
427

    
428
        public double getCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
429
                // not required here
430
                throw new Error("Undefined in this context");
431

    
432
        }
433

    
434
        public void setLayer(FLayer layer) {
435
                this.layer = (FLyrVect) layer;
436
                if (layer == null) {
437
                        return;
438
                }
439
                FeatureType type;
440
                try {
441
                        type = this.layer.getFeatureStore().getDefaultFeatureType();
442
                } catch (DataException e) {
443
                        throw new RuntimeException(this.getClass().getName(), e);
444
                }
445

    
446
                if (textFieldName != null) {
447
                        if (type.getIndex(textFieldName) < 0) {
448
                                // FIXME exception ??
449
                        }
450
                }
451
                if (rotationFieldName != null) {
452
                        if (type.getIndex(rotationFieldName) < 0) {
453
                                // FIXME exception ??
454
                        }
455
                }
456
                if (heightFieldName != null) {
457
                        if (type.getIndex(heightFieldName) < 0) {
458
                                // FIXME exception ??
459
                        }
460
                }
461
                if (colorFieldName != null) {
462
                        if (type.getIndex(colorFieldName) < 0) {
463
                                // FIXME exception ??
464
                        }
465
                }
466
        }
467

    
468
        public boolean shouldDrawLabels(double scale) {
469
                return layer.isWithinScale(scale);
470
        }
471
        public Color getColorFont() {
472
                return colorFont;
473
        }
474

    
475
        public void setColorFont(Color colorFont) {
476
                this.colorFont = colorFont;
477
        }
478

    
479
        public Font getFont() {
480
                return font;
481
        }
482

    
483
        public void setFont(Font selFont) {
484
                this.font = selFont;
485
        }
486

    
487
        /* (non-Javadoc)
488
         * @see org.gvsig.tools.persistence.Persistent#loadFromState(org.gvsig.tools.persistence.PersistentState)
489
         */
490
        public void loadFromState(PersistentState state)
491
                        throws PersistenceException {
492

    
493
                setTextField(state.getString(FIELD_TEXT));
494
                setHeightField(state.getString(FIELD_HEIGHT));
495
                setColorField(state.getString(FIELD_COLOR));
496
                setRotationField(state.getString(FIELD_ROTATION));
497
                setUnit(state.getInt(FIELD_UNIT));
498
                setFont((Font) state.get(FIELD_FONT));
499
                useFixedSize = state.getBoolean(FIELD_USE_FIXED_SIZE);
500
                setFixedSize(state.getDouble(FIELD_FIXED_SIZE));
501
                useFixedColor = state.getBoolean(FIELD_USE_FIXED_COLOR);
502
                setFixedColor((Color) state.get(FIELD_FIXED_COLOR));
503
                setReferenceSystem(state.getInt(FIELD_REFERENCE_SYSTEM));
504
                setLayer((FLayer) state.get(FIELD_LAYER));
505
                setColorFont((Color) state.get(FIELD_COLOR_FONT));
506
                setZoomConstraints((IZoomConstraints) state.get(FIELD_ZOOM_CONSTRAINTS));
507
                setLabelingMethod((ILabelingMethod) state.get(FIELD_LABELING_METHOD));
508
        }
509

    
510
        /* (non-Javadoc)
511
         * @see org.gvsig.tools.persistence.Persistent#saveToState(org.gvsig.tools.persistence.PersistentState)
512
         */
513
        public void saveToState(final PersistentState state) throws PersistenceException {
514
                state.set(FIELD_TEXT, getTextField());
515
                state.set(FIELD_HEIGHT, getHeightField());
516
                state.set(FIELD_COLOR, getColorField());
517
                state.set(FIELD_ROTATION, getRotationField());
518
                state.set(FIELD_UNIT, getUnit());
519
                state.set(FIELD_FONT, getFont());
520
                state.set(FIELD_USE_FIXED_SIZE, useFixedSize);
521
                state.set(FIELD_FIXED_SIZE, getFixedSize());
522
                state.set(FIELD_USE_FIXED_COLOR, useFixedColor);
523
                state.set(FIELD_FIXED_COLOR, getFixedColor());
524
                state.set(FIELD_REFERENCE_SYSTEM, getReferenceSystem());
525
                state.set(FIELD_LAYER, layer);
526
                state.set(FIELD_COLOR_FONT, getColorFont());
527
                state.set(FIELD_ZOOM_CONSTRAINTS, getZoomConstraints());
528
                state.set(FIELD_LABELING_METHOD, getLabelingMethod());
529
        }
530
        
531
        public static class RegisterPersistence implements Callable {
532

    
533
                public Object call() throws Exception {
534
                        PersistenceManager manager = ToolsLocator.getPersistenceManager();
535
                        if( manager.getDefinition(ATTR_IN_TABLE_LABELING_STRATEGY_PERSISTENCE_DEFINITION_NAME)==null ) {
536
                                DynStruct definition = manager.addDefinition(
537
                                                AttrInTableLabelingStrategy.class,
538
                                                ATTR_IN_TABLE_LABELING_STRATEGY_PERSISTENCE_DEFINITION_NAME,
539
                                                ATTR_IN_TABLE_LABELING_STRATEGY_PERSISTENCE_DEFINITION_NAME+" Persistence definition",
540
                                                null, 
541
                                                null
542
                                );
543
                                definition.addDynFieldString(FIELD_TEXT).setMandatory(true);
544
                                definition.addDynFieldString(FIELD_HEIGHT).setMandatory(false);
545
                                definition.addDynFieldString(FIELD_COLOR).setMandatory(false);
546
                                definition.addDynFieldString(FIELD_ROTATION).setMandatory(false);
547
                                definition.addDynFieldInt(FIELD_UNIT).setMandatory(true);
548
                                definition.addDynFieldObject(FIELD_FONT).setMandatory(false).setClassOfValue(Font.class);
549
                                definition.addDynFieldBoolean(FIELD_USE_FIXED_SIZE).setMandatory(true);
550
                                definition.addDynFieldDouble(FIELD_FIXED_SIZE).setMandatory(false);
551
                                definition.addDynFieldBoolean(FIELD_USE_FIXED_COLOR).setMandatory(true);
552
                                definition.addDynFieldObject(FIELD_FIXED_COLOR).setMandatory(false).setClassOfValue(Color.class);
553
                                definition.addDynFieldInt(FIELD_REFERENCE_SYSTEM).setMandatory(true);
554
                                definition.addDynFieldObject(FIELD_LAYER).setMandatory(true).setClassOfValue(FLyrVect.class);
555
                                definition.addDynFieldObject(FIELD_COLOR_FONT).setMandatory(false).setClassOfValue(Color.class);
556
                                definition.addDynFieldObject(FIELD_ZOOM_CONSTRAINTS).setMandatory(false).setClassOfValue(IZoomConstraints.class);
557
                                definition.addDynFieldObject(FIELD_LABELING_METHOD).setMandatory(true).setClassOfValue(ILabelingMethod.class);
558
                        }
559
                        return Boolean.TRUE;
560
                }
561
                
562
        }
563
}