Statistics
| Revision:

root / org.gvsig.legend.urbanhorizontalsignage / trunk / org.gvsig.legend.urbanhorizontalsignage / org.gvsig.legend.urbanhorizontalsignage.lib / org.gvsig.legend.urbanhorizontalsignage.lib.impl / src / main / java / org / gvsig / legend / urbanverticalsignage / lib / impl / DefaultPictureMarkerSymbolTableLegend.java @ 5144

History | View | Annotate | Download (14.4 KB)

1
package org.gvsig.legend.urbanverticalsignage.lib.impl;
2

    
3
import java.awt.Color;
4
import java.awt.geom.Point2D;
5
import java.awt.image.BufferedImage;
6
import java.util.ArrayList;
7
import java.util.List;
8
import javax.annotation.processing.SupportedSourceVersion;
9
import javax.lang.model.SourceVersion;
10
import org.apache.commons.collections4.map.LRUMap;
11
import org.apache.commons.lang3.StringUtils;
12
import org.gvsig.expressionevaluator.ExpressionBuilder;
13
import org.gvsig.expressionevaluator.ExpressionUtils;
14
import org.gvsig.fmap.dal.DALLocator;
15
import org.gvsig.fmap.dal.DataTypes;
16
import org.gvsig.fmap.dal.StoresRepository;
17
import org.gvsig.fmap.dal.exception.DataException;
18
import org.gvsig.fmap.dal.feature.Feature;
19
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
20
import org.gvsig.fmap.dal.feature.FeatureStore;
21
import org.gvsig.fmap.dal.feature.FeatureType;
22
import org.gvsig.fmap.geom.Geometry;
23
import org.gvsig.fmap.geom.GeometryUtils;
24
import org.gvsig.fmap.mapcontext.MapContextException;
25
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
26
import org.gvsig.legend.urbanverticalsignage.lib.api.PictureMarkerSymbolTableLegend;
27
import org.gvsig.symbology.SymbologyLocator;
28
import org.gvsig.symbology.SymbologyManager;
29
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl.AbstractVectorialLegend;
30
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.impl.SimpleMarkerSymbol;
31
import org.gvsig.tools.ToolsLocator;
32
import org.gvsig.tools.dataTypes.Coercion;
33
import org.gvsig.tools.persistence.PersistentState;
34
import org.gvsig.tools.persistence.exception.PersistenceException;
35
import org.gvsig.tools.swing.api.SimpleImage;
36
import org.slf4j.Logger;
37
import org.slf4j.LoggerFactory;
38

    
39
@SupportedSourceVersion(SourceVersion.RELEASE_8)
40
@SuppressWarnings("UseSpecificCatch")
41
public class DefaultPictureMarkerSymbolTableLegend 
42
        extends AbstractVectorialLegend 
43
        implements PictureMarkerSymbolTableLegend 
44
{
45
    
46
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultPictureMarkerSymbolTableLegend.class);
47

    
48
    private static final int IMAGESCACHE_SIZE = 100;
49
    
50
    transient private final Coercion toColor;
51
    transient private final SimpleMarkerSymbol defaultSymbol;
52
    transient private FeatureStore imagesStore;
53
    transient private ExpressionBuilder expressionBuilder;
54
    transient private final LRUMap<Object, BufferedImage[]> imagesCache;
55
    
56
    private double size;
57
    private int units;
58
    private Color lineToOffsetColor;
59
    private boolean drawLineToOffset;
60

    
61
    private String classifyingFieldName;
62
    private String offsetXFieldName;
63
    private String offsetYFieldName;
64
    private String rotationFieldName;
65
    private String lineToOffsetColorFieldlName;
66

    
67
    private String imagesTableName;
68
    private String imagesTableClassifyingFieldName;
69
    private String imageFieldName;
70
    private String imageSelectedFieldName;
71
    
72
    public DefaultPictureMarkerSymbolTableLegend() {
73
        
74
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
75
        this.defaultSymbol = new SimpleMarkerSymbol();
76
        this.toColor = ToolsLocator.getDataTypesManager().getCoercion(DataTypes.COLOR);
77
        this.size = DEFAULT_IMAGE_SIZE;
78
        this.drawLineToOffset = true;
79
        this.lineToOffsetColor = Color.DARK_GRAY;
80
        this.imagesCache = new LRUMap<>(IMAGESCACHE_SIZE);
81
    }
82

    
83
    @Override
84
    public ISymbol getDefaultSymbol() {
85
        return this.defaultSymbol;
86
    }
87

    
88
    @Override
89
    public void setDefaultSymbol(ISymbol is) {
90
        //DO NOTHING
91
    }
92

    
93
    private Color getColor(Feature feature, String attrname, Color defaultValue) {
94
        if( StringUtils.isBlank(attrname) ) {
95
            return defaultValue;
96
        }
97
        try {
98
            return (Color) toColor.coerce(feature.get(attrname));
99
        } catch(Exception ex) {
100
            return defaultValue;
101
        }
102
    }
103
    
104
    @Override
105
    public ISymbol getSymbolByFeature(Feature feature) throws MapContextException {
106
        ImageMarkerSymbol symbol = new ImageMarkerSymbol();
107
        
108
        Point2D.Double offset = new Point2D.Double(0,0);
109
        if( StringUtils.isNotBlank(this.offsetXFieldName)) {
110
            offset.x = feature.getDouble(this.offsetXFieldName);
111
        }
112
        if( StringUtils.isNotBlank(this.offsetYFieldName)) {
113
            offset.y = feature.getDouble(this.offsetXFieldName);
114
        }
115
        symbol.setOffset(offset);
116
        
117
        if( StringUtils.isNotBlank(this.rotationFieldName)) {
118
            symbol.setRotation(feature.getDouble(this.rotationFieldName));
119
        } else {
120
            symbol.setRotation(0);
121
        }
122
        
123
        if( drawLineToOffset && (offset.x==0 || offset.y==0))    {
124
            symbol.setDrawLineToOffset(true);
125
            symbol.setLineToOffsetColor(
126
                    getColor(
127
                            feature, 
128
                            this.lineToOffsetColorFieldlName, 
129
                            this.lineToOffsetColor
130
                    )
131
            );
132
        } else {
133
            symbol.setDrawLineToOffset(false);
134
            symbol.setLineToOffsetColor(Color.DARK_GRAY);
135
        }
136
        symbol.setSize(this.size);
137
        symbol.setUnit(this.units);
138
        
139
        Object classifyingValue = feature.get(this.classifyingFieldName);
140
        BufferedImage[] images = this.getImages(classifyingValue);
141
        symbol.setImage(images[0]);
142
        symbol.setImageSel(images[1]);
143
        return symbol;
144
    }
145

    
146
    @Override
147
    public int getShapeType() {
148
        return Geometry.TYPES.POINT;
149
    }
150

    
151
    private BufferedImage[] getImages(Object classifyingValue) {
152
        
153
        BufferedImage[] images;
154
        images = this.imagesCache.get(classifyingValue);
155
        if( images!=null ) {
156
            return images;
157
        }
158
        
159
        images = new BufferedImage[] { null, null };        
160
        try {
161
            FeatureStore store = this.getImagesStore();
162
            FeatureType featureType = store.getDefaultFeatureTypeQuietly();
163
            FeatureAttributeDescriptor attr = featureType.getAttributeDescriptor(this.imagesTableClassifyingFieldName);
164
            Object value = attr.coerce(classifyingValue);
165
            ExpressionBuilder builder = this.getExpressionBuilder();
166
            String filter = builder.eq(
167
                    builder.column(this.imagesTableClassifyingFieldName),
168
                    builder.constant(value)
169
            ).toString();
170
            Feature f = store.findFirst(filter);
171
            if( f!=null ) {
172
                SimpleImage image = (SimpleImage) f.getFromProfile(this.imageFieldName);
173
                if( image != null ) {
174
                    images[0] = image.getBufferedImage();
175
                }
176
                image = (SimpleImage) f.getFromProfile(this.imageSelectedFieldName);
177
                if( image != null ) {
178
                    images[1] = image.getBufferedImage();
179
                }
180
            }
181
        } catch(Exception ex) {
182
            LOGGER.debug("Can't retrieve images from table '"+this.imagesTableName+"'", ex);
183
        }
184
        this.imagesCache.put(classifyingValue, images);
185
        return images;
186
    }
187
    
188
    private ExpressionBuilder getExpressionBuilder() {
189
        if( this.expressionBuilder == null ) {
190
            this.expressionBuilder = ExpressionUtils.createExpressionBuilder();
191
        }
192
        return this.expressionBuilder;
193
    }
194
    
195
    private FeatureStore getImagesStore() {
196
        if( this.imagesStore == null ) {
197
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
198
            this.imagesStore = (FeatureStore) repository.getStore(this.imagesTableName);
199
        }
200
        return this.imagesStore;
201
    }
202
    
203
    @Override
204
    public void setShapeType(int i) {
205
    }
206

    
207
    @Override
208
    public boolean isUseDefaultSymbol() {
209
        return true;
210
    }
211

    
212
    @Override
213
    public void useDefaultSymbol(boolean bln) {
214
    }
215

    
216
    @Override
217
    public boolean isSuitableForShapeType(int shapeType) {
218
        return GeometryUtils.isSubtype(Geometry.TYPES.POINT, shapeType);
219
    }
220

    
221
    @Override
222
    public void loadFromState(PersistentState state) throws PersistenceException {
223
        super.loadFromState(state);
224
        
225
        this.size = state.getDouble("size",DEFAULT_IMAGE_SIZE);
226
        this.units = state.getInt("units",-1);
227
        this.lineToOffsetColor = (Color) state.get("lineToOffsetColor");
228
        this.drawLineToOffset = state.getBoolean("drawLineToOffset",true);
229
        this.classifyingFieldName = state.getString("classifyingFieldName");
230
        
231
        this.offsetXFieldName = state.getString("offsetXFieldName");
232
        this.offsetYFieldName = state.getString("offsetYFieldName");
233
        this.rotationFieldName = state.getString("rotationFieldName");
234
        this.lineToOffsetColorFieldlName = state.getString("lineToOffsetColorFieldlName");
235

    
236
        this.imagesTableName = state.getString("imagesTableName");
237
        this.imagesTableClassifyingFieldName = state.getString("imagesTableClassifyingFieldName");
238
        this.imageFieldName = state.getString("imageFieldName");
239
        this.imageSelectedFieldName = state.getString("imageSelectedFieldName");
240
        
241
    }
242

    
243
    @Override
244
    public void saveToState(PersistentState state) throws PersistenceException {
245
        super.saveToState(state);
246
        
247
        state.set("size", this.size);
248
        state.set("units", this.units);
249
        state.set("lineToOffsetColor", this.lineToOffsetColor);
250
        state.set("drawLineToOffset", this.drawLineToOffset);
251
        state.set("classifyingFieldName", this.classifyingFieldName);
252

    
253
        state.set("offsetXFieldName", this.offsetXFieldName);
254
        state.set("offsetYFieldName", this.offsetYFieldName);
255
        state.set("rotationFieldName", this.rotationFieldName);
256
        state.set("lineToOffsetColorFieldlName", this.lineToOffsetColorFieldlName);
257

    
258
        state.set("imagesTableName", this.imagesTableName);
259
        state.set("imagesTableClassifyingFieldName", this.imagesTableClassifyingFieldName);
260
        state.set("imageFieldName", this.imageFieldName);
261
        state.set("imageSelectedFieldName", this.imageSelectedFieldName);
262
        
263
    }
264

    
265
    @Override
266
    protected String[] getRequiredFeatureAttributeNames(FeatureStore fs) throws DataException {
267
        List<String> attributes = new ArrayList<>();
268
        if( StringUtils.isNotBlank(this.classifyingFieldName)) {
269
            attributes.add(this.classifyingFieldName);
270
        }
271
        if( StringUtils.isNotBlank(this.offsetXFieldName)) {
272
            attributes.add(this.offsetXFieldName);
273
        }
274
        if( StringUtils.isNotBlank(this.offsetYFieldName)) {
275
            attributes.add(this.offsetYFieldName);
276
        }
277
        if( StringUtils.isNotBlank(this.rotationFieldName)) {
278
            attributes.add(this.rotationFieldName);
279
        }
280
        if( StringUtils.isNotBlank(this.lineToOffsetColorFieldlName)) {
281
            attributes.add(this.lineToOffsetColorFieldlName);
282
        }
283
        attributes.add( fs.getDefaultFeatureType().getDefaultGeometryAttributeName() );
284
        return attributes.toArray(new String[attributes.size()]);
285
    }
286

    
287
    @Override
288
    public Color getDefaultLineToOffsetColor() {
289
        return this.lineToOffsetColor;
290
    }
291

    
292
    @Override
293
    public void setDefaultLineToOffsetColor(Color color) {
294
        this.lineToOffsetColor = color;
295
    }
296

    
297
    @Override
298
    public boolean isDrawLineToOffset() {
299
        return this.drawLineToOffset;
300
    }
301

    
302
    @Override
303
    public void setDrawLineToOffset(boolean drawLineToOffset) {
304
        this.drawLineToOffset = drawLineToOffset;
305
    }
306

    
307
    @Override
308
    public double getImageSize() {
309
        return this.size;
310
    }
311

    
312
    @Override
313
    public void setImageSize(double size) {
314
        this.size = size;
315
    }
316

    
317
    @Override
318
    public String getLineToOffsetColorFieldName() {
319
        return this.lineToOffsetColorFieldlName;
320
    }
321

    
322
    @Override
323
    public void setLineToOffsetColorFieldName(String fieldName) {
324
        this.lineToOffsetColorFieldlName = fieldName;
325
    }
326

    
327
    @Override
328
    public String getOffsetXFieldName() {
329
        return this.offsetXFieldName;
330
    }
331

    
332
    @Override
333
    public void setOffsetXFieldName(String fieldName) {
334
        this.offsetXFieldName = fieldName;
335
    }
336

    
337
    @Override
338
    public String getOffsetYFieldName() {
339
        return this.offsetYFieldName;
340
    }
341

    
342
    @Override
343
    public void setOffsetYFieldName(String fieldName) {
344
        this.offsetYFieldName = fieldName;
345
    }
346

    
347
    @Override
348
    public String getRotationFieldName() {
349
        return this.rotationFieldName;
350
    }
351

    
352
    @Override
353
    public void setRotationFieldName(String fieldName) {
354
        this.rotationFieldName = fieldName;
355
    }
356

    
357
    @Override
358
    public String getImagesTableName() {
359
        return imagesTableName;
360
    }
361

    
362
    @Override
363
    public void setImagesTableName(String imagesTableName) {
364
        this.imagesTableName = imagesTableName;
365
        this.imagesCache.clear();
366
    }
367

    
368
    @Override
369
    public String getImageFieldName() {
370
        return imageFieldName;
371
    }
372

    
373
    @Override
374
    public void setImageFieldName(String imageFieldName) {
375
        this.imageFieldName = imageFieldName;
376
        this.imagesCache.clear();
377
    }
378

    
379
    @Override
380
    public String getClassifyingFieldName() {
381
        return classifyingFieldName;
382
    }
383

    
384
    @Override
385
    public void setClassifyingFieldName(String classifyingFieldName) {
386
        this.classifyingFieldName = classifyingFieldName;
387
        this.imagesCache.clear();
388
    }
389

    
390
    @Override
391
    public String getImageSelectedFieldName() {
392
        return imageSelectedFieldName;
393
    }
394

    
395
    @Override
396
    public void setImageSelectedFieldName(String imageSelectedFieldName) {
397
        this.imageSelectedFieldName = imageSelectedFieldName;
398
        this.imagesCache.clear();
399
    }
400

    
401
    @Override
402
    public String getImagesTableClassifyingFieldName() {
403
        return imagesTableClassifyingFieldName;
404
    }
405

    
406
    @Override
407
    public void setImagesTableClassifyingFieldName(String imagesTableClassifyingFieldName) {
408
        this.imagesTableClassifyingFieldName = imagesTableClassifyingFieldName;
409
        this.imagesCache.clear();
410
    }
411

    
412
    @Override
413
    public String[] getDescriptions() {
414
        return new String[] { this.classifyingFieldName + "->" + this.imagesTableName};
415
    }
416

    
417
    @Override
418
    public ISymbol[] getSymbols() {
419
        return new ISymbol[] { this.defaultSymbol };
420
    }
421

    
422
    @Override
423
    public Object[] getValues() {
424
        return new Object[] { "" } ;
425
    }
426

    
427
    @Override
428
    public int getUnits() {
429
        return units;
430
    }
431

    
432
    @Override
433
    public void setUnits(int units) {
434
        this.units = units;
435
    }
436
}