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

History | View | Annotate | Download (11.2 KB)

1

    
2
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
3
 *
4
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
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 2
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 *
22
 *  Generalitat Valenciana
23
 *   Conselleria d'Infraestructures i Transport
24
 *   Av. Blasco Ib??ez, 50
25
 *   46010 VALENCIA
26
 *   SPAIN
27
 *
28
 *      +34 963862235
29
 *   gvsig@gva.es
30
 *      www.gvsig.gva.es
31
 *
32
 *    or
33
 *
34
 *   IVER T.I. S.A
35
 *   Salamanca 50
36
 *   46005 Valencia
37
 *   Spain
38
 *
39
 *   +34 963163400
40
 *   dac@iver.es
41
 */
42

    
43
package org.gvsig.fmap.dal.feature.impl;
44

    
45
import java.util.ArrayList;
46
import java.util.ConcurrentModificationException;
47
import java.util.Iterator;
48

    
49
import org.gvsig.fmap.dal.exception.DataException;
50
import org.gvsig.fmap.dal.feature.Feature;
51
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
52
import org.gvsig.fmap.dal.feature.FeatureIndex;
53
import org.gvsig.fmap.dal.feature.FeatureIndexes;
54
import org.gvsig.fmap.dal.feature.FeatureReference;
55
import org.gvsig.fmap.dal.feature.FeatureSet;
56
import org.gvsig.fmap.dal.feature.FeatureStore;
57
import org.gvsig.fmap.dal.feature.FeatureType;
58
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
59
import org.gvsig.fmap.geom.GeometryLocator;
60
import org.gvsig.fmap.geom.primitive.Envelope;
61
import org.gvsig.tools.dispose.DisposableIterator;
62
import org.slf4j.Logger;
63
import org.slf4j.LoggerFactory;
64

    
65
/**
66
 * DOCUMENT ME!
67
 *
68
 * @author Vicente Caballero Navarro
69
 */
70
public class SpatialManager {
71
    private static final Logger LOG = LoggerFactory.getLogger(SpatialManager.class);
72
    
73
    protected boolean isFullExtentDirty = true;
74
    private FeatureStore featureStore;
75
    private FeatureIndex featureIndex = null;
76
    private Envelope originalEnvelope = null;
77
    private Envelope fullEnvelope = null;
78
    private ArrayList feaOperation=new ArrayList();
79
    private boolean noSpatialData = false;
80

    
81
    public SpatialManager(FeatureStore featureStore, Envelope originalEnvelope)
82
            throws DataException {
83
        this.featureStore=featureStore;
84
        FeatureIndexes findexes=featureStore.getIndexes();
85
        // Comprobamos si hay algun campo espacial a manejar
86

    
87
        FeatureType fType = this.featureStore.getDefaultFeatureType();
88
        // TODO Multy FType !!
89
        if (fType.getDefaultGeometryAttributeIndex() < 0) {
90
            noSpatialData = true;
91
            return;
92
        }
93
        FeatureAttributeDescriptor attr = fType.getAttributeDescriptor(fType
94
                .getDefaultGeometryAttributeIndex());
95
        this.originalEnvelope = originalEnvelope;
96
        if ((originalEnvelope != null) && (!originalEnvelope.isEmpty())) {
97
            this.fullEnvelope = originalEnvelope.getGeometry().getEnvelope();
98
        } else {
99
            FeatureAttributeDescriptor geoAttr = fType.getAttributeDescriptor(fType.getDefaultGeometryAttributeIndex());
100
            try {
101
                this.fullEnvelope = GeometryLocator.getGeometryManager()
102
                        .createEnvelope(geoAttr.getGeometrySubType());
103
            } catch (Exception e) {
104
                // FIXME Excpetion
105
                throw new RuntimeException(e);
106
            }
107
        }
108
        if (!fType.hasOID()) {
109
            return;
110
        }
111

    
112
        Iterator iterator = findexes.iterator();
113
        FeatureIndex index;
114
        while (iterator.hasNext()) {
115
            index = (FeatureIndex) iterator.next();
116
            if (index.getAttributeNames().size() == 1
117
                    && index.getAttributeNames().contains(attr.getName())) {
118
                featureIndex = index;
119
                break;
120
            }
121
        }
122

    
123
        if (featureIndex instanceof DefaultFeatureIndex) {
124
            ((DefaultFeatureIndex) featureIndex).setValid(true);
125
        }
126
    }
127

    
128

    
129

    
130
    /**
131
     * DOCUMENT ME!
132
     *
133
     * @param feature DOCUMENT ME!
134
     * @param oldFeature DOCUMENT ME!
135
     */
136
    public void updateFeature(Feature feature, Feature oldFeature) {
137
        if (noSpatialData) {
138
            return;
139
        }
140
            try {
141
                    if (featureIndex != null) {
142
                            featureIndex.delete(oldFeature);
143
                    }
144
                feaOperation.add(new FeatureOperation(((DefaultFeature) oldFeature)
145
                        .getReference(), FeatureOperation.DELETE));
146
                    if (featureIndex != null) {
147
                            featureIndex.insert(feature);
148
                    }
149
                feaOperation.add(new FeatureOperation(((DefaultFeature) feature)
150
                        .getReference(), FeatureOperation.INSERT));
151
            } catch (DataException e) {
152
                throw new RuntimeException("Exception updating feature: "
153
                    + feature, e);
154
            }
155
            // } else {
156
            // fullEnvelope.add(feature.getDefaultEnvelope());
157
        isFullExtentDirty = true;
158
    }
159

    
160
    /**
161
     * DOCUMENT ME!
162
     *
163
     * @param feature DOCUMENT ME!
164
     */
165
    public void insertFeature(Feature feature) {
166
        if (noSpatialData) {
167
            return;
168
        }
169
            try {
170
                    if (featureIndex != null) {
171
                            featureIndex.insert(feature);
172
                    }
173
                feaOperation.add(new FeatureOperation(
174
                    ((DefaultFeature) feature).getReference(),
175
                    FeatureOperation.INSERT));
176
            } catch (DataException e) {
177
                throw new RuntimeException("Exception inserting feature: "
178
                    + feature, e);
179
            }
180
            isFullExtentDirty = true;
181
//        } else if (!isFullExtentDirty) {
182
//            fullEnvelope.add(feature.getDefaultEnvelope());
183
//        }
184
    }
185

    
186
    /**
187
     * DOCUMENT ME!
188
     *
189
     * @param feature DOCUMENT ME!
190
     */
191
    public void deleteFeature(Feature feature) {
192
        if (noSpatialData) {
193
            return;
194
        }
195
            try {
196
                    if (featureIndex != null) {
197
                            featureIndex.delete(feature);
198
                    }
199
                feaOperation.add(new FeatureOperation(((DefaultFeature) feature)
200
                        .getReference(), FeatureOperation.DELETE));
201
            } catch (DataException e) {
202
                throw new RuntimeException("Exception deleting feature: "
203
                    + feature, e);
204
            }
205
        isFullExtentDirty = true;
206
    }
207

    
208
    public void clear() {
209
    }
210

    
211
    public Envelope getEnvelope() throws DataException {
212
        if (noSpatialData) {
213
            return null;
214
        }
215
        if (!isFullExtentDirty){
216
            return this.fullEnvelope;
217
        }
218

    
219
        // FIXME in every changes when anyone ask for envelope it was regenerated.
220
        //       if we assume that the envelope may not be the minimum in edit mode
221
        //       this call must be very much faster
222

    
223

    
224
        FeatureAttributeDescriptor attr = featureStore.getDefaultFeatureType()
225
                .getAttributeDescriptor(
226
                        featureStore.getDefaultFeatureType()
227
                                .getDefaultGeometryAttributeIndex());
228
        Envelope fullEnvelope = null;
229

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

    
276

    
277

    
278
    public void cancelModifies() {
279
        if (noSpatialData) {
280
            return;
281
        }
282
        if (featureIndex != null){
283
            for (int i = feaOperation.size()-1 ; i>=0 ; i--){
284
                try {
285
                    FeatureOperation fo = (FeatureOperation) feaOperation.get(i);
286
                    if (fo.getOperation() == FeatureOperation.INSERT){                     
287
                        featureIndex.delete(fo.getFeatureReference().getFeature());
288
                    }else if (fo.getOperation() == FeatureOperation.DELETE){
289
                        featureIndex.insert(fo.getFeatureReference().getFeature());
290
                    }
291
                } catch (DataException e) {
292
                    LOG.error("Error canceling the edition", e);
293
                }           
294
            }
295
        }
296
        if (originalEnvelope!=null){
297
            fullEnvelope = originalEnvelope.getGeometry().getEnvelope();
298
        } else {
299
            fullEnvelope = null;
300
        }
301
        isFullExtentDirty = false;
302
    }
303

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

    
327
}