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.editvertex / src / main / java / org / gvsig / vectorediting / lib / prov / editvertex / EditVertexEditingProvider.java @ 492

History | View | Annotate | Download (34.2 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.editvertex;
25

    
26

    
27
import java.awt.Color;
28
import java.awt.geom.AffineTransform;
29
import java.util.ArrayList;
30
import java.util.Iterator;
31
import java.util.LinkedHashMap;
32
import java.util.List;
33

    
34
import org.cresques.cts.IProjection;
35

    
36
import org.gvsig.fmap.dal.exception.DataException;
37
import org.gvsig.fmap.dal.feature.EditableFeature;
38
import org.gvsig.fmap.dal.feature.Feature;
39
import org.gvsig.fmap.dal.feature.FeatureQuery;
40
import org.gvsig.fmap.dal.feature.FeatureSelection;
41
import org.gvsig.fmap.dal.feature.FeatureSet;
42
import org.gvsig.fmap.dal.feature.FeatureStore;
43
import org.gvsig.fmap.geom.Geometry;
44
import org.gvsig.fmap.geom.GeometryLocator;
45
import org.gvsig.fmap.geom.GeometryManager;
46
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
47
import org.gvsig.fmap.geom.exception.CreateGeometryException;
48
import org.gvsig.fmap.geom.operation.GeometryOperationException;
49
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
50
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
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.IntersectsGeometryEvaluator;
56
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
57
import org.gvsig.symbology.SymbologyLocator;
58
import org.gvsig.symbology.SymbologyManager;
59
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol;
60
import org.gvsig.tools.dispose.DisposableIterator;
61
import org.gvsig.tools.dynobject.DynObject;
62
import org.gvsig.tools.exception.BaseException;
63
import org.gvsig.tools.service.spi.ProviderServices;
64
import org.gvsig.vectorediting.lib.api.DrawingStatus;
65
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
66
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
67
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
68
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
69
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
70
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
71
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
72
import org.gvsig.vectorediting.lib.prov.editvertex.operation.EditVertexOperation;
73
import org.gvsig.vectorediting.lib.prov.editvertex.operation.EditVertexOperationUtils;
74
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
75
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
76
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
77
import org.gvsig.vectorediting.lib.spi.EditingProvider;
78
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
79
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
80
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
81
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
82

    
83
/**
84
 * @author fdiaz
85
 *
86
 */
87
public class EditVertexEditingProvider extends AbstractEditingProvider implements
88
    EditingProvider {
89

    
90
    private final int TOLERANCE_PIXELS = 3;
91

    
92
    private EditingServiceParameter selectionParameter;
93

    
94
    private EditingServiceParameter vertexSelectionPointParameter;
95

    
96
    private EditingServiceParameter actionParameter;
97

    
98
    private FeatureSelection selection;
99

    
100
    private Point selectedVertex;
101

    
102
    private Point pointToMove;
103

    
104
    private String action;
105

    
106
    private FeatureStore featureStore;
107

    
108
    private MapContext mapContext;
109

    
110
    /**
111
     * Default constructor.
112
     *
113
     * @param providerServices
114
     *            available services for this provider
115
     * @param parameters
116
     *            of this provider
117
     */
118
    public EditVertexEditingProvider(ProviderServices services,
119
        DynObject parameters) {
120
        super(services);
121

    
122
        this.featureStore =
123
            (FeatureStore) parameters
124
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
125

    
126
        this.mapContext =
127
            (MapContext) parameters
128
                .getDynValue(EditingProviderFactory.MAPCONTEXT_FIELD);
129

    
130
        this.selectionParameter =
131
            new DefaultEditingServiceParameter("selection", "uniqueselection",
132
                TYPE.SELECTION);
133

    
134
        this.vertexSelectionPointParameter =
135
            new DefaultEditingServiceParameter("selectvertex", "selectvertex",
136
                TYPE.POSITION);
137

    
138
        LinkedHashMap<String, String> options = new LinkedHashMap<String, String>();
139
        options.put("+", "insert_vertex");
140
        options.put("-", "remove_vertex");
141
        this.actionParameter =
142
            new DefaultEditingServiceParameter(
143
                "actionParameter",
144
                ((EditingProviderServices) getProviderServices()).makeConsoleMessage("moveVertexOr", options),
145
                TYPE.POSITION,
146
                TYPE.OPTION);
147
    }
148

    
149
    public EditingServiceParameter next() {
150
        if (selection == null) {
151
            return selectionParameter;
152
        } else if (selectedVertex == null) {
153
            return vertexSelectionPointParameter;
154
        } else if (action == null && pointToMove == null) {
155
            return actionParameter;
156
        }
157
        return null;
158
    }
159

    
160
    public DrawingStatus getDrawingStatus(Point mousePosition)
161
        throws DrawServiceException {
162
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
163
        EditingProviderManager editingProviderManager =
164
            EditingProviderLocator.getProviderManager();
165
        ISymbol selectedVertexSymbolEditing =
166
            editingProviderManager.getSymbol("selected-vertex-symbol-editing");
167
        ISymbol editedVertexSymbolEditing =
168
            editingProviderManager.getSymbol("edited-vertex-symbol-editing");
169
        Color colorToTextSymbol = Color.BLACK;
170
        if (selectedVertexSymbolEditing != null) {
171
            colorToTextSymbol = selectedVertexSymbolEditing
172
                .getColor();
173
        }
174

    
175
        double translationForTextSymbol =
176
            mapContext.getViewPort().toMapDistance(5);
177
        double tolerance =
178
            mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS);
179
        try {
180
            if (this.selection == null) {
181
                Geometry geometry = null;
182
                geometry = getNearestGeometry(mousePosition);
183
                if (geometry != null) {
184
                    List<Point> vertexesList = getVertexesList(geometry);
185
                    if (vertexesList != null) {
186
                        int i = 0;
187
                        for (Iterator<Point> iterator = vertexesList.iterator(); iterator
188
                            .hasNext();) {
189
                            Point point = (Point) iterator.next();
190
                            drawingStatus.addStatus(point,
191
                                selectedVertexSymbolEditing, "");
192
                            Point pointToText = (Point) point.cloneGeometry();
193
                            pointToText.transform(new AffineTransform(1, 0, 0,
194
                                1, translationForTextSymbol, 0));
195
                            drawingStatus.addStatus(pointToText,
196
                                getTextSymbol(colorToTextSymbol), String.valueOf(i++));
197
                        }
198
                    }
199
                }
200
            } else {
201
                Geometry selectedGeometry = getSelectedGeometry();
202
                if (selectedVertex == null) {
203
                    List<Point> vertexesList =
204
                        getVertexesList(selectedGeometry);
205
                    Point vertex =
206
                        getVertex(selectedGeometry, mousePosition, tolerance);
207
                    if (vertexesList != null) {
208
                        int i = 0;
209
                        int selectedIndex = -1;
210
                        for (Iterator<Point> iterator = vertexesList.iterator(); iterator
211
                            .hasNext();) {
212
                            Point point = (Point) iterator.next();
213
                            Point pointToText = (Point) point.cloneGeometry();
214
                            pointToText.transform(new AffineTransform(1, 0, 0,
215
                                1, translationForTextSymbol, 0));
216
                            if (vertex != null && vertex.equals(point)) {
217
                                selectedIndex = i++;
218
                            } else {
219
                                drawingStatus.addStatus(point,
220
                                    selectedVertexSymbolEditing, "");
221
                                drawingStatus
222
                                .addStatus(
223
                                    pointToText,
224
                                    getTextSymbol(colorToTextSymbol),
225
                                    String.valueOf(i++));
226
                            }
227
                        }
228
                        if (selectedIndex >= 0) {
229
                            Point pointToText = (Point) vertex.cloneGeometry();
230
                            pointToText.transform(new AffineTransform(1, 0, 0,
231
                                1, translationForTextSymbol, 0));
232
                            drawingStatus.addStatus(vertex,
233
                                editedVertexSymbolEditing, "");
234
                            drawingStatus
235
                                .addStatus(pointToText,
236
                                    getTextSymbol(colorToTextSymbol), String
237
                                        .valueOf(selectedIndex));
238

    
239
                        }
240
                    }
241
                } else {
242
                    List<Point> vertexesList =
243
                        getVertexesList(selectedGeometry);
244
                    if (vertexesList != null) {
245
                        int i = 0;
246
                        int selectedIndex = -1;
247
                        for (Iterator<Point> iterator = vertexesList.iterator(); iterator
248
                            .hasNext();) {
249
                            Point point = (Point) iterator.next();
250
                            Point pointToText = (Point) point.cloneGeometry();
251
                            pointToText.transform(new AffineTransform(1, 0, 0,
252
                                1, translationForTextSymbol, 0));
253
                            if (selectedVertex.equals(point)) {
254
                                selectedIndex = i++;
255
                            } else {
256
                                drawingStatus.addStatus(point,
257
                                    selectedVertexSymbolEditing, "");
258
                                drawingStatus.addStatus(pointToText,
259
                                    getTextSymbol(colorToTextSymbol), String.valueOf(i++));
260
                            }
261
                        }
262
                        if (selectedIndex >= 0) {
263
                            Point pointToText =
264
                                (Point) selectedVertex.cloneGeometry();
265
                            pointToText.transform(new AffineTransform(1, 0, 0, 1, translationForTextSymbol, 0));
266
                            drawingStatus.addStatus(selectedVertex,
267
                                editedVertexSymbolEditing, "");
268
                            drawingStatus
269
                                .addStatus(pointToText,
270
                                    getTextSymbol(colorToTextSymbol), String
271
                                        .valueOf(selectedIndex));
272
                            Geometry modifiedGeometry = this.getModifiedGeometry(selectedGeometry, selectedIndex, mousePosition);
273
                            addToDrawingStatus(drawingStatus, modifiedGeometry);
274
                            drawingStatus.addStatus(mousePosition,
275
                                selectedVertexSymbolEditing, "");
276
                            pointToText =
277
                                (Point) mousePosition.cloneGeometry();
278
                            pointToText.transform(new AffineTransform(1, 0, 0, 1, translationForTextSymbol, 0));
279
                            drawingStatus.addStatus(pointToText,
280
                                getTextSymbol(colorToTextSymbol), String.valueOf(selectedIndex));
281
                        }
282
                    }
283
                }
284
            }
285
        } catch (BaseException e) {
286
            throw new DrawServiceException(e);
287
        }
288
        return drawingStatus;
289
    }
290

    
291
    private void addToDrawingStatus(DefaultDrawingStatus drawingStatus,
292
        Geometry geometry) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
293

    
294
        if (geometry instanceof MultiPrimitive) {
295
            MultiPrimitive aggregate = (MultiPrimitive) geometry;
296
            for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
297
                Primitive primitive = aggregate.getPrimitiveAt(i);
298

    
299
                EditVertexOperation operation =
300
                    EditVertexOperationUtils.getOperation(primitive);
301
                if (operation != null) {
302
                    operation.addToDrawingStatus(drawingStatus, primitive);
303
                }
304
            }
305
        } else if (geometry instanceof Primitive) {
306
            Primitive primitive = (Primitive) geometry;
307
            EditVertexOperation operation =
308
                EditVertexOperationUtils.getOperation(primitive);
309
            if (operation != null) {
310
                operation.addToDrawingStatus(drawingStatus, primitive);
311
            }
312
        }
313
        return;
314
    }
315

    
316
    private Geometry getModifiedGeometry(Geometry geometry, int index,
317
        Point mousePosition) throws CreateGeometryException,
318
        GeometryOperationNotSupportedException, GeometryOperationException {
319
        
320
        if (geometry instanceof MultiPrimitive) {
321
            GeometryManager geometryManager =
322
                GeometryLocator.getGeometryManager();
323
            MultiPrimitive aggregate = (MultiPrimitive) geometry;
324
            GeometryType geometryType = aggregate.getGeometryType();
325
            MultiPrimitive newAggregate =
326
                (MultiPrimitive) geometryManager.create(geometryType.getType(),
327
                    geometryType.getSubType());
328
            for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
329
                Primitive primitive = aggregate.getPrimitiveAt(i);
330
                EditVertexOperation operation =
331
                    EditVertexOperationUtils.getOperation(primitive);
332
                if (operation != null) {
333
                    int numVertexes = operation.getNumVertex(primitive);
334
                    if (index > -1 && index < numVertexes) {
335
                        Geometry modifiedPrimitive =
336
                            operation.moveVertex(primitive, index,
337
                                mousePosition);
338
                        newAggregate
339
                            .addPrimitive((Primitive) modifiedPrimitive);
340
                        index = -1;
341
                    } else {
342
                        index -= numVertexes;
343
                        newAggregate.addPrimitive((Primitive) primitive
344
                            .cloneGeometry());
345
                    }
346
                }
347
            }
348
            return newAggregate;
349
        } else if (geometry instanceof Primitive) {
350
            Primitive primitive = (Primitive) geometry;
351
            EditVertexOperation operation =
352
                EditVertexOperationUtils.getOperation(primitive);
353
            if (operation != null) {
354
                return operation.moveVertex(primitive, index, mousePosition);
355
            }
356
        }
357
        return null;
358
    }
359

    
360
    private Geometry getInsertVertexGeometry(Geometry geometry, int index)
361
        throws CreateGeometryException {
362
        if (geometry instanceof MultiPrimitive) {
363
            GeometryManager geometryManager =
364
                GeometryLocator.getGeometryManager();
365
            MultiPrimitive aggregate = (MultiPrimitive) geometry;
366
            GeometryType geometryType = aggregate.getGeometryType();
367
            MultiPrimitive newAggregate =
368
                (MultiPrimitive) geometryManager.create(geometryType.getType(),
369
                    geometryType.getSubType());
370
            for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
371
                Primitive primitive = aggregate.getPrimitiveAt(i);
372
                EditVertexOperation operation =
373
                    EditVertexOperationUtils.getOperation(primitive);
374
                if (operation != null) {
375
                    int numVertexes = operation.getNumVertex(primitive);
376
                    if (index > -1 && index < numVertexes) {
377
                        Geometry modifiedPrimitive =
378
                            operation.insertVertex(primitive, index);
379
                        newAggregate
380
                            .addPrimitive((Primitive) modifiedPrimitive);
381
                        index = -1;
382
                    } else {
383
                        index -= numVertexes;
384
                        newAggregate.addPrimitive((Primitive) primitive
385
                            .cloneGeometry());
386
                    }
387
                }
388
            }
389
            return newAggregate;
390
        } else if (geometry instanceof Primitive) {
391
            Primitive primitive = (Primitive) geometry;
392
            EditVertexOperation operation =
393
                EditVertexOperationUtils.getOperation(primitive);
394
            if (operation != null) {
395
                return operation.insertVertex(primitive, index);
396
            }
397
        }
398
        return null;
399
    }
400

    
401
    private Geometry getRemovedVertexGeometry(Geometry geometry, int index)
402
        throws CreateGeometryException {
403
        if (geometry instanceof MultiPrimitive) {
404
            GeometryManager geometryManager =
405
                GeometryLocator.getGeometryManager();
406
            MultiPrimitive aggregate = (MultiPrimitive) geometry;
407
            GeometryType geometryType = aggregate.getGeometryType();
408
            MultiPrimitive newAggregate =
409
                (MultiPrimitive) geometryManager.create(geometryType.getType(),
410
                    geometryType.getSubType());
411
            for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
412
                Primitive primitive = aggregate.getPrimitiveAt(i);
413
                EditVertexOperation operation =
414
                    EditVertexOperationUtils.getOperation(primitive);
415
                if (operation != null) {
416
                    int numVertexes = operation.getNumVertex(primitive);
417
                    if (index > -1 && index < numVertexes) {
418
                        Geometry modifiedPrimitive =
419
                            operation.removeVertex(primitive, index);
420
                        newAggregate
421
                            .addPrimitive((Primitive) modifiedPrimitive);
422
                        index = -1;
423
                    } else {
424
                        index -= numVertexes;
425
                        newAggregate.addPrimitive((Primitive) primitive
426
                            .cloneGeometry());
427
                    }
428
                }
429
            }
430
            return newAggregate;
431
        } else if (geometry instanceof Primitive) {
432
            Primitive primitive = (Primitive) geometry;
433
            EditVertexOperation operation =
434
                EditVertexOperationUtils.getOperation(primitive);
435
            if (operation != null) {
436
                return operation.removeVertex(primitive, index);
437
            }
438
        }
439
        return null;
440
    }
441

    
442
    private ISimpleTextSymbol getTextSymbol(Color color){
443
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
444
        ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol();
445
        textSymbol.setFontSize(12);
446
        textSymbol.setColor(color);
447
        return textSymbol;
448
    }
449

    
450
    public void stop() throws StopServiceException {
451
        this.selection = null;
452
        this.selectedVertex = null;
453
        this.pointToMove = null;
454
        this.action = null;
455
    }
456

    
457
    public List<EditingServiceParameter> getParameters() {
458
        List<EditingServiceParameter> parameters =
459
            new ArrayList<EditingServiceParameter>();
460
        parameters.add(selectionParameter);
461
        parameters.add(vertexSelectionPointParameter);
462
        parameters.add(actionParameter);
463
        return parameters;
464
    }
465

    
466
    public void setValue(Object value) throws InvalidEntryException {
467
        EditingServiceParameter parameter = next();
468
        validateAndInsertValue(parameter, value);
469
    }
470

    
471
    private void validateAndInsertValue(
472
        final EditingServiceParameter parameter, Object value)
473
        throws InvalidEntryException {
474

    
475
        if (parameter == selectionParameter) {
476
            if (value instanceof FeatureSelection) {
477
                FeatureSelection featureSelection = (FeatureSelection) value;
478
                if (featureSelection.getSelectedCount() == 1) {
479
                    this.selection = featureSelection;
480
                } else {
481
                    throw new InvalidEntryException(null);
482
                }
483
            }
484
        } else {
485
            Geometry selectedGeometry;
486
            try {
487
                selectedGeometry = getSelectedGeometry();
488
            } catch (DataException e1) {
489
                throw new InvalidEntryException(e1);
490
            }
491
            if (parameter == vertexSelectionPointParameter
492
                && value instanceof Point) {
493
                Point point = (Point) value;
494
                double tolerance =
495
                    mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS);
496
                try {
497
                    this.selectedVertex =
498
                        getVertex(selectedGeometry, point, tolerance);
499
                } catch (BaseException e) {
500
                    throw new InvalidEntryException(e);
501
                }
502
                return;
503

    
504
            } else if (parameter == actionParameter) {
505
                if (value instanceof Point) {
506
                    this.pointToMove = (Point) value;
507
                } else if (value instanceof String) {
508

    
509
                    List<Point> vertexesList;
510
                    try {
511
                        vertexesList = getVertexesList(selectedGeometry);
512
                    } catch (BaseException e) {
513
                        throw new InvalidEntryException(e);
514
                    }
515
                    EditVertexOperation operation = null;
516
                    int selectedIndex = -1;
517
                    if (vertexesList != null) {
518
                        Primitive primitive = null;
519
                        if (selectedGeometry instanceof MultiPrimitive) {
520
                            MultiPrimitive aggregate =
521
                                (MultiPrimitive) selectedGeometry;
522
                            boolean found = false;
523
                            for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
524
                                selectedIndex = -1;
525
                                primitive = aggregate.getPrimitiveAt(i);
526
                                operation = EditVertexOperationUtils.getOperation(primitive);
527
                                if (operation != null) {
528
                                    int numVertexes =
529
                                        operation.getNumVertex(primitive);
530
                                    if(primitive instanceof OrientablePrimitive){
531
                                        OrientablePrimitive orientable =  (OrientablePrimitive)primitive;
532
                                        for (int j = 0; j < numVertexes; j++) {
533
                                            if(selectedVertex.equals(orientable.getVertex(j))){
534
                                                selectedIndex = j;
535
                                                found = true;
536
                                                break;
537
                                            }
538
                                        }
539
                                    }
540
                                }
541
                                if(found){
542
                                    break;
543
                                }
544
                            }
545
                        } else if (selectedGeometry instanceof Primitive) {
546
                            primitive = (Primitive) selectedGeometry;
547
                            operation =
548
                                EditVertexOperationUtils.getOperation(primitive);
549
                            if (operation != null) {
550
                                int numVertexes =
551
                                    operation.getNumVertex(primitive);
552
                                if(primitive instanceof OrientablePrimitive){
553
                                    OrientablePrimitive orientable =  (OrientablePrimitive)primitive;
554
                                    for (int j = 0; j < numVertexes; j++) {
555
                                        if(selectedVertex.equals(orientable.getVertex(j))){
556
                                            selectedIndex = j;
557
                                            break;
558
                                        }
559
                                    }
560
                                }
561
                            }
562
                        }
563

    
564
                        String str = (String) value;
565
                        if (str.equalsIgnoreCase("+") || str.equalsIgnoreCase("-")) {
566
                            if(operation!=null){
567
                                if (str.equalsIgnoreCase("+")) {
568
                                    if(selectedIndex<0 || !operation.canInsertVertex(primitive, selectedIndex)){
569
                                        throw new InvalidEntryException(null);
570
                                    }
571
                                } else if(str.equalsIgnoreCase("-")) {
572
                                    if(selectedIndex<0 || !operation.canRemoveVertex(primitive, selectedIndex)){
573
                                        throw new InvalidEntryException(null);
574
                                    }
575
                                }
576
                            }
577
                            this.action = str;
578
                        } else {
579
                            throw new InvalidEntryException(null);
580
                        }
581
                    }
582
                }
583
            }
584
        }
585
    }
586

    
587
    private Point getVertex(Geometry geometry, Point point, double tolerance)
588
        throws GeometryOperationNotSupportedException,
589
        GeometryOperationException, CreateGeometryException {
590
        List<Point> vertexesList = getVertexesList(geometry);
591
        double min = Double.POSITIVE_INFINITY;
592
        Point vertex = null;
593
        if (vertexesList != null) {
594
            for (Iterator<Point> iterator = vertexesList.iterator(); iterator
595
                .hasNext();) {
596
                Point point2 = (Point) iterator.next();
597
                double distance = point.distance(point2);
598
                if (distance <= tolerance) {
599
                    if (distance < min) {
600
                        vertex = point2;
601
                        min = distance;
602
                    }
603
                }
604
            }
605
        }
606
        return vertex;
607
    }
608

    
609
    private List<Point> getVertexesList(Geometry geometry) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
610
        if (geometry instanceof MultiPrimitive) {
611
            MultiPrimitive aggregate = (MultiPrimitive) geometry;
612
            List<Point> vertexesList = new ArrayList<Point>();
613
            for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
614
                Primitive primitive = aggregate.getPrimitiveAt(i);
615
                EditVertexOperation operation =
616
                    EditVertexOperationUtils.getOperation(primitive);
617
                if (operation != null) {
618
                    vertexesList.addAll(operation.getVertexesList(primitive));
619
                }
620
            }
621
            return vertexesList;
622
        } else if (geometry instanceof Primitive) {
623
            Primitive primitive = (Primitive) geometry;
624
            EditVertexOperation operation =
625
                EditVertexOperationUtils.getOperation(primitive);
626
            if (operation != null) {
627
                List<Point> vertexesList = operation.getVertexesList(primitive);
628
                return vertexesList;
629
            }
630
        }
631
        return null;
632
    }
633

    
634

    
635

    
636
    private FeatureSet getGeometryByBuffer(Geometry buffer)
637
        throws DataException {
638
        FeatureQuery queryByGeometry = featureStore.createFeatureQuery();
639

    
640
        // Get default SRS of default feature type
641
        IProjection defaultSRS =
642
            this.featureStore.getDefaultFeatureType().getDefaultSRS();
643

    
644
        // Name of default geometry type
645
        String geomName =
646
            featureStore.getDefaultFeatureType()
647
                .getDefaultGeometryAttributeName();
648

    
649
        IntersectsGeometryEvaluator iee =
650
            new IntersectsGeometryEvaluator(buffer, defaultSRS,
651
                featureStore.getDefaultFeatureType(), geomName);
652

    
653
        queryByGeometry.setFilter(iee);
654
        queryByGeometry.setAttributeNames(null);
655
        return this.featureStore.getFeatureSet(queryByGeometry);
656
    }
657

    
658
    private Geometry getNearestGeometry(final Point point) throws GeometryOperationNotSupportedException, GeometryOperationException, DataException{
659
        double tolerance =
660
            mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS);
661
        Geometry buffer = point.buffer(tolerance);
662
        FeatureSet featureSet = getGeometryByBuffer(buffer);
663
        double min = Double.POSITIVE_INFINITY;
664
        Geometry geometry = null;
665

    
666
        DisposableIterator iterator = featureSet.fastIterator();
667
        while (iterator.hasNext()) {
668
            Feature feat = (Feature) iterator.next();
669
            double distance = point.distance(feat.getDefaultGeometry());
670
            if (distance < min){
671
                geometry = feat.getDefaultGeometry();
672
                min = distance;
673
            }
674
        }
675
        iterator.dispose();
676
        return geometry;
677
    }
678

    
679
    private Geometry getSelectedGeometry() throws DataException {
680

    
681
        Geometry selectedGeometry = null;
682
            if (this.selection != null && this.selection.getSelectedCount() == 1) {
683
                DisposableIterator it = this.selection.fastIterator();
684
                while (it.hasNext()) {
685
                    Feature feature = (Feature) it.next();
686
                    selectedGeometry = feature.getDefaultGeometry();
687
                }
688
                it.dispose();
689
            }
690
        return selectedGeometry;
691
    }
692

    
693

    
694
    public Geometry finish() throws FinishServiceException {
695
        return null;
696
    }
697

    
698
    public void finishAndStore() throws FinishServiceException {
699
        if (this.selection != null) {
700
            try {
701
                Geometry selectedGeometry = getSelectedGeometry();
702
                List<Point> vertexesList;
703
                vertexesList = getVertexesList(selectedGeometry);
704
                if(vertexesList != null){
705
                    int selectedIndex = getSelectedIndex(vertexesList);
706
                    Geometry modifiedGeometry = null;
707
                    if (pointToMove != null) {
708
                        if (selectedIndex >= 0) {
709
                            modifiedGeometry =
710
                                this.getModifiedGeometry(selectedGeometry,
711
                                    selectedIndex, pointToMove);
712
                        }
713
                    } else if (action != null){
714
                        if(action.equalsIgnoreCase("+")){
715
                            modifiedGeometry =
716
                                this.getInsertVertexGeometry(selectedGeometry, selectedIndex);
717

    
718
                        } else if(action.equalsIgnoreCase("-")){
719
                            modifiedGeometry = this.getRemovedVertexGeometry(selectedGeometry, selectedIndex);
720

    
721
                        }
722
                    }
723
                    DisposableIterator it = null;
724

    
725
                    try {
726
                        it = selection.fastIterator();
727

    
728
                        while (it.hasNext()) {
729
                            Feature feature = (Feature) it.next();
730
                            EditableFeature editableFeature =
731
                                feature.getEditable();
732
                            editableFeature.setDefaultGeometry(modifiedGeometry);
733
                            ((EditingProviderServices) getProviderServices())
734
                                .updateFeatureInFeatureStore(
735
                                    editableFeature, featureStore);
736
                        }
737
                    } catch (BaseException e) {
738
                        throw new FinishServiceException(e);
739
                    } finally {
740
                        it.dispose();
741
                    }
742

    
743
                }
744
            } catch (BaseException e) {
745
                throw new FinishServiceException(e);
746
            }
747
        }
748

    
749
    }
750

    
751
    private int getSelectedIndex(List<Point> vertexesList){
752
        int selectedIndex = -1;
753
        if (vertexesList != null) {
754
            int i = 0;
755
            for (Iterator<Point> iterator = vertexesList.iterator(); iterator
756
                .hasNext();) {
757
                Point point = (Point) iterator.next();
758
                if (selectedVertex.equals(point)) {
759
                    selectedIndex = i;
760
                    break;
761
                }
762
                i++;
763
            }
764
        }
765
        return selectedIndex;
766
    }
767

    
768
    public void start() throws StartServiceException, InvalidEntryException {
769
        FeatureSelection selected = null;
770
        if (featureStore != null) {
771
            try {
772
                selected = featureStore.getFeatureSelection();
773
                long selectedCount = selected.getSelectedCount();
774
                if(selectedCount==1){
775
                    this.selection = selected;
776
                } else {
777
                    selected.deselectAll();
778
                }
779
            } catch (DataException e) {
780
                throw new StartServiceException(e);
781
            }
782
        }
783
    }
784

    
785
    public String getName() {
786
        return EditVertexEditingProviderFactory.PROVIDER_NAME;
787
    }
788

    
789
}