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 @ 5185

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.offsetYFieldName);
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
                    images[1] = images[0];
176
                }
177
                image = (SimpleImage) f.getFromProfile(this.imageSelectedFieldName);
178
                if( image != null && !image.isEmpty() ) {
179
                    images[1] = image.getBufferedImage();
180
                }
181
            }
182
        } catch(Exception ex) {
183
            LOGGER.debug("Can't retrieve images from table '"+this.imagesTableName+"'", ex);
184
        }
185
        this.imagesCache.put(classifyingValue, images);
186
        return images;
187
    }
188
    
189
    private ExpressionBuilder getExpressionBuilder() {
190
        if( this.expressionBuilder == null ) {
191
            this.expressionBuilder = ExpressionUtils.createExpressionBuilder();
192
        }
193
        return this.expressionBuilder;
194
    }
195
    
196
    private FeatureStore getImagesStore() {
197
        if( this.imagesStore == null ) {
198
            StoresRepository repository = DALLocator.getDataManager().getStoresRepository();
199
            this.imagesStore = (FeatureStore) repository.getStore(this.imagesTableName);
200
        }
201
        return this.imagesStore;
202
    }
203
    
204
    @Override
205
    public void setShapeType(int i) {
206
    }
207

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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