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

History | View | Annotate | Download (11.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.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 (featureIndex != null) {
125
                            featureIndex.delete(oldFeature);
126
                    }
127
                feaOperation.add(new FeatureOperation(((DefaultFeature) oldFeature)
128
                        .getReference(), FeatureOperation.DELETE));
129
                    if (featureIndex != null) {
130
                            featureIndex.insert(feature);
131
                    }
132
                feaOperation.add(new FeatureOperation(((DefaultFeature) feature)
133
                        .getReference(), FeatureOperation.INSERT));
134
            } catch (DataException e) {
135
                throw new RuntimeException("Exception updating feature: "
136
                    + feature, e);
137
            }
138
            // } else {
139
            // fullEnvelope.add(feature.getDefaultEnvelope());
140
        isFullExtentDirty = true;
141
    }
142

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

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

    
191
    public void clear() {
192
    }
193

    
194
    public Envelope getEnvelope() throws DataException {
195
        if (noSpatialData) {
196
            return null;
197
        }
198
        if (!isFullExtentDirty){
199
            return this.fullEnvelope;
200
        }
201

    
202
        // FIXME in every changes when anyone ask for envelope it was regenerated.
203
        //       if we assume that the envelope may not be the minimum in edit mode
204
        //       this call must be very much faster
205

    
206

    
207
        FeatureAttributeDescriptor attr = featureStore.getDefaultFeatureType()
208
                .getAttributeDescriptor(
209
                        featureStore.getDefaultFeatureType()
210
                                .getDefaultGeometryAttributeIndex());
211
        Envelope fullEnvelope = null;
212

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

    
259

    
260

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

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

    
315
}