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

History | View | Annotate | Download (20.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.GeometryLocator;
42
import org.gvsig.fmap.geom.GeometryManager;
43
import org.gvsig.fmap.geom.GeometryUtils;
44
import org.gvsig.fmap.geom.aggregate.MultiCurve;
45
import org.gvsig.fmap.geom.exception.CreateGeometryException;
46
import org.gvsig.fmap.geom.operation.GeometryOperationException;
47
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
48
import org.gvsig.fmap.geom.primitive.Arc;
49
import org.gvsig.fmap.geom.primitive.Curve;
50
import org.gvsig.fmap.geom.primitive.Line;
51
import org.gvsig.fmap.geom.primitive.Point;
52
import org.gvsig.fmap.geom.primitive.Primitive;
53
import org.gvsig.fmap.geom.type.GeometryType;
54
import org.gvsig.fmap.mapcontext.MapContext;
55
import org.gvsig.fmap.mapcontext.layers.vectorial.SpatialEvaluatorsFactory;
56
import org.gvsig.tools.dynobject.DynObject;
57
import org.gvsig.tools.evaluator.Evaluator;
58
import org.gvsig.tools.exception.BaseException;
59
import org.gvsig.tools.service.spi.ProviderServices;
60
import org.gvsig.tools.visitor.VisitCanceledException;
61
import org.gvsig.tools.visitor.Visitor;
62
import org.gvsig.vectorediting.lib.api.DrawingStatus;
63
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
64
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
65
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
66
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
67
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
68
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
69
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
70
import org.gvsig.vectorediting.lib.prov.extendline.operation.ExtendLineOperation;
71
import org.gvsig.vectorediting.lib.prov.extendline.operation.ExtendLineOperationUtils;
72
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
73
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
74
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
75
import org.gvsig.vectorediting.lib.spi.EditingProvider;
76
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
77
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
78

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

    
86
    private final int TOLERANCE_PIXELS = 3;
87

    
88
    private Point insertedPoint;
89

    
90
    private final EditingServiceParameter selectionParameter;
91

    
92
    private final EditingServiceParameter geometryToExtendToParameter;
93

    
94
    protected Map<EditingServiceParameter, Object> values;
95

    
96
    private final FeatureStore featureStore;
97

    
98
    private final MapContext mapContext;
99

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

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

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

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

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

    
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, CreateGeometryException {
216
        ExtendLineOperation operation
217
                = ExtendLineOperationUtils.getOperation((Primitive) curve);
218

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

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

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

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

    
238
    public void setValue(Object value) throws InvalidEntryException {
239
        EditingServiceParameter parameter = next();
240
        validateAndInsertValue(parameter, value);
241
    }
242

    
243
    private void validateAndInsertValue(
244
            final EditingServiceParameter parameter, Object value)
245
            throws InvalidEntryException {
246

    
247
        if (parameter == selectionParameter) {
248
            if (value instanceof FeatureSelection) {
249
                FeatureSelection featureSelection = (FeatureSelection) value;
250
                if (featureSelection.getSelectedCount() > 0) {
251
                    try {
252
                        featureSelection.accept(new Visitor() {
253

    
254
                            public void visit(Object obj)
255
                                    throws VisitCanceledException, BaseException {
256
                                Feature feature = (Feature) obj;
257
                                Geometry geometry
258
                                        = feature.getDefaultGeometry();
259

    
260
                                if (!isValidGeometryToSelect(geometry)) {
261
                                    throw new InvalidEntryException(null);
262
                                }
263
                            }
264
                        });
265
                        values.put(parameter, featureSelection);
266
                        return;
267
                    } catch (BaseException e) {
268
                        throw new InvalidEntryException(e);
269
                    }
270
                }
271
            }
272
        } else if (parameter == geometryToExtendToParameter) {
273
            if (value instanceof Point) {
274
                Point point = (Point) value;
275

    
276
//                EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
277
                Geometry geometry = getGeometry(point); //editingProviderServices.getGeometryOfVisibleLayers(point, featureStore, mapContext);
278
                if (geometry != null) {
279
                    values.put(parameter, geometry);
280
                    insertedPoint = point;
281
                }
282

    
283
//                try {
284
//                    double tolerance =
285
//                        mapContext.getViewPort()
286
//                            .toMapDistance(TOLERANCE_PIXELS);
287
//
288
//                    // Create buffer with tolerance to get geometries to be
289
//                    // extended
290
//                    Geometry buffer = point.buffer(tolerance);
291
//                    FeatureSet geometries = getGeometryByBuffer(buffer);
292
//
293
//                    if (geometries.getSize() > 0) {
294
//
295
//                        geometries.accept(new Visitor() {
296
//
297
//                            public void visit(Object obj)
298
//                                throws VisitCanceledException, BaseException {
299
//                                Feature feature = (Feature) obj;
300
//                                Geometry geometry =
301
//                                    feature.getDefaultGeometry();
302
//                                GeometryType geoType =
303
//                                    geometry.getGeometryType();
304
//
305
//                                if (!geoType.isTypeOf(CURVE)
306
//                                    && !geoType.isTypeOf(MULTICURVE)) {
307
//                                    throw new InvalidEntryException(null);
308
//                                }
309
//                            }
310
//                        });
311
//
312
//                        insertedPoint = point;
313
//                        geometryToExtendTo = geometries;
314
//                        return;
315
//                    }
316
//                } catch (BaseException e) {
317
//                    throw new InvalidEntryException(e);
318
//                }
319
            }
320
        }
321
        throw new InvalidEntryException(null);
322
    }
323

    
324
    private boolean isValidGeometryToSelect(Geometry geometry) {
325
        GeometryType geoType
326
                = geometry.getGeometryType();
327
        if (!geoType.isTypeOf(CURVE)
328
                && !geoType.isTypeOf(MULTICURVE)) {
329
            return false;
330
        }
331

    
332
        if (geoType.isTypeOf(CURVE)) {
333
            if (geometry instanceof Line ) {
334
                Line line = (Line) geometry;
335
                if (line.isClosed()) {
336
                    return false;
337
                }
338
                return true;
339
            }
340
            if (geometry instanceof Arc ) {
341
                Arc arc = (Arc) geometry;
342
                if (arc.getInitPoint().equals(arc.getEndPoint())) {
343
                    return false;
344
                }
345
                return true;
346
            }
347
            return false;
348
        }
349

    
350
        if (geoType.isTypeOf(MULTICURVE)) {
351
            MultiCurve multiCurve = (MultiCurve) geometry;
352
            for (Geometry geom : multiCurve) {
353
                if (!isValidGeometryToSelect(geom)) {
354
                    return false;
355
                }
356
            }
357
        }
358
        return true;
359

    
360
    }
361

    
362
    private Geometry getGeometry(Point point) {
363
        EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
364
        Geometry geometry = editingProviderServices.getGeometryOfVisibleLayers(point, featureStore, mapContext);
365
        return geometry;
366
    }
367

    
368
    private FeatureSet getGeometryByBuffer(Geometry buffer) throws DataException {
369
        FeatureQuery queryByGeometry = featureStore.createFeatureQuery();
370

    
371
        // Get default SRS of default feature type
372
        IProjection defaultSRS
373
                = this.featureStore.getDefaultFeatureType().getDefaultSRS();
374

    
375
        Evaluator iee = SpatialEvaluatorsFactory.getInstance().intersects(
376
                buffer,
377
                defaultSRS,
378
                featureStore
379
        );
380

    
381
        queryByGeometry.setFilter(iee);
382
        queryByGeometry.setAttributeNames(null);
383
        return this.featureStore.getFeatureSet(queryByGeometry);
384
    }
385

    
386
    public Geometry finish() throws FinishServiceException {
387
        return null;
388
    }
389

    
390
    public void finishAndStore() throws FinishServiceException {
391
        FeatureSelection selection = (FeatureSelection) values.get(selectionParameter);
392
        Geometry geometryToExtendTo = (Geometry) values.get(geometryToExtendToParameter);
393
        if (selection != null && geometryToExtendTo != null) {
394

    
395
            try {
396
                selection.accept(new Visitor() {
397
                    @Override
398
                    public void visit(Object obj) throws VisitCanceledException, BaseException {
399
                        Feature feature = (Feature) obj;
400
                        Geometry geometry = feature.getDefaultGeometry();
401
                        EditableFeature eFeature = feature.getEditable();
402

    
403
                        if (geometry instanceof MultiCurve) {
404

    
405
                            // Create new multicurve geometry
406
                            MultiCurve extendedMultiCurve
407
                                    = createMultiCurve(geometry);
408

    
409
                            // Iterate overs primitives and execute extend
410
                            // line operation
411
                            MultiCurve multiCurve = (MultiCurve) geometry;
412

    
413
                            for (int i = 0; i < multiCurve
414
                                    .getPrimitivesNumber(); i++) {
415

    
416
                                Curve curve = multiCurve.getCurveAt(i);
417
                                Curve extendedCurve
418
                                        = extendLine(insertedPoint, curve, geometryToExtendTo);
419
                                extendedMultiCurve.addCurve(extendedCurve);
420
                            }
421

    
422
                            eFeature.setDefaultGeometry(extendedMultiCurve);
423

    
424
                        } else if (geometry instanceof Curve) {
425
                            Curve extendedCurve
426
                                    = extendLine(insertedPoint, (Curve) geometry, geometryToExtendTo);
427
                            eFeature.setDefaultGeometry(extendedCurve);
428
                        }
429

    
430
//                        Curve extendedCurve
431
//                                = extendLine(insertedPoint, (Curve) geometry, geometryToExtendTo);
432
//                        eFeature.setDefaultGeometry(extendedCurve);
433
                        selection.update(eFeature);
434
                    }
435

    
436
                });
437

    
438
//                geometryToExtendTo.accept(new Visitor() {
439
//
440
//                    public void visit(Object obj)
441
//                        throws VisitCanceledException, BaseException {
442
//                        Feature feature = (Feature) obj;
443
//                        Geometry geometry = feature.getDefaultGeometry();
444
//                        EditableFeature eFeature = feature.getEditable();
445
//
446
//                        if (geometry instanceof MultiCurve) {
447
//
448
//                            // Create new multicurve geometry
449
//                            MultiCurve extendedMultiCurve =
450
//                                createMultiCurve(geometry);
451
//
452
//                            // Iterate overs primitives and execute extend
453
//                            // line operation
454
//                            MultiCurve multiCurve = (MultiCurve) geometry;
455
//
456
//                            for (int i = 0; i < multiCurve
457
//                                .getPrimitivesNumber(); i++) {
458
//
459
//                                Curve curve = multiCurve.getCurveAt(i);
460
//                                Curve extendedCurve =
461
//                                    extendLine(insertedPoint, curve);
462
//                                extendedMultiCurve.addCurve(extendedCurve);
463
//                            }
464
//
465
//                            eFeature.setDefaultGeometry(extendedMultiCurve);
466
//
467
//                        } else if (geometry instanceof Curve) {
468
//                            Curve extendedCurve =
469
//                                extendLine(insertedPoint, (Curve) geometry);
470
//                            eFeature.setDefaultGeometry(extendedCurve);
471
//                        }
472
//
473
//                        geometryToExtendTo.update(eFeature);
474
//                    }
475
//                });
476
//
477
//                geometryToExtendTo.dispose();
478
            } catch (BaseException e) {
479
                throw new FinishServiceException(e);
480
            }
481
        }
482
    }
483

    
484
    private MultiCurve createMultiCurve(Geometry geometry)
485
            throws FinishServiceException {
486

    
487
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
488
        int subtype = geometry.getGeometryType().getSubType();
489
        MultiCurve extendedMultiCurve = null;
490

    
491
        try {
492
            extendedMultiCurve = geoManager.createMultiCurve(subtype);
493
        } catch (CreateGeometryException e) {
494
            throw new FinishServiceException(e);
495
        }
496
        return extendedMultiCurve;
497
    }
498

    
499
    public void start() throws StartServiceException, InvalidEntryException {
500
        this.values = new HashMap<>();
501
        FeatureSelection selected = null;
502
        if (featureStore != null && values.get(selectionParameter) == null) {
503
            try {
504
                selected = featureStore.getFeatureSelection();
505
            } catch (DataException e) {
506
                throw new StartServiceException(e);
507
            }
508
            if (selected.getSelectedCount() > 0) {
509
                try {
510
                    setValue(selected);
511
                } catch (InvalidEntryException e) {
512
                    throw new InvalidEntryException(e);
513
                }
514
            }
515
        }
516
    }
517

    
518
    public String getName() {
519
        return ExtendLineEditingProviderFactory.PROVIDER_NAME;
520
    }
521

    
522
}