Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / rendering / legend / styling / AttrInTableLabelingStrategy.java @ 23303

History | View | Annotate | Download (14.2 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.data.ReadException;
16
import org.gvsig.fmap.data.feature.Feature;
17
import org.gvsig.fmap.data.feature.FeatureCollection;
18
import org.gvsig.fmap.data.feature.FeatureType;
19
import org.gvsig.fmap.geom.Geometry;
20
import org.gvsig.fmap.geom.operation.CreateLabels;
21
import org.gvsig.fmap.geom.operation.CreateLabelsOperationContext;
22
import org.gvsig.fmap.geom.operation.GeometryOperationException;
23
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
24
import org.gvsig.fmap.geom.primitive.Envelope;
25
import org.gvsig.fmap.geom.primitive.Point2D;
26
import org.gvsig.fmap.geom.utils.FConstant;
27
import org.gvsig.fmap.geom.utils.FLabel;
28
import org.gvsig.fmap.mapcontext.MapContext;
29
import org.gvsig.fmap.mapcontext.ViewPort;
30
import org.gvsig.fmap.mapcontext.layers.FLayer;
31
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
32
import org.gvsig.fmap.mapcontext.rendering.legend.NullValue;
33
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
34
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupportToolkit;
35
import org.gvsig.fmap.mapcontext.rendering.symbols.SimpleTextSymbol;
36
import org.gvsig.tools.exception.BaseException;
37

    
38
import com.iver.utiles.StringUtilities;
39
import com.iver.utiles.XMLEntity;
40
import com.iver.utiles.swing.threads.Cancellable;
41

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

    
68
        public ILabelingMethod getLabelingMethod() {
69
                return this.method;
70
        }
71

    
72
        public void setLabelingMethod(ILabelingMethod method) {
73
                this.method = method;
74
        }
75

    
76
        public IPlacementConstraints getPlacementConstraints() {
77
                return null; // (automatically handled by the driver)
78
        }
79

    
80
        public void setPlacementConstraints(IPlacementConstraints constraints) {
81
                // nothing
82
        }
83

    
84
        public IZoomConstraints getZoomConstraints() {
85
                return zoom;
86
        }
87

    
88
        public void setZoomConstraints(IZoomConstraints constraints) {
89
                this.zoom = constraints;
90
        }
91

    
92
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort, Cancellable cancel, double dpi)
93
        throws ReadException {
94
                double scale = viewPort.getScale();
95
                double fontScaleFactor = FConstant.FONT_HEIGHT_SCALE_FACTOR;
96

    
97
                SimpleTextSymbol sym = new SimpleTextSymbol();
98

    
99
                sym.setFont(getFont());
100
                sym.setTextColor(getColorFont());
101

    
102
                sym.setUnit(unit);
103
                sym.setReferenceSystem(referenceSystem);
104
                if (zoom==null ||
105
                        ( zoom.isUserDefined() && (scale >= zoom.getMaxScale())
106
                        && (scale <= zoom.getMinScale()) ) ) {
107
                        FeatureCollection collection = null;
108
                        try {
109
                                // limit the labeling to the visible extent
110
//                                FBitSet bs = layer.queryByRect(viewPort.getAdjustedExtent());
111

    
112
                            String featureFilter = null;
113
                            String[] fields = this.getUsedFields();
114

    
115
                            if (!viewPort.getAdjustedExtent().contains(
116
                                                (Envelope) layer.getFeatureStore().getMetadata().get(
117
                                                                "extent"))) {
118
                                        featureFilter=layer.getDataStoreFilterForGeomerty(
119
                                                viewPort.getAdjustedExtent().getGeometry(),
120
                                                layer.getFeatureStore().getDefaultFeatureType().getDefaultGeometry(),
121
                                                null);
122
                            }
123
                                        String[] oldFields = fields;
124
                                        fields = new String[oldFields.length + 1];
125
                                        fields[0] = layer.getFeatureStore().getDefaultFeatureType()
126
                                                        .getDefaultGeometry();
127
                                        System.arraycopy(oldFields, 0, fields, 1, oldFields.length);
128

    
129

    
130

    
131
                                collection = (FeatureCollection) layer.getFeatureStore()
132
                                                .getDataCollection(
133
                                                fields,
134
                                                featureFilter,
135
                                                null
136
                                                );
137

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

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

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

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

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

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

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

    
232
                        }
233

    
234
                }
235
        }
236

    
237
        public String getClassName() {
238
                return getClass().getName();
239
        }
240

    
241
        public XMLEntity getXMLEntity() {
242
                XMLEntity xml = new XMLEntity();
243
                xml.putProperty("className", getClassName());
244

    
245
                try {
246
                        xml.putProperty("HeightField", getHeightField());
247
                } catch (ReadException e) {
248
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextHeight field.\n"+e.getMessage());
249
                }
250

    
251
                try {
252
                        xml.putProperty("TextField", getTextField());
253
                } catch (ReadException e) {
254
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextField field.\n"+e.getMessage());
255
                }
256

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

    
268
                if (getColorFont() != null) {
269
                        xml.putProperty("color", StringUtilities
270
                                        .color2String(getColorFont()));
271
                }
272
                xml.putProperty("Unit", unit);
273

    
274
                return xml;
275

    
276
        }
277

    
278
        public String getRotationField() throws ReadException {
279
                if (idRotationField == -1) {
280
                        return null;
281
                }
282
                return ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getByOrder(idRotationField).getName();
283
        }
284

    
285
        public int getRotationFieldId() {
286
                return idRotationField;
287
        }
288

    
289
        public void setRotationFieldId(int fieldId) {
290
                this.idRotationField = fieldId;
291
                this.usedFields = null;
292
        }
293

    
294
        public String getTextField() throws ReadException {
295
                if (idTextField == -1) {
296
                        return null;
297
                }
298
                return ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getByOrder(idTextField).getName();
299
        }
300

    
301
        public int getTextFieldId() {
302
                return idTextField;
303
        }
304

    
305
        public void setTextFieldId(int fieldId) {
306
                this.idTextField = fieldId;
307
                this.usedFields = null;
308
        }
309

    
310
        public String getHeightField() throws ReadException {
311
                if (idHeightField == -1) {
312
                        return null;
313
                }
314
                return ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getByOrder(idHeightField).getName();
315
        }
316

    
317
        public int getHeightFieldId() {
318
                return idHeightField;
319
        }
320

    
321
        public void setHeightFieldId(int fieldId) {
322
                this.idHeightField = fieldId;
323
                this.usedFields = null;
324
        }
325

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

    
332
                if (xml.contains("HeightField")) {
333
                        setHeightField("HeightField");
334
                }
335

    
336
                if (xml.contains("RotationField")) {
337
                        setRotationField("RotationField");
338
                }
339

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

    
350
                if (xml.contains("color")) {
351
                        Color newColor = StringUtilities.string2Color(xml
352
                                        .getStringProperty("color"));
353
                        setColorFont(newColor);
354
                }
355
        }
356

    
357
        public void setTextField(String textFieldName) {
358
                try {
359
                        idTextField = ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getFieldIndex(textFieldName);
360
                        this.usedFields = null;
361
                } catch (ReadException e) {
362
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
363
                }
364
        }
365

    
366
        public void setRotationField(String rotationFieldName) {
367
                if (rotationFieldName != null) {
368
                        try {
369
                                idRotationField = ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getFieldIndex(rotationFieldName);
370
                        } catch (ReadException e) {
371
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
372
                        }
373
                } else {
374
                        idRotationField = -1;
375
                }
376
                this.usedFields = null;
377
        }
378

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

    
398

    
399
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintRequestAttributeSet properties) throws ReadException {
400
                isPrinting = true;
401
                PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
402
                if (resolution.equals(PrintQuality.NORMAL)){
403
                        printDPI=300;
404
                } else if (resolution.equals(PrintQuality.HIGH)) {
405
                        printDPI=600;
406
                } else if (resolution.equals(PrintQuality.DRAFT)) {
407
                        printDPI=72;
408
                }
409
                draw(null, g, viewPort, cancel, printDPI);
410
                isPrinting = false;
411
        }
412

    
413
        public void setUsesFixedSize(boolean b) {
414
                useFixedSize = b;
415
                this.usedFields = null;
416
        }
417

    
418
        public boolean usesFixedSize() {
419
                return useFixedSize;
420
        }
421

    
422
        public double getFixedSize() {
423
                return fixedSize;
424
        }
425

    
426
        public void setFixedSize(double fixedSize) {
427
                this.fixedSize = fixedSize;
428
        }
429

    
430
        public void setUnit(int unitIndex) {
431
                unit = unitIndex;
432

    
433
        }
434

    
435
        public int getUnit() {
436
                return unit;
437
        }
438

    
439
        public String[] getUsedFields() {
440
                if (this.usedFields == null) {
441
                        Vector v = new Vector();
442
                        try {
443
                                if (!this.usesFixedSize()) {
444
                                        if (getHeightField() != null) {
445
                                                v.add(getHeightField());
446
                                        }
447
                                }
448
                                if (getRotationField() != null) {
449
                                        v.add(getRotationField());
450
                                }
451
                                if (getTextField() != null) {
452
                                        v.add(getTextField());
453
                                }
454
                        } catch (ReadException e) {
455
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
456
                        }
457
                        this.usedFields = (String[]) v.toArray(new String[v.size()]);
458
                }
459
                return this.usedFields;
460
        }
461

    
462
        public int getReferenceSystem() {
463
                return referenceSystem;
464
        }
465

    
466
        public void setReferenceSystem(int referenceSystem) {
467
                this.referenceSystem = referenceSystem;
468
        }
469

    
470
        public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
471
                // not required here
472
                throw new Error("Undefined in this context");
473
        }
474

    
475
        public void setCartographicSize(double cartographicSize, Geometry geom) {
476
                // not required here
477
                throw new Error("Undefined in this context");
478
        }
479

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

    
484
        }
485

    
486
        public void setLayer(FLayer layer) {
487
                this.layer = (FLyrVect) layer;
488
        }
489

    
490
        public boolean shouldDrawLabels(double scale) {
491
                return layer.isWithinScale(scale);
492
        }
493
        public Color getColorFont() {
494
                return colorFont;
495
        }
496

    
497
        public void setColorFont(Color colorFont) {
498
                this.colorFont = colorFont;
499
        }
500

    
501
        public Font getFont() {
502
                return font;
503
        }
504

    
505
        public void setFont(Font selFont) {
506
                this.font = selFont;
507
        }
508
}