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

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

    
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.tools.dispose.DisposableIterator;
54
import org.gvsig.tools.dynobject.DynObject;
55
import org.gvsig.tools.exception.BaseException;
56
import org.gvsig.tools.service.spi.ProviderServices;
57
import org.gvsig.tools.visitor.VisitCanceledException;
58
import org.gvsig.tools.visitor.Visitor;
59
import org.gvsig.vectorediting.lib.api.DrawingStatus;
60
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
61
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
62
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
63
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
64
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
65
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
66
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
67
import org.gvsig.vectorediting.lib.prov.extendline.operation.ExtendLineOperation;
68
import org.gvsig.vectorediting.lib.prov.extendline.operation.ExtendLineOperationUtils;
69
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
70
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
71
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
72
import org.gvsig.vectorediting.lib.spi.EditingProvider;
73
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
74

    
75
/**
76
 * @author llmarques
77
 *
78
 */
79
public class ExtendLineEditingProvider extends AbstractEditingProvider
80
    implements EditingProvider {
81

    
82
    private final int TOLERANCE_PIXELS = 3;
83

    
84
    private Point insertedPoint;
85

    
86
    private EditingServiceParameter selectionParameter;
87

    
88
    private EditingServiceParameter linesToExtendParameter;
89

    
90
    private FeatureSelection selection;
91

    
92
    private FeatureSet linesToExtend;
93

    
94
    private FeatureStore featureStore;
95

    
96
    private MapContext mapContext;
97

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

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

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

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

    
123
        this.linesToExtendParameter =
124
            new DefaultEditingServiceParameter("line_to_extend",
125
                "line_to_extend", TYPE.POSITION);
126
    }
127

    
128
    public EditingServiceParameter next() {
129
        if (selection == null) {
130
            return selectionParameter;
131
        } else if (linesToExtend == null) {
132
            return linesToExtendParameter;
133
        }
134
        return null;
135
    }
136

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

    
140
        if (selection != null) {
141
            DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
142
            double tolerance =
143
                mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS);
144

    
145
            Geometry buffer;
146
            FeatureSet geometries;
147
            DisposableIterator it = null;
148
            try {
149
                // Create buffer with tolerance to get the geometry to be
150
                // extended
151
                buffer = mousePosition.buffer(tolerance);
152
                geometries = getGeometryByBuffer(buffer);
153

    
154
                it = geometries.fastIterator();
155
                while (it.hasNext()) {
156
                    Feature feature = (Feature) it.next();
157
                    if (!selection.isSelected(feature)) {
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);
170
                                    drawingStatus.addGeometry(extendedCurve);
171
                                }
172
                            }
173

    
174
                        } else if (geometry instanceof Curve) {
175
                            if (!isClosed((Curve) geometry)) {
176
                                Curve extendedCurve =
177
                                    extendLine(mousePosition, (Curve) geometry);
178
                                drawingStatus.addGeometry(extendedCurve);
179
                            }
180
                        }
181
                    }
182
                }
183

    
184
            } catch (BaseException e) {
185
                throw new DrawServiceException(e);
186
            } finally {
187
                it.dispose();
188
            }
189
            return drawingStatus;
190
        }
191
        return null;
192
    }
193

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

    
210
    private Curve extendLine(Point mousePosition, Curve curve)
211
        throws GeometryOperationNotSupportedException,
212
        GeometryOperationException, DataException, CreateGeometryException {
213
        ExtendLineOperation operation =
214
            ExtendLineOperationUtils.getOperation((Primitive) curve);
215

    
216
        return operation.extendLine(curve, mousePosition, selection);
217
    }
218

    
219
    public void stop() throws StopServiceException {
220
        selection = null;
221
        linesToExtend = null;
222
    }
223

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

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

    
237
    private void validateAndInsertValue(
238
        final EditingServiceParameter parameter, Object value)
239
        throws InvalidEntryException {
240

    
241
        if (parameter == selectionParameter) {
242
            if (value instanceof FeatureSelection) {
243
                FeatureSelection featureSelection = (FeatureSelection) value;
244
                if (featureSelection.getSelectedCount() > 0) {
245
                    try {
246
                        featureSelection.accept(new Visitor() {
247

    
248
                            public void visit(Object obj)
249
                                throws VisitCanceledException, BaseException {
250
                                Feature feature = (Feature) obj;
251
                                Geometry geometry =
252
                                    feature.getDefaultGeometry();
253
                                GeometryType geoType =
254
                                    geometry.getGeometryType();
255

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

    
279
                    // Create buffer with tolerance to get geometries to be
280
                    // extended
281
                    Geometry buffer = point.buffer(tolerance);
282
                    FeatureSet geometries = getGeometryByBuffer(buffer);
283

    
284
                    if (geometries.getSize() > 0) {
285

    
286
                        geometries.accept(new Visitor() {
287

    
288
                            public void visit(Object obj)
289
                                throws VisitCanceledException, BaseException {
290
                                Feature feature = (Feature) obj;
291
                                Geometry geometry =
292
                                    feature.getDefaultGeometry();
293
                                GeometryType geoType =
294
                                    geometry.getGeometryType();
295

    
296
                                if (!geoType.isTypeOf(CURVE)
297
                                    && !geoType.isTypeOf(MULTICURVE)) {
298
                                    throw new InvalidEntryException(null);
299
                                }
300
                            }
301
                        });
302

    
303
                        insertedPoint = point;
304
                        linesToExtend = geometries;
305
                        return;
306
                    }
307
                } catch (BaseException e) {
308
                    throw new InvalidEntryException(e);
309
                }
310
            }
311
        }
312
        throw new InvalidEntryException(null);
313
    }
314

    
315
    public FeatureSet getGeometryByBuffer(Geometry buffer) throws DataException {
316
        FeatureQuery queryByGeometry = featureStore.createFeatureQuery();
317

    
318
        // Get default SRS of default feature type
319
        IProjection defaultSRS =
320
            this.featureStore.getDefaultFeatureType().getDefaultSRS();
321

    
322
        // Name of default geometry type
323
        String geomName =
324
            featureStore.getDefaultFeatureType()
325
                .getDefaultGeometryAttributeName();
326

    
327
        IntersectsGeometryEvaluator iee =
328
            new IntersectsGeometryEvaluator(buffer, defaultSRS,
329
                featureStore.getDefaultFeatureType(), geomName);
330

    
331
        queryByGeometry.setFilter(iee);
332
        queryByGeometry.setAttributeNames(null);
333
        return this.featureStore.getFeatureSet(queryByGeometry);
334
    }
335

    
336
    public Geometry finish() throws FinishServiceException {
337
        return null;
338
    }
339

    
340
    public void finishAndStore() throws FinishServiceException {
341
        if (selection != null && linesToExtend != null) {
342

    
343
            try {
344
                linesToExtend.accept(new Visitor() {
345

    
346
                    public void visit(Object obj)
347
                        throws VisitCanceledException, BaseException {
348
                        Feature feature = (Feature) obj;
349
                        Geometry geometry = feature.getDefaultGeometry();
350
                        EditableFeature eFeature = feature.getEditable();
351

    
352
                        if (geometry instanceof MultiCurve) {
353

    
354
                            // Create new multicurve geometry
355
                            MultiCurve extendedMultiCurve =
356
                                createMultiCurve(geometry);
357

    
358
                            // Iterate overs primitives and execute extend
359
                            // line operation
360
                            MultiCurve multiCurve = (MultiCurve) geometry;
361

    
362
                            for (int i = 0; i < multiCurve
363
                                .getPrimitivesNumber(); i++) {
364

    
365
                                Curve curve = multiCurve.getCurveAt(i);
366
                                Curve extendedCurve =
367
                                    extendLine(insertedPoint, curve);
368
                                extendedMultiCurve.addCurve(extendedCurve);
369
                            }
370

    
371
                            eFeature.setDefaultGeometry(extendedMultiCurve);
372

    
373
                        } else if (geometry instanceof Curve) {
374
                            Curve extendedCurve =
375
                                extendLine(insertedPoint, (Curve) geometry);
376
                            eFeature.setDefaultGeometry(extendedCurve);
377
                        }
378

    
379
                        linesToExtend.update(eFeature);
380
                    }
381
                });
382

    
383
                linesToExtend.dispose();
384

    
385
            } catch (BaseException e) {
386
                throw new FinishServiceException(e);
387
            }
388
        }
389
    }
390

    
391
    private MultiCurve createMultiCurve(Geometry geometry)
392
        throws FinishServiceException {
393

    
394
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
395
        int subtype = geometry.getGeometryType().getSubType();
396
        MultiCurve extendedMultiCurve = null;
397

    
398
        try {
399
            extendedMultiCurve = geoManager.createMultiCurve(subtype);
400
        } catch (CreateGeometryException e) {
401
            throw new FinishServiceException(e);
402
        }
403
        return extendedMultiCurve;
404
    }
405

    
406
    public void start() throws StartServiceException, InvalidEntryException {
407
        selection = null;
408
        linesToExtend = null;
409
        FeatureSelection selected = null;
410
        if (featureStore != null) {
411
            try {
412
                selected = featureStore.getFeatureSelection();
413
            } catch (DataException e) {
414
                throw new StartServiceException(e);
415
            }
416
            if (selected.getSelectedCount() > 0) {
417
                try {
418
                    setValue(selected);
419
                } catch (InvalidEntryException e) {
420
                    throw new InvalidEntryException(e);
421
                }
422
            }
423
        }
424
    }
425

    
426
    public String getName() {
427
        return ExtendLineEditingProviderFactory.PROVIDER_NAME;
428
    }
429

    
430
}