Statistics
| Revision:

root / branches / v2_0_0_prep / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / rendering / legend / styling / AttrInTableLabelingStrategy.java @ 21200

History | View | Annotate | Download (11.8 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.Iterator;
6
import java.util.Vector;
7
import java.util.logging.Level;
8
import java.util.logging.Logger;
9

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

    
13
import org.gvsig.data.ReadException;
14
import org.gvsig.data.vectorial.Feature;
15
import org.gvsig.data.vectorial.FeatureCollection;
16
import org.gvsig.data.vectorial.FeatureType;
17
import org.gvsig.fmap.geom.Geometry;
18
import org.gvsig.fmap.geom.operation.GeometryOperationException;
19
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
20
import org.gvsig.fmap.geom.primitive.Point2D;
21
import org.gvsig.fmap.geometry.operation.CreateLabels;
22
import org.gvsig.fmap.geometry.operation.CreateLabelsOperationContext;
23
import org.gvsig.fmap.geometry.utils.FConstant;
24
import org.gvsig.fmap.geometry.utils.FLabel;
25
import org.gvsig.fmap.mapcontext.MapContext;
26
import org.gvsig.fmap.mapcontext.ViewPort;
27
import org.gvsig.fmap.mapcontext.layers.FLayer;
28
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
29
import org.gvsig.fmap.mapcontext.rendering.legend.NullValue;
30
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
31
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupportToolkit;
32
import org.gvsig.fmap.mapcontext.rendering.symbols.SimpleTextSymbol;
33

    
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 ReadException {
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
                                FeatureCollection collection=(FeatureCollection)layer.getFeatureStore().getDataCollection(new String[0],null,null);
98
//                                ReadableVectorial source = layer.getSource();
99
//                                SelectableDataSource recordSet = source.getRecordset();
100
                                Iterator iterator=collection.iterator();
101
                                CreateLabelsOperationContext cloc=new CreateLabelsOperationContext();
102
                                cloc.setDublicates(true);
103
                                cloc.setPosition(0);
104
                                while(iterator.hasNext()){
105
                                        if (cancel.isCanceled()){
106
                                                return;
107
                                        }
108
                                        Feature feature=(Feature)iterator.next();
109
//                                for(int i=bs.nextSetBit(0); i>=0 && !cancel.isCanceled(); i=bs.nextSetBit(i+1)) {
110
//                                        Value[] vv = recordSet.getRow(i);
111
                                        double size;
112

    
113
                                        if (useFixedSize){
114
                                                // uses fixed size
115
                                                size = fixedSize * fontScaleFactor;
116
                                        } else if (idHeightField != -1) {
117
                                                // text size is defined in the table
118
                                                try {
119
                                                        size = ((Number) feature.get(idHeightField)).doubleValue() * fontScaleFactor;
120
                                                } catch (ClassCastException ccEx) {
121
                                                        if (!NullValue.class.equals(feature.get(idHeightField).getClass())) {
122
                                                                throw new ReadException("Unknown", ccEx);
123
                                                        }
124
                                                        // a null value
125
                                                        Logger.getAnonymousLogger().
126
                                                                warning("Null text height value for text '"+feature.get(idTextField).toString()+"'");
127
                                                        continue;
128
                                                }
129
                                        } else {
130
                                                // otherwise will use the size in the symbol
131
                                                size = sym.getFont().getSize();
132
                                        }
133

    
134
                                        size = CartographicSupportToolkit.
135
                                                                getCartographicLength(this,
136
                                                                                                          size,
137
                                                                                                          viewPort,
138
                                                                                                          MapContext.getScreenDPI());
139
//                                                                                                          dpi);
140
//                                                                toScreenUnitYAxis(this,
141
//                                                                                                  size,
142
//                                                                                                  viewPort
143
//                                                                                                 );
144

    
145
                                        if (size <= MIN_TEXT_SIZE) {
146
                                                // label is too small to be readable, will be skipped
147
                                                // this speeds up the rendering in wider zooms
148
                                                continue;
149
                                        }
150

    
151
                                        sym.setFontSize(size);
152
                                        double rotation = 0D;
153
                                        if (idRotationField!= -1) {
154
                                                // text rotation is defined in the table
155
                                                rotation = -Math.toRadians(((Number) feature.get(idRotationField)).doubleValue());
156
                                        }
157

    
158
                                        Geometry geom = (Geometry)feature.getDefaultGeometry();
159
                                        sym.setText(feature.get(idTextField).toString());
160
                                        sym.setRotation(rotation);
161

    
162
                                        FLabel[] aux =(FLabel[])geom.invokeOperation(CreateLabels.CODE,cloc);
163
//                                        FLabel[] aux = geom.createLabels(0, true);
164
                                        for (int j = 0; j < aux.length; j++) {
165
                                                Point2D p = new Point2D(aux[j].getOrig());
166
                                                p.transform(viewPort.getAffineTransform());
167
                                                sym.draw(g, null, p, cancel);
168
                                        }
169
                                }
170
                        } catch (ReadException e) {
171
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer.\n" +
172
                                                e.getMessage());
173
                        } catch (GeometryOperationNotSupportedException e) {
174
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer.\n" +
175
                                                e.getMessage());
176
                        } catch (GeometryOperationException e) {
177
                                Logger.getAnonymousLogger().log(Level.SEVERE, "Could not draw annotation in the layer.\n" +
178
                                                e.getMessage());
179
                        }
180

    
181
                }
182
        }
183

    
184
        public String getClassName() {
185
                return getClass().getName();
186
        }
187

    
188
        public XMLEntity getXMLEntity() {
189
                XMLEntity xml = new XMLEntity();
190
                xml.putProperty("className", getClassName());
191

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

    
198
                try {
199
                        xml.putProperty("TextField", getTextField());
200
                } catch (ReadException e) {
201
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextField field.\n"+e.getMessage());
202
                }
203

    
204
                try {
205
                        xml.putProperty("RotationField", getRotationField());
206
                } catch (ReadException e) {
207
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing RotationField field.\n"+e.getMessage());
208
                }
209

    
210
                xml.putProperty("Unit", unit);
211
                return xml;
212

    
213
        }
214

    
215
        public String getRotationField() throws ReadException {
216
                if (idRotationField == -1) return null;
217
                return ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getByOrder(idRotationField).getName();
218
        }
219

    
220
        public int getRotationFieldId() {
221
                return idRotationField;
222
        }
223

    
224
        public void setRotationFieldId(int fieldId) {
225
                this.idRotationField = fieldId;
226
        }
227

    
228
        public String getTextField() throws ReadException {
229
                if (idTextField == -1) return null;
230
                return ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getByOrder(idTextField).getName();
231
        }
232

    
233
        public int getTextFieldId() {
234
                return idTextField;
235
        }
236

    
237
        public void setTextFieldId(int fieldId) {
238
                this.idTextField = fieldId;
239
        }
240

    
241
        public String getHeightField() throws ReadException {
242
                if (idHeightField == -1) return null;
243
                return ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getByOrder(idHeightField).getName();
244
        }
245

    
246
        public int getHeightFieldId() {
247
                return idHeightField;
248
        }
249

    
250
        public void setHeightFieldId(int fieldId) {
251
                this.idHeightField = fieldId;
252
        }
253

    
254
        public void setXMLEntity(XMLEntity xml) {
255
                if (xml.contains("TextField" ))
256
                        setTextField(xml.getStringProperty("TextField"));
257

    
258
                if (xml.contains("HeightField"))
259
                        setHeightField("HeightField");
260

    
261
                if (xml.contains("RotationField"))
262
                        setRotationField("RotationField");
263

    
264
                if (xml.contains("UnitFactor"))
265
                        setUnit(xml.getIntProperty("Unit"));
266
        }
267

    
268
        public void setTextField(String textFieldName) {
269
                try {
270
                        idTextField = ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getFieldIndex(textFieldName);
271
                } catch (ReadException e) {
272
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
273
                }
274
        }
275

    
276
        public void setRotationField(String rotationFieldName) {
277
                if (rotationFieldName != null) {
278
                        try {
279
                                idRotationField = ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getFieldIndex(rotationFieldName);
280
                        } catch (ReadException e) {
281
                                Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
282
                        }
283
                } else idRotationField = -1;
284
        }
285

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

    
302

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

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

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

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

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

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

    
336
        }
337

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

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

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

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

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

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

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

    
377
        }
378

    
379
        public void setLayer(FLayer layer) {
380
                this.layer = (FLyrVect) layer;
381
        }
382

    
383
        public boolean shouldDrawLabels(double scale) {
384
                return layer.isWithinScale(scale);
385
        }
386
}