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

History | View | Annotate | Download (17.1 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
    public EditingServiceParameter next() {
127
        if (values.get(selectionParameter) == null) {
128
            return selectionParameter;
129
        } else if (values.get(geometryToExtendToParameter) == null) {
130
            return geometryToExtendToParameter;
131
        }
132
        return null;
133
    }
134

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

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

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

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

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

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

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

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

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

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

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

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

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

    
259
                                if (!isValidGeometryToSelect(geometry)) {
260
                                    throw new InvalidEntryException(null);
261
                                }
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
                if (line.isClosed()) {
299
                    return false;
300
                }
301
                return true;
302
            }
303
            if (geometry instanceof Arc ) {
304
                Arc arc = (Arc) geometry;
305
                if (arc.getInitPoint().equals(arc.getEndPoint())) {
306
                    return false;
307
                }
308
                return true;
309
            }
310
            return false;
311
        }
312

    
313
        if (geoType.isTypeOf(MULTICURVE)) {
314
            MultiCurve multiCurve = (MultiCurve) geometry;
315
            for (Geometry geom : multiCurve) {
316
                if (!isValidGeometryToSelect(geom)) {
317
                    return false;
318
                }
319
            }
320
        }
321
        return true;
322

    
323
    }
324

    
325
    private Geometry getGeometry(Point point) {
326
        EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
327
        Geometry geometry = editingProviderServices.getGeometryOfVisibleLayers(point, featureStore, mapContext);
328
        return geometry;
329
    }
330

    
331
    private FeatureSet getGeometryByBuffer(Geometry buffer) throws DataException {
332
        FeatureQuery queryByGeometry = featureStore.createFeatureQuery();
333

    
334
        // Get default SRS of default feature type
335
        IProjection defaultSRS
336
                = this.featureStore.getDefaultFeatureType().getDefaultSRS();
337

    
338
        Evaluator iee = SpatialEvaluatorsFactory.getInstance().intersects(
339
                buffer,
340
                defaultSRS,
341
                featureStore
342
        );
343

    
344
        queryByGeometry.setFilter(iee);
345
        queryByGeometry.setAttributeNames(null);
346
        return this.featureStore.getFeatureSet(queryByGeometry);
347
    }
348

    
349
    public Geometry finish() throws FinishServiceException {
350
        return null;
351
    }
352

    
353
    public void finishAndStore() throws FinishServiceException {
354
        FeatureSelection selection = (FeatureSelection) values.get(selectionParameter);
355
        Geometry geometryToExtendTo = (Geometry) values.get(geometryToExtendToParameter);
356
        if (selection != null && geometryToExtendTo != null) {
357

    
358
            try {
359
                selection.accept(new Visitor() {
360
                    @Override
361
                    public void visit(Object obj) throws VisitCanceledException, BaseException {
362
                        Feature feature = (Feature) obj;
363
                        Geometry geometry = feature.getDefaultGeometry();
364
                        EditableFeature eFeature = feature.getEditable();
365

    
366
                        if (geometry instanceof MultiCurve) {
367

    
368
                            // Create new multicurve geometry
369
                            MultiCurve extendedMultiCurve
370
                                    = createMultiCurve(geometry);
371

    
372
                            // Iterate overs primitives and execute extend
373
                            // line operation
374
                            MultiCurve multiCurve = (MultiCurve) geometry;
375

    
376
                            for (int i = 0; i < multiCurve
377
                                    .getPrimitivesNumber(); i++) {
378

    
379
                                Curve curve = multiCurve.getCurveAt(i);
380
                                Curve extendedCurve
381
                                        = extendLine(insertedPoint, curve, geometryToExtendTo);
382
                                extendedMultiCurve.addCurve(extendedCurve);
383
                            }
384

    
385
                            eFeature.setDefaultGeometry(extendedMultiCurve);
386

    
387
                        } else if (geometry instanceof Curve) {
388
                            Curve extendedCurve
389
                                    = extendLine(insertedPoint, (Curve) geometry, geometryToExtendTo);
390
                            eFeature.setDefaultGeometry(extendedCurve);
391
                        }
392

    
393
                        selection.update(eFeature);
394
                    }
395

    
396
                });
397

    
398
            } catch (BaseException e) {
399
                throw new FinishServiceException(e);
400
            }
401
        }
402
    }
403

    
404
    private MultiCurve createMultiCurve(Geometry geometry)
405
            throws FinishServiceException {
406

    
407
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
408
        int subtype = geometry.getGeometryType().getSubType();
409
        MultiCurve extendedMultiCurve = null;
410

    
411
        try {
412
            extendedMultiCurve = geoManager.createMultiCurve(subtype);
413
        } catch (GeometryException e) {
414
            throw new FinishServiceException(e);
415
        }
416
        return extendedMultiCurve;
417
    }
418

    
419
    public void start() throws StartServiceException, InvalidEntryException {
420
        this.values = new HashMap<>();
421
        FeatureSelection selected = null;
422
        if (featureStore != null && values.get(selectionParameter) == null) {
423
            try {
424
                selected = featureStore.getFeatureSelection();
425
            } catch (DataException e) {
426
                throw new StartServiceException(e);
427
            }
428
            if (selected.getSelectedCount() > 0) {
429
                try {
430
                    setValue(selected);
431
                } catch (InvalidEntryException e) {
432
                    throw new InvalidEntryException(e);
433
                }
434
            }
435
        }
436
    }
437

    
438
    public String getName() {
439
        return ExtendLineEditingProviderFactory.PROVIDER_NAME;
440
    }
441

    
442
    @Override
443
    public Object getValue(EditingServiceParameter parameter) {
444
        return values!=null?values.get(parameter):null;
445
    }
446
}