Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / rendering / styling / labeling / AttrInTableLabelingStrategy.java @ 29957

History | View | Annotate | Download (15.5 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.StringUtilities;
40
import com.iver.utiles.XMLEntity;
41
import com.iver.utiles.swing.threads.Cancellable;
42

    
43
/**
44
 * LabelingStrategy used when the user wants to use label sizes, rotations, etc. from
45
 * the values included in fields of the datasource's table
46
 *
47
 * @author jaume dominguez faus - jaume.dominguez@iver.es
48
 *
49
 */
50
public class AttrInTableLabelingStrategy implements ILabelingStrategy, CartographicSupport {
51

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

    
76
        public ILabelingMethod getLabelingMethod() {
77
                return this.method;
78
        }
79

    
80
        public void setLabelingMethod(ILabelingMethod method) {
81
                this.method = method;
82
        }
83

    
84
        public IPlacementConstraints getPlacementConstraints() {
85
                return null; // (automatically handled by the driver)
86
        }
87

    
88
        public void setPlacementConstraints(IPlacementConstraints constraints) {
89
                // nothing
90
        }
91

    
92
        public IZoomConstraints getZoomConstraints() {
93
                return zoom;
94
        }
95

    
96
        public void setZoomConstraints(IZoomConstraints constraints) {
97
                this.zoom = constraints;
98
        }
99

    
100
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort, Cancellable cancel, double dpi)
101
        throws ReadDriverException {
102
                double scale = viewPort.getScale();
103
//                double fontScaleFactor = FConstant.FONT_HEIGHT_SCALE_FACTOR;
104

    
105

    
106
                SimpleTextSymbol sym = new SimpleTextSymbol();
107

    
108
                sym.setFont(getFont());
109

    
110
                sym.setUnit(unit);
111
                sym.setReferenceSystem(referenceSystem);
112

    
113
                if (zoom==null ||
114
                        ( zoom.isUserDefined() && (scale <= zoom.getMaxScale())
115
                        && (scale >= zoom.getMinScale()) ) ) {
116
                        try {
117
                                // limit the labeling to the visible extent
118
                                FBitSet bs = layer.queryByRect(viewPort.getAdjustedExtent());
119

    
120
                                ReadableVectorial source = layer.getSource();
121
                                SelectableDataSource recordSet = layer.getRecordset();
122

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

    
148
                                        size = CartographicSupportToolkit.
149
                                                                getCartographicLength(this,
150
                                                                                                          size,
151
                                                                                                          viewPort,
152
                                                                                                          MapContext.getScreenDPI());
153
//                                                                                                          dpi);
154
//                                                                toScreenUnitYAxis(this,
155
//                                                                                                  size,
156
//                                                                                                  viewPort
157
//                                                                                                 );
158

    
159
                                        if (size <= MIN_TEXT_SIZE) {
160
                                                // label is too small to be readable, will be skipped
161
                                                // this speeds up the rendering in wider zooms
162
                                                continue;
163
                                        }
164

    
165
                                        sym.setFontSize(size);
166

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

    
186
                                        sym.setTextColor(color);
187

    
188
                                        double rotation = 0D;
189
                                        if (idRotationField!= -1) {
190
                                                // text rotation is defined in the table
191
                                                rotation = -Math.toRadians(((NumericValue) vv[idRotationField]).doubleValue());
192
                                        }
193

    
194
                                        IGeometry geom = source.getShape(i);
195
                                        if (layer.getCoordTrans()!=null){
196
                                                geom.reProject(layer.getCoordTrans());
197
                                        }
198
                                        sym.setText(vv[idTextField].toString());
199
                                        sym.setRotation(rotation);
200

    
201
                                        FLabel[] aux = geom.createLabels(0, true);
202
                                        for (int j = 0; j < aux.length; j++) {
203
                                                FPoint2D p = new FPoint2D(aux[j].getOrig());
204
                                                p.transform(viewPort.getAffineTransform());
205
                                                if (properties==null)
206
                                                        sym.draw(g, null, p, cancel);
207
                                                else
208
                                                        sym.print(g, null, p, properties);
209
                                        }
210

    
211

    
212
                                }
213
                        } catch (VisitorException e) {
214
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not get the layer extent.\n" +
215
                                                e.getMessage());
216
                        } catch (ExpansionFileReadException e) {
217
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer" +
218
                                                "\""+layer.getName()+"\".\nIs the layer being edited?.\n"+e.getMessage());
219
                        } catch (ReadDriverException e) {
220
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer.\n" +
221
                                                e.getMessage());
222
                        }
223

    
224
                }
225
        }
226

    
227
        public String getClassName() {
228
                return getClass().getName();
229
        }
230

    
231
        public XMLEntity getXMLEntity() {
232
                XMLEntity xml = new XMLEntity();
233
                xml.putProperty("className", getClassName());
234
                xml.putProperty("labelingStrategy", "labelingStrategy");
235

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

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

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

    
257
                try {
258
                        if (getRotationField() != null)
259
                                xml.putProperty("RotationField", getRotationField());
260
                } catch (ReadDriverException e) {
261
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing RotationField field.\n"+e.getMessage());
262
                }
263

    
264
                if(getFont() != null){
265
                        xml.putProperty("fontSize", getFont().getSize());
266
                        xml.putProperty("fontName", getFont().getName());
267
                        xml.putProperty("fontStyle", getFont().getStyle());
268
                }
269
                if(getColorFont() != null)
270
                        xml.putProperty("Color", StringUtilities.color2String(getColorFont()));
271
                xml.putProperty("useFixedSize", useFixedSize);
272
                xml.putProperty("useFixedColor", useFixedColor);
273
                xml.putProperty("fixedColor", StringUtilities.color2String(fixedColor));
274
                xml.putProperty("fixedSize", fixedSize);
275
                xml.putProperty("Unit", unit);
276
                xml.putProperty("referenceSystem",referenceSystem);
277
                return xml;
278

    
279
        }
280

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

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

    
291
        public void setRotationFieldId(int fieldId) {
292
                this.idRotationField = fieldId;
293
        }
294

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

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

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

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

    
315
        public int getHeightFieldId() {
316
                return idHeightField;
317
        }
318

    
319
        public void setHeightFieldId(int fieldId) {
320
                this.idHeightField = fieldId;
321
        }
322

    
323
        public String getColorField() throws ReadDriverException {
324
                if (idColorField == -1) return null;
325
                return ((SelectableDataSource) layer.getRecordset())
326
                                .getFieldName(idColorField);
327
        }
328

    
329
        public int getColorFieldId() {
330
                return idColorField;
331
        }
332

    
333
        public void setColorFieldId(int fieldId) {
334
                this.idColorField = fieldId;
335
        }
336

    
337

    
338
        public void setXMLEntity(XMLEntity xml) {
339
                if (xml.contains("TextField" ))
340
                        setTextField(xml.getStringProperty("TextField"));
341

    
342
                if (xml.contains("HeightField"))
343
                        setHeightField(xml.getStringProperty("HeightField"));
344

    
345
                if (xml.contains("ColorField"))
346
                        setColorField(xml.getStringProperty("ColorField"));
347

    
348
                if (xml.contains("RotationField"))
349
                        setRotationField(xml.getStringProperty("RotationField"));
350

    
351
                if (xml.contains("Unit"))
352
                        setUnit(xml.getIntProperty("Unit"));
353

    
354
                if (xml.contains("fontName")){
355
                        Font font=new Font(xml.getStringProperty("fontName"),xml.getIntProperty("fontStyle"),xml.getIntProperty("fontSize"));
356
                        setFont(font);
357
                }
358
                if (xml.contains("useFixedSize")){
359
                        useFixedSize=xml.getBooleanProperty("useFixedSize");
360
                        fixedSize=xml.getDoubleProperty("fixedSize");
361
                }
362
                if (xml.contains("useFixedColor")){
363
                        useFixedColor=xml.getBooleanProperty("useFixedColor");
364
                        fixedColor=StringUtilities.string2Color(xml.getStringProperty("fixedColor"));
365
                }
366
                if (xml.contains("referenceSystem"))
367
                        referenceSystem=xml.getIntProperty("referenceSystem");
368

    
369
        }
370

    
371
        public void setTextField(String textFieldName) {
372
                this.textFieldName=textFieldName;
373
        }
374

    
375
        public void setRotationField(String rotationFieldName) {
376
                if (rotationFieldName != null) {
377
                        this.rotationFieldName=rotationFieldName;
378
                } else idRotationField = -1;
379
        }
380

    
381
        /**
382
         * Sets the field that contains the size of the text. The size is computed
383
         * in meters. To use any other unit, call setUnit(int) with the scale factor from meters
384
         * (for centimeters, call <b>setUnitFactor(0.01))</b>.
385
         * @param heightFieldName
386
         */
387
        public void setHeightField(String heightFieldName) {
388
                if (heightFieldName != null) {
389
                        this.heightFieldName=heightFieldName;
390
                } else idHeightField = -1;
391
        }
392

    
393

    
394
        public void setColorField(String colorFieldName) {
395
                if (colorFieldName != null) {
396
                        this.colorFieldName=colorFieldName;
397
                } else idColorField = -1;
398
        }
399

    
400
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintRequestAttributeSet properties) throws ReadDriverException {
401
                this.properties=properties;
402
                draw(null, g, viewPort, cancel, printDPI);
403
                this.properties=null;
404
        }
405

    
406
        public void setUsesFixedSize(boolean b) {
407
                useFixedSize = b;
408
        }
409

    
410
        public boolean usesFixedSize() {
411
                return useFixedSize;
412
        }
413

    
414
        public double getFixedSize() {
415
                return fixedSize;
416
        }
417

    
418
        public void setFixedSize(double fixedSize) {
419
                this.fixedSize = fixedSize;
420
        }
421

    
422
        public void setUsesFixedColor(boolean b) {
423
                useFixedColor = b;
424
        }
425

    
426
        public boolean usesFixedColor() {
427
                return useFixedColor;
428
        }
429

    
430
        public Color getFixedColor() {
431
                return fixedColor;
432
        }
433

    
434
        public void setFixedColor(Color fixedColor) {
435
                this.fixedColor = fixedColor;
436
        }
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
                Vector v = new Vector();
450
                try {
451
                        if (getHeightField()!=null) v.add(getHeightField());
452
                        if (getRotationField()!=null) v.add(getRotationField());
453
                        if (getTextField()!=null) v.add(getTextField());
454
                        if (getHeightField()!=null) v.add(getHeightField());
455
                } catch (ReadDriverException e) {
456
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
457
                }
458
                return (String[]) v.toArray(new String[v.size()]);
459
        }
460

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

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

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

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

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

    
483
        }
484

    
485
        public void setLayer(FLayer layer) {
486
                this.layer = (FLyrVect) layer;
487
                try{
488
                        SelectableDataSource sds=this.layer.getRecordset();
489
                        if (textFieldName!=null)
490
                        idTextField = sds.getFieldIndexByName(textFieldName);
491
                        if (rotationFieldName!=null)
492
                        idRotationField = sds.getFieldIndexByName(rotationFieldName);
493
                        if (heightFieldName!=null)
494
                        idHeightField = sds.getFieldIndexByName(heightFieldName);
495
                        if (colorFieldName!=null)
496
                        idColorField = sds.getFieldIndexByName(colorFieldName);
497
                } catch (ReadDriverException e) {
498
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
499
                }
500
        }
501

    
502
        public boolean shouldDrawLabels(double scale) {
503
                return layer.isWithinScale(scale);
504
        }
505

    
506
        public Color getColorFont() {
507
                return colorFont;
508
        }
509

    
510
        public void setColorFont(Color colorFont) {
511
                this.colorFont = colorFont;
512
        }
513

    
514
        public Font getFont() {
515
                if(font == null)
516
                        font = SymbologyFactory.DefaultTextFont;
517
                return font;
518
        }
519

    
520
        public void setFont(Font selFont) {
521
                this.font = selFont;
522
        }
523
}