Statistics
| Revision:

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

History | View | Annotate | Download (18.2 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 boolean withHalo = false;
67
        private Color haloColor = Color.WHITE;
68
        private float haloWidth = 3;
69
        public Color getHaloColor() {
70
                return haloColor;
71
        }
72

    
73
        public void setHaloColor(Color haloColor) {
74
                this.haloColor = haloColor;
75
        }
76

    
77
        public float getHaloWidth() {
78
                return haloWidth;
79
        }
80

    
81
        public void setHaloWidth(float haloWidth) {
82
                this.haloWidth = haloWidth;
83
        }
84

    
85
        public void setWithHalo(boolean withHalo) {
86
                this.withHalo = withHalo;
87
        }
88

    
89
        private int referenceSystem;
90
        // private double  printDPI_;
91
        private Font font;
92
        private Color colorFont;
93
        private String textFieldName;
94
        private String rotationFieldName;
95
        private String heightFieldName;
96
        private String colorFieldName;
97
        private PrintRequestAttributeSet properties;
98

    
99
        public ILabelingMethod getLabelingMethod() {
100
                return this.method;
101
        }
102

    
103
        public void setLabelingMethod(ILabelingMethod method) {
104
                this.method = method;
105
        }
106

    
107
        public IPlacementConstraints getPlacementConstraints() {
108
                return null; // (automatically handled by the driver)
109
        }
110

    
111
        public void setPlacementConstraints(IPlacementConstraints constraints) {
112
                // nothing
113
        }
114

    
115
        public IZoomConstraints getZoomConstraints() {
116
                return zoom;
117
        }
118

    
119
        public void setZoomConstraints(IZoomConstraints constraints) {
120
                this.zoom = constraints;
121
        }
122

    
123
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort, Cancellable cancel, double _dpi)
124
        throws ReadDriverException {
125
                if (idTextField==-1)
126
                        return;
127
//                double scale = viewPort.getScale();//deprecated
128
                double scale = layer.getMapContext().getScaleView();
129
//                double fontScaleFactor = FConstant.FONT_HEIGHT_SCALE_FACTOR;
130

    
131

    
132
                SimpleTextSymbol sym = new SimpleTextSymbol();
133

    
134
                sym.setFont(getFont());
135

    
136
                sym.setUnit(unit);
137
                sym.setReferenceSystem(referenceSystem);
138
                sym.setDrawWithHalo(isWithHalo());
139
                if (isWithHalo()) {
140
                        sym.setHaloWidth(getHaloWidth());
141
                        sym.setHaloColor(getHaloColor());
142
                }
143

    
144
                if (zoom==null ||
145
                        ( zoom.isUserDefined() && (scale <= zoom.getMaxScale())
146
                        && (scale >= zoom.getMinScale()) ) ) {
147
                        try {
148
                                // limit the labeling to the visible extent
149
                                FBitSet bs = layer.queryByRect(viewPort.getAdjustedExtent());
150

    
151
                                ReadableVectorial source = layer.getSource();
152
                                SelectableDataSource recordSet = layer.getRecordset();
153
                                recordSet.start();
154
                                boolean reproject=layer.getProjection()!=null && !layer.getProjection().getAbrev().equals(
155
                                                layer.getMapContext().getViewPort().getProjection().getAbrev()) &&
156
                                                (layer.getCoordTrans()!=null);
157

    
158

    
159
                                if ((idTextField == -1) || (idTextField >= recordSet.getFieldCount())) {
160
                                        System.err.println("Ha habido un error. Se ha perdido el campo de etiquetado. Probablemente por quitar un join o edici?n externa.");
161
                                        return;
162
                                }
163

    
164
                                for(int i=bs.nextSetBit(0); i>=0 && !cancel.isCanceled(); i=bs.nextSetBit(i+1)) {
165
                                        Value[] vv = recordSet.getRow(i);
166
                                        double size;
167
                                        Color color = null;
168
                                        if (useFixedSize){
169
                                                // uses fixed size
170
                                                size = fixedSize;// * fontScaleFactor;
171
                                        } else if (idHeightField != -1) {
172
                                                // text size is defined in the table
173
                                                try {
174
                                                        size = ((NumericValue) vv[idHeightField]).doubleValue();// * fontScaleFactor;
175
                                                } catch (ClassCastException ccEx) {
176
                                                        if (!NullValue.class.equals(vv[idHeightField].getClass())) {
177
                                                                throw new ReadDriverException("Unknown", ccEx);
178
                                                        }
179
                                                        // a null value
180
                                                        Logger.getAnonymousLogger().
181
                                                                warning("Null text height value for text '"+vv[idTextField].toString()+"'");
182
                                                        continue;
183
                                                }
184
                                        } else {
185
                                                // otherwise will use the size in the symbol
186
                                                size = sym.getFont().getSize();
187
                                        }
188

    
189
                                        size = CartographicSupportToolkit.
190
                                                                getCartographicLength(this,
191
                                                                                                          size,
192
                                                                                                          viewPort,
193
                                                                                                          _dpi);
194
                                          // MapContext.getScreenDPI());
195
//                                                                toScreenUnitYAxis(this,
196
//                                                                                                  size,
197
//                                                                                                  viewPort
198
//                                                                                                 );
199

    
200
                                        if (size <= MIN_TEXT_SIZE) {
201
                                                // label is too small to be readable, will be skipped
202
                                                // this speeds up the rendering in wider zooms
203
                                                continue;
204
                                        }
205

    
206
                                        sym.setFontSize(size);
207

    
208
                                        if (useFixedColor){
209
                                                color = fixedColor;
210
                                        } else if (idColorField != -1) {
211
                                                // text size is defined in the table
212
                                                try {
213
                                                        color = new Color(((NumericValue) vv[idColorField]).intValue());
214
                                                } catch (ClassCastException ccEx) {
215
                                                        if (!NullValue.class.equals(vv[idColorField].getClass())) {
216
                                                                throw new ReadDriverException("Unknown", ccEx);
217
                                                        }
218
                                                        // a null value
219
                                                        Logger.getAnonymousLogger().
220
                                                                warning("Null color value for text '"+vv[idTextField].toString()+"'");
221
                                                        continue;
222
                                                }
223
                                        } else {
224
                                                color = sym.getTextColor();
225
                                        }
226

    
227
                                        sym.setTextColor(color);
228

    
229
                                        double rotation = 0D;
230
                                        if (idRotationField!= -1) {
231
                                                // text rotation is defined in the table
232
                                                if(!(vv[idRotationField] instanceof NullValue))
233
                                                        rotation = -Math.toRadians(((NumericValue) vv[idRotationField]).doubleValue());
234
                                        }
235

    
236
                                        IGeometry geom = source.getShape(i);
237
                                        if (reproject){
238
                                                geom.reProject(layer.getCoordTrans());
239
                                        }
240
                                        sym.setText(vv[idTextField].toString());
241
                                        sym.setRotation(rotation);
242

    
243
                                        FLabel[] aux = geom.createLabels(0, true);
244
                                        for (int j = 0; j < aux.length; j++) {
245
                                                FPoint2D p = new FPoint2D(aux[j].getOrig());
246
                                                p.transform(viewPort.getAffineTransform());
247
                                                if (idRotationField == -1)
248
                                                        sym.setRotation(aux[j].getRotation());
249
                                                
250
                                                if (properties==null) {
251
                                                        sym.draw(g, null, p, cancel);
252
                                                }
253
                                                else
254
                                                        sym.print(g, null, p, properties);
255
                                        }
256

    
257

    
258
                                }
259
                                recordSet.stop();
260
                        } catch (VisitorException e) {
261
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not get the layer extent.\n" +
262
                                                e.getMessage());
263
                        } catch (ExpansionFileReadException e) {
264
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer" +
265
                                                "\""+layer.getName()+"\".\nIs the layer being edited?.\n"+e.getMessage());
266
                        } catch (ReadDriverException e) {
267
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer.\n" +
268
                                                e.getMessage());
269
                        }
270

    
271
                }
272
        }
273

    
274
        public String getClassName() {
275
                return getClass().getName();
276
        }
277

    
278
        public XMLEntity getXMLEntity() {
279
                XMLEntity xml = new XMLEntity();
280
                xml.putProperty("className", getClassName());
281
                xml.putProperty("labelingStrategy", "labelingStrategy");
282

    
283
                try {
284
                        String height=getHeightField();
285
                        if( height!= null)
286
                                xml.putProperty("HeightField", height);
287
                } catch (ReadDriverException e) {
288
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextHeight field.\n"+e.getMessage());
289
                }
290

    
291
                try {
292
                        String color=getColorField();
293
                        if(color != null)
294
                                xml.putProperty("ColorField", color);
295
                } catch (ReadDriverException e) {
296
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing ColorField field.\n"+e.getMessage());
297
                }
298

    
299
                try {
300
                        String text=getTextField();
301
                        if(text != null)
302
                                xml.putProperty("TextField", text);
303
                } catch (ReadDriverException e) {
304
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextField field.\n"+e.getMessage());
305
                }
306

    
307
                try {
308
                        String rotation=getRotationField();
309
                        if (rotation != null)
310
                                xml.putProperty("RotationField", rotation);
311
                } catch (ReadDriverException e) {
312
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing RotationField field.\n"+e.getMessage());
313
                }
314

    
315
                if(getFont() != null){
316
                        xml.putProperty("fontSize", getFont().getSize());
317
                        xml.putProperty("fontName", getFont().getName());
318
                        xml.putProperty("fontStyle", getFont().getStyle());
319
                }
320
                if(getColorFont() != null)
321
                        xml.putProperty("Color", StringUtilities.color2String(getColorFont()));
322
                xml.putProperty("useFixedSize", useFixedSize);
323
                xml.putProperty("useFixedColor", useFixedColor);
324
                xml.putProperty("fixedColor", StringUtilities.color2String(fixedColor));
325
                xml.putProperty("fixedSize", fixedSize);
326
                xml.putProperty("Unit", unit);
327
                xml.putProperty("referenceSystem",referenceSystem);
328
                if (isWithHalo()) {
329
                        xml.putProperty("haloWidth", getHaloWidth());
330
                        xml.putProperty("haloColor", StringUtilities.color2String(getHaloColor()));
331
                }
332

    
333
                return xml;
334

    
335
        }
336

    
337
        public String getRotationField() throws ReadDriverException {
338
                if (idRotationField == -1) return null;
339
                return ((SelectableDataSource) layer.getRecordset())
340
                                .getFieldName(idRotationField);
341
        }
342

    
343
        public int getRotationFieldId() {
344
                return idRotationField;
345
        }
346

    
347
        public void setRotationFieldId(int fieldId) {
348
                this.idRotationField = fieldId;
349
        }
350

    
351
        public String getTextField() throws ReadDriverException {
352
                if (idTextField == -1) return null;
353
                try {
354
                        String fieldName = ((SelectableDataSource) layer.getRecordset()).getFieldAlias(idTextField);
355
                        return fieldName;
356
                }
357
                catch (ArrayIndexOutOfBoundsException e) {
358
                        // Probablmente hemos quitado un join y la leyenda se basaba en un campo de la segunda tabla
359
                        e.printStackTrace();
360
                        return null;
361
                }
362
        }
363

    
364
        public int getTextFieldId() {
365
                return idTextField;
366
        }
367

    
368
        public void setTextFieldId(int fieldId) {
369
                this.idTextField = fieldId;
370
        }
371

    
372
        public String getHeightField() throws ReadDriverException {
373
                if (idHeightField == -1) return null;
374
                return ((SelectableDataSource) layer.getRecordset())
375
                                .getFieldAlias(idHeightField);
376
        }
377

    
378
        public int getHeightFieldId() {
379
                return idHeightField;
380
        }
381

    
382
        public void setHeightFieldId(int fieldId) {
383
                this.idHeightField = fieldId;
384
        }
385

    
386
        public String getColorField() throws ReadDriverException {
387
                if (idColorField == -1) return null;
388
                return ((SelectableDataSource) layer.getRecordset())
389
                                .getFieldAlias(idColorField);
390
        }
391

    
392
        public int getColorFieldId() {
393
                return idColorField;
394
        }
395

    
396
        public void setColorFieldId(int fieldId) {
397
                this.idColorField = fieldId;
398
        }
399

    
400

    
401
        public void setXMLEntity(XMLEntity xml) {
402
                if (xml.contains("TextField" ))
403
                        setTextField(xml.getStringProperty("TextField"));
404

    
405
                if (xml.contains("HeightField"))
406
                        setHeightField(xml.getStringProperty("HeightField"));
407

    
408
                if (xml.contains("ColorField"))
409
                        setColorField(xml.getStringProperty("ColorField"));
410

    
411
                if (xml.contains("RotationField"))
412
                        setRotationField(xml.getStringProperty("RotationField"));
413

    
414
                if (xml.contains("Unit"))
415
                        setUnit(xml.getIntProperty("Unit"));
416

    
417
                if (xml.contains("fontName")){
418
                        Font font=new Font(xml.getStringProperty("fontName"),xml.getIntProperty("fontStyle"),xml.getIntProperty("fontSize"));
419
                        setFont(font);
420
                }
421
                if (xml.contains("useFixedSize")){
422
                        useFixedSize=xml.getBooleanProperty("useFixedSize");
423
                        fixedSize=xml.getDoubleProperty("fixedSize");
424
                }
425
                if (xml.contains("useFixedColor")){
426
                        useFixedColor=xml.getBooleanProperty("useFixedColor");
427
                        fixedColor=StringUtilities.string2Color(xml.getStringProperty("fixedColor"));
428
                }
429
                if (xml.contains("referenceSystem"))
430
                        referenceSystem=xml.getIntProperty("referenceSystem");
431
                
432
                if (xml.contains("haloWidth")) {
433
                        float haloWidth = xml.getFloatProperty("haloWidth");
434
                        setHaloColor(StringUtilities.string2Color(xml.getStringProperty("haloColor")));
435
                        setHaloWidth(haloWidth);
436
                        setWithHalo(true);
437
                }
438

    
439

    
440
        }
441

    
442
        public void setTextField(String textFieldName) {
443
                this.textFieldName=textFieldName;
444
        }
445

    
446
        public void setRotationField(String rotationFieldName) {
447
                if (rotationFieldName != null) {
448
                        this.rotationFieldName=rotationFieldName;
449
                } else idRotationField = -1;
450
        }
451

    
452
        /**
453
         * Sets the field that contains the size of the text. The size is computed
454
         * in meters. To use any other unit, call setUnit(int) with the scale factor from meters
455
         * (for centimeters, call <b>setUnitFactor(0.01))</b>.
456
         * @param heightFieldName
457
         */
458
        public void setHeightField(String heightFieldName) {
459
                if (heightFieldName != null) {
460
                        this.heightFieldName=heightFieldName;
461
                } else idHeightField = -1;
462
        }
463

    
464

    
465
        public void setColorField(String colorFieldName) {
466
                if (colorFieldName != null) {
467
                        this.colorFieldName=colorFieldName;
468
                } else idColorField = -1;
469
        }
470

    
471
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintRequestAttributeSet properties) throws ReadDriverException {
472
                this.properties=properties;
473

    
474
                double _dpi = 72;
475
                PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
476
                if (resolution.equals(PrintQuality.NORMAL)){
477
                        _dpi = 300;
478
                } else if (resolution.equals(PrintQuality.HIGH)){
479
                        _dpi = 600;
480
                } else if (resolution.equals(PrintQuality.DRAFT)){
481
                        _dpi = 72;
482
                }
483

    
484
                draw(null, g, viewPort, cancel, _dpi);
485
                this.properties=null;
486
        }
487

    
488
        public void setUsesFixedSize(boolean b) {
489
                useFixedSize = b;
490
        }
491

    
492
        public boolean usesFixedSize() {
493
                return useFixedSize;
494
        }
495

    
496
        public double getFixedSize() {
497
                return fixedSize;
498
        }
499

    
500
        public void setFixedSize(double fixedSize) {
501
                this.fixedSize = fixedSize;
502
        }
503

    
504
        public void setUsesFixedColor(boolean b) {
505
                useFixedColor = b;
506
        }
507

    
508
        public boolean usesFixedColor() {
509
                return useFixedColor;
510
        }
511

    
512
        public Color getFixedColor() {
513
                return fixedColor;
514
        }
515

    
516
        public void setFixedColor(Color fixedColor) {
517
                this.fixedColor = fixedColor;
518
        }
519

    
520

    
521
        public void setUnit(int unitIndex) {
522
                unit = unitIndex;
523

    
524
        }
525

    
526
        public int getUnit() {
527
                return unit;
528
        }
529

    
530
        public String[] getUsedFields() {
531
                Vector v = new Vector();
532
                try {
533
                        if (getHeightField()!=null) v.add(getHeightField());
534
                        if (getRotationField()!=null) v.add(getRotationField());
535
                        if (getTextField()!=null) v.add(getTextField());
536
                        if (getHeightField()!=null) v.add(getHeightField());
537
                } catch (ReadDriverException e) {
538
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
539
                }
540
                return (String[]) v.toArray(new String[v.size()]);
541
        }
542

    
543
        public int getReferenceSystem() {
544
                return referenceSystem;
545
        }
546

    
547
        public void setReferenceSystem(int referenceSystem) {
548
                this.referenceSystem = referenceSystem;
549
        }
550

    
551
        public double toCartographicSize(ViewPort viewPort, double dpi, FShape shp) {
552
                // not required here
553
                throw new Error("Undefined in this context");
554
        }
555

    
556
        public void setCartographicSize(double cartographicSize, FShape shp) {
557
                // not required here
558
                throw new Error("Undefined in this context");
559
        }
560

    
561
        public double getCartographicSize(ViewPort viewPort, double dpi, FShape shp) {
562
                // not required here
563
                throw new Error("Undefined in this context");
564

    
565
        }
566

    
567
        public void setLayer(FLayer layer) {
568
                this.layer = (FLyrVect) layer;
569
                try{
570
                        SelectableDataSource sds=this.layer.getRecordset();
571
                        if (textFieldName!=null){
572
                                idTextField = sds.getFieldIndexByName(textFieldName);
573
//                                if (idTextField==-1){
574
//                                        if (textFieldName.startsWith("link_")){
575
//                                                textFieldName=textFieldName.substring(5, textFieldName.length());
576
//                                                textFieldName="j_"+textFieldName;
577
//                                        }
578
//                                        idTextField = sds.getFieldIndexByName(textFieldName);
579
//                                }
580
                        }
581
                        if (rotationFieldName!=null)
582
                        idRotationField = sds.getFieldIndexByName(rotationFieldName);
583
                        if (heightFieldName!=null)
584
                        idHeightField = sds.getFieldIndexByName(heightFieldName);
585
                        if (colorFieldName!=null)
586
                        idColorField = sds.getFieldIndexByName(colorFieldName);
587
                } catch (ReadDriverException e) {
588
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
589
                }
590
        }
591

    
592
        public boolean shouldDrawLabels(double scale) {
593
                return layer.isWithinScale(scale);
594
        }
595

    
596
        public Color getColorFont() {
597
                return colorFont;
598
        }
599

    
600
        public void setColorFont(Color colorFont) {
601
                this.colorFont = colorFont;
602
        }
603

    
604
        public Font getFont() {
605
                if(font == null)
606
                        font = SymbologyFactory.DefaultTextFont;
607
                return font;
608
        }
609

    
610
        public void setFont(Font selFont) {
611
                this.font = selFont;
612
        }
613

    
614
        public boolean isWithHalo() {
615
                return withHalo;
616
        }
617
}