Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / fmap / dal / feature / impl / editing / memory / SpatialManager.java @ 45785

History | View | Annotate | Download (11.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
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.fmap.dal.feature.impl.editing.memory;
25

    
26
import java.util.ArrayList;
27
import java.util.ConcurrentModificationException;
28
import java.util.Iterator;
29

    
30
import org.gvsig.fmap.dal.exception.DataException;
31
import org.gvsig.fmap.dal.feature.Feature;
32
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
33
import org.gvsig.fmap.dal.feature.FeatureIndex;
34
import org.gvsig.fmap.dal.feature.FeatureIndexes;
35
import org.gvsig.fmap.dal.feature.FeatureReference;
36
import org.gvsig.fmap.dal.feature.FeatureSet;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.dal.feature.FeatureType;
39
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
40
import org.gvsig.fmap.dal.feature.impl.DefaultFeature;
41
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureIndex;
42
import org.gvsig.fmap.geom.GeometryLocator;
43
import org.gvsig.fmap.geom.primitive.Envelope;
44
import org.gvsig.tools.dispose.DisposableIterator;
45
import org.slf4j.Logger;
46
import org.slf4j.LoggerFactory;
47

    
48
/**
49
 * DOCUMENT ME!
50
 *
51
 * @author Vicente Caballero Navarro
52
 */
53
public class SpatialManager {
54
    private static final Logger LOG = LoggerFactory.getLogger(SpatialManager.class);
55
    
56
    protected boolean isFullExtentDirty = true;
57
    private FeatureStore featureStore;
58
    private FeatureIndex featureIndex = null;
59
    private Envelope originalEnvelope = null;
60
    private Envelope fullEnvelope = null;
61
    private ArrayList feaOperation=new ArrayList();
62
    private boolean noSpatialData = false;
63

    
64
    public SpatialManager(FeatureStore featureStore, Envelope originalEnvelope)
65
            throws DataException {
66
        this.featureStore=featureStore;
67
        FeatureIndexes findexes=featureStore.getIndexes();
68
        // Comprobamos si hay algun campo espacial a manejar
69

    
70
        FeatureType fType = this.featureStore.getDefaultFeatureType();
71
        // TODO Multy FType !!
72
        if (fType.getDefaultGeometryAttributeIndex() < 0) {
73
            noSpatialData = true;
74
            return;
75
        }
76
        FeatureAttributeDescriptor attr = fType.getAttributeDescriptor(fType
77
                .getDefaultGeometryAttributeIndex());
78
        this.originalEnvelope = originalEnvelope;
79
        if ((originalEnvelope != null) && (!originalEnvelope.isEmpty())) {
80
            this.fullEnvelope = originalEnvelope.getGeometry().getEnvelope();
81
        } else {
82
            FeatureAttributeDescriptor geoAttr = fType.getAttributeDescriptor(fType.getDefaultGeometryAttributeIndex());
83
            try {
84
                this.fullEnvelope = GeometryLocator.getGeometryManager()
85
                        .createEnvelope(geoAttr.getGeometrySubType());
86
            } catch (Exception e) {
87
                // FIXME Excpetion
88
                throw new RuntimeException(e);
89
            }
90
        }
91
        if (!fType.hasOID()) {
92
            return;
93
        }
94

    
95
        Iterator iterator = findexes.iterator();
96
        FeatureIndex index;
97
        while (iterator.hasNext()) {
98
            index = (FeatureIndex) iterator.next();
99
            if (index.getAttributeNames().size() == 1
100
                    && index.getAttributeNames().contains(attr.getName())) {
101
                featureIndex = index;
102
                break;
103
            }
104
        }
105

    
106
        if (featureIndex instanceof DefaultFeatureIndex) {
107
            ((DefaultFeatureIndex) featureIndex).setValid(true);
108
        }
109
    }
110

    
111

    
112

    
113
    /**
114
     * DOCUMENT ME!
115
     *
116
     * @param feature DOCUMENT ME!
117
     * @param oldFeature DOCUMENT ME!
118
     */
119
    public void updateFeature(Feature feature, Feature oldFeature) {
120
        if (noSpatialData) {
121
            return;
122
        }
123
        try {
124
            if (oldFeature != null) {
125
                if (featureIndex != null) {
126
                    featureIndex.delete(oldFeature);
127
                }
128
                final FeatureReference reference = oldFeature.getReference();
129
                feaOperation.add(new FeatureOperation(reference, FeatureOperation.DELETE));
130
            }
131
            if (featureIndex != null) {
132
                featureIndex.insert(feature);
133
            }
134
            feaOperation.add(
135
                    new FeatureOperation(
136
                            feature.getReference(),
137
                            FeatureOperation.INSERT
138
                    )
139
            );
140
        } catch (DataException e) {
141
            throw new RuntimeException("Exception updating feature: "
142
                    + feature, e);
143
        }
144
        // } else {
145
        // fullEnvelope.add(feature.getDefaultEnvelope());
146
        isFullExtentDirty = true;
147
    }
148

    
149
    /**
150
     * DOCUMENT ME!
151
     *
152
     * @param feature DOCUMENT ME!
153
     */
154
    public void insertFeature(Feature feature) {
155
        if (noSpatialData) {
156
            return;
157
        }
158
            try {
159
                    if (featureIndex != null) {
160
                            featureIndex.insert(feature);
161
                    }
162
                feaOperation.add(new FeatureOperation(
163
                    ((DefaultFeature) feature).getReference(),
164
                    FeatureOperation.INSERT));
165
            } catch (DataException e) {
166
                throw new RuntimeException("Exception inserting feature: "
167
                    + feature, e);
168
            }
169
            isFullExtentDirty = true;
170
//        } else if (!isFullExtentDirty) {
171
//            fullEnvelope.add(feature.getDefaultEnvelope());
172
//        }
173
    }
174

    
175
    /**
176
     * DOCUMENT ME!
177
     *
178
     * @param feature DOCUMENT ME!
179
     */
180
    public void deleteFeature(Feature feature) {
181
        if (noSpatialData) {
182
            return;
183
        }
184
            try {
185
                    if (featureIndex != null) {
186
                            featureIndex.delete(feature);
187
                    }
188
                feaOperation.add(new FeatureOperation(((DefaultFeature) feature)
189
                        .getReference(), FeatureOperation.DELETE));
190
            } catch (DataException e) {
191
                throw new RuntimeException("Exception deleting feature: "
192
                    + feature, e);
193
            }
194
        isFullExtentDirty = true;
195
    }
196

    
197
    public void clear() {
198
    }
199

    
200
    public Envelope getEnvelope() throws DataException {
201
        if (noSpatialData) {
202
            return null;
203
        }
204
        if (!isFullExtentDirty){
205
            return this.fullEnvelope;
206
        }
207

    
208
        // FIXME in every changes when anyone ask for envelope it was regenerated.
209
        //       if we assume that the envelope may not be the minimum in edit mode
210
        //       this call must be very much faster
211

    
212

    
213
        FeatureAttributeDescriptor attr = featureStore.getDefaultFeatureType()
214
                .getAttributeDescriptor(
215
                        featureStore.getDefaultFeatureType()
216
                                .getDefaultGeometryAttributeIndex());
217
        Envelope fullEnvelope = null;
218

    
219
        FeatureSet set = null;
220
        DisposableIterator iterator = null;
221
        try {
222
            set = featureStore.getFeatureSet();
223
            iterator = set.fastIterator();
224
            //First while to initialize the feature envelope
225
            while (iterator.hasNext()) {
226
                Feature feature = (Feature) iterator.next();
227
                Envelope envelope = feature.getDefaultEnvelope();
228
                if (envelope != null){
229
                    fullEnvelope = (Envelope)envelope.clone();
230
                    break;
231
                }
232
            }           
233
            //Second while to add new evelopes tho the full envelope
234
            while (iterator.hasNext()) {
235
                Feature feature = (Feature) iterator.next();
236
                Envelope envelope = feature.getDefaultEnvelope();           
237
                if(envelope!=null){
238
                    fullEnvelope.add(envelope);
239
                }
240
            }
241
            //Creating an empty envelope by default
242
            if (fullEnvelope == null){
243
                fullEnvelope = GeometryLocator.getGeometryManager().createEnvelope(
244
                    attr.getGeometrySubType());
245
            }
246
        } catch (ConcurrentModificationException e) {
247
            throw e;
248
        } catch (ConcurrentDataModificationException e) {
249
            throw e;
250
        } catch (Exception e) {
251
            throw new RuntimeException(e);
252
        } finally {
253
            if (iterator != null) {
254
                iterator.dispose();
255
            }
256
            if (set != null) {
257
                set.dispose();
258
            }
259
        }
260
        this.fullEnvelope = fullEnvelope;
261
        this.isFullExtentDirty = false;
262
        return fullEnvelope;
263
    }
264

    
265

    
266

    
267
    public void cancelModifies() {
268
        if (noSpatialData) {
269
            return;
270
        }
271
        if (featureIndex != null){
272
            for (int i = feaOperation.size()-1 ; i>=0 ; i--){
273
                try {
274
                    FeatureOperation fo = (FeatureOperation) feaOperation.get(i);
275
                    if (fo.getOperation() == FeatureOperation.INSERT){                     
276
                        featureIndex.delete(fo.getFeatureReference().getFeature());
277
                    }else if (fo.getOperation() == FeatureOperation.DELETE){
278
                        featureIndex.insert(fo.getFeatureReference().getFeature());
279
                    }
280
                } catch (DataException e) {
281
                    LOG.error("Error canceling the edition", e);
282
                }           
283
            }
284
        }
285
        if (originalEnvelope!=null){
286
            try {
287
                fullEnvelope = (Envelope) originalEnvelope.clone();
288
            } catch (CloneNotSupportedException e) {
289
                // Should never happen
290
                LOG.error("While cloning envelope", e);
291
            }
292
        } else {
293
            fullEnvelope = null;
294
        }
295
        isFullExtentDirty = false;
296
    }
297

    
298
    private class FeatureOperation{
299
        final static int INSERT=0;
300
        final static int DELETE=1;
301
        private FeatureReference ref;
302
        private int operation;
303
        public FeatureOperation(FeatureReference fe,int op){
304
            ref=fe;
305
            operation=op;
306
        }
307
        public FeatureReference getFeatureReference() {
308
            return ref;
309
        }
310
        public void setFeatureReference(FeatureReference ref) {
311
            this.ref = ref;
312
        }
313
        public int getOperation() {
314
            return operation;
315
        }
316
        public void setOperation(int operation) {
317
            this.operation = operation;
318
        }
319
    }
320

    
321
}