Statistics
| Revision:

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

History | View | Annotate | Download (9.17 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
                                                sym.draw(g, viewPort.getAffineTransform(), p);
145
                                        }
146
                                }
147
                        } catch (VisitorException e) {
148
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not get the layer extent.\n" +
149
                                                e.getMessage());
150
                        } catch (ExpansionFileReadException e) {
151
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer" +
152
                                                "\""+layer.getName()+"\".\nIs the layer being edited?.\n"+e.getMessage());
153
                        } catch (ReadDriverException e) {
154
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer.\n" +
155
                                                e.getMessage());
156
                        }
157

    
158
                }
159
        }
160

    
161
        public void setLayer(FLyrVect lyrVect) {
162
                this.layer = lyrVect;
163
        }
164

    
165
        public String getClassName() {
166
                return getClass().getName();
167
        }
168

    
169
        public XMLEntity getXMLEntity() {
170
                XMLEntity xml = new XMLEntity();
171
                xml.putProperty("className", getClassName());
172

    
173
                try {
174
                        xml.putProperty("HeightField", getHeightField());
175
                } catch (ReadDriverException e) {
176
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextHeight field.\n"+e.getMessage());
177
                }
178

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

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

    
191
                xml.putProperty("UnitFactor", unitFactor);
192
                return xml;
193

    
194
        }
195

    
196
        public String getRotationField() throws ReadDriverException {
197
                if (idRotationField == -1) return null;
198
                return ((SelectableDataSource) layer.getRecordset())
199
                                .getFieldName(idRotationField);
200
        }
201

    
202
        public int getRotationFieldId() {
203
                return idRotationField;
204
        }
205

    
206
        public void setRotationFieldId(int fieldId) {
207
                this.idRotationField = fieldId;
208
        }
209

    
210
        public String getTextField() throws ReadDriverException {
211
                if (idTextField == -1) return null;
212
                return ((SelectableDataSource) layer.getRecordset())
213
                                .getFieldName(idTextField);
214
        }
215

    
216
        public int getTextFieldId() {
217
                return idTextField;
218
        }
219

    
220
        public void setTextFieldId(int fieldId) {
221
                this.idTextField = fieldId;
222
        }
223

    
224
        public String getHeightField() throws ReadDriverException {
225
                if (idHeightField == -1) return null;
226
                return ((SelectableDataSource) layer.getRecordset())
227
                                .getFieldName(idHeightField);
228
        }
229

    
230
        public int getHeightFieldId() {
231
                return idHeightField;
232
        }
233

    
234
        public void setHeightFieldId(int fieldId) {
235
                this.idHeightField = fieldId;
236
        }
237

    
238
        public void setXMLEntity(XMLEntity xml) {
239
                if (xml.contains("TextField" ))
240
                        setTextField(xml.getStringProperty("TextField"));
241

    
242
                if (xml.contains("HeightField"))
243
                        setHeightField("HeightField");
244

    
245
                if (xml.contains("RotationField"))
246
                        setRotationField("RotationField");
247

    
248
                if (xml.contains("UnitFactor"))
249
                        setUnitFactor(xml.getDoubleProperty("UnitFactor"));
250
        }
251

    
252
        public void setTextField(String textFieldName) {
253
                try {
254
                        idTextField = ((SelectableDataSource) layer.getRecordset())
255
                                                                .getFieldIndexByName(textFieldName);
256
                } catch (ReadDriverException e) {
257
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
258
                }
259
        }
260

    
261
        public void setRotationField(String rotationFieldName) {
262
                try {
263
                        idRotationField = ((SelectableDataSource) layer.getRecordset())
264
                                                                .getFieldIndexByName(rotationFieldName);
265
                } catch (ReadDriverException e) {
266
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
267
                }
268
        }
269

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

    
285
        public void setUnitFactor(double unitFactor) {
286
                this.unitFactor = unitFactor;
287
        }
288

    
289
        public double getUnitFactor() {
290
                return unitFactor;
291
        }
292

    
293
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintRequestAttributeSet properties) throws ReadDriverException {
294
                draw(null, g, viewPort, cancel);
295
        }
296

    
297
        public void setUsesFixedSize(boolean b) {
298
                useFixedSize = b;
299
        }
300

    
301
        public boolean usesFixedSize() {
302
                return useFixedSize;
303
        }
304

    
305
        public double getFixedSize() {
306
                return fixedSize;
307
        }
308

    
309
        public void setFixedSize(double fixedSize) {
310
                this.fixedSize = fixedSize;
311
        }
312
}