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

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.editing.memory;
25

    
26
import java.util.ArrayList;
27
import java.util.Iterator;
28
import java.util.logging.Level;
29
import org.gvsig.fmap.dal.exception.CloneException;
30
import org.gvsig.fmap.dal.exception.CreateException;
31
import org.gvsig.fmap.dal.exception.DataException;
32
import org.gvsig.fmap.dal.feature.EditableFeature;
33
import org.gvsig.fmap.dal.feature.Feature;
34
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
35
import org.gvsig.fmap.dal.feature.FeatureIndex;
36
import org.gvsig.fmap.dal.feature.FeatureIndexes;
37
import org.gvsig.fmap.dal.feature.FeatureReference;
38
import org.gvsig.fmap.dal.feature.FeatureType;
39
import org.gvsig.fmap.dal.feature.impl.DefaultFeature;
40
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureIndex;
41
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore;
42
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
43
import org.gvsig.fmap.geom.GeometryLocator;
44
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
45
import org.gvsig.fmap.geom.primitive.Envelope;
46
import org.slf4j.Logger;
47
import org.slf4j.LoggerFactory;
48

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

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

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

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

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

    
110

    
111

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

    
146
    /**
147
     * DOCUMENT ME!
148
     *
149
     * @param feature DOCUMENT ME!
150
     */
151
    public void insertFeature(Feature feature) {
152
        if (noSpatialData) {
153
            return;
154
        }
155
            try {
156
                    if (featureIndex != null) {
157
                            featureIndex.insert(feature);
158
                    }
159
                feaOperation.add(new FeatureOperation(
160
                    ((DefaultFeature) feature).getReference(),
161
                    FeatureOperation.INSERT));
162
            } catch (DataException e) {
163
                throw new RuntimeException("Exception inserting feature: "
164
                    + feature, e);
165
            }
166
            isFullExtentDirty = true;
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(this.isFullExtentDirty) {
199
            FeatureAttributeDescriptor attr = featureStore.getDefaultFeatureType().getDefaultGeometryAttribute();
200

    
201
            Envelope envelope = getProviderEnvelope();
202
            if (envelope == null) {
203
                try {
204
                    envelope = GeometryLocator.getGeometryManager().createEnvelope(
205
                            this.featureStore.getDefaultFeatureType().getDefaultGeometryAttribute().getGeomType().getSubType());
206
                } catch (CreateEnvelopeException ex) {
207
                    throw new CreateException("envelope", ex);
208
                }
209
            } else {
210
                try {
211
                    envelope = (Envelope) envelope.clone();
212
                } catch (Exception ex) {
213
                    throw new CloneException(ex);
214
                }
215
            }
216

    
217
            FeatureManager featManager = featureStore.getFeatureManager();
218

    
219
            // Si en edicion se provoca un disminucion en el envelope. no hacemos nada 
220
            // para premiar la velocidad de pintado. Ya se resolvera al finalizar edicion.
221

    
222
            Iterator<EditableFeature> inserted = featManager.getInsertedFeatures();
223
            if(inserted != null){
224
                while (inserted.hasNext()) {
225
                    EditableFeature next = inserted.next();
226
                    envelope.add(next.getDefaultEnvelope());
227
                }
228
            }
229

    
230
            Iterator<EditableFeature> updated = featManager.getUpdatedFeatures();
231
            if(updated != null){
232
                while (updated.hasNext()) {
233
                    EditableFeature next = updated.next();
234
                    envelope.add(next.getDefaultEnvelope());
235
                }
236
            }
237
            this.fullEnvelope = envelope;
238
            this.isFullExtentDirty = false;
239
        }
240
        return this.fullEnvelope;
241
    }
242
    
243
    public void cancelModifies() {
244
        if (noSpatialData) {
245
            return;
246
        }
247
        if (featureIndex != null){
248
            for (int i = feaOperation.size()-1 ; i>=0 ; i--){
249
                try {
250
                    FeatureOperation fo = (FeatureOperation) feaOperation.get(i);
251
                    if (fo.getOperation() == FeatureOperation.INSERT){                     
252
                        featureIndex.delete(fo.getFeatureReference().getFeature());
253
                    }else if (fo.getOperation() == FeatureOperation.DELETE){
254
                        featureIndex.insert(fo.getFeatureReference().getFeature());
255
                    }
256
                } catch (DataException e) {
257
                    LOG.error("Error canceling the edition", e);
258
                }           
259
            }
260
        }
261
        if (originalEnvelope!=null){
262
            try {
263
                fullEnvelope = (Envelope) originalEnvelope.clone();
264
            } catch (CloneNotSupportedException e) {
265
                // Should never happen
266
                LOG.error("While cloning envelope", e);
267
            }
268
        } else {
269
            fullEnvelope = null;
270
        }
271
        isFullExtentDirty = false;
272
    }
273

    
274
    private class FeatureOperation{
275
        final static int INSERT=0;
276
        final static int DELETE=1;
277
        private FeatureReference ref;
278
        private int operation;
279
        public FeatureOperation(FeatureReference fe,int op){
280
            ref=fe;
281
            operation=op;
282
        }
283
        public FeatureReference getFeatureReference() {
284
            return ref;
285
        }
286
        public void setFeatureReference(FeatureReference ref) {
287
            this.ref = ref;
288
        }
289
        public int getOperation() {
290
            return operation;
291
        }
292
        public void setOperation(int operation) {
293
            this.operation = operation;
294
        }
295
    }
296
    
297
    private Envelope getProviderEnvelope() throws DataException {
298
        FeatureStoreProvider provider = this.featureStore.getProvider();
299
        Envelope envelope = provider.getEnvelope();
300
        return envelope;
301
    }
302

    
303
}