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.extendline / src / main / java / org / gvsig / vectorediting / lib / prov / extendline / ExtendLineEditingProvider.java @ 2616

History | View | Annotate | Download (16.8 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2015 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
package org.gvsig.vectorediting.lib.prov.extendline;
25

    
26
import java.util.ArrayList;
27
import java.util.HashMap;
28
import java.util.List;
29
import java.util.Map;
30
import org.cresques.cts.IProjection;
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.FeatureQuery;
35
import org.gvsig.fmap.dal.feature.FeatureSelection;
36
import org.gvsig.fmap.dal.feature.FeatureSet;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.geom.Geometry;
39
import static org.gvsig.fmap.geom.Geometry.TYPES.CURVE;
40
import static org.gvsig.fmap.geom.Geometry.TYPES.MULTICURVE;
41
import org.gvsig.fmap.geom.GeometryException;
42
import org.gvsig.fmap.geom.GeometryLocator;
43
import org.gvsig.fmap.geom.GeometryManager;
44
import org.gvsig.fmap.geom.aggregate.MultiCurve;
45
import org.gvsig.fmap.geom.operation.GeometryOperationException;
46
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
47
import org.gvsig.fmap.geom.primitive.Arc;
48
import org.gvsig.fmap.geom.primitive.Curve;
49
import org.gvsig.fmap.geom.primitive.Line;
50
import org.gvsig.fmap.geom.primitive.Point;
51
import org.gvsig.fmap.geom.primitive.Primitive;
52
import org.gvsig.fmap.geom.type.GeometryType;
53
import org.gvsig.fmap.mapcontext.MapContext;
54
import org.gvsig.fmap.mapcontext.layers.vectorial.SpatialEvaluatorsFactory;
55
import org.gvsig.tools.dynobject.DynObject;
56
import org.gvsig.tools.evaluator.Evaluator;
57
import org.gvsig.tools.exception.BaseException;
58
import org.gvsig.tools.service.spi.ProviderServices;
59
import org.gvsig.tools.visitor.VisitCanceledException;
60
import org.gvsig.tools.visitor.Visitor;
61
import org.gvsig.vectorediting.lib.api.DrawingStatus;
62
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
63
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
64
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
65
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
66
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
67
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
68
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
69
import org.gvsig.vectorediting.lib.prov.extendline.operation.ExtendLineOperation;
70
import org.gvsig.vectorediting.lib.prov.extendline.operation.ExtendLineOperationUtils;
71
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
72
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
73
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
74
import org.gvsig.vectorediting.lib.spi.EditingProvider;
75
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
76
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
77

    
78
/**
79
 * @author llmarques
80
 *
81
 */
82
public class ExtendLineEditingProvider extends AbstractEditingProvider
83
        implements EditingProvider {
84

    
85
    private final int TOLERANCE_PIXELS = 3;
86

    
87
    private Point insertedPoint;
88

    
89
    private final EditingServiceParameter selectionParameter;
90

    
91
    private final EditingServiceParameter geometryToExtendToParameter;
92

    
93
    protected Map<EditingServiceParameter, Object> values;
94

    
95
    private final FeatureStore featureStore;
96

    
97
    private final MapContext mapContext;
98

    
99
    /**
100
     * Default constructor.
101
     *
102
     * @param services available services for this provider
103
     * @param parameters of this provider
104
     */
105
    public ExtendLineEditingProvider(ProviderServices services,
106
            DynObject parameters) {
107
        super(services);
108

    
109
        this.featureStore
110
                = (FeatureStore) parameters
111
                        .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
112

    
113
        this.mapContext
114
                = (MapContext) parameters
115
                        .getDynValue(EditingProviderFactory.MAPCONTEXT_FIELD);
116

    
117
        this.selectionParameter
118
                = new DefaultEditingServiceParameter("selection", "selection",
119
                        TYPE.SELECTION);
120

    
121
        this.geometryToExtendToParameter
122
                = new DefaultEditingServiceParameter("geometry_to_extend_to",
123
                        "geometry_to_extend_to", TYPE.POSITION);
124
    }
125

    
126
    @Override
127
    public EditingServiceParameter next() {
128
        if (values.get(selectionParameter) == null) {
129
            return selectionParameter;
130
        } else if (values.get(geometryToExtendToParameter) == null) {
131
            return geometryToExtendToParameter;
132
        }
133
        return null;
134
    }
135

    
136
    @Override
137
    public DrawingStatus getDrawingStatus(Point mousePosition)
138
            throws DrawServiceException {
139

    
140
        FeatureSelection selection = (FeatureSelection) values.get(selectionParameter);
141
        if (selection != null) {
142
            DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
143
            // We do not show the possible result when moving the mouse
144
            // due to possible performance problems working with databases
145

    
146
//            EditingProviderManager editingProviderManager
147
//                    = EditingProviderLocator.getProviderManager();
148
//            ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
149
//            DisposableIterator selectionIterator = null;
150
//            try {
151
//                Geometry boundaryGeometry = getGeometry(mousePosition);
152
//                if (boundaryGeometry != null) {
153
//
154
//                    selectionIterator = selection.fastIterator();
155
//                    while (selectionIterator.hasNext()) {
156
//                        Feature feature = (Feature) selectionIterator.next();
157
//
158
//                        Geometry geometry = feature.getDefaultGeometry();
159
//
160
//                        if (geometry instanceof MultiCurve) {
161
//                            MultiCurve multiCurve = (MultiCurve) geometry;
162
//
163
//                            for (int i = 0; i < multiCurve
164
//                                    .getPrimitivesNumber(); i++) {
165
//
166
//                                Curve curve = multiCurve.getCurveAt(i);
167
//                                if (!isClosed(curve)) {
168
//                                    Curve extendedCurve
169
//                                            = extendLine(mousePosition, curve, boundaryGeometry);
170
//                                    drawingStatus.addStatus(extendedCurve, lineSymbolEditing, "");
171
//                                }
172
//                            }
173
//
174
//                        } else if (geometry instanceof Curve) {
175
//                            if (!isClosed((Curve) geometry)) {
176
//                                Curve extendedCurve
177
//                                        = extendLine(mousePosition, (Curve) geometry, boundaryGeometry);
178
//                                drawingStatus.addStatus(extendedCurve, lineSymbolEditing, "");
179
//                            }
180
//                        }
181
//
182
//                    }
183
//                    DisposeUtils.dispose(selectionIterator);
184
//
185
//                }
186
//
187
//            } catch (BaseException e) {
188
//                throw new DrawServiceException(e);
189
//            } finally {
190
//                DisposeUtils.dispose(selectionIterator);
191
//            }
192
            return drawingStatus;
193
        }
194
        return null;
195
    }
196

    
197
    private boolean isClosed(Curve curve) {
198
        if (curve instanceof Arc) {
199
            Arc arc = (Arc) curve;
200
            if (arc.getInitPoint().equals(arc.getEndPoint())) {
201
                return true;
202
            }
203
        } else if (curve instanceof Curve) {
204
            Point firstPoint = curve.getVertex(0);
205
            Point lastPoint = curve.getVertex(curve.getNumVertices() - 1);
206
            if (firstPoint.equals(lastPoint)) {
207
                return true;
208
            }
209
        }
210
        return false;
211
    }
212

    
213
    private Curve extendLine(Point mousePosition, Curve curve, Geometry boundaryGeometry)
214
            throws GeometryOperationNotSupportedException,
215
            GeometryOperationException, DataException, GeometryException {
216
        ExtendLineOperation operation
217
                = ExtendLineOperationUtils.getOperation((Primitive) curve);
218

    
219
        return operation.extendLine(curve, mousePosition, boundaryGeometry);
220
    }
221

    
222
    @Override
223
    public void stop() throws StopServiceException {
224
        values.clear();
225
    }
226

    
227
    @Override
228
    public List<EditingServiceParameter> getParameters() {
229
        List<EditingServiceParameter> parameters = new ArrayList<>();
230
        parameters.add(selectionParameter);
231
        parameters.add(geometryToExtendToParameter);
232
        return parameters;
233
    }
234

    
235
    @Override
236
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
237
        validateAndInsertValue(parameter, value);
238
    }
239

    
240
    @Override
241
    public void setValue(Object value) throws InvalidEntryException {
242
        EditingServiceParameter parameter = next();
243
        validateAndInsertValue(parameter, value);
244
    }
245

    
246
    private void validateAndInsertValue(
247
            final EditingServiceParameter parameter, Object value)
248
            throws InvalidEntryException {
249

    
250
        if (parameter == selectionParameter) {
251
            if (value instanceof FeatureSelection) {
252
                FeatureSelection featureSelection = (FeatureSelection) value;
253
                if (featureSelection.getSelectedCount() > 0) {
254
                    try {
255
                        featureSelection.accept((Object obj) -> {
256
                            Feature feature = (Feature) obj;
257
                            Geometry geometry
258
                                    = feature.getDefaultGeometry();
259
                            
260
                            if (!isValidGeometryToSelect(geometry)) {
261
                                throw new InvalidEntryException(null);
262
                            }
263
                        });
264
                        values.put(parameter, featureSelection);
265
                        return;
266
                    } catch (BaseException e) {
267
                        throw new InvalidEntryException(e);
268
                    }
269
                }
270
            }
271
        } else if (parameter == geometryToExtendToParameter) {
272
            if (value instanceof Point) {
273
                Point point = (Point) value;
274

    
275
                Geometry geometry = getGeometry(point);
276
                if (geometry != null) {
277
                    values.put(parameter, geometry);
278
                    insertedPoint = point;
279
                    return;
280
                }
281

    
282
            }
283
        }
284
        throw new InvalidEntryException(null);
285
    }
286

    
287
    private boolean isValidGeometryToSelect(Geometry geometry) {
288
        GeometryType geoType
289
                = geometry.getGeometryType();
290
        if (!geoType.isTypeOf(CURVE)
291
                && !geoType.isTypeOf(MULTICURVE)) {
292
            return false;
293
        }
294

    
295
        if (geoType.isTypeOf(CURVE)) {
296
            if (geometry instanceof Line ) {
297
                Line line = (Line) geometry;
298
                return !line.isClosed();
299
            }
300
            if (geometry instanceof Arc ) {
301
                Arc arc = (Arc) geometry;
302
                return !arc.getInitPoint().equals(arc.getEndPoint());
303
            }
304
            return false;
305
        }
306

    
307
        if (geoType.isTypeOf(MULTICURVE)) {
308
            MultiCurve multiCurve = (MultiCurve) geometry;
309
            for (Geometry geom : multiCurve) {
310
                if (!isValidGeometryToSelect(geom)) {
311
                    return false;
312
                }
313
            }
314
        }
315
        return true;
316

    
317
    }
318

    
319
    private Geometry getGeometry(Point point) {
320
        EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
321
        Geometry geometry = editingProviderServices.getGeometryOfVisibleLayers(point, featureStore, mapContext);
322
        return geometry;
323
    }
324

    
325
    private FeatureSet getGeometryByBuffer(Geometry buffer) throws DataException {
326
        FeatureQuery queryByGeometry = featureStore.createFeatureQuery();
327

    
328
        // Get default SRS of default feature type
329
        IProjection defaultSRS
330
                = this.featureStore.getDefaultFeatureType().getDefaultSRS();
331

    
332
        Evaluator iee = SpatialEvaluatorsFactory.getInstance().intersects(
333
                buffer,
334
                defaultSRS,
335
                featureStore
336
        );
337

    
338
        queryByGeometry.setFilter(iee);
339
        queryByGeometry.setAttributeNames(null);
340
        return this.featureStore.getFeatureSet(queryByGeometry);
341
    }
342

    
343
    @Override
344
    public Geometry finish() throws FinishServiceException {
345
        return null;
346
    }
347

    
348
    @Override
349
    public void finishAndStore() throws FinishServiceException {
350
        FeatureSelection selection = (FeatureSelection) values.get(selectionParameter);
351
        Geometry geometryToExtendTo = (Geometry) values.get(geometryToExtendToParameter);
352
        if (selection != null && geometryToExtendTo != null) {
353

    
354
            try {
355
                selection.accept((Object obj) -> {
356
                    Feature feature = (Feature) obj;
357
                    Geometry geometry = feature.getDefaultGeometry();
358
                    EditableFeature eFeature = feature.getEditable();
359
                    
360
                    if (geometry instanceof MultiCurve) {
361
                        
362
                        // Create new multicurve geometry
363
                        MultiCurve extendedMultiCurve
364
                                = createMultiCurve(geometry);
365
                        
366
                        // Iterate overs primitives and execute extend
367
                        // line operation
368
                        MultiCurve multiCurve = (MultiCurve) geometry;
369
                        
370
                        for (int i = 0; i < multiCurve
371
                                .getPrimitivesNumber(); i++) {
372
                            
373
                            Curve curve = multiCurve.getCurveAt(i);
374
                            Curve extendedCurve
375
                                    = extendLine(insertedPoint, curve, geometryToExtendTo);
376
                            extendedMultiCurve.addCurve(extendedCurve);
377
                        }
378
                        
379
                        eFeature.setDefaultGeometry(extendedMultiCurve);
380
                        
381
                    } else if (geometry instanceof Curve) {
382
                        Curve extendedCurve
383
                                = extendLine(insertedPoint, (Curve) geometry, geometryToExtendTo);
384
                        eFeature.setDefaultGeometry(extendedCurve);
385
                    }
386

    
387
                    selection.update(eFeature);
388
                });
389

    
390
            } catch (BaseException e) {
391
                throw new FinishServiceException(e);
392
            }
393
        }
394
    }
395

    
396
    private MultiCurve createMultiCurve(Geometry geometry)
397
            throws FinishServiceException {
398

    
399
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
400
        int subtype = geometry.getGeometryType().getSubType();
401
        MultiCurve extendedMultiCurve = null;
402

    
403
        try {
404
            extendedMultiCurve = geoManager.createMultiCurve(subtype);
405
        } catch (GeometryException e) {
406
            throw new FinishServiceException(e);
407
        }
408
        return extendedMultiCurve;
409
    }
410

    
411
    @Override
412
    public void start() throws StartServiceException, InvalidEntryException {
413
        this.values = new HashMap<>();
414
        FeatureSelection selected = null;
415
        if (featureStore != null && values.get(selectionParameter) == null) {
416
            try {
417
                selected = featureStore.getFeatureSelection();
418
            } catch (DataException e) {
419
                throw new StartServiceException(e);
420
            }
421
            if (selected.getSelectedCount() > 0) {
422
                try {
423
                    setValue(selected);
424
                } catch (InvalidEntryException e) {
425
                    throw new InvalidEntryException(e);
426
                }
427
            }
428
        }
429
    }
430

    
431
    @Override
432
    public String getName() {
433
        return ExtendLineEditingProviderFactory.PROVIDER_NAME;
434
    }
435

    
436
    @Override
437
    public Object getValue(EditingServiceParameter parameter) {
438
        return values!=null?values.get(parameter):null;
439
    }
440
}