Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.lib / org.gvsig.vectorediting.lib.prov / org.gvsig.vectorediting.lib.prov.split / src / main / java / org / gvsig / vectorediting / lib / prov / split / SplitEditingProvider.java @ 496

History | View | Annotate | Download (14.7 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2014 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 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., 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

    
25
package org.gvsig.vectorediting.lib.prov.split;
26

    
27
import java.util.ArrayList;
28
import java.util.HashMap;
29
import java.util.List;
30
import java.util.Map;
31

    
32
import org.gvsig.fmap.dal.exception.DataException;
33
import org.gvsig.fmap.dal.feature.EditableFeature;
34
import org.gvsig.fmap.dal.feature.Feature;
35
import org.gvsig.fmap.dal.feature.FeatureSelection;
36
import org.gvsig.fmap.dal.feature.FeatureStore;
37
import org.gvsig.fmap.geom.Geometry;
38
import org.gvsig.fmap.geom.Geometry.TYPES;
39
import org.gvsig.fmap.geom.GeometryLocator;
40
import org.gvsig.fmap.geom.GeometryManager;
41
import org.gvsig.fmap.geom.aggregate.MultiCurve;
42
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
43
import org.gvsig.fmap.geom.exception.CreateGeometryException;
44
import org.gvsig.fmap.geom.operation.GeometryOperationException;
45
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
46
import org.gvsig.fmap.geom.primitive.Curve;
47
import org.gvsig.fmap.geom.primitive.Point;
48
import org.gvsig.fmap.geom.primitive.Primitive;
49
import org.gvsig.fmap.geom.type.GeometryType;
50
import org.gvsig.tools.dispose.DisposableIterator;
51
import org.gvsig.tools.dynobject.DynObject;
52
import org.gvsig.tools.exception.BaseException;
53
import org.gvsig.tools.service.spi.ProviderServices;
54
import org.gvsig.tools.visitor.VisitCanceledException;
55
import org.gvsig.tools.visitor.Visitor;
56
import org.gvsig.vectorediting.lib.api.DrawingStatus;
57
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
58
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
59
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
60
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
61
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
62
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
63
import org.gvsig.vectorediting.lib.api.exceptions.VectorEditingException;
64
import org.gvsig.vectorediting.lib.prov.split.operation.SplitOperation;
65
import org.gvsig.vectorediting.lib.prov.split.operation.SplitOperationUtils;
66
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
67
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
68
import org.gvsig.vectorediting.lib.spi.EditingProvider;
69
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
70
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
71

    
72
/**
73
 * @author llmarques
74
 *
75
 */
76
public class SplitEditingProvider extends AbstractEditingProvider implements
77
    EditingProvider {
78

    
79
    private EditingServiceParameter selection;
80

    
81
    private EditingServiceParameter splitGeometry;
82

    
83
    private FeatureStore featureStore;
84

    
85
    private Map<EditingServiceParameter, Object> values;
86

    
87
    /**
88
     * Default constructor.
89
     *
90
     * @param providerServices
91
     *            available services for this provider
92
     * @param parameters
93
     *            of this provider
94
     */
95
    public SplitEditingProvider(ProviderServices services, DynObject parameters) {
96
        super(services);
97

    
98
        this.featureStore =
99
            (FeatureStore) parameters
100
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
101

    
102
        this.selection =
103
            new DefaultEditingServiceParameter("selection", "selection",
104
                EditingServiceParameter.TYPE.SELECTION);
105

    
106
        this.splitGeometry =
107
            new DefaultEditingServiceParameter("draw_geometry_to_split",
108
                "draw_geometry_to_split", Geometry.TYPES.CURVE,
109
                EditingServiceParameter.TYPE.GEOMETRY);
110
    }
111

    
112
    public EditingServiceParameter next() {
113
        if (values.get(selection) == null) {
114
            return selection;
115
        } else if (values.get(splitGeometry) == null) {
116
            return splitGeometry;
117
        }
118
        return null;
119
    }
120

    
121
    public DrawingStatus getDrawingStatus(Point mousePosition)
122
        throws DrawServiceException {
123
        return null;
124
    }
125

    
126
    public void stop() throws StopServiceException {
127
        if (values != null) {
128
            values.clear();
129
        }
130
    }
131

    
132
    public List<EditingServiceParameter> getParameters() {
133
        List<EditingServiceParameter> parameters =
134
            new ArrayList<EditingServiceParameter>();
135
        parameters.add(selection);
136
        parameters.add(splitGeometry);
137
        return parameters;
138
    }
139

    
140
    public void setValue(Object value) throws InvalidEntryException {
141
        EditingServiceParameter parameter = next();
142
        validateAndInsertValue(parameter, value);
143
    }
144

    
145
    private void validateAndInsertValue(EditingServiceParameter parameter,
146
        Object value) throws InvalidEntryException {
147

    
148
        if (values != null && value != null) {
149

    
150
            if (value instanceof FeatureSelection) {
151

    
152
                FeatureSelection featureSelection = (FeatureSelection) value;
153

    
154
                try {
155
                    featureSelection.accept(new Visitor() {
156

    
157
                        public void visit(Object obj)
158
                            throws VisitCanceledException, BaseException {
159
                            Feature feature = (Feature) obj;
160
                            Geometry geometry = feature.getDefaultGeometry();
161
                            GeometryType geoType = geometry.getGeometryType();
162

    
163
                            if (geoType.isTypeOf(POINT)
164
                                || geoType.isTypeOf(MULTIPOINT)) {
165
                                throw new InvalidEntryException(null);
166
                            }
167
                        }
168
                    });
169

    
170
                    values.put(selection, value);
171
                    return;
172
                } catch (BaseException e) {
173
                    throw new InvalidEntryException(e);
174
                }
175

    
176
            } else if (value instanceof Geometry) {
177

    
178
                Geometry geometry = (Geometry) value;
179

    
180
                if (geometry instanceof MultiCurve) {
181
                    MultiCurve multiCurve = (MultiCurve) geometry;
182
                    for (int i = 0; i < multiCurve.getPrimitivesNumber(); i++) {
183
                        if (isValid((Curve) multiCurve.getPrimitiveAt(i))) {
184
                            values.put(splitGeometry, geometry);
185
                            return;
186
                        }
187
                    }
188

    
189
                } else if (geometry instanceof Curve) {
190
                    if (isValid((Curve) geometry)) {
191
                        values.put(splitGeometry, geometry);
192
                        return;
193
                    }
194
                }
195
            }
196
        }
197
        throw new InvalidEntryException(null);
198
    }
199

    
200
    private boolean isValid(final Curve curve) {
201
        FeatureSelection featureSelection =
202
            (FeatureSelection) values.get(selection);
203

    
204
        try {
205
            featureSelection.accept(new Visitor() {
206

    
207
                public void visit(Object obj) throws VisitCanceledException,
208
                    BaseException {
209
                    Feature feature = (Feature) obj;
210
                    Geometry geometry = feature.getDefaultGeometry();
211

    
212
                    Geometry intersection = geometry.intersection(curve);
213

    
214
                    if (intersection == null
215
                        || (!intersection.getGeometryType().isTypeOf(POINT)
216
                        && !intersection.getGeometryType().isTypeOf(MULTIPOINT)
217
                        && !intersection.getGeometryType().isTypeOf(CURVE)
218
                        && !intersection.getGeometryType().isTypeOf(MULTICURVE))) {
219
                        throw new VectorEditingException();
220
                    }
221
                }
222
            });
223
            return true;
224
        } catch (BaseException e) {
225
            return false;
226
        }
227
    }
228
    
229
    public Geometry finish() throws FinishServiceException {
230
        return null;
231
    }
232

    
233
    public void finishAndStore() throws FinishServiceException {
234

    
235
        if (values != null) {
236

    
237
            EditingProviderServices editingProviderServices =
238
                (EditingProviderServices) getProviderServices();
239

    
240
            FeatureSelection featureSelection =
241
                (FeatureSelection) values.get(selection);
242
            Geometry splitter = (Geometry) values.get(splitGeometry);
243

    
244
            DisposableIterator it = null;
245
            try {
246
                it = featureSelection.fastIterator();
247

    
248
                while (it.hasNext()) {
249
                    Feature feature = (Feature) it.next();
250
                    Geometry geometryToBeSplitted =
251
                        feature.getDefaultGeometry();
252
                    GeometryType geoType =
253
                        geometryToBeSplitted.getGeometryType();
254

    
255
                    if (geoType.isTypeOf(TYPES.SURFACE)
256
                        || geoType.isTypeOf(TYPES.CURVE)) {
257

    
258
                        MultiPrimitive splittedGeometries =
259
                            (MultiPrimitive) split(
260
                                (Primitive) geometryToBeSplitted, splitter);
261

    
262
                        for (int j = 0; j < splittedGeometries
263
                            .getPrimitivesNumber(); j++) {
264
                            copyAlfanumericDataAndInsert(
265
                                splittedGeometries.getPrimitiveAt(j), feature);
266
                        }
267

    
268
                    } else if (geoType.isTypeOf(TYPES.MULTISURFACE)
269
                        || geoType.isTypeOf(TYPES.MULTICURVE)) {
270

    
271
                        MultiPrimitive multiPrimitive =
272
                            (MultiPrimitive) geometryToBeSplitted;
273
                        
274
                        // Multigeometry composed by no splitted geometries.
275
                        GeometryManager geoManager = GeometryLocator.getGeometryManager();
276
                        MultiPrimitive multiNoSplitted;
277
                        if(geoType.isTypeOf(TYPES.MULTISURFACE)){
278
                            multiNoSplitted =
279
                                geoManager.createMultiSurface(editingProviderServices
280
                                    .getSubType(featureStore));
281
                        } else {
282
                            multiNoSplitted =
283
                                geoManager.createMultiCurve(editingProviderServices
284
                                    .getSubType(featureStore));
285
                        }
286
                        
287
                        for (int i = 0; i < multiPrimitive
288
                            .getPrimitivesNumber(); i++) {
289
                            
290
                            Geometry geoSplitted =
291
                                split(multiPrimitive.getPrimitiveAt(i),
292
                                    splitter);
293
                           
294
                            if (geoSplitted instanceof MultiPrimitive) {
295
                                // If the result of split is a multiprimitive,
296
                                // it has splitted
297
                                MultiPrimitive multiSplitted = (MultiPrimitive) geoSplitted;
298
                                // Splitted geometries should be saved as
299
                                // primitives
300
                                for (int j = 0; j < multiSplitted
301
                                    .getPrimitivesNumber(); j++) {
302
                                    copyAlfanumericDataAndInsert(
303
                                        multiSplitted.getPrimitiveAt(j),
304
                                        feature);
305
                                }
306
                            } else {
307
                                // If the result of split is a primitive, it has
308
                                // not splitted. Add it to mulriNoSplitted to save it later.
309
                                multiNoSplitted
310
                                    .addPrimitive((Primitive) geoSplitted);
311
                            }
312
                        }
313
                        
314
                        if(multiNoSplitted.getPrimitivesNumber() > 0){
315
                            // Not splitted geometries should be saved as multigeometry
316
                            copyAlfanumericDataAndInsert(multiNoSplitted,
317
                                feature);
318
                        }
319
                    }
320
                    
321
                    editingProviderServices.deleteFeatureFromFeatureStore(
322
                        feature, featureStore);
323
                }
324

    
325
                featureSelection.deselectAll();
326
                featureStore.getFeatureSelection().deselectAll();
327

    
328
            } catch (BaseException e) {
329
                throw new FinishServiceException(e);
330
            } finally {
331
                it.dispose();
332
            }
333
        }
334
    }
335

    
336
    private void copyAlfanumericDataAndInsert(Geometry geometry, Feature feature)
337
        throws DataException {
338
        EditingProviderServices editingProviderServices =
339
            (EditingProviderServices) getProviderServices();
340

    
341
        EditableFeature eFeature =
342
            editingProviderServices.getFeatureCopyWithoutPK(featureStore,
343
                feature);
344
        eFeature.setDefaultGeometry(geometry);
345
        editingProviderServices.insertFeatureIntoFeatureStore(eFeature,
346
            featureStore);
347
    }
348

    
349
    private Geometry split(Primitive geometry, Geometry splitter)
350
        throws CreateGeometryException, GeometryOperationNotSupportedException,
351
        GeometryOperationException {
352
        SplitOperation operation = SplitOperationUtils.getOperation(geometry);
353

    
354
        if (operation != null) {
355
            return operation.split(geometry, splitter);
356
        }
357
        return null;
358
    }
359

    
360
    public void start() throws StartServiceException, InvalidEntryException {
361
        values = new HashMap<EditingServiceParameter, Object>();
362
        FeatureSelection selected = null;
363
        if (featureStore != null) {
364
            try {
365
                selected = featureStore.getFeatureSelection();
366
            } catch (DataException e) {
367
                throw new StartServiceException(e);
368
            }
369
            if (selected.getSelectedCount() > 0) {
370
                setValue(selected);
371
            }
372
        }
373
    }
374

    
375
    public String getName() {
376
        return SplitEditingProviderFactory.PROVIDER_NAME;
377
    }
378

    
379
}