Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2021 / extensions / org.gvsig.symbology / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / legend / styling / AttrInTableLabelingStrategy.java @ 34111

History | View | Annotate | Download (17.4 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.ILabelingStrategy;
30
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IPlacementConstraints;
31
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IZoomConstraints;
32
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
33
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.CartographicSupportToolkit;
34
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.impl.SimpleTextSymbol;
35
import org.gvsig.tools.ToolsLocator;
36
import org.gvsig.tools.dispose.DisposableIterator;
37
import org.gvsig.tools.dynobject.DynStruct;
38
import org.gvsig.tools.exception.BaseException;
39
import org.gvsig.tools.persistence.PersistenceManager;
40
import org.gvsig.tools.persistence.PersistentState;
41
import org.gvsig.tools.persistence.exception.PersistenceException;
42
import org.gvsig.tools.task.Cancellable;
43
import org.gvsig.tools.util.Callable;
44
import org.slf4j.LoggerFactory;
45

    
46

    
47

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

    
94
        public ILabelingMethod getLabelingMethod() {
95
                return this.method;
96
        }
97

    
98
        public void setLabelingMethod(ILabelingMethod method) {
99
                this.method = method;
100
        }
101

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

    
106
        public void setPlacementConstraints(IPlacementConstraints constraints) {
107
                // nothing
108
        }
109

    
110
        public IZoomConstraints getZoomConstraints() {
111
                return zoom;
112
        }
113

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

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

    
122
                SimpleTextSymbol sym = new SimpleTextSymbol();
123

    
124
                sym.setFont(getFont());
125

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

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

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

    
161
                                FeatureStore featureStore=layer.getFeatureStore();
162

    
163
                                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
164
                                fields.add(geomName);
165

    
166
                                FeatureQuery featureQuery=featureStore.createFeatureQuery();
167

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

    
173

    
174

    
175
                                set = featureStore
176
                                                .getFeatureSet(featureQuery);
177

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

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

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

    
215
                                        sym.setFontSize(size);
216

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

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

    
237
                                        sym.setTextColor(color);
238

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

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

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

    
271
                        }
272

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

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

    
293
        public String getClassName() {
294
                return getClass().getName();
295
        }
296

    
297
        public String getRotationField()  {
298
                return this.rotationFieldName;
299
        }
300

    
301
        public String getTextField()  {
302
                return this.textFieldName;
303
        }
304

    
305
        public String getHeightField() {
306
                return this.heightFieldName;
307
        }
308

    
309
        public String getColorField()  {
310
                return this.colorFieldName;
311
        }
312

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

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

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

    
334

    
335
        public void setColorField(String colorFieldName) {
336
                this.colorFieldName = colorFieldName;
337
        }
338

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

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

    
349
        public boolean usesFixedSize() {
350
                return useFixedSize;
351
        }
352

    
353
        public double getFixedSize() {
354
                return fixedSize;
355
        }
356

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

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

    
367
        public boolean usesFixedColor() {
368
                return useFixedColor;
369
        }
370

    
371
        public Color getFixedColor() {
372
                return fixedColor;
373
        }
374

    
375
        public void setFixedColor(Color fixedColor) {
376
                this.fixedColor = fixedColor;
377
        }
378

    
379

    
380
        public void setUnit(int unitIndex) {
381
                unit = unitIndex;
382

    
383
        }
384

    
385
        public int getUnit() {
386
                return unit;
387
        }
388

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

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

    
412
        public int getReferenceSystem() {
413
                return referenceSystem;
414
        }
415

    
416
        public void setReferenceSystem(int referenceSystem) {
417
                this.referenceSystem = referenceSystem;
418
        }
419

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

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

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

    
434
        }
435

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

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

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

    
477
        public void setColorFont(Color colorFont) {
478
                this.colorFont = colorFont;
479
        }
480

    
481
        public Font getFont() {
482
                return font;
483
        }
484

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

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

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

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

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