Statistics
| Revision:

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

History | View | Annotate | Download (16.6 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
                if (idTextField==-1)
103
                        return;
104
//                double scale = viewPort.getScale();//deprecated
105
                double scale = layer.getMapContext().getScaleView();
106
//                double fontScaleFactor = FConstant.FONT_HEIGHT_SCALE_FACTOR;
107

    
108

    
109
                SimpleTextSymbol sym = new SimpleTextSymbol();
110

    
111
                sym.setFont(getFont());
112

    
113
                sym.setUnit(unit);
114
                sym.setReferenceSystem(referenceSystem);
115

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

    
123
                                ReadableVectorial source = layer.getSource();
124
                                SelectableDataSource recordSet = layer.getRecordset();
125
                                boolean reproject=layer.getProjection()!=null && !layer.getProjection().getAbrev().equals(
126
                                                layer.getMapContext().getViewPort().getProjection().getAbrev()) &&
127
                                                (layer.getCoordTrans()!=null);
128
                                
129
                                
130
                                if ((idTextField == -1) || (idTextField >= recordSet.getFieldCount())) {
131
                                        System.err.println("Ha habido un error. Se ha perdido el campo de etiquetado. Probablemente por quitar un join o edici?n externa.");
132
                                        return;
133
                                }
134

    
135
                                for(int i=bs.nextSetBit(0); i>=0 && !cancel.isCanceled(); i=bs.nextSetBit(i+1)) {
136
                                        Value[] vv = recordSet.getRow(i);
137
                                        double size;
138
                                        Color color = null;
139
                                        if (useFixedSize){
140
                                                // uses fixed size
141
                                                size = fixedSize;// * fontScaleFactor;
142
                                        } else if (idHeightField != -1) {
143
                                                // text size is defined in the table
144
                                                try {
145
                                                        size = ((NumericValue) vv[idHeightField]).doubleValue();// * fontScaleFactor;
146
                                                } catch (ClassCastException ccEx) {
147
                                                        if (!NullValue.class.equals(vv[idHeightField].getClass())) {
148
                                                                throw new ReadDriverException("Unknown", ccEx);
149
                                                        }
150
                                                        // a null value
151
                                                        Logger.getAnonymousLogger().
152
                                                                warning("Null text height value for text '"+vv[idTextField].toString()+"'");
153
                                                        continue;
154
                                                }
155
                                        } else {
156
                                                // otherwise will use the size in the symbol
157
                                                size = sym.getFont().getSize();
158
                                        }
159

    
160
                                        size = CartographicSupportToolkit.
161
                                                                getCartographicLength(this,
162
                                                                                                          size,
163
                                                                                                          viewPort,
164
                                                                                                          MapContext.getScreenDPI());
165
//                                                                                                          dpi);
166
//                                                                toScreenUnitYAxis(this,
167
//                                                                                                  size,
168
//                                                                                                  viewPort
169
//                                                                                                 );
170

    
171
                                        if (size <= MIN_TEXT_SIZE) {
172
                                                // label is too small to be readable, will be skipped
173
                                                // this speeds up the rendering in wider zooms
174
                                                continue;
175
                                        }
176

    
177
                                        sym.setFontSize(size);
178

    
179
                                        if (useFixedColor){
180
                                                color = fixedColor;
181
                                        } else if (idColorField != -1) {
182
                                                // text size is defined in the table
183
                                                try {
184
                                                        color = new Color(((NumericValue) vv[idColorField]).intValue());
185
                                                } catch (ClassCastException ccEx) {
186
                                                        if (!NullValue.class.equals(vv[idColorField].getClass())) {
187
                                                                throw new ReadDriverException("Unknown", ccEx);
188
                                                        }
189
                                                        // a null value
190
                                                        Logger.getAnonymousLogger().
191
                                                                warning("Null color value for text '"+vv[idTextField].toString()+"'");
192
                                                        continue;
193
                                                }
194
                                        } else {
195
                                                color = sym.getTextColor();
196
                                        }
197

    
198
                                        sym.setTextColor(color);
199

    
200
                                        double rotation = 0D;
201
                                        if (idRotationField!= -1) {
202
                                                // text rotation is defined in the table
203
                                                if(!(vv[idRotationField] instanceof NullValue))
204
                                                        rotation = -Math.toRadians(((NumericValue) vv[idRotationField]).doubleValue());
205
                                        }
206

    
207
                                        IGeometry geom = source.getShape(i);
208
                                        if (reproject){
209
                                                geom.reProject(layer.getCoordTrans());
210
                                        }
211
                                        sym.setText(vv[idTextField].toString());
212
                                        sym.setRotation(rotation);
213

    
214
                                        FLabel[] aux = geom.createLabels(0, true);
215
                                        for (int j = 0; j < aux.length; j++) {
216
                                                FPoint2D p = new FPoint2D(aux[j].getOrig());
217
                                                p.transform(viewPort.getAffineTransform());
218
                                                if (properties==null)
219
                                                        sym.draw(g, null, p, cancel);
220
                                                else
221
                                                        sym.print(g, null, p, properties);
222
                                        }
223

    
224

    
225
                                }
226
                        } catch (VisitorException e) {
227
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not get the layer extent.\n" +
228
                                                e.getMessage());
229
                        } catch (ExpansionFileReadException e) {
230
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer" +
231
                                                "\""+layer.getName()+"\".\nIs the layer being edited?.\n"+e.getMessage());
232
                        } catch (ReadDriverException e) {
233
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer.\n" +
234
                                                e.getMessage());
235
                        }
236

    
237
                }
238
        }
239

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

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

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

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

    
263
                try {
264
                        if(getTextField() != null)
265
                                xml.putProperty("TextField", getTextField());
266
                } catch (ReadDriverException e) {
267
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextField field.\n"+e.getMessage());
268
                }
269

    
270
                try {
271
                        if (getRotationField() != null)
272
                                xml.putProperty("RotationField", getRotationField());
273
                } catch (ReadDriverException e) {
274
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing RotationField field.\n"+e.getMessage());
275
                }
276

    
277
                if(getFont() != null){
278
                        xml.putProperty("fontSize", getFont().getSize());
279
                        xml.putProperty("fontName", getFont().getName());
280
                        xml.putProperty("fontStyle", getFont().getStyle());
281
                }
282
                if(getColorFont() != null)
283
                        xml.putProperty("Color", StringUtilities.color2String(getColorFont()));
284
                xml.putProperty("useFixedSize", useFixedSize);
285
                xml.putProperty("useFixedColor", useFixedColor);
286
                xml.putProperty("fixedColor", StringUtilities.color2String(fixedColor));
287
                xml.putProperty("fixedSize", fixedSize);
288
                xml.putProperty("Unit", unit);
289
                xml.putProperty("referenceSystem",referenceSystem);
290
                return xml;
291

    
292
        }
293

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

    
300
        public int getRotationFieldId() {
301
                return idRotationField;
302
        }
303

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

    
308
        public String getTextField() throws ReadDriverException {
309
                if (idTextField == -1) return null;
310
                try {
311
                        String fieldName = ((SelectableDataSource) layer.getRecordset()).getFieldAlias(idTextField); 
312
                        return fieldName;
313
                }
314
                catch (ArrayIndexOutOfBoundsException e) {
315
                        // Probablmente hemos quitado un join y la leyenda se basaba en un campo de la segunda tabla
316
                        e.printStackTrace();
317
                        return null;
318
                }
319
        }
320

    
321
        public int getTextFieldId() {
322
                return idTextField;
323
        }
324

    
325
        public void setTextFieldId(int fieldId) {
326
                this.idTextField = fieldId;
327
        }
328

    
329
        public String getHeightField() throws ReadDriverException {
330
                if (idHeightField == -1) return null;
331
                return ((SelectableDataSource) layer.getRecordset())
332
                                .getFieldAlias(idHeightField);
333
        }
334

    
335
        public int getHeightFieldId() {
336
                return idHeightField;
337
        }
338

    
339
        public void setHeightFieldId(int fieldId) {
340
                this.idHeightField = fieldId;
341
        }
342

    
343
        public String getColorField() throws ReadDriverException {
344
                if (idColorField == -1) return null;
345
                return ((SelectableDataSource) layer.getRecordset())
346
                                .getFieldAlias(idColorField);
347
        }
348

    
349
        public int getColorFieldId() {
350
                return idColorField;
351
        }
352

    
353
        public void setColorFieldId(int fieldId) {
354
                this.idColorField = fieldId;
355
        }
356

    
357

    
358
        public void setXMLEntity(XMLEntity xml) {
359
                if (xml.contains("TextField" ))
360
                        setTextField(xml.getStringProperty("TextField"));
361

    
362
                if (xml.contains("HeightField"))
363
                        setHeightField(xml.getStringProperty("HeightField"));
364

    
365
                if (xml.contains("ColorField"))
366
                        setColorField(xml.getStringProperty("ColorField"));
367

    
368
                if (xml.contains("RotationField"))
369
                        setRotationField(xml.getStringProperty("RotationField"));
370

    
371
                if (xml.contains("Unit"))
372
                        setUnit(xml.getIntProperty("Unit"));
373

    
374
                if (xml.contains("fontName")){
375
                        Font font=new Font(xml.getStringProperty("fontName"),xml.getIntProperty("fontStyle"),xml.getIntProperty("fontSize"));
376
                        setFont(font);
377
                }
378
                if (xml.contains("useFixedSize")){
379
                        useFixedSize=xml.getBooleanProperty("useFixedSize");
380
                        fixedSize=xml.getDoubleProperty("fixedSize");
381
                }
382
                if (xml.contains("useFixedColor")){
383
                        useFixedColor=xml.getBooleanProperty("useFixedColor");
384
                        fixedColor=StringUtilities.string2Color(xml.getStringProperty("fixedColor"));
385
                }
386
                if (xml.contains("referenceSystem"))
387
                        referenceSystem=xml.getIntProperty("referenceSystem");
388

    
389
        }
390

    
391
        public void setTextField(String textFieldName) {
392
                this.textFieldName=textFieldName;
393
        }
394

    
395
        public void setRotationField(String rotationFieldName) {
396
                if (rotationFieldName != null) {
397
                        this.rotationFieldName=rotationFieldName;
398
                } else idRotationField = -1;
399
        }
400

    
401
        /**
402
         * Sets the field that contains the size of the text. The size is computed
403
         * in meters. To use any other unit, call setUnit(int) with the scale factor from meters
404
         * (for centimeters, call <b>setUnitFactor(0.01))</b>.
405
         * @param heightFieldName
406
         */
407
        public void setHeightField(String heightFieldName) {
408
                if (heightFieldName != null) {
409
                        this.heightFieldName=heightFieldName;
410
                } else idHeightField = -1;
411
        }
412

    
413

    
414
        public void setColorField(String colorFieldName) {
415
                if (colorFieldName != null) {
416
                        this.colorFieldName=colorFieldName;
417
                } else idColorField = -1;
418
        }
419

    
420
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintRequestAttributeSet properties) throws ReadDriverException {
421
                this.properties=properties;
422
                draw(null, g, viewPort, cancel, printDPI);
423
                this.properties=null;
424
        }
425

    
426
        public void setUsesFixedSize(boolean b) {
427
                useFixedSize = b;
428
        }
429

    
430
        public boolean usesFixedSize() {
431
                return useFixedSize;
432
        }
433

    
434
        public double getFixedSize() {
435
                return fixedSize;
436
        }
437

    
438
        public void setFixedSize(double fixedSize) {
439
                this.fixedSize = fixedSize;
440
        }
441

    
442
        public void setUsesFixedColor(boolean b) {
443
                useFixedColor = b;
444
        }
445

    
446
        public boolean usesFixedColor() {
447
                return useFixedColor;
448
        }
449

    
450
        public Color getFixedColor() {
451
                return fixedColor;
452
        }
453

    
454
        public void setFixedColor(Color fixedColor) {
455
                this.fixedColor = fixedColor;
456
        }
457

    
458

    
459
        public void setUnit(int unitIndex) {
460
                unit = unitIndex;
461

    
462
        }
463

    
464
        public int getUnit() {
465
                return unit;
466
        }
467

    
468
        public String[] getUsedFields() {
469
                Vector v = new Vector();
470
                try {
471
                        if (getHeightField()!=null) v.add(getHeightField());
472
                        if (getRotationField()!=null) v.add(getRotationField());
473
                        if (getTextField()!=null) v.add(getTextField());
474
                        if (getHeightField()!=null) v.add(getHeightField());
475
                } catch (ReadDriverException e) {
476
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
477
                }
478
                return (String[]) v.toArray(new String[v.size()]);
479
        }
480

    
481
        public int getReferenceSystem() {
482
                return referenceSystem;
483
        }
484

    
485
        public void setReferenceSystem(int referenceSystem) {
486
                this.referenceSystem = referenceSystem;
487
        }
488

    
489
        public double toCartographicSize(ViewPort viewPort, double dpi, FShape shp) {
490
                // not required here
491
                throw new Error("Undefined in this context");
492
        }
493

    
494
        public void setCartographicSize(double cartographicSize, FShape shp) {
495
                // not required here
496
                throw new Error("Undefined in this context");
497
        }
498

    
499
        public double getCartographicSize(ViewPort viewPort, double dpi, FShape shp) {
500
                // not required here
501
                throw new Error("Undefined in this context");
502

    
503
        }
504

    
505
        public void setLayer(FLayer layer) {
506
                this.layer = (FLyrVect) layer;
507
                try{
508
                        SelectableDataSource sds=this.layer.getRecordset();
509
                        if (textFieldName!=null){
510
                                idTextField = sds.getFieldIndexByName(textFieldName);
511
//                                if (idTextField==-1){
512
//                                        if (textFieldName.startsWith("link_")){
513
//                                                textFieldName=textFieldName.substring(5, textFieldName.length());
514
//                                                textFieldName="j_"+textFieldName;
515
//                                        }
516
//                                        idTextField = sds.getFieldIndexByName(textFieldName);
517
//                                }
518
                        }
519
                        if (rotationFieldName!=null)
520
                        idRotationField = sds.getFieldIndexByName(rotationFieldName);
521
                        if (heightFieldName!=null)
522
                        idHeightField = sds.getFieldIndexByName(heightFieldName);
523
                        if (colorFieldName!=null)
524
                        idColorField = sds.getFieldIndexByName(colorFieldName);
525
                } catch (ReadDriverException e) {
526
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
527
                }
528
        }
529

    
530
        public boolean shouldDrawLabels(double scale) {
531
                return layer.isWithinScale(scale);
532
        }
533

    
534
        public Color getColorFont() {
535
                return colorFont;
536
        }
537

    
538
        public void setColorFont(Color colorFont) {
539
                this.colorFont = colorFont;
540
        }
541

    
542
        public Font getFont() {
543
                if(font == null)
544
                        font = SymbologyFactory.DefaultTextFont;
545
                return font;
546
        }
547

    
548
        public void setFont(Font selFont) {
549
                this.font = selFont;
550
        }
551
}