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

History | View | Annotate | Download (16.5 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

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

    
27
import java.util.ArrayList;
28
import java.util.List;
29

    
30
import org.cresques.cts.IProjection;
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.FeatureQuery;
36
import org.gvsig.fmap.dal.feature.FeatureSelection;
37
import org.gvsig.fmap.dal.feature.FeatureSet;
38
import org.gvsig.fmap.dal.feature.FeatureStore;
39
import org.gvsig.fmap.geom.Geometry;
40
import org.gvsig.fmap.geom.GeometryLocator;
41
import org.gvsig.fmap.geom.GeometryManager;
42
import org.gvsig.fmap.geom.aggregate.MultiCurve;
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.Arc;
47
import org.gvsig.fmap.geom.primitive.Curve;
48
import org.gvsig.fmap.geom.primitive.Point;
49
import org.gvsig.fmap.geom.primitive.Primitive;
50
import org.gvsig.fmap.geom.type.GeometryType;
51
import org.gvsig.fmap.mapcontext.MapContext;
52
import org.gvsig.fmap.mapcontext.layers.vectorial.IntersectsGeometryEvaluator;
53
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
54
import org.gvsig.tools.dispose.DisposableIterator;
55
import org.gvsig.tools.dynobject.DynObject;
56
import org.gvsig.tools.exception.BaseException;
57
import org.gvsig.tools.service.spi.ProviderServices;
58
import org.gvsig.tools.visitor.VisitCanceledException;
59
import org.gvsig.tools.visitor.Visitor;
60
import org.gvsig.vectorediting.lib.api.DrawingStatus;
61
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
62
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
63
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
64
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
65
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
66
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
67
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
68
import org.gvsig.vectorediting.lib.prov.extendline.operation.ExtendLineOperation;
69
import org.gvsig.vectorediting.lib.prov.extendline.operation.ExtendLineOperationUtils;
70
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
71
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
72
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
73
import org.gvsig.vectorediting.lib.spi.EditingProvider;
74
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
75
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
76
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
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 EditingServiceParameter selectionParameter;
90

    
91
    private EditingServiceParameter linesToExtendParameter;
92

    
93
    private FeatureSelection selection;
94

    
95
    private FeatureSet linesToExtend;
96

    
97
    private FeatureStore featureStore;
98

    
99
    private MapContext mapContext;
100

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

    
114
        this.featureStore =
115
            (FeatureStore) parameters
116
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
117

    
118
        this.mapContext =
119
            (MapContext) parameters
120
                .getDynValue(EditingProviderFactory.MAPCONTEXT_FIELD);
121

    
122
        this.selectionParameter =
123
            new DefaultEditingServiceParameter("selection", "selection",
124
                TYPE.SELECTION);
125

    
126
        this.linesToExtendParameter =
127
            new DefaultEditingServiceParameter("line_to_extend",
128
                "line_to_extend", TYPE.POSITION);
129
    }
130

    
131
    public EditingServiceParameter next() {
132
        if (selection == null) {
133
            return selectionParameter;
134
        } else if (linesToExtend == null) {
135
            return linesToExtendParameter;
136
        }
137
        return null;
138
    }
139

    
140
    public DrawingStatus getDrawingStatus(Point mousePosition)
141
        throws DrawServiceException {
142

    
143
        if (selection != null) {
144
            DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
145
            EditingProviderManager editingProviderManager =
146
                EditingProviderLocator.getProviderManager();
147
            ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
148

    
149
            double tolerance =
150
                mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS);
151

    
152
            Geometry buffer;
153
            FeatureSet geometries;
154
            DisposableIterator it = null;
155
            try {
156
                // Create buffer with tolerance to get the geometry to be
157
                // extended
158
                buffer = mousePosition.buffer(tolerance);
159
                geometries = getGeometryByBuffer(buffer);
160

    
161
                it = geometries.fastIterator();
162
                while (it.hasNext()) {
163
                    Feature feature = (Feature) it.next();
164
                    if (!selection.isSelected(feature)) {
165
                        Geometry geometry = feature.getDefaultGeometry();
166

    
167

    
168
                        if (geometry instanceof MultiCurve) {
169
                            MultiCurve multiCurve = (MultiCurve) geometry;
170

    
171
                            for (int i = 0; i < multiCurve
172
                                .getPrimitivesNumber(); i++) {
173

    
174
                                Curve curve = multiCurve.getCurveAt(i);
175
                                if (!isClosed(curve)) {
176
                                    Curve extendedCurve =
177
                                        extendLine(mousePosition, curve);
178
                                    drawingStatus.addStatus(extendedCurve,lineSymbolEditing, "");
179
                                }
180
                            }
181

    
182
                        } else if (geometry instanceof Curve) {
183
                            if (!isClosed((Curve) geometry)) {
184
                                Curve extendedCurve =
185
                                    extendLine(mousePosition, (Curve) geometry);
186
                                drawingStatus.addStatus(extendedCurve,lineSymbolEditing, "");
187
                            }
188
                        }
189
                    }
190
                }
191

    
192
            } catch (BaseException e) {
193
                throw new DrawServiceException(e);
194
            } finally {
195
                it.dispose();
196
            }
197
            return drawingStatus;
198
        }
199
        return null;
200
    }
201

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

    
218
    private Curve extendLine(Point mousePosition, Curve curve)
219
        throws GeometryOperationNotSupportedException,
220
        GeometryOperationException, DataException, CreateGeometryException {
221
        ExtendLineOperation operation =
222
            ExtendLineOperationUtils.getOperation((Primitive) curve);
223

    
224
        return operation.extendLine(curve, mousePosition, selection);
225
    }
226

    
227
    public void stop() throws StopServiceException {
228
        linesToExtend = null;
229
    }
230

    
231
    public List<EditingServiceParameter> getParameters() {
232
        List<EditingServiceParameter> parameters =
233
            new ArrayList<EditingServiceParameter>();
234
        parameters.add(selectionParameter);
235
        parameters.add(linesToExtendParameter);
236
        return parameters;
237
    }
238

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

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

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

    
255
                            public void visit(Object obj)
256
                                throws VisitCanceledException, BaseException {
257
                                Feature feature = (Feature) obj;
258
                                Geometry geometry =
259
                                    feature.getDefaultGeometry();
260
                                GeometryType geoType =
261
                                    geometry.getGeometryType();
262

    
263
                                if (!geoType.isTypeOf(SURFACE)
264
                                    && !geoType.isTypeOf(MULTISURFACE)
265
                                    && !geoType.isTypeOf(CURVE)
266
                                    && !geoType.isTypeOf(MULTICURVE)) {
267
                                    throw new InvalidEntryException(null);
268
                                }
269
                            }
270
                        });
271
                        selection = featureSelection;
272
                        return;
273
                    } catch (BaseException e) {
274
                        throw new InvalidEntryException(e);
275
                    }
276
                }
277
            }
278
        } else if (parameter == linesToExtendParameter) {
279
            if (value instanceof Point) {
280
                Point point = (Point) value;
281
                try {
282
                    double tolerance =
283
                        mapContext.getViewPort()
284
                            .toMapDistance(TOLERANCE_PIXELS);
285

    
286
                    // Create buffer with tolerance to get geometries to be
287
                    // extended
288
                    Geometry buffer = point.buffer(tolerance);
289
                    FeatureSet geometries = getGeometryByBuffer(buffer);
290

    
291
                    if (geometries.getSize() > 0) {
292

    
293
                        geometries.accept(new Visitor() {
294

    
295
                            public void visit(Object obj)
296
                                throws VisitCanceledException, BaseException {
297
                                Feature feature = (Feature) obj;
298
                                Geometry geometry =
299
                                    feature.getDefaultGeometry();
300
                                GeometryType geoType =
301
                                    geometry.getGeometryType();
302

    
303
                                if (!geoType.isTypeOf(CURVE)
304
                                    && !geoType.isTypeOf(MULTICURVE)) {
305
                                    throw new InvalidEntryException(null);
306
                                }
307
                            }
308
                        });
309

    
310
                        insertedPoint = point;
311
                        linesToExtend = geometries;
312
                        return;
313
                    }
314
                } catch (BaseException e) {
315
                    throw new InvalidEntryException(e);
316
                }
317
            }
318
        }
319
        throw new InvalidEntryException(null);
320
    }
321

    
322
    private FeatureSet getGeometryByBuffer(Geometry buffer) throws DataException {
323
        FeatureQuery queryByGeometry = featureStore.createFeatureQuery();
324

    
325
        // Get default SRS of default feature type
326
        IProjection defaultSRS =
327
            this.featureStore.getDefaultFeatureType().getDefaultSRS();
328

    
329
        // Name of default geometry type
330
        String geomName =
331
            featureStore.getDefaultFeatureType()
332
                .getDefaultGeometryAttributeName();
333

    
334
        IntersectsGeometryEvaluator iee =
335
            new IntersectsGeometryEvaluator(buffer, defaultSRS,
336
                featureStore.getDefaultFeatureType(), geomName);
337

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

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

    
347
    public void finishAndStore() throws FinishServiceException {
348
        if (selection != null && linesToExtend != null) {
349

    
350
            try {
351
                linesToExtend.accept(new Visitor() {
352

    
353
                    public void visit(Object obj)
354
                        throws VisitCanceledException, BaseException {
355
                        Feature feature = (Feature) obj;
356
                        Geometry geometry = feature.getDefaultGeometry();
357
                        EditableFeature eFeature = feature.getEditable();
358

    
359
                        if (geometry instanceof MultiCurve) {
360

    
361
                            // Create new multicurve geometry
362
                            MultiCurve extendedMultiCurve =
363
                                createMultiCurve(geometry);
364

    
365
                            // Iterate overs primitives and execute extend
366
                            // line operation
367
                            MultiCurve multiCurve = (MultiCurve) geometry;
368

    
369
                            for (int i = 0; i < multiCurve
370
                                .getPrimitivesNumber(); i++) {
371

    
372
                                Curve curve = multiCurve.getCurveAt(i);
373
                                Curve extendedCurve =
374
                                    extendLine(insertedPoint, curve);
375
                                extendedMultiCurve.addCurve(extendedCurve);
376
                            }
377

    
378
                            eFeature.setDefaultGeometry(extendedMultiCurve);
379

    
380
                        } else if (geometry instanceof Curve) {
381
                            Curve extendedCurve =
382
                                extendLine(insertedPoint, (Curve) geometry);
383
                            eFeature.setDefaultGeometry(extendedCurve);
384
                        }
385

    
386
                        linesToExtend.update(eFeature);
387
                    }
388
                });
389

    
390
                linesToExtend.dispose();
391

    
392
            } catch (BaseException e) {
393
                throw new FinishServiceException(e);
394
            }
395
        }
396
    }
397

    
398
    private MultiCurve createMultiCurve(Geometry geometry)
399
        throws FinishServiceException {
400

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

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

    
413
    public void start() throws StartServiceException, InvalidEntryException {
414
        linesToExtend = null;
415
        FeatureSelection selected = null;
416
        if (featureStore != null) {
417
            try {
418
                selected = featureStore.getFeatureSelection();
419
            } catch (DataException e) {
420
                throw new StartServiceException(e);
421
            }
422
            if (selected.getSelectedCount() > 0) {
423
                try {
424
                    setValue(selected);
425
                } catch (InvalidEntryException e) {
426
                    throw new InvalidEntryException(e);
427
                }
428
            }
429
        }
430
    }
431

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

    
436
}