Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / rendering / styling / AttrInTableLabeling.java @ 11009

History | View | Annotate | Download (9.33 KB)

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

    
3
import java.awt.Color;
4
import java.awt.Graphics2D;
5
import java.awt.image.BufferedImage;
6
import java.util.logging.Level;
7
import java.util.logging.Logger;
8

    
9
import javax.print.attribute.PrintRequestAttributeSet;
10

    
11
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
12
import com.hardcode.gdbms.engine.values.NullValue;
13
import com.hardcode.gdbms.engine.values.NumericValue;
14
import com.hardcode.gdbms.engine.values.Value;
15
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
16
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
17
import com.iver.cit.gvsig.fmap.ViewPort;
18
import com.iver.cit.gvsig.fmap.core.FPoint2D;
19
import com.iver.cit.gvsig.fmap.core.FShape;
20
import com.iver.cit.gvsig.fmap.core.IGeometry;
21
import com.iver.cit.gvsig.fmap.core.symbols.SimpleTextSymbol;
22
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
23
import com.iver.cit.gvsig.fmap.core.v02.FLabel;
24
import com.iver.cit.gvsig.fmap.layers.FBitSet;
25
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
26
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
27
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
28
import com.iver.utiles.XMLEntity;
29
import com.iver.utiles.swing.threads.Cancellable;
30

    
31
/**
32
 * LabelingStrategy used when the user wants to use label sizes, rotations, etc. from
33
 * the values included in fields of the datasource's table
34
 *
35
 * @author jaume dominguez faus - jaume.dominguez@iver.es
36
 *
37
 */
38
public class AttrInTableLabeling implements ILabelingStrategy {
39
        public static final double MIN_TEXT_SIZE = 3;
40
        private ILabelingMethod method = new DefaultLabelingMethod();
41
        private IZoomConstraints zoom;
42
        private int idTextField;
43
        private int idHeightField;
44
        private int idRotationField;
45
        private FLyrVect layer;
46
        private double unitFactor = 1D;
47
        private double fixedSize;
48
        private boolean useFixedSize;
49

    
50
        public ILabelingMethod getLabelingMethod() {
51
                return this.method;
52
        }
53

    
54
        public void setLabelingMethod(ILabelingMethod method) {
55
                this.method = method;
56
        }
57

    
58
        public IPlacementConstraints getPlacementConstraints() {
59
                return null; // (automatically handled by the driver)
60
        }
61

    
62
        public void setPlacementConstraints(IPlacementConstraints constraints) {
63
                // nothing
64
        }
65

    
66
        public IZoomConstraints getZoomConstraints() {
67
                return zoom;
68
        }
69

    
70
        public void setZoomConstraints(IZoomConstraints constraints) {
71
                this.zoom = constraints;
72
        }
73

    
74
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort, Cancellable cancel)
75
        throws ReadDriverException {
76
                double scale = viewPort.getScale();
77
                double fontScaleFactor = FConstant.FONT_HEIGHT_SCALE_FACTOR;
78

    
79
                if (unitFactor >= 0) {
80
                        // distance units
81
                        fontScaleFactor *= Math.abs(
82
                                        viewPort.getAffineTransform().getScaleY()*unitFactor
83
                        );
84
                }
85

    
86
                LabelClass lClass = method.getDefaultLabelClass();
87
                SimpleTextSymbol sym = (SimpleTextSymbol) lClass.getLabelSymbol();
88
                if (zoom==null ||
89
                        ( zoom.isUserDefined() && (scale >= zoom.getMaxScale())
90
                        && (scale <= zoom.getMinScale()) ) ) {
91
                        try {
92
                                // limit the labeling to the visible extent
93
                                FBitSet bs = layer.queryByRect(viewPort.getAdjustedExtent());
94

    
95
                                ReadableVectorial source = layer.getSource();
96
                                SelectableDataSource recordSet = source.getRecordset();
97

    
98
                                for(int i=bs.nextSetBit(0); i>=0; i=bs.nextSetBit(i+1)) {
99
                                        Value[] vv = recordSet.getRow(i);
100
                                        double size;
101

    
102
                                        if (useFixedSize){
103
                                                // uses fixed size
104
                                                size = fixedSize * fontScaleFactor;
105
                                        } else if (idHeightField != -1) {
106
                                                // text size is defined in the table
107
                                                try {
108
                                                        size = ((NumericValue) vv[idHeightField]).doubleValue() * fontScaleFactor;
109
                                                } catch (ClassCastException ccEx) {
110
                                                        if (!NullValue.class.equals(vv[idHeightField].getClass())) {
111
                                                                throw new ReadDriverException("Unknown", ccEx);
112
                                                        }
113
                                                        // a null value
114
                                                        Logger.getAnonymousLogger().
115
                                                                warning("Null text height value for text '"+vv[idTextField].toString()+"'");
116
                                                        continue;
117
                                                }
118
                                        } else {
119
                                                // otherwise will use the size in the symbol
120
                                                size = sym.getFont().getSize();
121
                                        }
122

    
123
                                        if (size <= MIN_TEXT_SIZE) {
124
                                                // label is too small to be readable, will be skipped
125
                                                // this speeds up the rendering in wider zooms
126
                                                continue;
127
                                        }
128

    
129
                                        sym.setFontSize(size);
130
                                        double rotation = 0D;
131
                                        if (idRotationField!= -1) {
132
                                                // text rotation is defined in the table
133
                                                rotation = -Math.toRadians(((NumericValue) vv[idRotationField]).doubleValue());
134
                                        }
135

    
136
                                        IGeometry geom = source.getShape(i);
137
                                        sym.setText(vv[idTextField].toString());
138
                                        sym.setRotation(rotation);
139

    
140
                                        FLabel[] aux = geom.createLabels(0, true);
141
                                        g.setColor(Color.GREEN);
142
                                        for (int j = 0; j < aux.length; j++) {
143
                                                FPoint2D p = new FPoint2D(aux[j].getOrig());
144
                                                FPoint2D p2 = (FPoint2D)p.cloneFShape();
145
                                                p2.transform(viewPort.getAffineTransform());
146
                                                FShape s = sym.getTextWrappingShape(g, p2);
147
                                                sym.draw(g, viewPort.getAffineTransform(), p);
148
                                                g.draw(s);
149

    
150

    
151
                                        }
152

    
153
                                }
154
                        } catch (VisitorException e) {
155
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not get the layer extent.\n" +
156
                                                e.getMessage());
157
                        } catch (ExpansionFileReadException e) {
158
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer" +
159
                                                "\""+layer.getName()+"\".\nIs the layer being edited?.\n"+e.getMessage());
160
                        } catch (ReadDriverException e) {
161
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer.\n" +
162
                                                e.getMessage());
163
                        }
164

    
165
                }
166
        }
167

    
168
        public void setLayer(FLyrVect lyrVect) {
169
                this.layer = lyrVect;
170
        }
171

    
172
        public String getClassName() {
173
                return getClass().getName();
174
        }
175

    
176
        public XMLEntity getXMLEntity() {
177
                XMLEntity xml = new XMLEntity();
178
                xml.putProperty("className", getClassName());
179

    
180
                try {
181
                        xml.putProperty("HeightField", getHeightField());
182
                } catch (ReadDriverException e) {
183
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextHeight field.\n"+e.getMessage());
184
                }
185

    
186
                try {
187
                        xml.putProperty("TextField", getTextField());
188
                } catch (ReadDriverException e) {
189
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextField field.\n"+e.getMessage());
190
                }
191

    
192
                try {
193
                        xml.putProperty("RotationField", getRotationField());
194
                } catch (ReadDriverException e) {
195
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing RotationField field.\n"+e.getMessage());
196
                }
197

    
198
                xml.putProperty("UnitFactor", unitFactor);
199
                return xml;
200

    
201
        }
202

    
203
        public String getRotationField() throws ReadDriverException {
204
                if (idRotationField == -1) return null;
205
                return ((SelectableDataSource) layer.getRecordset())
206
                                .getFieldName(idRotationField);
207
        }
208

    
209
        public int getRotationFieldId() {
210
                return idRotationField;
211
        }
212

    
213
        public void setRotationFieldId(int fieldId) {
214
                this.idRotationField = fieldId;
215
        }
216

    
217
        public String getTextField() throws ReadDriverException {
218
                if (idTextField == -1) return null;
219
                return ((SelectableDataSource) layer.getRecordset())
220
                                .getFieldName(idTextField);
221
        }
222

    
223
        public int getTextFieldId() {
224
                return idTextField;
225
        }
226

    
227
        public void setTextFieldId(int fieldId) {
228
                this.idTextField = fieldId;
229
        }
230

    
231
        public String getHeightField() throws ReadDriverException {
232
                if (idHeightField == -1) return null;
233
                return ((SelectableDataSource) layer.getRecordset())
234
                                .getFieldName(idHeightField);
235
        }
236

    
237
        public int getHeightFieldId() {
238
                return idHeightField;
239
        }
240

    
241
        public void setHeightFieldId(int fieldId) {
242
                this.idHeightField = fieldId;
243
        }
244

    
245
        public void setXMLEntity(XMLEntity xml) {
246
                if (xml.contains("TextField" ))
247
                        setTextField(xml.getStringProperty("TextField"));
248

    
249
                if (xml.contains("HeightField"))
250
                        setHeightField("HeightField");
251

    
252
                if (xml.contains("RotationField"))
253
                        setRotationField("RotationField");
254

    
255
                if (xml.contains("UnitFactor"))
256
                        setUnitFactor(xml.getDoubleProperty("UnitFactor"));
257
        }
258

    
259
        public void setTextField(String textFieldName) {
260
                try {
261
                        idTextField = ((SelectableDataSource) layer.getRecordset())
262
                                                                .getFieldIndexByName(textFieldName);
263
                } catch (ReadDriverException e) {
264
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
265
                }
266
        }
267

    
268
        public void setRotationField(String rotationFieldName) {
269
                try {
270
                        idRotationField = ((SelectableDataSource) layer.getRecordset())
271
                                                                .getFieldIndexByName(rotationFieldName);
272
                } catch (ReadDriverException e) {
273
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
274
                }
275
        }
276

    
277
        /**
278
         * Sets the field that contains the size of the text. The size is computed
279
         * in meters. To use any other unit, call setUnit(int) with the scale factor from meters
280
         * (for centimeters, call <b>setUnitFactor(0.01))</b>.
281
         * @param heightFieldName
282
         */
283
        public void setHeightField(String heightFieldName) {
284
                try {
285
                        idHeightField = ((SelectableDataSource) layer.getRecordset())
286
                                                                .getFieldIndexByName(heightFieldName);
287
                } catch (ReadDriverException e) {
288
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
289
                }
290
        }
291

    
292
        public void setUnitFactor(double unitFactor) {
293
                this.unitFactor = unitFactor;
294
        }
295

    
296
        public double getUnitFactor() {
297
                return unitFactor;
298
        }
299

    
300
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintRequestAttributeSet properties) throws ReadDriverException {
301
                draw(null, g, viewPort, cancel);
302
        }
303

    
304
        public void setUsesFixedSize(boolean b) {
305
                useFixedSize = b;
306
        }
307

    
308
        public boolean usesFixedSize() {
309
                return useFixedSize;
310
        }
311

    
312
        public double getFixedSize() {
313
                return fixedSize;
314
        }
315

    
316
        public void setFixedSize(double fixedSize) {
317
                this.fixedSize = fixedSize;
318
        }
319
}