Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / rendering / styling / labeling / AttrInTableLabelingStrategy.java @ 25471

History | View | Annotate | Download (14.8 KB)

1
package com.iver.cit.gvsig.fmap.rendering.styling.labeling;
2

    
3
import java.awt.Color;
4
import java.awt.Font;
5
import java.awt.Graphics2D;
6
import java.awt.geom.Rectangle2D;
7
import java.awt.image.BufferedImage;
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.cresques.cts.ICoordTrans;
16

    
17
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
18
import com.hardcode.gdbms.engine.values.NullValue;
19
import com.hardcode.gdbms.engine.values.NumericValue;
20
import com.hardcode.gdbms.engine.values.Value;
21
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
22
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
23
import com.iver.cit.gvsig.fmap.MapContext;
24
import com.iver.cit.gvsig.fmap.ViewPort;
25
import com.iver.cit.gvsig.fmap.core.CartographicSupport;
26
import com.iver.cit.gvsig.fmap.core.CartographicSupportToolkit;
27
import com.iver.cit.gvsig.fmap.core.FPoint2D;
28
import com.iver.cit.gvsig.fmap.core.FShape;
29
import com.iver.cit.gvsig.fmap.core.IGeometry;
30
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
31
import com.iver.cit.gvsig.fmap.core.symbols.SimpleTextSymbol;
32
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
33
import com.iver.cit.gvsig.fmap.core.v02.FLabel;
34
import com.iver.cit.gvsig.fmap.layers.FBitSet;
35
import com.iver.cit.gvsig.fmap.layers.FLayer;
36
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
37
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
38
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
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

    
51
        public static final double MIN_TEXT_SIZE = 3;
52
        private ILabelingMethod method = new DefaultLabelingMethod();
53
        private IZoomConstraints zoom;
54
        private int idTextField;
55
        private int idHeightField;
56
        private int idRotationField;
57
        private int idColorField;
58
        private FLyrVect layer;
59
//        private double unitFactor = 1D;
60
        private double fixedSize;
61
        private Color fixedColor;
62
        private int unit = -1; //(pixel)
63
        private boolean useFixedSize;
64
        private boolean useFixedColor;
65
        private int referenceSystem;
66
        private boolean isPrinting;
67
        private double  printDPI;
68
        private Font font;
69
        private Color colorFont;
70

    
71
        public ILabelingMethod getLabelingMethod() {
72
                return this.method;
73
        }
74

    
75
        public void setLabelingMethod(ILabelingMethod method) {
76
                this.method = method;
77
        }
78

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

    
83
        public void setPlacementConstraints(IPlacementConstraints constraints) {
84
                // nothing
85
        }
86

    
87
        public IZoomConstraints getZoomConstraints() {
88
                return zoom;
89
        }
90

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

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

    
100

    
101
                SimpleTextSymbol sym = new SimpleTextSymbol();
102

    
103
                sym.setFont(getFont());
104

    
105
                sym.setUnit(unit);
106
                sym.setReferenceSystem(referenceSystem);
107

    
108
                if (zoom==null ||
109
                        ( zoom.isUserDefined() && (scale >= zoom.getMaxScale())
110
                        && (scale <= zoom.getMinScale()) ) ) {
111
                        try {
112
                                // limit the labeling to the visible extent
113
                                FBitSet bs = layer.queryByRect(viewPort.getAdjustedExtent());
114

    
115
                                ReadableVectorial source = layer.getSource();
116
                                SelectableDataSource recordSet = source.getRecordset();
117

    
118
                                for(int i=bs.nextSetBit(0); i>=0 && !cancel.isCanceled(); i=bs.nextSetBit(i+1)) {
119
                                        Value[] vv = recordSet.getRow(i);
120
                                        double size;
121
                                        Color color = null;
122
                                        if (useFixedSize){
123
                                                // uses fixed size
124
                                                size = fixedSize * fontScaleFactor;
125
                                        } else if (idHeightField != -1) {
126
                                                // text size is defined in the table
127
                                                try {
128
                                                        size = ((NumericValue) vv[idHeightField]).doubleValue() * fontScaleFactor;
129
                                                } catch (ClassCastException ccEx) {
130
                                                        if (!NullValue.class.equals(vv[idHeightField].getClass())) {
131
                                                                throw new ReadDriverException("Unknown", ccEx);
132
                                                        }
133
                                                        // a null value
134
                                                        Logger.getAnonymousLogger().
135
                                                                warning("Null text height value for text '"+vv[idTextField].toString()+"'");
136
                                                        continue;
137
                                                }
138
                                        } else {
139
                                                // otherwise will use the size in the symbol
140
                                                size = sym.getFont().getSize();
141
                                        }
142

    
143
                                        size = CartographicSupportToolkit.
144
                                                                getCartographicLength(this,
145
                                                                                                          size,
146
                                                                                                          viewPort,
147
                                                                                                          MapContext.getScreenDPI());
148
//                                                                                                          dpi);
149
//                                                                toScreenUnitYAxis(this,
150
//                                                                                                  size,
151
//                                                                                                  viewPort
152
//                                                                                                 );
153

    
154
                                        if (size <= MIN_TEXT_SIZE) {
155
                                                // label is too small to be readable, will be skipped
156
                                                // this speeds up the rendering in wider zooms
157
                                                continue;
158
                                        }
159

    
160
                                        sym.setFontSize(size);
161

    
162
                                        if (useFixedColor){
163
                                                color = fixedColor;
164
                                        } else if (idColorField != -1) {
165
                                                // text size is defined in the table
166
                                                try {
167
                                                        color = new Color(((NumericValue) vv[idColorField]).intValue());
168
                                                } catch (ClassCastException ccEx) {
169
                                                        if (!NullValue.class.equals(vv[idColorField].getClass())) {
170
                                                                throw new ReadDriverException("Unknown", ccEx);
171
                                                        }
172
                                                        // a null value
173
                                                        Logger.getAnonymousLogger().
174
                                                                warning("Null color value for text '"+vv[idTextField].toString()+"'");
175
                                                        continue;
176
                                                }
177
                                        } else {
178
                                                color = sym.getTextColor();
179
                                        }
180

    
181
                                        sym.setTextColor(color);
182

    
183
                                        double rotation = 0D;
184
                                        if (idRotationField!= -1) {
185
                                                // text rotation is defined in the table
186
                                                rotation = -Math.toRadians(((NumericValue) vv[idRotationField]).doubleValue());
187
                                        }
188

    
189
                                        IGeometry geom = source.getShape(i);
190
                                        if (layer.getCoordTrans()!=null){
191
                                                geom.reProject(layer.getCoordTrans());
192
                                        }
193
                                        sym.setText(vv[idTextField].toString());
194
                                        sym.setRotation(rotation);
195

    
196
                                        FLabel[] aux = geom.createLabels(0, true);
197
                                        for (int j = 0; j < aux.length; j++) {
198
                                                FPoint2D p = new FPoint2D(aux[j].getOrig());
199
                                                p.transform(viewPort.getAffineTransform());
200
                                                sym.draw(g, null, p, cancel);
201
                                        }
202

    
203

    
204
                                }
205
                        } catch (VisitorException e) {
206
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not get the layer extent.\n" +
207
                                                e.getMessage());
208
                        } catch (ExpansionFileReadException e) {
209
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer" +
210
                                                "\""+layer.getName()+"\".\nIs the layer being edited?.\n"+e.getMessage());
211
                        } catch (ReadDriverException e) {
212
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer.\n" +
213
                                                e.getMessage());
214
                        }
215

    
216
                }
217
        }
218

    
219
        public String getClassName() {
220
                return getClass().getName();
221
        }
222

    
223
        public XMLEntity getXMLEntity() {
224
                XMLEntity xml = new XMLEntity();
225
                xml.putProperty("className", getClassName());
226
                xml.putProperty("labelingStrategy", "labelingStrategy");
227

    
228
                try {
229
                        if(getHeightField() != null)
230
                                xml.putProperty("HeightField", getHeightField());
231
                } catch (ReadDriverException e) {
232
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextHeight field.\n"+e.getMessage());
233
                }
234

    
235
                try {
236
                        if(getColorField() != null)
237
                                xml.putProperty("ColorField", getColorField());
238
                } catch (ReadDriverException e) {
239
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing ColorField field.\n"+e.getMessage());
240
                }
241

    
242
                try {
243
                        if(getTextField() != null)
244
                                xml.putProperty("TextField", getTextField());
245
                } catch (ReadDriverException e) {
246
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextField field.\n"+e.getMessage());
247
                }
248

    
249
                try {
250
                        if (getRotationField() != null)
251
                                xml.putProperty("RotationField", getRotationField());
252
                } catch (ReadDriverException e) {
253
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing RotationField field.\n"+e.getMessage());
254
                }
255

    
256
                if(getFont() != null)
257
                        xml.putProperty("Font", getFont());
258
                if(getColorFont() != null)
259
                        xml.putProperty("Color", getColorFont());
260

    
261
                xml.putProperty("Unit", unit);
262
                return xml;
263

    
264
        }
265

    
266
        public String getRotationField() throws ReadDriverException {
267
                if (idRotationField == -1) return null;
268
                return ((SelectableDataSource) layer.getRecordset())
269
                                .getFieldName(idRotationField);
270
        }
271

    
272
        public int getRotationFieldId() {
273
                return idRotationField;
274
        }
275

    
276
        public void setRotationFieldId(int fieldId) {
277
                this.idRotationField = fieldId;
278
        }
279

    
280
        public String getTextField() throws ReadDriverException {
281
                if (idTextField == -1) return null;
282
                return ((SelectableDataSource) layer.getRecordset())
283
                                .getFieldName(idTextField);
284
        }
285

    
286
        public int getTextFieldId() {
287
                return idTextField;
288
        }
289

    
290
        public void setTextFieldId(int fieldId) {
291
                this.idTextField = fieldId;
292
        }
293

    
294
        public String getHeightField() throws ReadDriverException {
295
                if (idHeightField == -1) return null;
296
                return ((SelectableDataSource) layer.getRecordset())
297
                                .getFieldName(idHeightField);
298
        }
299

    
300
        public int getHeightFieldId() {
301
                return idHeightField;
302
        }
303

    
304
        public void setHeightFieldId(int fieldId) {
305
                this.idHeightField = fieldId;
306
        }
307

    
308
        public String getColorField() throws ReadDriverException {
309
                if (idColorField == -1) return null;
310
                return ((SelectableDataSource) layer.getRecordset())
311
                                .getFieldName(idColorField);
312
        }
313

    
314
        public int getColorFieldId() {
315
                return idColorField;
316
        }
317

    
318
        public void setColorFieldId(int fieldId) {
319
                this.idColorField = fieldId;
320
        }
321

    
322

    
323
        public void setXMLEntity(XMLEntity xml) {
324
                if (xml.contains("TextField" ))
325
                        setTextField(xml.getStringProperty("TextField"));
326

    
327
                if (xml.contains("HeightField"))
328
                        setHeightField("HeightField");
329

    
330
                if (xml.contains("ColorField"))
331
                        setHeightField("ColorField");
332

    
333
                if (xml.contains("RotationField"))
334
                        setRotationField("RotationField");
335

    
336
                if (xml.contains("UnitFactor"))
337
                        setUnit(xml.getIntProperty("Unit"));
338

    
339
                if (xml.contains("Font"))
340
                        setUnit(xml.getIntProperty("Font"));
341

    
342
                if (xml.contains("Color"))
343
                        setUnit(xml.getIntProperty("Color"));
344
        }
345

    
346
        public void setTextField(String textFieldName) {
347
                try {
348
                        idTextField = ((SelectableDataSource) layer.getRecordset())
349
                                                                .getFieldIndexByName(textFieldName);
350
                } catch (ReadDriverException e) {
351
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
352
                }
353
        }
354

    
355
        public void setRotationField(String rotationFieldName) {
356
                if (rotationFieldName != null) {
357
                        try {
358
                                idRotationField = ((SelectableDataSource) layer.getRecordset())
359
                                        .getFieldIndexByName(rotationFieldName);
360
                        } catch (ReadDriverException e) {
361
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
362
                        }
363
                } else idRotationField = -1;
364
        }
365

    
366
        /**
367
         * Sets the field that contains the size of the text. The size is computed
368
         * in meters. To use any other unit, call setUnit(int) with the scale factor from meters
369
         * (for centimeters, call <b>setUnitFactor(0.01))</b>.
370
         * @param heightFieldName
371
         */
372
        public void setHeightField(String heightFieldName) {
373
                if (heightFieldName != null) {
374
                        try {
375
                                idHeightField = ((SelectableDataSource) layer.getRecordset())
376
                                .getFieldIndexByName(heightFieldName);
377
                        } catch (ReadDriverException e) {
378
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
379
                        }
380
                } else idHeightField = -1;
381
        }
382

    
383

    
384
        public void setColorField(String colorFieldName) {
385
                if (colorFieldName != null) {
386
                        try {
387
                                idColorField = ((SelectableDataSource) layer.getRecordset())
388
                                .getFieldIndexByName(colorFieldName);
389
                        } catch (ReadDriverException e) {
390
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
391
                        }
392
                } else idColorField = -1;
393
        }
394

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

    
409
        public void setUsesFixedSize(boolean b) {
410
                useFixedSize = b;
411
        }
412

    
413
        public boolean usesFixedSize() {
414
                return useFixedSize;
415
        }
416

    
417
        public double getFixedSize() {
418
                return fixedSize;
419
        }
420

    
421
        public void setFixedSize(double fixedSize) {
422
                this.fixedSize = fixedSize;
423
        }
424

    
425
        public void setUsesFixedColor(boolean b) {
426
                useFixedColor = b;
427
        }
428

    
429
        public boolean usesFixedColor() {
430
                return useFixedColor;
431
        }
432

    
433
        public Color getFixedColor() {
434
                return fixedColor;
435
        }
436

    
437
        public void setFixedColor(Color fixedColor) {
438
                this.fixedColor = fixedColor;
439
        }
440

    
441

    
442
        public void setUnit(int unitIndex) {
443
                unit = unitIndex;
444

    
445
        }
446

    
447
        public int getUnit() {
448
                return unit;
449
        }
450

    
451
        public String[] getUsedFields() {
452
                Vector v = new Vector();
453
                try {
454
                        if (getHeightField()!=null) v.add(getHeightField());
455
                        if (getRotationField()!=null) v.add(getRotationField());
456
                        if (getTextField()!=null) v.add(getTextField());
457
                        if (getHeightField()!=null) v.add(getHeightField());
458
                } catch (ReadDriverException e) {
459
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
460
                }
461
                return (String[]) v.toArray(new String[v.size()]);
462
        }
463

    
464
        public int getReferenceSystem() {
465
                return referenceSystem;
466
        }
467

    
468
        public void setReferenceSystem(int referenceSystem) {
469
                this.referenceSystem = referenceSystem;
470
        }
471

    
472
        public double toCartographicSize(ViewPort viewPort, double dpi, FShape shp) {
473
                // not required here
474
                throw new Error("Undefined in this context");
475
        }
476

    
477
        public void setCartographicSize(double cartographicSize, FShape shp) {
478
                // not required here
479
                throw new Error("Undefined in this context");
480
        }
481

    
482
        public double getCartographicSize(ViewPort viewPort, double dpi, FShape shp) {
483
                // not required here
484
                throw new Error("Undefined in this context");
485

    
486
        }
487

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

    
492
        public boolean shouldDrawLabels(double scale) {
493
                return layer.isWithinScale(scale);
494
        }
495

    
496
        public Color getColorFont() {
497
                return colorFont;
498
        }
499

    
500
        public void setColorFont(Color colorFont) {
501
                this.colorFont = colorFont;
502
        }
503

    
504
        public Font getFont() {
505
                if(font == null)
506
                        font = SymbologyFactory.DefaultTextFont;
507
                return font;
508
        }
509

    
510
        public void setFont(Font selFont) {
511
                this.font = selFont;
512
        }
513
}