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 / SpatialManager.java @ 40559

History | View | Annotate | Download (10.9 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;
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.geom.GeometryLocator;
41
import org.gvsig.fmap.geom.primitive.Envelope;
42
import org.gvsig.tools.dispose.DisposableIterator;
43
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
45

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

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

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

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

    
104
        if (featureIndex instanceof DefaultFeatureIndex) {
105
            ((DefaultFeatureIndex) featureIndex).setValid(true);
106
        }
107
    }
108

    
109

    
110

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

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

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

    
189
    public void clear() {
190
    }
191

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

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

    
204

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

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

    
257

    
258

    
259
    public void cancelModifies() {
260
        if (noSpatialData) {
261
            return;
262
        }
263
        if (featureIndex != null){
264
            for (int i = feaOperation.size()-1 ; i>=0 ; i--){
265
                try {
266
                    FeatureOperation fo = (FeatureOperation) feaOperation.get(i);
267
                    if (fo.getOperation() == FeatureOperation.INSERT){                     
268
                        featureIndex.delete(fo.getFeatureReference().getFeature());
269
                    }else if (fo.getOperation() == FeatureOperation.DELETE){
270
                        featureIndex.insert(fo.getFeatureReference().getFeature());
271
                    }
272
                } catch (DataException e) {
273
                    LOG.error("Error canceling the edition", e);
274
                }           
275
            }
276
        }
277
        if (originalEnvelope!=null){
278
            fullEnvelope = originalEnvelope.getGeometry().getEnvelope();
279
        } else {
280
            fullEnvelope = null;
281
        }
282
        isFullExtentDirty = false;
283
    }
284

    
285
    private class FeatureOperation{
286
        final static int INSERT=0;
287
        final static int DELETE=1;
288
        private FeatureReference ref;
289
        private int operation;
290
        public FeatureOperation(FeatureReference fe,int op){
291
            ref=fe;
292
            operation=op;
293
        }
294
        public FeatureReference getFeatureReference() {
295
            return ref;
296
        }
297
        public void setFeatureReference(FeatureReference ref) {
298
            this.ref = ref;
299
        }
300
        public int getOperation() {
301
            return operation;
302
        }
303
        public void setOperation(int operation) {
304
            this.operation = operation;
305
        }
306
    }
307

    
308
}