Statistics
| Revision:

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

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

    
159
                }
160
        }
161

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

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

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

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

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

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

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

    
195
        }
196

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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