Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap / src / org / gvsig / fmap / mapcontext / rendering / legend / styling / AttrInTableLabelingStrategy.java @ 21128

History | View | Annotate | Download (12 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.FeatureStore;
17
import org.gvsig.data.vectorial.FeatureType;
18
import org.gvsig.fmap.core.geometries.utils.FConstant;
19
import org.gvsig.fmap.core.geometries.utils.FLabel;
20
import org.gvsig.fmap.geom.Geometry;
21
import org.gvsig.fmap.geom.operation.CreateLabels;
22
import org.gvsig.fmap.geom.operation.CreateLabelsOperationContext;
23
import org.gvsig.fmap.geom.operation.DrawInts;
24
import org.gvsig.fmap.geom.operation.GeometryOperationException;
25
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
26
import org.gvsig.fmap.geom.primitive.Point2D;
27

    
28
import org.gvsig.fmap.mapcontext.MapContext;
29
import org.gvsig.fmap.mapcontext.ViewPort;
30
import org.gvsig.fmap.mapcontext.layers.FBitSet;
31
import org.gvsig.fmap.mapcontext.layers.FLayer;
32
import org.gvsig.fmap.mapcontext.layers.ReadableVectorial;
33
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
34
import org.gvsig.fmap.mapcontext.rendering.legend.NullValue;
35
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
36
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupportToolkit;
37
import org.gvsig.fmap.mapcontext.rendering.symbols.SimpleTextSymbol;
38

    
39
import com.iver.utiles.XMLEntity;
40
import com.iver.utiles.swing.threads.Cancellable;
41

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

    
65
        public ILabelingMethod getLabelingMethod() {
66
                return this.method;
67
        }
68

    
69
        public void setLabelingMethod(ILabelingMethod method) {
70
                this.method = method;
71
        }
72

    
73
        public IPlacementConstraints getPlacementConstraints() {
74
                return null; // (automatically handled by the driver)
75
        }
76

    
77
        public void setPlacementConstraints(IPlacementConstraints constraints) {
78
                // nothing
79
        }
80

    
81
        public IZoomConstraints getZoomConstraints() {
82
                return zoom;
83
        }
84

    
85
        public void setZoomConstraints(IZoomConstraints constraints) {
86
                this.zoom = constraints;
87
        }
88

    
89
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort, Cancellable cancel, double dpi)
90
        throws ReadException {
91
                double scale = viewPort.getScale();
92
                double fontScaleFactor = FConstant.FONT_HEIGHT_SCALE_FACTOR;
93

    
94
                LabelClass lClass = method.getDefaultLabelClass();
95
                SimpleTextSymbol sym = (SimpleTextSymbol) lClass.getTextSymbol();
96
                if (zoom==null ||
97
                        ( zoom.isUserDefined() && (scale >= zoom.getMaxScale())
98
                        && (scale <= zoom.getMinScale()) ) ) {
99
                        try {
100
                                // limit the labeling to the visible extent
101
//                                FBitSet bs = layer.queryByRect(viewPort.getAdjustedExtent());
102
                                FeatureCollection collection=(FeatureCollection)layer.getFeatureStore().getDataCollection(new String[0],null,null);
103
//                                ReadableVectorial source = layer.getSource();
104
//                                SelectableDataSource recordSet = source.getRecordset();
105
                                Iterator iterator=collection.iterator();
106
                                CreateLabelsOperationContext cloc=new CreateLabelsOperationContext();
107
                                cloc.setDublicates(true);
108
                                cloc.setPosition(0);
109
                                while(iterator.hasNext()){
110
                                        if (cancel.isCanceled()){
111
                                                return;
112
                                        }
113
                                        Feature feature=(Feature)iterator.next();
114
//                                for(int i=bs.nextSetBit(0); i>=0 && !cancel.isCanceled(); i=bs.nextSetBit(i+1)) {
115
//                                        Value[] vv = recordSet.getRow(i);
116
                                        double size;
117

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

    
139
                                        size = CartographicSupportToolkit.
140
                                                                getCartographicLength(this,
141
                                                                                                          size,
142
                                                                                                          viewPort,
143
                                                                                                          MapContext.getScreenDPI());
144
//                                                                                                          dpi);
145
//                                                                toScreenUnitYAxis(this,
146
//                                                                                                  size,
147
//                                                                                                  viewPort
148
//                                                                                                 );
149

    
150
                                        if (size <= MIN_TEXT_SIZE) {
151
                                                // label is too small to be readable, will be skipped
152
                                                // this speeds up the rendering in wider zooms
153
                                                continue;
154
                                        }
155

    
156
                                        sym.setFontSize(size);
157
                                        double rotation = 0D;
158
                                        if (idRotationField!= -1) {
159
                                                // text rotation is defined in the table
160
                                                rotation = -Math.toRadians(((Number) feature.get(idRotationField)).doubleValue());
161
                                        }
162

    
163
                                        Geometry geom = (Geometry)feature.getDefaultGeometry();
164
                                        sym.setText(feature.get(idTextField).toString());
165
                                        sym.setRotation(rotation);
166

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

    
186
                }
187
        }
188

    
189
        public String getClassName() {
190
                return getClass().getName();
191
        }
192

    
193
        public XMLEntity getXMLEntity() {
194
                XMLEntity xml = new XMLEntity();
195
                xml.putProperty("className", getClassName());
196

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

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

    
209
                try {
210
                        xml.putProperty("RotationField", getRotationField());
211
                } catch (ReadException e) {
212
                        Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing RotationField field.\n"+e.getMessage());
213
                }
214

    
215
                xml.putProperty("Unit", unit);
216
                return xml;
217

    
218
        }
219

    
220
        public String getRotationField() throws ReadException {
221
                if (idRotationField == -1) return null;
222
                return ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getByOrder(idRotationField).getName();
223
        }
224

    
225
        public int getRotationFieldId() {
226
                return idRotationField;
227
        }
228

    
229
        public void setRotationFieldId(int fieldId) {
230
                this.idRotationField = fieldId;
231
        }
232

    
233
        public String getTextField() throws ReadException {
234
                if (idTextField == -1) return null;
235
                return ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getByOrder(idTextField).getName();
236
        }
237

    
238
        public int getTextFieldId() {
239
                return idTextField;
240
        }
241

    
242
        public void setTextFieldId(int fieldId) {
243
                this.idTextField = fieldId;
244
        }
245

    
246
        public String getHeightField() throws ReadException {
247
                if (idHeightField == -1) return null;
248
                return ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getByOrder(idHeightField).getName();
249
        }
250

    
251
        public int getHeightFieldId() {
252
                return idHeightField;
253
        }
254

    
255
        public void setHeightFieldId(int fieldId) {
256
                this.idHeightField = fieldId;
257
        }
258

    
259
        public void setXMLEntity(XMLEntity xml) {
260
                if (xml.contains("TextField" ))
261
                        setTextField(xml.getStringProperty("TextField"));
262

    
263
                if (xml.contains("HeightField"))
264
                        setHeightField("HeightField");
265

    
266
                if (xml.contains("RotationField"))
267
                        setRotationField("RotationField");
268

    
269
                if (xml.contains("UnitFactor"))
270
                        setUnit(xml.getIntProperty("Unit"));
271
        }
272

    
273
        public void setTextField(String textFieldName) {
274
                try {
275
                        idTextField = ((FeatureType)layer.getFeatureStore().getFeatureTypes().get(0)).getFieldIndex(textFieldName);
276
                } catch (ReadException e) {
277
                        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
278
                }
279
        }
280

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

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

    
307

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

    
322
        public void setUsesFixedSize(boolean b) {
323
                useFixedSize = b;
324
        }
325

    
326
        public boolean usesFixedSize() {
327
                return useFixedSize;
328
        }
329

    
330
        public double getFixedSize() {
331
                return fixedSize;
332
        }
333

    
334
        public void setFixedSize(double fixedSize) {
335
                this.fixedSize = fixedSize;
336
        }
337

    
338
        public void setUnit(int unitIndex) {
339
                unit = unitIndex;
340

    
341
        }
342

    
343
        public int getUnit() {
344
                return unit;
345
        }
346

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

    
360
        public int getReferenceSystem() {
361
                return referenceSystem;
362
        }
363

    
364
        public void setReferenceSystem(int referenceSystem) {
365
                this.referenceSystem = referenceSystem;
366
        }
367

    
368
        public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
369
                // not required here
370
                throw new Error("Undefined in this context");
371
        }
372

    
373
        public void setCartographicSize(double cartographicSize, Geometry geom) {
374
                // not required here
375
                throw new Error("Undefined in this context");
376
        }
377

    
378
        public double getCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
379
                // not required here
380
                throw new Error("Undefined in this context");
381

    
382
        }
383

    
384
        public void setLayer(FLayer layer) {
385
                this.layer = (FLyrVect) layer;
386
        }
387

    
388
        public boolean shouldDrawLabels(double scale) {
389
                return layer.isWithinScale(scale);
390
        }
391
}