Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap / src / org / gvsig / fmap / mapcontext / rendering / legend / styling / AttrInTableLabelingStrategy.java @ 20989

History | View | Annotate | Download (11.3 KB)

1
package org.gvsig.fmap.mapcontext.rendering.legend.styling;
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 org.gvsig.fmap.core.geometries.IGeometry;
13
import org.gvsig.fmap.core.geometries.utils.FConstant;
14
import org.gvsig.fmap.core.geometries.utils.FLabel;
15
import org.gvsig.fmap.core.shapes.FPoint2D;
16
import org.gvsig.fmap.core.shapes.FShape;
17
import org.gvsig.fmap.datasources.SelectableDataSource;
18
import org.gvsig.fmap.drivers.exceptions.ExpansionFileReadException;
19
import org.gvsig.fmap.drivers.exceptions.VisitorException;
20
import org.gvsig.fmap.mapcontext.MapContext;
21
import org.gvsig.fmap.mapcontext.ViewPort;
22
import org.gvsig.fmap.mapcontext.layers.FBitSet;
23
import org.gvsig.fmap.mapcontext.layers.FLayer;
24
import org.gvsig.fmap.mapcontext.layers.ReadableVectorial;
25
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
26
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
27
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupportToolkit;
28
import org.gvsig.fmap.mapcontext.rendering.symbols.SimpleTextSymbol;
29

    
30
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
31
import com.hardcode.gdbms.engine.values.NullValue;
32
import com.hardcode.gdbms.engine.values.NumericValue;
33
import com.hardcode.gdbms.engine.values.Value;
34
import com.iver.utiles.XMLEntity;
35
import com.iver.utiles.swing.threads.Cancellable;
36

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

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

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

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

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

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

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

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

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

    
98
                                ReadableVectorial source = layer.getSource();
99
                                SelectableDataSource recordSet = source.getRecordset();
100

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

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

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

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

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

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

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

    
172
                }
173
        }
174

    
175
        public String getClassName() {
176
                return getClass().getName();
177
        }
178

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

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

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

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

    
201
                xml.putProperty("Unit", unit);
202
                return xml;
203

    
204
        }
205

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

    
212
        public int getRotationFieldId() {
213
                return idRotationField;
214
        }
215

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

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

    
226
        public int getTextFieldId() {
227
                return idTextField;
228
        }
229

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

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

    
240
        public int getHeightFieldId() {
241
                return idHeightField;
242
        }
243

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

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

    
252
                if (xml.contains("HeightField"))
253
                        setHeightField("HeightField");
254

    
255
                if (xml.contains("RotationField"))
256
                        setRotationField("RotationField");
257

    
258
                if (xml.contains("UnitFactor"))
259
                        setUnit(xml.getIntProperty("Unit"));
260
        }
261

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

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

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

    
299

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

    
314
        public void setUsesFixedSize(boolean b) {
315
                useFixedSize = b;
316
        }
317

    
318
        public boolean usesFixedSize() {
319
                return useFixedSize;
320
        }
321

    
322
        public double getFixedSize() {
323
                return fixedSize;
324
        }
325

    
326
        public void setFixedSize(double fixedSize) {
327
                this.fixedSize = fixedSize;
328
        }
329

    
330
        public void setUnit(int unitIndex) {
331
                unit = unitIndex;
332

    
333
        }
334

    
335
        public int getUnit() {
336
                return unit;
337
        }
338

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

    
352
        public int getReferenceSystem() {
353
                return referenceSystem;
354
        }
355

    
356
        public void setReferenceSystem(int referenceSystem) {
357
                this.referenceSystem = referenceSystem;
358
        }
359

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

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

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

    
374
        }
375

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