Statistics
| Revision:

gvsig-projects-pool / org.gvsig.topology / trunk / org.gvsig.topology / org.gvsig.topology.lib / org.gvsig.topology.lib.impl / src / main / java / org / gvsig / topology / lib / impl / DefaultTopologyDataSet.java @ 726

History | View | Annotate | Download (13.2 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
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.topology.lib.impl;
25

    
26
import java.util.Iterator;
27
import java.util.Map;
28
import org.apache.commons.collections.IteratorUtils;
29
import org.apache.commons.lang3.StringUtils;
30
import org.apache.commons.lang3.mutable.MutableObject;
31
import org.gvsig.expressionevaluator.Expression;
32
import org.gvsig.fmap.dal.EditingNotification;
33
import org.gvsig.fmap.dal.EditingNotificationManager;
34
import org.gvsig.fmap.dal.exception.DataException;
35
import org.gvsig.fmap.dal.feature.EditableFeature;
36
import org.gvsig.fmap.dal.feature.Feature;
37
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
38
import org.gvsig.fmap.dal.feature.FeatureReference;
39
import org.gvsig.fmap.dal.feature.FeatureStore;
40
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
41
import org.gvsig.fmap.dal.feature.FeatureType;
42
import org.gvsig.fmap.dal.swing.DALSwingLocator;
43
import org.gvsig.fmap.geom.Geometry;
44
import org.gvsig.fmap.geom.GeometryLocator;
45
import org.gvsig.fmap.geom.GeometryManager;
46
import org.gvsig.fmap.geom.SpatialIndex;
47
import org.gvsig.fmap.geom.type.GeometryType;
48
import org.gvsig.tools.exception.BaseException;
49
import org.gvsig.tools.util.PropertiesSupportHelper;
50
import org.gvsig.tools.visitor.VisitCanceledException;
51
import org.gvsig.tools.visitor.Visitor;
52
import org.gvsig.topology.lib.api.CancelOperationException;
53
import org.gvsig.topology.lib.api.PerformOperationException;
54
import org.gvsig.topology.lib.api.TopologyDataSet;
55
import org.gvsig.topology.lib.api.TopologyLocator;
56
import org.gvsig.topology.lib.api.TopologyManager;
57
import org.json.JSONObject;
58
import org.gvsig.topology.lib.api.TopologyServices;
59
import org.slf4j.Logger;
60
import org.slf4j.LoggerFactory;
61

    
62
/**
63
 *
64
 * @author jjdelcerro
65
 */
66
@SuppressWarnings({"EqualsAndHashcode","UseSpecificCatch"})
67
public class DefaultTopologyDataSet implements TopologyDataSet {
68

    
69
    private final static Logger LOGGER = LoggerFactory.getLogger(DefaultTopologyDataSet.class);
70
    
71
    private TopologyServices services;
72
    private String name;
73
    private FeatureStore store;
74
    private boolean needFinishEditing;
75
    private String fullName;
76
    private PropertiesSupportHelper propertiesHelper;
77
    private MutableObject<SpatialIndex> spatialIndex = null;
78
    
79
    public DefaultTopologyDataSet() {
80
        this.services = null;
81
        this.name = null;
82
        this.store = null;
83
        this.needFinishEditing = false;
84
        this.fullName = null;
85
        this.propertiesHelper = new PropertiesSupportHelper();
86
    }
87

    
88
    public DefaultTopologyDataSet(TopologyServices services, String name, FeatureStore store) {
89
        this.services = services;
90
        this.name = name;
91
        this.store = store;
92
        this.needFinishEditing = false;
93
        if( store!=null ) {
94
            this.fullName = store.getFullName();
95
        }
96
    }
97

    
98
    public void restart() {
99
        this.store  = null;
100
        this.spatialIndex = null;
101
    }
102
    
103
    @Override
104
    public boolean equals(Object obj) {
105
        if( !(obj instanceof DefaultTopologyDataSet) ) {
106
            return false;
107
        }
108
        DefaultTopologyDataSet other = (DefaultTopologyDataSet)obj;
109
        if( this.store != other.store ) {
110
            return false;
111
        }
112
        if( !StringUtils.equals(this.getName(), other.getName()) ) {
113
            return false;
114
        }
115
        return true;
116
    }
117

    
118
    @Override
119
    public String getName() {
120
        return this.name;
121
    }
122

    
123
    @Override
124
    public void setName(String name) {
125
        this.name = name;
126
    }
127

    
128
    @Override
129
    public String toString() {
130
        try {
131
            FeatureAttributeDescriptor attr = this.getStore().getDefaultFeatureType().getDefaultGeometryAttribute();
132
            String geomType = attr.getGeomType().getName();
133
            return this.name + " ("+ geomType + ")";
134
        } catch(Exception ex) {
135
            return this.name ;
136
        }
137
    }
138

    
139
    @Override
140
    public FeatureStore getStore() {
141
        if (this.store == null) {
142
            this.store = this.services.getFeatureStore(this);
143
        }
144
        return this.store;
145
    }
146

    
147
    @Override
148
    public long getSize() {
149
        try {
150
            long size = this.getStore().getFeatureCount();
151
            return size;
152
        } catch (DataException ex) {
153
            // TODO: mensage al log
154
            return 0;
155
        }
156
    }
157

    
158
    @Override
159
    public boolean isThisStore(FeatureStore store) {
160
        if( store == null ) {
161
            return false;
162
        }
163
        return StringUtils.equals(this.fullName, store.getFullName());
164
    }
165
    
166
    @Override
167
    public int getGeometryType() {
168
        try {
169
            FeatureStore theStore = this.getStore();
170
            FeatureType featureType = theStore.getDefaultFeatureType();
171
            FeatureAttributeDescriptor attr = featureType.getDefaultGeometryAttribute();
172
            GeometryType geomType = attr.getGeomType();
173
            return geomType.getType();
174
        } catch (Exception ex) {
175
            return Geometry.TYPES.GEOMETRY;
176
        }
177
    }
178

    
179
    @Override
180
    public void accept(Visitor visitor) throws VisitCanceledException {
181
        FeatureStore st = this.getStore();
182
        try {
183
            st.accept(visitor);
184
        } catch(VisitCanceledException ex) {
185
            throw ex;
186
        } catch(BaseException ex) {
187
            throw new RuntimeException(ex);
188
        }
189
    }
190

    
191
    @Override
192
    public void edit() throws DataException {
193
        FeatureStore theStore = this.getStore();
194
        if (!theStore.isEditing()) {
195
            theStore.edit();
196
            this.needFinishEditing = true;
197
        }
198
    }
199

    
200
    @Override
201
    public void finishEditing() throws DataException {
202
        if (this.needFinishEditing) {
203
            this.getStore().finishEditing();
204
        }
205
    }
206

    
207
    @Override
208
    public EditableFeature createNewFeature() throws DataException {
209
        EditableFeature f = this.getStore().createNewFeature();
210
        return f;
211
    }
212

    
213
    public void perform(
214
            String operation,
215
            Feature feature
216
    ) throws DataException {
217
        this.edit();
218

    
219
        EditingNotificationManager editingNotificationManager
220
                = DALSwingLocator.getEditingNotificationManager();
221
        FeatureStore theStore = this.getStore();
222
        
223
        EditingNotification notification
224
                = editingNotificationManager.notifyObservers(this, // source
225
                        operation, // type
226
                        null,// document
227
                        null,// layer
228
                        theStore,// store
229
                        feature// feature
230
                );
231

    
232
        if (notification.isCanceled()) {
233
            String msg = String.format(
234
                    "Can't insert feature into %1$s, canceled by some observer.",
235
                    this.getName());
236
            throw new CancelOperationException(msg);
237
        }
238
        
239
        String after = null;
240
        if( operation.equalsIgnoreCase(EditingNotification.BEFORE_REMOVE_FEATURE) ) {
241
            theStore.delete(feature);
242
            after = EditingNotification.AFTER_REMOVE_FEATURE;
243
            
244
        } else {
245
            if (notification.shouldValidateTheFeature()) {
246
                if (!editingNotificationManager.validateFeature(feature)) {
247
                    String msg = String.format("%1$s is not valid", feature.toString());
248
                    throw new PerformOperationException(msg);
249
                }
250
            }
251
            switch(operation) {
252
                case EditingNotification.BEFORE_UPDATE_FEATURE:
253
                    theStore.update((EditableFeature) feature);
254
                    after = EditingNotification.AFTER_UPDATE_FEATURE;
255
                    break;
256

    
257
                case EditingNotification.BEFORE_INSERT_FEATURE:
258
                    theStore.insert((EditableFeature) feature);
259
                    after = EditingNotification.AFTER_INSERT_FEATURE;
260
                    break;
261
            }
262
        }
263

    
264
        editingNotificationManager.notifyObservers(this,
265
                after, null, null,
266
                theStore, feature);
267

    
268
    }
269

    
270
    @Override
271
    public void insert(final EditableFeature feature) throws DataException {
272
        perform(
273
            EditingNotification.BEFORE_INSERT_FEATURE,
274
            feature
275
        );
276
    }
277

    
278
    @Override
279
    public void update(final EditableFeature feature) throws DataException {
280
        perform(
281
            EditingNotification.BEFORE_UPDATE_FEATURE,
282
            feature
283
        );
284
    }
285

    
286
    @Override
287
    public void delete(final Feature feature) throws DataException {
288
        perform(
289
            EditingNotification.BEFORE_REMOVE_FEATURE,
290
            feature
291
        );
292
    }
293

    
294
    @Override
295
    public void delete(final FeatureReference feature) throws DataException {
296
        perform(
297
            EditingNotification.BEFORE_REMOVE_FEATURE,
298
            feature.getFeature()
299
        );
300
    }
301

    
302
    @Override
303
    public JSONObject toJSON() {
304
        JSONObject jsonDataSet = new JSONObject();
305
        jsonDataSet.put("name", this.name);
306
        jsonDataSet.put("fullName", this.fullName);
307

    
308
        return jsonDataSet;
309
    }
310

    
311
    @Override
312
    public void fromJSON(String json) {
313
        this.fromJSON(new JSONObject(json));
314
    }
315

    
316
    @Override
317
    public void fromJSON(JSONObject json) {
318
        TopologyManager manager = TopologyLocator.getTopologyManager();
319
        this.name = json.getString("name");
320
        this.fullName = null;
321
        if( json.has("fullName") ) {
322
            this.fullName = json.getString("fullName");
323
        }
324
        this.store = null;
325
        this.needFinishEditing = false;
326
        this.services = manager.getDefaultServices();
327
    }
328

    
329
    @Override
330
    public Object getProperty(String string) {
331
        return this.propertiesHelper.getProperty(name);
332
    }
333

    
334
    @Override
335
    public void setProperty(String string, Object o) {
336
        this.propertiesHelper.setProperty(name, o);
337
    }
338

    
339
    @Override
340
    public Map<String, Object> getProperties() {
341
        return this.propertiesHelper.getProperties();
342
    }
343

    
344
    public SpatialIndex getSpatialIndex() {
345
        if( this.spatialIndex == null ) {
346
            this.spatialIndex = new MutableObject<>();
347
            FeatureStore theStore = this.getStore();
348
            FeatureStoreProviderFactory storeFactory = (FeatureStoreProviderFactory) theStore.getProviderFactory();
349
            if( storeFactory.useLocalIndexesCanImprovePerformance()==FeatureStoreProviderFactory.YES ) {
350
                try {
351
                    GeometryManager geomManager = GeometryLocator.getGeometryManager();
352
                    final SpatialIndex geomIndex = geomManager.createSpatialIndex(
353
                            GeometryManager.SPATIALINDEX_DEFAULT_QUADTREE,
354
                            null
355
                    );
356
                    final SpatialIndex dataIndex = theStore.wrapSpatialIndex(geomIndex);
357
                    try {
358
                        store.accept(new Visitor() {
359
                            @Override
360
                            public void visit(Object o) throws VisitCanceledException, BaseException {
361
                                Feature f = (Feature) o;
362
                                Geometry geom = f.getDefaultGeometry();
363
                                if (geom != null) {
364
                                    dataIndex.insert(geom, f);
365
                                }
366
                            }
367
                        });
368
                    } catch (VisitCanceledException ex) {
369
                    }
370
                    this.spatialIndex.setValue(dataIndex);
371
                } catch (Exception ex) {
372
                    LOGGER.warn("Can't create spatial index", ex);
373
                }
374
            }
375
        }
376
        return this.spatialIndex.getValue();
377
    }
378

    
379
    public Iterable<FeatureReference> query(Geometry geom) {
380
        SpatialIndex index = this.getSpatialIndex();
381
        if( index == null ) {
382
            return (Iterable<FeatureReference>) IteratorUtils.EMPTY_ITERATOR;
383
        }
384
        final Iterator it = index.query(geom);
385
        if( it == null ) {
386
            return (Iterable<FeatureReference>) IteratorUtils.EMPTY_ITERATOR;
387
        }
388
        return new Iterable<FeatureReference>() {
389
            @Override
390
            public Iterator<FeatureReference> iterator() {
391
                return it;
392
            }
393
        };
394
    }
395

    
396
    @Override
397
    public Feature findFirst(Expression filter) {
398
        try {
399
            return this.getStore().findFirst(filter);
400
        } catch (Exception ex) {
401
            return null;
402
        }
403
    }
404

    
405
}