Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.mapcontext / org.gvsig.fmap.mapcontext.api / src / main / java / org / gvsig / fmap / mapcontext / layers / vectorial / impl / DefaultGraphicLayer.java @ 42219

History | View | Annotate | Download (14.4 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.mapcontext.layers.vectorial.impl;
24

    
25
import java.util.Iterator;
26

    
27
import org.cresques.cts.ICoordTrans;
28
import org.cresques.cts.IProjection;
29
import org.gvsig.fmap.dal.DALLocator;
30
import org.gvsig.fmap.dal.DataManager;
31
import org.gvsig.fmap.dal.DataTypes;
32
import org.gvsig.fmap.dal.exception.DataException;
33
import org.gvsig.fmap.dal.exception.ReadException;
34
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
35
import org.gvsig.fmap.dal.feature.EditableFeature;
36
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
37
import org.gvsig.fmap.dal.feature.EditableFeatureType;
38
import org.gvsig.fmap.dal.feature.Feature;
39
import org.gvsig.fmap.dal.feature.FeatureSet;
40
import org.gvsig.fmap.dal.feature.FeatureStore;
41
import org.gvsig.fmap.dal.feature.FeatureType;
42
import org.gvsig.fmap.geom.Geometry;
43
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
44
import org.gvsig.fmap.geom.Geometry.TYPES;
45
import org.gvsig.fmap.geom.GeometryLocator;
46
import org.gvsig.fmap.geom.GeometryManager;
47
import org.gvsig.fmap.geom.primitive.Envelope;
48
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
49
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
50
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
51
import org.gvsig.fmap.mapcontext.layers.vectorial.GraphicLayer;
52
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
53
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorialUniqueValueLegend;
54
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
55
import org.gvsig.tools.dispose.DisposableIterator;
56
import org.gvsig.tools.exception.BaseException;
57
import org.slf4j.Logger;
58
import org.slf4j.LoggerFactory;
59

    
60
/**
61
 * Default {@link GraphicLayer} implementation.
62
 *
63
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
64
 */
65
public class DefaultGraphicLayer extends FLyrVect implements GraphicLayer {
66

    
67
    private static final String DEFAULT = "default";
68
    protected static final Logger logger = LoggerFactory.getLogger(DefaultGraphicLayer.class);
69
    private static DataManager dataManager = DALLocator.getDataManager();
70
    private IVectorialUniqueValueLegend legend = null;
71

    
72
    private FeatureStore store = null;
73
    private long ids = 0;
74

    
75
    private int symbolId = -1;
76

    
77
    private int featureIdIndex;
78
    private int groupIdIndex;
79
    private int geomIndex;
80
    private int idsymIndex;
81
    private int labelIndex;
82
    private int tagIndex;
83
    private int priorityIndex;
84

    
85
    public void initialize(IProjection projection) throws ValidateDataParametersException, DataException, LoadLayerException {
86
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
87
        store = dataManager.createMemoryStore(FEATURE_ATTR_PRIORITY);
88
        store.edit();
89

    
90
        EditableFeatureType editableFeatureType = store.getDefaultFeatureType().getEditable();
91

    
92
        editableFeatureType.add(GraphicLayer.FEATURE_ATTR_GROUPID, DataTypes.STRING);
93

    
94
        EditableFeatureAttributeDescriptor geometryDescriptor = editableFeatureType.add(GraphicLayer.FEATURE_ATTR_GEOMETRY, DataTypes.GEOMETRY);
95
        try {
96
            geometryDescriptor.setGeometryType(geomManager.getGeometryType(TYPES.GEOMETRY, SUBTYPES.GEOM2D));
97
        } catch (Exception e) {
98
            logger.info("Can't create/assign geomery type to feature type of GraphicLayer.", e);
99
        }
100
        geometryDescriptor.setSRS(projection);
101
        editableFeatureType.setDefaultGeometryAttributeName(GraphicLayer.FEATURE_ATTR_GEOMETRY);
102

    
103
        editableFeatureType.add(GraphicLayer.FEATURE_ATTR_IDSYMBOL, DataTypes.INT);
104

    
105
        editableFeatureType.add(GraphicLayer.FEATURE_ATTR_LABEL, DataTypes.STRING);
106

    
107
        EditableFeatureAttributeDescriptor featureIdDescriptor
108
                = editableFeatureType.add(GraphicLayer.FEATURE_ATTR_FEATUREID, DataTypes.LONG);
109

    
110
        editableFeatureType.add(GraphicLayer.FEATURE_ATTR_TAG, DataTypes.OBJECT);
111
        editableFeatureType.add(GraphicLayer.FEATURE_ATTR_PRIORITY, DataTypes.INT);
112

    
113
        featureIdDescriptor.setIsPrimaryKey(true);
114
        editableFeatureType.setHasOID(true);
115

    
116
        store.update(editableFeatureType);
117

    
118
        store.finishEditing();
119

    
120
        FeatureType ftype = store.getDefaultFeatureType();
121
        featureIdIndex = ftype.getIndex(GraphicLayer.FEATURE_ATTR_FEATUREID);
122
        groupIdIndex = ftype.getIndex(GraphicLayer.FEATURE_ATTR_GROUPID);
123
        geomIndex = ftype.getIndex(GraphicLayer.FEATURE_ATTR_GEOMETRY);
124
        idsymIndex = ftype.getIndex(GraphicLayer.FEATURE_ATTR_IDSYMBOL);
125
        labelIndex = ftype.getIndex(GraphicLayer.FEATURE_ATTR_LABEL);
126
        tagIndex = ftype.getIndex(GraphicLayer.FEATURE_ATTR_TAG);
127
        priorityIndex = ftype.getIndex(GraphicLayer.FEATURE_ATTR_PRIORITY);
128

    
129
        this.bindToDataStore(store);
130

    
131
        setName("Graphic Layer");
132
    }
133

    
134
    public void addGraphic(String groupId, Geometry geom, int idsym) {
135
        addGraphic(groupId, geom, idsym, null, null, DEFAULT_PRIORITY);
136
    }
137

    
138
    public void addGraphic(Geometry geom, int idsym) {
139
        addGraphic(DEFAULT, geom, idsym, null, null, DEFAULT_PRIORITY);
140
    }
141

    
142
    public void addGraphic(Geometry geom, int idsym, String label) {
143
        addGraphic(DEFAULT, geom, idsym, label, null, DEFAULT_PRIORITY);
144
    }
145

    
146
    public void addGraphic(String groupId, Geometry geom, int idsym, String label) {
147
        addGraphic(groupId, geom, idsym, label, null, DEFAULT_PRIORITY);
148
    }
149

    
150
    public void addGraphic(String groupId, Geometry geom, int idsym, String label,
151
            Object tag, int priority) {
152

    
153
        try {
154
            store.beginComplexNotification();
155
            // Just in case another thread is going to read from the store
156
            synchronized (store) {
157
                if (store.isEditing() || store.isAppending() ) {
158
                    insertGeometry(groupId, geom, idsym, label, tag, priority);
159
                } else {
160
                    store.edit(FeatureStore.MODE_APPEND);
161
                    try {
162
                        insertGeometry(groupId, geom, idsym, label, tag, priority);
163
                        store.finishEditing();
164
                    } catch(Throwable th) {
165
                        try {
166
                            store.cancelEditing();
167
                        } catch(Throwable th2) {
168
                            // Do nothing
169
                        }
170
                        throw th;
171
                    }
172
                }
173
            }
174
        } catch (Throwable th) {
175
            logger.warn("Error adding a geometry to the graphic layer", th);
176
        } finally {
177
            try {
178
                store.endComplexNotification();
179
            } catch(Exception ex) {
180
                // Do nothing
181
            }
182
        }
183
    }
184

    
185
    private void insertGeometry(String groupId, Geometry geom, int idsym,
186
            String label, Object tag, int priority) throws DataException {
187
        EditableFeature feature = store.createNewFeature().getEditable();
188
        feature.setString(groupIdIndex, groupId);
189
        feature.setGeometry(geomIndex, geom);
190
        feature.setInt(idsymIndex, idsym);
191
        feature.setString(labelIndex, label);
192
        feature.setLong(featureIdIndex, ids);
193
        feature.set(tagIndex, tag);
194
        feature.setInt(priorityIndex, priority);
195

    
196
        ids++;
197

    
198
        store.insert(feature);
199
    }
200

    
201
    public void addGraphics(String groupId, Iterator geoms, int idsym) {
202
        addGraphics(groupId, geoms, idsym, null, null, DEFAULT_PRIORITY);
203
    }
204

    
205
    public void addGraphics(String groupId, Iterator geoms, int idsym,
206
            String label) {
207
        addGraphics(groupId, geoms, idsym, label, null, DEFAULT_PRIORITY);
208
    }
209

    
210
    public void addGraphics(String groupId, Iterator geoms, int idsym,
211
            String label, Object tag, int priority) {
212
        try {
213
            // Just in case another thread is going to read from the store
214
            synchronized (store) {
215
                if (store.isEditing() || store.isAppending() ) {
216
                    store.disableNotifications();
217
                    for (; geoms.hasNext();) {
218
                        Geometry geom = (Geometry) geoms.next();
219
                        insertGeometry(groupId, geom, idsym, label, tag, priority);
220
                    }
221
                    store.enableNotifications();
222
                } else {
223
                    store.edit(FeatureStore.MODE_APPEND);
224
                    try {
225
                        store.disableNotifications();
226
                        for (; geoms.hasNext();) {
227
                            Geometry geom = (Geometry) geoms.next();
228
                            insertGeometry(groupId, geom, idsym, label, tag, priority);
229
                        }
230
                        store.enableNotifications();
231
                        store.finishEditing();
232
                    } catch(Throwable th) {
233
                        try {
234
                            store.cancelEditing();
235
                        } catch(Throwable th2) {
236
                            // Do nothing
237
                        }
238
                        throw th;
239
                        
240
                    }
241
                }
242
            }
243
        } catch (Throwable th) {
244
            logger.warn("Error adding a geometry to the graphic layer", th);
245
        }
246
    }
247

    
248
    public int addSymbol(ISymbol newSymbol) {
249
        symbolId++;
250
        legend.addSymbol(new Integer(symbolId), newSymbol);
251
        return symbolId;
252
    }
253

    
254
    public ISymbol getSymbol(int symbolPos) {
255
        return legend.getSymbolByValue(new Integer(symbolPos));
256
    }
257

    
258
    public int getSymbolId(ISymbol symbol) {
259
        Object key = legend.getSymbolKey(symbol);
260
        return key == null ? -1 : ((Number) key).intValue();
261
    }
262

    
263
    public void clearAllGraphics() {
264
        DisposableIterator iterator = null;
265
        FeatureSet featureSet = null;
266
        try {
267
            if (!store.isEditing()) {
268
                store.edit();
269
                featureSet = store.getFeatureSet();
270
                for (iterator = featureSet.fastIterator(); iterator.hasNext();) {
271
                    Feature feature = (Feature) iterator.next();
272
                    featureSet.delete(feature);
273
                }
274
                store.finishEditing();
275
            } else {
276
                featureSet = store.getFeatureSet();
277
                for (iterator = featureSet.fastIterator(); iterator.hasNext();) {
278
                    Feature feature = (Feature) iterator.next();
279
                    featureSet.delete(feature);
280
                }
281
            }
282
        } catch (DataException e) {
283
            logger.warn("Error clearing all the geometry of the graphic layer", e);
284
        } finally {
285
            if (featureSet != null) {
286
                featureSet.dispose();
287
            }
288
            if (iterator != null) {
289
                iterator.dispose();
290
            }
291
        }
292
    }
293

    
294
    public int clearAllSymbols() {
295
        legend.clear();
296
        symbolId = -1;
297
        return symbolId;
298
    }
299

    
300
    public void removeGraphics(String groupId) {
301
        DisposableIterator iterator = null;
302
        FeatureSet featureSet = null;
303
        try {
304
            store.beginComplexNotification();
305
            if (!store.isEditing()) {
306
                store.edit();
307
                featureSet = store.getFeatureSet();
308
                store.beginEditingGroup(groupId);
309
                for (iterator = featureSet.fastIterator(); iterator.hasNext();) {
310
                    Feature feature = (Feature) iterator.next();
311
                    if (feature.get(FEATURE_ATTR_GROUPID).equals(groupId)) {
312
                        featureSet.delete(feature);
313
                    }
314
                }
315
                store.endEditingGroup();
316
                store.finishEditing();
317
            } else {
318
                featureSet = store.getFeatureSet();
319
                store.beginEditingGroup(groupId);
320
                for (iterator = featureSet.fastIterator(); iterator.hasNext();) {
321
                    Feature feature = (Feature) iterator.next();
322
                    if (feature.get(FEATURE_ATTR_GROUPID).equals(groupId)) {
323
                        featureSet.delete(feature);
324
                    }
325
                }
326
                store.endEditingGroup();
327
            }
328
            store.endComplexNotification();
329
        } catch (DataException e) {
330
            logger.warn("Error clearing all the geometry of the graphic layer", e);
331
        } finally {
332
            if (featureSet != null) {
333
                featureSet.dispose();
334
            }
335
            if (iterator != null) {
336
                iterator.dispose();
337
            }
338
        }
339
    }
340

    
341
    protected void doDispose() throws BaseException {
342
        super.doDispose();
343
        if (store != null) {
344
            store.dispose();
345
            store = null;
346
        }
347
    }
348

    
349
    public void setLegend(IVectorLegend legend) throws LegendLayerException {
350
        if (legend instanceof IVectorialUniqueValueLegend) {
351
            super.setLegend(legend);
352
            this.legend = (IVectorialUniqueValueLegend) legend;
353
            this.legend.setClassifyingFieldNames(new String[]{FEATURE_ATTR_IDSYMBOL});
354
        } else {
355
            if (this.legend != null) { // Skip the first assignment, is always bad.
356
                logger.warn("The allocation of legend type '" + legend.getClass().getName() + "' is ignored. Required a legend of type IVectorialUniqueValueLegend.");
357
            }
358
        }
359
    }
360

    
361
    public Envelope getFullEnvelope() throws ReadException {
362
        Envelope rAux;
363
        try {
364
            rAux = getFeatureStore().getEnvelope();
365
        } catch (BaseException e) {
366
            throw new ReadException(getName(), e);
367
        }
368

    
369
        if (rAux == null) {
370
            return null;
371
        }
372

    
373
        ICoordTrans ct = getCoordTrans();
374
        if (ct != null) {
375
            rAux = rAux.convert(ct);
376
        }
377
        return rAux;
378
    }
379
}