Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / rendering / styling / labeling / AttrInTableLabelingStrategy.java @ 22363

History | View | Annotate | Download (11.3 KB)

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

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

    
9
import javax.print.attribute.PrintRequestAttributeSet;
10
import javax.print.attribute.standard.PrintQuality;
11

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

    
36
/**
37
 * LabelingStrategy used when the user wants to use label sizes, rotations, etc. from
38
 * the values included in fields of the datasource's table
39
 *
40
 * @author jaume dominguez faus - jaume.dominguez@iver.es
41
 *
42
 */
43
public class AttrInTableLabelingStrategy implements ILabelingStrategy, CartographicSupport {
44
        public static final double MIN_TEXT_SIZE = 3;
45
        private ILabelingMethod method = new DefaultLabelingMethod();
46
        private IZoomConstraints zoom;
47
        private int idTextField;
48
        private int idHeightField;
49
        private int idRotationField;
50
        private FLyrVect layer;
51
//        private double unitFactor = 1D;
52
        private double fixedSize;
53
        private int unit = -1; //(pixel)
54
        private boolean useFixedSize;
55
        private int referenceSystem;
56
        private boolean isPrinting;
57
        private double  printDPI;
58

    
59
        public ILabelingMethod getLabelingMethod() {
60
                return this.method;
61
        }
62

    
63
        public void setLabelingMethod(ILabelingMethod method) {
64
                this.method = method;
65
        }
66

    
67
        public IPlacementConstraints getPlacementConstraints() {
68
                return null; // (automatically handled by the driver)
69
        }
70

    
71
        public void setPlacementConstraints(IPlacementConstraints constraints) {
72
                // nothing
73
        }
74

    
75
        public IZoomConstraints getZoomConstraints() {
76
                return zoom;
77
        }
78

    
79
        public void setZoomConstraints(IZoomConstraints constraints) {
80
                this.zoom = constraints;
81
        }
82

    
83
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort, Cancellable cancel, double dpi)
84
        throws ReadDriverException {
85
                double scale = viewPort.getScale();
86
                double fontScaleFactor = FConstant.FONT_HEIGHT_SCALE_FACTOR;
87

    
88
                
89
                SimpleTextSymbol sym = new SimpleTextSymbol();
90
                sym.setUnit(unit);
91
                sym.setReferenceSystem(referenceSystem);
92
                
93
                if (zoom==null ||
94
                        ( zoom.isUserDefined() && (scale >= zoom.getMaxScale())
95
                        && (scale <= zoom.getMinScale()) ) ) {
96
                        try {
97
                                // limit the labeling to the visible extent
98
                                FBitSet bs = layer.queryByRect(viewPort.getAdjustedExtent());
99

    
100
                                ReadableVectorial source = layer.getSource();
101
                                SelectableDataSource recordSet = source.getRecordset();
102

    
103
                                for(int i=bs.nextSetBit(0); i>=0 && !cancel.isCanceled(); i=bs.nextSetBit(i+1)) {
104
                                        Value[] vv = recordSet.getRow(i);
105
                                        double size;
106

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

    
128
                                        size = CartographicSupportToolkit.
129
                                                                getCartographicLength(this,
130
                                                                                                          size,
131
                                                                                                          viewPort,
132
                                                                                                          MapContext.getScreenDPI());
133
//                                                                                                          dpi);
134
//                                                                toScreenUnitYAxis(this,
135
//                                                                                                  size,
136
//                                                                                                  viewPort
137
//                                                                                                 );
138

    
139
                                        if (size <= MIN_TEXT_SIZE) {
140
                                                // label is too small to be readable, will be skipped
141
                                                // this speeds up the rendering in wider zooms
142
                                                continue;
143
                                        }
144

    
145
                                        sym.setFontSize(size);
146
                                        double rotation = 0D;
147
                                        if (idRotationField!= -1) {
148
                                                // text rotation is defined in the table
149
                                                rotation = -Math.toRadians(((NumericValue) vv[idRotationField]).doubleValue());
150
                                        }
151

    
152
                                        IGeometry geom = source.getShape(i);
153
                                        sym.setText(vv[idTextField].toString());
154
                                        sym.setRotation(rotation);
155

    
156
                                        FLabel[] aux = geom.createLabels(0, true);
157
                                        for (int j = 0; j < aux.length; j++) {
158
                                                FPoint2D p = new FPoint2D(aux[j].getOrig());
159
                                                p.transform(viewPort.getAffineTransform());
160
                                                sym.draw(g, null, p, cancel);
161
                                        }
162
                                }
163
                        } catch (VisitorException e) {
164
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not get the layer extent.\n" +
165
                                                e.getMessage());
166
                        } catch (ExpansionFileReadException e) {
167
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer" +
168
                                                "\""+layer.getName()+"\".\nIs the layer being edited?.\n"+e.getMessage());
169
                        } catch (ReadDriverException e) {
170
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer.\n" +
171
                                                e.getMessage());
172
                        }
173

    
174
                }
175
        }
176

    
177
        public String getClassName() {
178
                return getClass().getName();
179
        }
180

    
181
        public XMLEntity getXMLEntity() {
182
                XMLEntity xml = new XMLEntity();
183
                xml.putProperty("className", getClassName());
184

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

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

    
197
                try {
198
                        xml.putProperty("RotationField", getRotationField());
199
                } catch (ReadDriverException e) {
200
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing RotationField field.\n"+e.getMessage());
201
                }
202

    
203
                xml.putProperty("Unit", unit);
204
                return xml;
205

    
206
        }
207

    
208
        public String getRotationField() throws ReadDriverException {
209
                if (idRotationField == -1) return null;
210
                return ((SelectableDataSource) layer.getRecordset())
211
                                .getFieldName(idRotationField);
212
        }
213

    
214
        public int getRotationFieldId() {
215
                return idRotationField;
216
        }
217

    
218
        public void setRotationFieldId(int fieldId) {
219
                this.idRotationField = fieldId;
220
        }
221

    
222
        public String getTextField() throws ReadDriverException {
223
                if (idTextField == -1) return null;
224
                return ((SelectableDataSource) layer.getRecordset())
225
                                .getFieldName(idTextField);
226
        }
227

    
228
        public int getTextFieldId() {
229
                return idTextField;
230
        }
231

    
232
        public void setTextFieldId(int fieldId) {
233
                this.idTextField = fieldId;
234
        }
235

    
236
        public String getHeightField() throws ReadDriverException {
237
                if (idHeightField == -1) return null;
238
                return ((SelectableDataSource) layer.getRecordset())
239
                                .getFieldName(idHeightField);
240
        }
241

    
242
        public int getHeightFieldId() {
243
                return idHeightField;
244
        }
245

    
246
        public void setHeightFieldId(int fieldId) {
247
                this.idHeightField = fieldId;
248
        }
249

    
250
        public void setXMLEntity(XMLEntity xml) {
251
                if (xml.contains("TextField" ))
252
                        setTextField(xml.getStringProperty("TextField"));
253

    
254
                if (xml.contains("HeightField"))
255
                        setHeightField("HeightField");
256

    
257
                if (xml.contains("RotationField"))
258
                        setRotationField("RotationField");
259

    
260
                if (xml.contains("UnitFactor"))
261
                        setUnit(xml.getIntProperty("Unit"));
262
        }
263

    
264
        public void setTextField(String textFieldName) {
265
                try {
266
                        idTextField = ((SelectableDataSource) layer.getRecordset())
267
                                                                .getFieldIndexByName(textFieldName);
268
                } catch (ReadDriverException e) {
269
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
270
                }
271
        }
272

    
273
        public void setRotationField(String rotationFieldName) {
274
                if (rotationFieldName != null) {
275
                        try {
276
                                idRotationField = ((SelectableDataSource) layer.getRecordset())
277
                                        .getFieldIndexByName(rotationFieldName);
278
                        } catch (ReadDriverException e) {
279
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
280
                        }
281
                } else idRotationField = -1;
282
        }
283

    
284
        /**
285
         * Sets the field that contains the size of the text. The size is computed
286
         * in meters. To use any other unit, call setUnit(int) with the scale factor from meters
287
         * (for centimeters, call <b>setUnitFactor(0.01))</b>.
288
         * @param heightFieldName
289
         */
290
        public void setHeightField(String heightFieldName) {
291
                if (heightFieldName != null) {
292
                        try {
293
                                idHeightField = ((SelectableDataSource) layer.getRecordset())
294
                                .getFieldIndexByName(heightFieldName);
295
                        } catch (ReadDriverException e) {
296
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
297
                        }
298
                } else idHeightField = -1;
299
        }
300

    
301

    
302
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintRequestAttributeSet properties) throws ReadDriverException {
303
                isPrinting = true;
304
                PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
305
                if (resolution.equals(PrintQuality.NORMAL)){
306
                        printDPI=300;
307
                } else if (resolution.equals(PrintQuality.HIGH)) {
308
                        printDPI=600;
309
                } else if (resolution.equals(PrintQuality.DRAFT)) {
310
                        printDPI=72;
311
                }
312
                draw(null, g, viewPort, cancel, printDPI);
313
                isPrinting = false;
314
        }
315

    
316
        public void setUsesFixedSize(boolean b) {
317
                useFixedSize = b;
318
        }
319

    
320
        public boolean usesFixedSize() {
321
                return useFixedSize;
322
        }
323

    
324
        public double getFixedSize() {
325
                return fixedSize;
326
        }
327

    
328
        public void setFixedSize(double fixedSize) {
329
                this.fixedSize = fixedSize;
330
        }
331

    
332
        public void setUnit(int unitIndex) {
333
                unit = unitIndex;
334

    
335
        }
336

    
337
        public int getUnit() {
338
                return unit;
339
        }
340

    
341
        public String[] getUsedFields() {
342
                Vector v = new Vector();
343
                try {
344
                        if (getHeightField()!=null) v.add(getHeightField());
345
                        if (getRotationField()!=null) v.add(getRotationField());
346
                        if (getTextField()!=null) v.add(getTextField());
347
                        if (getHeightField()!=null) v.add(getHeightField());
348
                } catch (ReadDriverException e) {
349
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
350
                }
351
                return (String[]) v.toArray(new String[v.size()]);
352
        }
353

    
354
        public int getReferenceSystem() {
355
                return referenceSystem;
356
        }
357

    
358
        public void setReferenceSystem(int referenceSystem) {
359
                this.referenceSystem = referenceSystem;
360
        }
361

    
362
        public double toCartographicSize(ViewPort viewPort, double dpi, FShape shp) {
363
                // not required here
364
                throw new Error("Undefined in this context");
365
        }
366

    
367
        public void setCartographicSize(double cartographicSize, FShape shp) {
368
                // not required here
369
                throw new Error("Undefined in this context");
370
        }
371

    
372
        public double getCartographicSize(ViewPort viewPort, double dpi, FShape shp) {
373
                // not required here
374
                throw new Error("Undefined in this context");
375

    
376
        }
377

    
378
        public void setLayer(FLayer layer) {
379
                this.layer = (FLyrVect) layer;
380
        }
381
        
382
        public boolean shouldDrawLabels(double scale) {
383
                return layer.isWithinScale(scale);
384
        }
385
}