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

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
                "new_position",
144
                ((EditingProviderServices) getProviderServices()).makeConsoleMessage("new_position", options),
145
                options,
146
                TYPE.POSITION,
147
                TYPE.OPTION);
148
    }
149

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

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

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

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

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

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

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

    
317
    private Geometry getModifiedGeometry(Geometry geometry, int index,
318
        Point mousePosition) throws CreateGeometryException,
319
        GeometryOperationNotSupportedException, GeometryOperationException {
320

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
635

    
636

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

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

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

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

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

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

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

    
680
    private Geometry getSelectedGeometry() throws DataException {
681

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

    
694

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

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

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

    
722
                        }
723
                    }
724
                    DisposableIterator it = null;
725

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

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

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

    
750
    }
751

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

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

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

    
790
}