Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / rendering / legend / styling / AttrInTableLabelingStrategy.java @ 24711

History | View | Annotate | Download (15 KB)

1
package org.gvsig.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.Iterator;
8
import java.util.Vector;
9
import java.util.logging.Level;
10
import java.util.logging.Logger;
11

    
12
import javax.print.attribute.PrintRequestAttributeSet;
13
import javax.print.attribute.standard.PrintQuality;
14

    
15
import org.gvsig.fmap.dal.exception.DataException;
16
import org.gvsig.fmap.dal.exception.ReadException;
17
import org.gvsig.fmap.dal.feature.Feature;
18
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
19
import org.gvsig.fmap.dal.feature.FeatureQuery;
20
import org.gvsig.fmap.dal.feature.FeatureSet;
21
import org.gvsig.fmap.dal.feature.FeatureStore;
22
import org.gvsig.fmap.dal.feature.FeatureType;
23
import org.gvsig.fmap.geom.Geometry;
24
import org.gvsig.fmap.geom.operation.CreateLabels;
25
import org.gvsig.fmap.geom.operation.CreateLabelsOperationContext;
26
import org.gvsig.fmap.geom.operation.GeometryOperationException;
27
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
28
import org.gvsig.fmap.geom.primitive.Envelope;
29
import org.gvsig.fmap.geom.primitive.Point2D;
30
import org.gvsig.fmap.geom.utils.FConstant;
31
import org.gvsig.fmap.geom.utils.FLabel;
32
import org.gvsig.fmap.mapcontext.MapContext;
33
import org.gvsig.fmap.mapcontext.ViewPort;
34
import org.gvsig.fmap.mapcontext.layers.FLayer;
35
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
36
import org.gvsig.fmap.mapcontext.rendering.legend.NullValue;
37
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
38
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupportToolkit;
39
import org.gvsig.fmap.mapcontext.rendering.symbols.SimpleTextSymbol;
40
import org.gvsig.tools.evaluator.sqljep.SQLJEPEvaluator;
41
import org.gvsig.tools.exception.BaseException;
42

    
43
import com.iver.utiles.StringUtilities;
44
import com.iver.utiles.XMLEntity;
45
import com.iver.utiles.swing.threads.Cancellable;
46

    
47
/**
48
 * LabelingStrategy used when the user wants to use label sizes, rotations, etc. from
49
 * the values included in fields of the datasource's table
50
 *
51
 * @author jaume dominguez faus - jaume.dominguez@iver.es
52
 *
53
 */
54
public class AttrInTableLabelingStrategy implements ILabelingStrategy, CartographicSupport {
55
        public static final double MIN_TEXT_SIZE = 3;
56
        private ILabelingMethod method = new DefaultLabelingMethod();
57
        private IZoomConstraints zoom;
58
        private int idTextField;
59
        private int idHeightField;
60
        private int idRotationField;
61
        private FLyrVect layer;
62
//        private double unitFactor = 1D;
63
        private double fixedSize;
64
        private int unit = -1; //(pixel)
65
        private boolean useFixedSize;
66
        private int referenceSystem;
67
        private boolean isPrinting;
68
        private double  printDPI;
69
        private String[] usedFields = null;
70
        private Font font;
71
        private Color colorFont;
72

    
73
        public ILabelingMethod getLabelingMethod() {
74
                return this.method;
75
        }
76

    
77
        public void setLabelingMethod(ILabelingMethod method) {
78
                this.method = method;
79
        }
80

    
81
        public IPlacementConstraints getPlacementConstraints() {
82
                return null; // (automatically handled by the driver)
83
        }
84

    
85
        public void setPlacementConstraints(IPlacementConstraints constraints) {
86
                // nothing
87
        }
88

    
89
        public IZoomConstraints getZoomConstraints() {
90
                return zoom;
91
        }
92

    
93
        public void setZoomConstraints(IZoomConstraints constraints) {
94
                this.zoom = constraints;
95
        }
96

    
97
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort, Cancellable cancel, double dpi)
98
        throws ReadException {
99
                double scale = viewPort.getScale();
100
                double fontScaleFactor = FConstant.FONT_HEIGHT_SCALE_FACTOR;
101

    
102
                SimpleTextSymbol sym = new SimpleTextSymbol();
103

    
104
                sym.setFont(getFont());
105
                sym.setTextColor(getColorFont());
106

    
107
                sym.setUnit(unit);
108
                sym.setReferenceSystem(referenceSystem);
109
                if (zoom==null ||
110
                        ( zoom.isUserDefined() && (scale >= zoom.getMaxScale())
111
                        && (scale <= zoom.getMinScale()) ) ) {
112
                        FeatureSet collection = null;
113
                        try {
114
                                // limit the labeling to the visible extent
115
//                                FBitSet bs = layer.queryByRect(viewPort.getAdjustedExtent());
116

    
117
                            String featureFilter = null;
118
                            String[] fields = this.getUsedFields();
119
                            FeatureStore featureStore=layer.getFeatureStore();
120
                            if (!viewPort.getAdjustedExtent().contains(
121
                                                (Envelope) featureStore.getMetadata().get(
122
                                                                "extent"))) {
123
                                        featureFilter=layer.getDataStoreFilterForGeomerty(
124
                                                viewPort.getAdjustedExtent().getGeometry(),
125
                                                layer.getFeatureStore().getDefaultFeatureType().getDefaultGeometryAttributeName(),
126
                                                null);
127
                            }
128
                                        String[] oldFields = fields;
129
                                        fields = new String[oldFields.length + 1];
130
                                        fields[0] = featureStore.getDefaultFeatureType()
131
                                                        .getDefaultGeometryAttributeName();
132
                                        System.arraycopy(oldFields, 0, fields, 1, oldFields.length);
133

    
134
                                        FeatureQuery featureQuery=featureStore.createFeatureQuery();
135
                                        featureQuery.setAttributeNames(fields);
136
                                        ??featureQuery.setFilter(new SQLJEPEvaluator(featureFilter));
137

    
138
                                collection = (FeatureSet)featureStore
139
                                                .getFeatureSet(featureQuery);
140

    
141
//                                ReadableVectorial source = layer.getSource();
142
//                                SelectableDataSource recordSet = source.getRecordset();
143
                                Iterator iterator=collection.iterator();
144
                                CreateLabelsOperationContext cloc=new CreateLabelsOperationContext();
145
                                cloc.setDublicates(true);
146
                                cloc.setPosition(0);
147
                                while(iterator.hasNext()){
148
                                        if (cancel.isCanceled()){
149
                                                return;
150
                                        }
151
                                        Feature feature=(Feature)iterator.next();
152
//                                for(int i=bs.nextSetBit(0); i>=0 && !cancel.isCanceled(); i=bs.nextSetBit(i+1)) {
153
//                                        Value[] vv = recordSet.getRow(i);
154
                                        double size;
155

    
156
                                        if (useFixedSize){
157
                                                // uses fixed size
158
                                                size = fixedSize * fontScaleFactor;
159
                                        } else if (idHeightField != -1) {
160
                                                // text size is defined in the table
161
                                                try {
162
                                                        Object obj=feature.get(idHeightField);
163
                                                        if (obj!=null) {
164
                                                                size = ((Number) obj).doubleValue() * fontScaleFactor;
165
                                                        } else {
166
                                                                size=0;
167
                                                        }
168
                                                } catch (ClassCastException ccEx) {
169
                                                        if (!NullValue.class.equals(feature.get(idHeightField).getClass())) {
170
                                                                throw new ReadException("Unknown", ccEx);
171
                                                        }
172
                                                        // a null value
173
                                                        Logger.getAnonymousLogger().
174
                                                                warning("Null text height value for text '"+feature.get(idTextField).toString()+"'");
175
                                                        continue;
176
                                                }
177
                                        } else {
178
                                                // otherwise will use the size in the symbol
179
                                                size = sym.getFont().getSize();
180
                                        }
181

    
182
                                        size = CartographicSupportToolkit.
183
                                                                getCartographicLength(this,
184
                                                                                                          size,
185
                                                                                                          viewPort,
186
                                                                                                          MapContext.getScreenDPI());
187
//                                                                                                          dpi);
188
//                                                                toScreenUnitYAxis(this,
189
//                                                                                                  size,
190
//                                                                                                  viewPort
191
//                                                                                                 );
192

    
193
                                        if (size <= MIN_TEXT_SIZE) {
194
                                                // label is too small to be readable, will be skipped
195
                                                // this speeds up the rendering in wider zooms
196
                                                continue;
197
                                        }
198

    
199
                                        sym.setFontSize(size);
200
                                        double rotation = 0D;
201
                                        if (idRotationField!= -1) {
202
                                                // text rotation is defined in the table
203
                                                rotation = -Math.toRadians(((Number) feature.get(idRotationField)).doubleValue());
204
                                        }
205

    
206
                                        Geometry geom = (Geometry)feature.getDefaultGeometry();
207
                                        Object obj=feature.get(idTextField);
208
                                        if (obj!=null) {
209
                                                sym.setText(obj.toString());
210
                                        }
211
                                        sym.setRotation(rotation);
212

    
213
                                        FLabel[] aux =(FLabel[])geom.invokeOperation(CreateLabels.CODE,cloc);
214
//                                        FLabel[] aux = geom.createLabels(0, true);
215
                                        for (int j = 0; j < aux.length; j++) {
216
                                                Point2D p = new Point2D(aux[j].getOrig());
217
                                                p.transform(viewPort.getAffineTransform());
218
                                                sym.draw(g, null, p, cancel);
219
                                        }
220
                                }
221
                        } catch (GeometryOperationNotSupportedException e) {
222
                                throw new ReadException(
223
                                                "Could not draw annotation in the layer.", e);
224
                        } catch (GeometryOperationException e) {
225
                                throw new ReadException(
226
                                                "Could not draw annotation in the layer.", e);
227
                        } catch (BaseException e) {
228
                                throw new ReadException(
229
                                                "Could not draw annotation in the layer.", e);
230
                        } finally {
231
                                if (collection != null) {
232
                                        collection.dispose();
233
                                }
234

    
235
                        }
236

    
237
                }
238
        }
239

    
240
        public String getClassName() {
241
                return getClass().getName();
242
        }
243

    
244
        public XMLEntity getXMLEntity() {
245
                XMLEntity xml = new XMLEntity();
246
                xml.putProperty("className", getClassName());
247

    
248
                try {
249
                        xml.putProperty("HeightField", getHeightField());
250
                } catch (DataException e) {
251
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextHeight field.\n"+e.getMessage());
252
                }
253

    
254
                try {
255
                        xml.putProperty("TextField", getTextField());
256
                } catch (DataException e) {
257
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextField field.\n"+e.getMessage());
258
                }
259

    
260
                try {
261
                        xml.putProperty("RotationField", getRotationField());
262
                } catch (DataException e) {
263
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing RotationField field.\n"+e.getMessage());
264
                }
265
                if (getFont() != null) {
266
                        xml.putProperty("fontName", getFont().getFontName());
267
                        xml.putProperty("fontStyle", getFont().getStyle());
268
                        xml.putProperty("fontSize", getFont().getFontName());
269
                }
270

    
271
                if (getColorFont() != null) {
272
                        xml.putProperty("color", StringUtilities
273
                                        .color2String(getColorFont()));
274
                }
275
                xml.putProperty("Unit", unit);
276

    
277
                return xml;
278

    
279
        }
280

    
281
        public String getRotationField() throws DataException {
282
                if (idRotationField == -1) {
283
                        return null;
284
                }
285
                return ((FeatureAttributeDescriptor)((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).get(idRotationField)).getName();
286
        }
287

    
288
        public int getRotationFieldId() {
289
                return idRotationField;
290
        }
291

    
292
        public void setRotationFieldId(int fieldId) {
293
                this.idRotationField = fieldId;
294
                this.usedFields = null;
295
        }
296

    
297
        public String getTextField() throws DataException {
298
                if (idTextField == -1) {
299
                        return null;
300
                }
301
                return ((FeatureAttributeDescriptor)((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).get(idTextField)).getName();
302
        }
303

    
304
        public int getTextFieldId() {
305
                return idTextField;
306
        }
307

    
308
        public void setTextFieldId(int fieldId) {
309
                this.idTextField = fieldId;
310
                this.usedFields = null;
311
        }
312

    
313
        public String getHeightField() throws DataException {
314
                if (idHeightField == -1) {
315
                        return null;
316
                }
317
                return ((FeatureAttributeDescriptor)((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).get(idHeightField)).getName();
318
        }
319

    
320
        public int getHeightFieldId() {
321
                return idHeightField;
322
        }
323

    
324
        public void setHeightFieldId(int fieldId) {
325
                this.idHeightField = fieldId;
326
                this.usedFields = null;
327
        }
328

    
329
        public void setXMLEntity(XMLEntity xml) {
330
                this.usedFields = null;
331
                if (xml.contains("TextField" )) {
332
                        setTextField(xml.getStringProperty("TextField"));
333
                }
334

    
335
                if (xml.contains("HeightField")) {
336
                        setHeightField("HeightField");
337
                }
338

    
339
                if (xml.contains("RotationField")) {
340
                        setRotationField("RotationField");
341
                }
342

    
343
                if (xml.contains("UnitFactor")) {
344
                        setUnit(xml.getIntProperty("Unit"));
345
                }
346
                if (xml.contains("fontName")) {
347
                        Font newFont = new Font(xml.getStringProperty("fontName"), xml
348
                                        .getIntProperty("fontStyle"), xml
349
                                        .getIntProperty("fontSize"));
350
                        setFont(newFont);
351
                }
352

    
353
                if (xml.contains("color")) {
354
                        Color newColor = StringUtilities.string2Color(xml
355
                                        .getStringProperty("color"));
356
                        setColorFont(newColor);
357
                }
358
        }
359

    
360
        public void setTextField(String textFieldName) {
361
                try {
362
                        idTextField = ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getIndex(textFieldName);
363
                        this.usedFields = null;
364
                } catch (ReadException e) {
365
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
366
                } catch (DataException e) {
367
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
368
                }
369
        }
370

    
371
        public void setRotationField(String rotationFieldName) {
372
                if (rotationFieldName != null) {
373
                        try {
374
                                idRotationField = ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getIndex(rotationFieldName);
375
                        } catch (ReadException e) {
376
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
377
                        } catch (DataException e) {
378
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
379
                        }
380
                } else {
381
                        idRotationField = -1;
382
                }
383
                this.usedFields = null;
384
        }
385

    
386
        /**
387
         * Sets the field that contains the size of the text. The size is computed
388
         * in meters. To use any other unit, call setUnit(int) with the scale factor from meters
389
         * (for centimeters, call <b>setUnitFactor(0.01))</b>.
390
         * @param heightFieldName
391
         */
392
        public void setHeightField(String heightFieldName) {
393
                if (heightFieldName != null) {
394
                        try {
395
                                idHeightField = ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getIndex(heightFieldName);
396
                        } catch (ReadException e) {
397
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
398
                        } catch (DataException e) {
399
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
400
                        }
401
                } else {
402
                        idHeightField = -1;
403
                }
404
                this.usedFields = null;
405
        }
406

    
407

    
408
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintRequestAttributeSet properties) throws ReadException {
409
                isPrinting = true;
410
                PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
411
                if (resolution.equals(PrintQuality.NORMAL)){
412
                        printDPI=300;
413
                } else if (resolution.equals(PrintQuality.HIGH)) {
414
                        printDPI=600;
415
                } else if (resolution.equals(PrintQuality.DRAFT)) {
416
                        printDPI=72;
417
                }
418
                draw(null, g, viewPort, cancel, printDPI);
419
                isPrinting = false;
420
        }
421

    
422
        public void setUsesFixedSize(boolean b) {
423
                useFixedSize = b;
424
                this.usedFields = null;
425
        }
426

    
427
        public boolean usesFixedSize() {
428
                return useFixedSize;
429
        }
430

    
431
        public double getFixedSize() {
432
                return fixedSize;
433
        }
434

    
435
        public void setFixedSize(double fixedSize) {
436
                this.fixedSize = fixedSize;
437
        }
438

    
439
        public void setUnit(int unitIndex) {
440
                unit = unitIndex;
441

    
442
        }
443

    
444
        public int getUnit() {
445
                return unit;
446
        }
447

    
448
        public String[] getUsedFields() {
449
                if (this.usedFields == null) {
450
                        Vector v = new Vector();
451
                        try {
452
                                if (!this.usesFixedSize()) {
453
                                        if (getHeightField() != null) {
454
                                                v.add(getHeightField());
455
                                        }
456
                                }
457
                                if (getRotationField() != null) {
458
                                        v.add(getRotationField());
459
                                }
460
                                if (getTextField() != null) {
461
                                        v.add(getTextField());
462
                                }
463
                        } catch (DataException e) {
464
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
465
                        }
466
                        this.usedFields = (String[]) v.toArray(new String[v.size()]);
467
                }
468
                return this.usedFields;
469
        }
470

    
471
        public int getReferenceSystem() {
472
                return referenceSystem;
473
        }
474

    
475
        public void setReferenceSystem(int referenceSystem) {
476
                this.referenceSystem = referenceSystem;
477
        }
478

    
479
        public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
480
                // not required here
481
                throw new Error("Undefined in this context");
482
        }
483

    
484
        public void setCartographicSize(double cartographicSize, Geometry geom) {
485
                // not required here
486
                throw new Error("Undefined in this context");
487
        }
488

    
489
        public double getCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
490
                // not required here
491
                throw new Error("Undefined in this context");
492

    
493
        }
494

    
495
        public void setLayer(FLayer layer) {
496
                this.layer = (FLyrVect) layer;
497
        }
498

    
499
        public boolean shouldDrawLabels(double scale) {
500
                return layer.isWithinScale(scale);
501
        }
502
        public Color getColorFont() {
503
                return colorFont;
504
        }
505

    
506
        public void setColorFont(Color colorFont) {
507
                this.colorFont = colorFont;
508
        }
509

    
510
        public Font getFont() {
511
                return font;
512
        }
513

    
514
        public void setFont(Font selFont) {
515
                this.font = selFont;
516
        }
517
}