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

History | View | Annotate | Download (13.4 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.aggregate.MultiCurve;
40
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
41
import org.gvsig.fmap.geom.exception.CreateGeometryException;
42
import org.gvsig.fmap.geom.operation.GeometryOperationException;
43
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
44
import org.gvsig.fmap.geom.primitive.Curve;
45
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
46
import org.gvsig.fmap.geom.primitive.Point;
47
import org.gvsig.fmap.geom.primitive.Primitive;
48
import org.gvsig.fmap.geom.type.GeometryType;
49
import org.gvsig.tools.dispose.DisposableIterator;
50
import org.gvsig.tools.dynobject.DynObject;
51
import org.gvsig.tools.exception.BaseException;
52
import org.gvsig.tools.service.spi.ProviderServices;
53
import org.gvsig.tools.visitor.VisitCanceledException;
54
import org.gvsig.tools.visitor.Visitor;
55
import org.gvsig.vectorediting.lib.api.DrawingStatus;
56
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
57
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
58
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
59
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
60
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
61
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
62
import org.gvsig.vectorediting.lib.api.exceptions.VectorEditingException;
63
import org.gvsig.vectorediting.lib.prov.split.operation.SplitOperation;
64
import org.gvsig.vectorediting.lib.prov.split.operation.SplitOperationUtils;
65
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
66
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
67
import org.gvsig.vectorediting.lib.spi.EditingProvider;
68
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
69
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
70

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

    
78
    private EditingServiceParameter selection;
79

    
80
    private EditingServiceParameter splitGeometry;
81

    
82
    private FeatureStore featureStore;
83

    
84
    private Map<EditingServiceParameter, Object> values;
85

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

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

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

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

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

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

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

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

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

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

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

    
149
            if (value instanceof FeatureSelection) {
150

    
151
                FeatureSelection featureSelection = (FeatureSelection) value;
152

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

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

    
162
                            if (geoType.isTypeOf(POINT)
163
                                || geoType.isTypeOf(MULTIPOINT)
164
                                || !isClosed(geometry)) {
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()
216
                            .isTypeOf(MULTIPOINT) && !intersection
217
                            .getGeometryType().isTypeOf(CURVE))) {
218
                        throw new VectorEditingException();
219
                    }
220
                }
221
            });
222
            return true;
223
        } catch (BaseException e) {
224
            return false;
225
        }
226
    }
227

    
228
    private boolean isClosed(Geometry geometry) {
229

    
230
        if (geometry instanceof OrientablePrimitive) {
231

    
232
            OrientablePrimitive orientablePrimitive =
233
                (OrientablePrimitive) geometry;
234
            Point firstPoint = orientablePrimitive.getVertex(0);
235
            Point lastPoint =
236
                orientablePrimitive.getVertex(orientablePrimitive
237
                    .getNumVertices() - 1);
238

    
239
            if (firstPoint.equals(lastPoint)) {
240
                return true;
241
            }
242

    
243
        } else if (geometry instanceof MultiPrimitive) {
244

    
245
            MultiPrimitive multiPrimitive = (MultiPrimitive) geometry;
246

    
247
            boolean bool = true;
248
            for (int i = 0; i < multiPrimitive.getPrimitivesNumber(); i++) {
249
                if (bool) {
250
                    bool = bool && isClosed(multiPrimitive.getPrimitiveAt(i));
251
                } else {
252
                    break;
253
                }
254
            }
255
            return bool;
256
        }
257
        return false;
258
    }
259

    
260
    public Geometry finish() throws FinishServiceException {
261
        return null;
262
    }
263

    
264
    public void finishAndStore() throws FinishServiceException {
265

    
266
        if (values != null) {
267

    
268
            EditingProviderServices editingProviderServices =
269
                (EditingProviderServices) getProviderServices();
270

    
271
            FeatureSelection featureSelection =
272
                (FeatureSelection) values.get(selection);
273
            Geometry splitter = (Geometry) values.get(splitGeometry);
274

    
275
            DisposableIterator it = null;
276
            try {
277
                it = featureSelection.fastIterator();
278

    
279
                while (it.hasNext()) {
280
                    Feature feature = (Feature) it.next();
281
                    Geometry geometryToBeSplitted =
282
                        feature.getDefaultGeometry();
283
                    GeometryType geoType =
284
                        geometryToBeSplitted.getGeometryType();
285

    
286
                    if (geoType.isTypeOf(TYPES.SURFACE)
287
                        || geoType.isTypeOf(TYPES.CURVE)) {
288

    
289
                        MultiPrimitive splittedGeometries =
290
                            (MultiPrimitive) split(
291
                                (Primitive) geometryToBeSplitted, splitter);
292

    
293
                        copyAlfanumericDataAndInsert(splittedGeometries,
294
                            feature);
295

    
296
                    } else if (geoType.isTypeOf(TYPES.MULTISURFACE)
297
                        || geoType.isTypeOf(TYPES.MULTICURVE)) {
298

    
299
                        MultiPrimitive multiPrimitive =
300
                            (MultiPrimitive) geometryToBeSplitted;
301

    
302
                        for (int i = 0; i < multiPrimitive
303
                            .getPrimitivesNumber(); i++) {
304

    
305
                            MultiPrimitive splittedGeometries =
306
                                (MultiPrimitive) split(
307
                                    multiPrimitive.getPrimitiveAt(i), splitter);
308

    
309
                            copyAlfanumericDataAndInsert(splittedGeometries,
310
                                feature);
311
                        }
312
                    }
313
                    editingProviderServices.deleteFeatureFromFeatureStore(
314
                        feature, featureStore);
315
                }
316

    
317
                featureSelection.deselectAll();
318
                featureStore.getFeatureSelection().deselectAll();
319

    
320
            } catch (BaseException e) {
321
                throw new FinishServiceException(e);
322
            } finally {
323
                it.dispose();
324
                featureSelection.dispose();
325
            }
326
        }
327
    }
328

    
329
    private void copyAlfanumericDataAndInsert(MultiPrimitive multiPrimitive,
330
        Feature feature) throws DataException {
331
        EditingProviderServices editingProviderServices =
332
            (EditingProviderServices) getProviderServices();
333

    
334
        for (int j = 0; j < multiPrimitive.getPrimitivesNumber(); j++) {
335

    
336
            EditableFeature eFeature =
337
                editingProviderServices.getFeatureCopyWithoutPK(featureStore,
338
                    feature);
339
            eFeature.setDefaultGeometry(multiPrimitive.getPrimitiveAt(j));
340
            editingProviderServices.insertFeatureIntoFeatureStore(eFeature,
341
                featureStore);
342
        }
343
    }
344

    
345
    private Geometry split(Primitive geometry, Geometry splitter)
346
        throws CreateGeometryException, GeometryOperationNotSupportedException,
347
        GeometryOperationException {
348
        SplitOperation operation = SplitOperationUtils.getOperation(geometry);
349

    
350
        if (operation != null) {
351
            return operation.split(geometry, splitter);
352
        }
353
        return null;
354
    }
355

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

    
371
    public String getName() {
372
        return SplitEditingProviderFactory.PROVIDER_NAME;
373
    }
374

    
375
}