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

History | View | Annotate | Download (38.5 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2015 gvSIG Association
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
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
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

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

    
85
/**
86
 * @author fdiaz
87
 *
88
 */
89
public class EditVertexEditingProvider extends AbstractEditingProvider implements
90
    EditingProvider {
91
    private static final Logger logger = LoggerFactory
92
        .getLogger(EditVertexEditingProvider.class);
93

    
94
    private final int TOLERANCE_PIXELS = 3;
95

    
96
    private EditingServiceParameter selectionParameter;
97

    
98
    private EditingServiceParameter vertexSelectionPointParameter;
99

    
100
    private EditingServiceParameter actionParameter;
101

    
102
    private FeatureSelection selection;
103

    
104
    private Point selectedVertex;
105
    private int selectedIndex;
106

    
107
    private Point pointToMove;
108

    
109
    private String action;
110

    
111
    private FeatureStore featureStore;
112

    
113
    private MapContext mapContext;
114

    
115
    /**
116
     * Default constructor.
117
     * @param services
118
     *            available services for this provider
119
     * @param parameters
120
     *            of this provider
121
     */
122
    public EditVertexEditingProvider(ProviderServices services,
123
        DynObject parameters) {
124
        super(services);
125

    
126
        selectedIndex = -1;
127

    
128
        this.featureStore =
129
            (FeatureStore) parameters
130
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
131

    
132
        this.mapContext =
133
            (MapContext) parameters
134
                .getDynValue(EditingProviderFactory.MAPCONTEXT_FIELD);
135

    
136
        this.selectionParameter =
137
            new DefaultEditingServiceParameter("selection", "uniqueselection",
138
                TYPE.SELECTION);
139

    
140
        this.vertexSelectionPointParameter =
141
            new DefaultEditingServiceParameter("selectvertex", "selectvertex",
142
                TYPE.POSITION,
143
                TYPE.VALUE);
144

    
145
        LinkedHashMap<String, String> options = new LinkedHashMap<String, String>();
146
        options.put("+", "insert_vertex");
147
        options.put("-", "remove_vertex");
148
        GeometryType geomType = null;
149
        try {
150
            geomType = featureStore.getDefaultFeatureType().getDefaultGeometryAttribute().getGeomType();
151
        } catch (DataException e) {
152
            String message =
153
                String.format("Error getting feature type of %1",
154
                    featureStore);
155
            logger.info(message, e);
156
        }
157
        if(geomType != null && (geomType.isSubTypeOf(Geometry.SUBTYPES.GEOM3D) || geomType.isSubTypeOf(Geometry.SUBTYPES.GEOM3DM))){
158
            this.actionParameter =
159
                new DefaultEditingServiceParameter(
160
                    "new_position_or_z_value",
161
                    ((EditingProviderServices) getProviderServices()).makeConsoleMessage("new_position_or_z_value", options),
162
                    options,
163
                    TYPE.POSITION,
164
                    TYPE.OPTION,
165
                    TYPE.VALUE);
166
        } else {
167
            this.actionParameter =
168
                new DefaultEditingServiceParameter("new_position",
169
                    ((EditingProviderServices) getProviderServices()).makeConsoleMessage("new_position", options),
170
                    options, TYPE.POSITION, TYPE.OPTION);
171
        }
172
    }
173

    
174
    public EditingServiceParameter next() {
175
        if (selection == null) {
176
            return selectionParameter;
177
        } else if (selectedVertex == null) {
178
            return vertexSelectionPointParameter;
179
        } else if (action == null && pointToMove == null) {
180
            return actionParameter;
181
        }
182
        return null;
183
    }
184

    
185
    public DrawingStatus getDrawingStatus(Point mousePosition)
186
        throws DrawServiceException {
187
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
188
        EditingProviderManager editingProviderManager =
189
            EditingProviderLocator.getProviderManager();
190
        ISymbol selectedVertexSymbolEditing =
191
            editingProviderManager.getSymbol("selected-vertex-symbol-editing");
192
        ISymbol editedVertexSymbolEditing =
193
            editingProviderManager.getSymbol("edited-vertex-symbol-editing");
194
        Color colorToTextSymbol = Color.BLACK;
195
        if (selectedVertexSymbolEditing != null) {
196
            colorToTextSymbol = selectedVertexSymbolEditing
197
                .getColor();
198
        }
199

    
200
        double translationForTextSymbol =
201
            mapContext.getViewPort().toMapDistance(5);
202
        double tolerance =
203
            mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS);
204
        try {
205
            if (this.selection == null) {
206
                Geometry geometry = null;
207
                geometry = getNearestGeometry(mousePosition);
208
                if (geometry != null) {
209
                    List<Point> vertexesList = getVertexesList(geometry);
210
                    if (vertexesList != null) {
211
                        int i = 0;
212
                        for (Iterator<Point> iterator = vertexesList.iterator(); iterator
213
                            .hasNext();) {
214
                            Point point = (Point) iterator.next();
215
                            drawingStatus.addStatus(point,
216
                                selectedVertexSymbolEditing, "");
217
                            Point pointToText = (Point) point.cloneGeometry();
218
                            pointToText.transform(new AffineTransform(1, 0, 0,
219
                                1, translationForTextSymbol, 0));
220
                            drawingStatus.addStatus(pointToText,
221
                                getTextSymbol(colorToTextSymbol), String.valueOf(i++));
222
                        }
223
                    }
224
                }
225
            } else {
226
                Geometry selectedGeometry = getSelectedGeometry();
227
                if (selectedVertex == null) {
228
                    List<Point> vertexesList =
229
                        getVertexesList(selectedGeometry);
230
                    Point vertex =
231
                        getVertex(selectedGeometry, mousePosition, tolerance);
232
                    if (vertexesList != null) {
233
                        int i = 0;
234
                        int selectedIndex = -1;
235
                        for (Iterator<Point> iterator = vertexesList.iterator(); iterator
236
                            .hasNext();) {
237
                            Point point = (Point) iterator.next();
238
                            Point pointToText = (Point) point.cloneGeometry();
239
                            pointToText.transform(new AffineTransform(1, 0, 0,
240
                                1, translationForTextSymbol, 0));
241
                            if (vertex != null && vertex.equals(point)) {
242
                                if(selectedIndex<0){
243
                                    selectedIndex = i++;
244
                                } else {
245
                                    i++;
246
                                }
247
                            } else {
248
                                drawingStatus.addStatus(point,
249
                                    selectedVertexSymbolEditing, "");
250
                                drawingStatus
251
                                .addStatus(
252
                                    pointToText,
253
                                    getTextSymbol(colorToTextSymbol),
254
                                    String.valueOf(i++));
255
                            }
256
                        }
257
                        if (selectedIndex >= 0) {
258
                            Point pointToText = (Point) vertex.cloneGeometry();
259
                            pointToText.transform(new AffineTransform(1, 0, 0,
260
                                1, translationForTextSymbol, 0));
261
                            drawingStatus.addStatus(vertex,
262
                                editedVertexSymbolEditing, "");
263
                            drawingStatus
264
                                .addStatus(pointToText,
265
                                    getTextSymbol(colorToTextSymbol),
266
                                    createInfoPointMessage(pointToText, selectedIndex)
267
                                    );
268

    
269
                        }
270
                    }
271
                } else {
272
                    List<Point> vertexesList =
273
                        getVertexesList(selectedGeometry);
274
                    if (vertexesList != null) {
275
                        int i = 0;
276
                        if (selectedIndex < 0) {
277
                            for (Iterator<Point> iterator = vertexesList.iterator(); iterator.hasNext();) {
278
                                Point point = (Point) iterator.next();
279
                                Point pointToText = (Point) point.cloneGeometry();
280
                                pointToText.transform(new AffineTransform(1, 0, 0, 1, translationForTextSymbol, 0));
281
                                if (selectedVertex.equals(point)) {
282
                                    if (selectedIndex < 0) {
283
                                        selectedIndex = i++;
284
                                    } else {
285
                                        i++;
286
                                    }
287
                                } else {
288
                                    drawingStatus.addStatus(point, selectedVertexSymbolEditing, "");
289
                                    drawingStatus.addStatus(pointToText, getTextSymbol(colorToTextSymbol),
290
                                        String.valueOf(i++));
291
                                }
292
                            }
293
                        }
294
                        if (selectedIndex >= 0) {
295
                            Point pointToText =
296
                                (Point) selectedVertex.cloneGeometry();
297
                            pointToText.transform(new AffineTransform(1, 0, 0, 1, translationForTextSymbol, 0));
298
                            drawingStatus.addStatus(selectedVertex,
299
                                editedVertexSymbolEditing, "");
300
                            drawingStatus
301
                            .addStatus(pointToText,
302
                                getTextSymbol(colorToTextSymbol), createInfoPointMessage(pointToText, selectedIndex));
303
                            Point newPosition = (Point) selectedVertex.cloneGeometry();
304
                            newPosition.setX(mousePosition.getX());
305
                            newPosition.setY(mousePosition.getY());
306
                            Geometry modifiedGeometry = this.getModifiedGeometry(selectedGeometry, selectedIndex, newPosition);
307
                            addToDrawingStatus(drawingStatus, modifiedGeometry);
308

    
309
                            drawingStatus.addStatus(mousePosition,
310
                                selectedVertexSymbolEditing, "");
311
                            pointToText =(Point) selectedVertex.cloneGeometry();
312
                            pointToText.setX(mousePosition.getX());
313
                            pointToText.setY(mousePosition.getY());
314
                            pointToText.transform(new AffineTransform(1, 0, 0, 1, translationForTextSymbol, 0));
315
                            drawingStatus.addStatus(pointToText,
316
                                getTextSymbol(colorToTextSymbol), createInfoPointMessage(pointToText, selectedIndex));
317
                        }
318
                    }
319
                }
320
            }
321
        } catch (BaseException e) {
322
            throw new DrawServiceException(e);
323
        }
324
        return drawingStatus;
325
    }
326

    
327
    private String createInfoPointMessage(Point point, int index) throws GeometryOperationNotSupportedException, GeometryOperationException{
328
        StringBuilder builder = new StringBuilder();
329
        builder.append(index);
330
        builder.append(" ");
331
        builder.append(point.convertToWKT().replaceAll("POINT ", "").replaceAll(" ", " , "));
332
        return builder.toString();
333
    }
334

    
335
    private void addToDrawingStatus(DefaultDrawingStatus drawingStatus,
336
        Geometry geometry) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
337

    
338
        if (geometry instanceof MultiPrimitive) {
339
            MultiPrimitive aggregate = (MultiPrimitive) geometry;
340
            for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
341
                Primitive primitive = aggregate.getPrimitiveAt(i);
342

    
343
                EditVertexOperation operation =
344
                    EditVertexOperationUtils.getOperation(primitive);
345
                if (operation != null) {
346
                    operation.addToDrawingStatus(drawingStatus, primitive);
347
                }
348
            }
349
        } else if (geometry instanceof Primitive) {
350
            Primitive primitive = (Primitive) geometry;
351
            EditVertexOperation operation =
352
                EditVertexOperationUtils.getOperation(primitive);
353
            if (operation != null) {
354
                operation.addToDrawingStatus(drawingStatus, primitive);
355
            }
356
        }
357
        return;
358
    }
359

    
360
    private Geometry getModifiedGeometry(Geometry geometry, int index,
361
        Point newPosition) throws CreateGeometryException,
362
        GeometryOperationNotSupportedException, GeometryOperationException {
363

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

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

    
445
    private Geometry getRemovedVertexGeometry(Geometry geometry, int index)
446
        throws CreateGeometryException {
447
        if (geometry instanceof MultiPrimitive) {
448
            GeometryManager geometryManager =
449
                GeometryLocator.getGeometryManager();
450
            MultiPrimitive aggregate = (MultiPrimitive) geometry;
451
            GeometryType geometryType = aggregate.getGeometryType();
452
            MultiPrimitive newAggregate =
453
                (MultiPrimitive) geometryManager.create(geometryType.getType(),
454
                    geometryType.getSubType());
455
            for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
456
                Primitive primitive = aggregate.getPrimitiveAt(i);
457
                EditVertexOperation operation =
458
                    EditVertexOperationUtils.getOperation(primitive);
459
                if (operation != null) {
460
                    int numVertexes = operation.getNumVertex(primitive);
461
                    if (index > -1 && index < numVertexes) {
462
                        Geometry modifiedPrimitive =
463
                            operation.removeVertex(primitive, index);
464
                        newAggregate
465
                            .addPrimitive((Primitive) modifiedPrimitive);
466
                        index = -1;
467
                    } else {
468
                        index -= numVertexes;
469
                        newAggregate.addPrimitive((Primitive) primitive
470
                            .cloneGeometry());
471
                    }
472
                }
473
            }
474
            return newAggregate;
475
        } else if (geometry instanceof Primitive) {
476
            Primitive primitive = (Primitive) geometry;
477
            EditVertexOperation operation =
478
                EditVertexOperationUtils.getOperation(primitive);
479
            if (operation != null) {
480
                return operation.removeVertex(primitive, index);
481
            }
482
        }
483
        return null;
484
    }
485

    
486
    private ISimpleTextSymbol getTextSymbol(Color color){
487
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
488
        ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol();
489
        textSymbol.setFontSize(12);
490
        textSymbol.setColor(color);
491
        return textSymbol;
492
    }
493

    
494
    public void stop() throws StopServiceException {
495
        this.selection = null;
496
        this.selectedVertex = null;
497
        this.pointToMove = null;
498
        this.action = null;
499
    }
500

    
501
    public List<EditingServiceParameter> getParameters() {
502
        List<EditingServiceParameter> parameters =
503
            new ArrayList<EditingServiceParameter>();
504
        parameters.add(selectionParameter);
505
        parameters.add(vertexSelectionPointParameter);
506
        parameters.add(actionParameter);
507
        return parameters;
508
    }
509

    
510
    public void setValue(Object value) throws InvalidEntryException {
511
        EditingServiceParameter parameter = next();
512
        validateAndInsertValue(parameter, value);
513
    }
514

    
515
    private void validateAndInsertValue(
516
        final EditingServiceParameter parameter, Object value)
517
        throws InvalidEntryException {
518

    
519
        if (parameter == selectionParameter) {
520
            if (value instanceof FeatureSelection) {
521
                FeatureSelection featureSelection = (FeatureSelection) value;
522
                if (featureSelection.getSelectedCount() == 1) {
523
                    this.selection = featureSelection;
524
                } else {
525
                    throw new InvalidEntryException(null);
526
                }
527
            }
528
        } else {
529
            Geometry selectedGeometry;
530
            try {
531
                selectedGeometry = getSelectedGeometry();
532
            } catch (DataException e1) {
533
                throw new InvalidEntryException(e1);
534
            }
535
            if (parameter == vertexSelectionPointParameter) {
536
                if (value instanceof Point) {
537
                    Point point = (Point) value;
538
                    double tolerance = mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS);
539
                    try {
540
                        this.selectedVertex = getVertex(selectedGeometry, point, tolerance);
541
                        selectedIndex = getSelectedIndex(getVertexesList(selectedGeometry));
542
                    } catch (BaseException e) {
543
                        throw new InvalidEntryException(e);
544
                    }
545
                    return;
546
                } else if (value instanceof Double) {
547
                    Double index = (Double) value;
548
                    if (index != Math.round(index)) {
549
                        throw new InvalidEntryException(null);
550
                    } else {
551
                        List<Point> vertexesList;
552
                        try {
553
                            vertexesList = getVertexesList(selectedGeometry);
554
                        } catch (BaseException e) {
555
                            throw new InvalidEntryException(e);
556
                        }
557
                        if(index >= vertexesList.size()){
558
                            throw new InvalidEntryException(null);
559
                        }
560
                        this.selectedIndex = index.intValue();
561
                        this.selectedVertex = vertexesList.get(this.selectedIndex);
562
                    }
563
                }
564

    
565
            } else if (parameter == actionParameter) {
566
                if (value instanceof Point) {
567
                    this.pointToMove = (Point) value;
568
                } else if (value instanceof String) {
569

    
570
                    List<Point> vertexesList;
571
                    try {
572
                        vertexesList = getVertexesList(selectedGeometry);
573
                    } catch (BaseException e) {
574
                        throw new InvalidEntryException(e);
575
                    }
576
                    EditVertexOperation operation = null;
577
                    if (vertexesList != null) {
578
                        Primitive primitive = null;
579
                        if (selectedIndex < 0) {
580
                            if (selectedGeometry instanceof MultiPrimitive) {
581
                                MultiPrimitive aggregate = (MultiPrimitive) selectedGeometry;
582
                                boolean found = false;
583
                                for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
584
                                    // selectedIndex = -1;
585
                                    primitive = aggregate.getPrimitiveAt(i);
586
                                    operation = EditVertexOperationUtils.getOperation(primitive);
587
                                    if (operation != null) {
588
                                        int numVertexes = operation.getNumVertex(primitive);
589
                                        if (primitive instanceof OrientablePrimitive) {
590
                                            OrientablePrimitive orientable = (OrientablePrimitive) primitive;
591
                                            for (int j = 0; j < numVertexes; j++) {
592
                                                if (selectedVertex.equals(orientable.getVertex(j))) {
593
                                                    selectedIndex = j;
594
                                                    found = true;
595
                                                    break;
596
                                                }
597
                                            }
598
                                        }
599
                                    }
600
                                    if (found) {
601
                                        break;
602
                                    }
603
                                }
604
                            }
605
                        } else if (selectedGeometry instanceof Primitive) {
606
                            primitive = (Primitive) selectedGeometry;
607
                            if (selectedIndex < 0) {
608

    
609
                                operation = EditVertexOperationUtils.getOperation(primitive);
610
                                if (operation != null) {
611
                                    int numVertexes = operation.getNumVertex(primitive);
612
                                    if (primitive instanceof OrientablePrimitive) {
613
                                        OrientablePrimitive orientable = (OrientablePrimitive) primitive;
614
                                        for (int j = 0; j < numVertexes; j++) {
615
                                            if (selectedVertex.equals(orientable.getVertex(j))) {
616
                                                selectedIndex = j;
617
                                                break;
618
                                            }
619
                                        }
620
                                    }
621
                                }
622
                            }
623
                        }
624

    
625
                        String str = (String) value;
626
                        if (str.equalsIgnoreCase("+") || str.equalsIgnoreCase("-")) {
627
                            if (operation != null) {
628
                                if (str.equalsIgnoreCase("+")) {
629
                                    if (selectedIndex < 0 || !operation.canInsertVertex(primitive, selectedIndex)) {
630
                                        throw new InvalidEntryException(null);
631
                                    }
632
                                } else if (str.equalsIgnoreCase("-")) {
633
                                    if (selectedIndex < 0 || !operation.canRemoveVertex(primitive, selectedIndex)) {
634
                                        throw new InvalidEntryException(null);
635
                                    }
636
                                }
637
                            }
638
                            this.action = str;
639
                        } else {
640
                            if (str.equalsIgnoreCase("z")) {
641

    
642
                            } else {
643
                                throw new InvalidEntryException(null);
644
                            }
645
                        }
646
                    }
647
                } else if (value instanceof Double) {
648
                    this.pointToMove = (Point) selectedVertex.cloneGeometry();
649
                    this.pointToMove.setCoordinateAt(2, (Double) value);
650
                }
651
            }
652
        }
653
    }
654

    
655
    private Point getVertex(Geometry geometry, Point point, double tolerance)
656
        throws GeometryOperationNotSupportedException,
657
        GeometryOperationException, CreateGeometryException {
658
        List<Point> vertexesList = getVertexesList(geometry);
659
        double min = Double.POSITIVE_INFINITY;
660
        Point vertex = null;
661
        if (vertexesList != null) {
662
            for (Iterator<Point> iterator = vertexesList.iterator(); iterator
663
                .hasNext();) {
664
                Point point2 = (Point) iterator.next();
665
                double distance = getDistance(point, point2);
666
                if (distance <= tolerance) {
667
                    if (distance < min) {
668
                        vertex = point2;
669
                        min = distance;
670
                    }
671
                }
672
            }
673
        }
674
        return vertex;
675
    }
676

    
677
    private double getDistance(Point p1, Point p2) throws GeometryOperationNotSupportedException, GeometryOperationException, CreateGeometryException{
678
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
679
        if(p1.getDimension()==p2.getDimension()){
680
            return p1.distance(p2);
681
        } else {
682
            Point auxP1 = geomManager.createPoint(p1.getX(), p1.getY(), Geometry.SUBTYPES.GEOM2D);
683
            Point auxP2 = geomManager.createPoint(p2.getX(), p2.getY(), Geometry.SUBTYPES.GEOM2D);
684
            return auxP1.distance(auxP2);
685
        }
686
    }
687

    
688
    private List<Point> getVertexesList(Geometry geometry) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
689
        if (geometry instanceof MultiPrimitive) {
690
            MultiPrimitive aggregate = (MultiPrimitive) geometry;
691
            List<Point> vertexesList = new ArrayList<Point>();
692
            for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
693
                Primitive primitive = aggregate.getPrimitiveAt(i);
694
                EditVertexOperation operation =
695
                    EditVertexOperationUtils.getOperation(primitive);
696
                if (operation != null) {
697
                    vertexesList.addAll(operation.getVertexesList(primitive));
698
                }
699
            }
700
            return vertexesList;
701
        } else if (geometry instanceof Primitive) {
702
            Primitive primitive = (Primitive) geometry;
703
            EditVertexOperation operation =
704
                EditVertexOperationUtils.getOperation(primitive);
705
            if (operation != null) {
706
                List<Point> vertexesList = operation.getVertexesList(primitive);
707
                return vertexesList;
708
            }
709
        }
710
        return null;
711
    }
712

    
713

    
714

    
715
    private FeatureSet getGeometryByBuffer(Geometry buffer)
716
        throws DataException {
717
        FeatureQuery queryByGeometry = featureStore.createFeatureQuery();
718

    
719
        // Get default SRS of default feature type
720
        IProjection defaultSRS =
721
            this.featureStore.getDefaultFeatureType().getDefaultSRS();
722

    
723
        // Name of default geometry type
724
        String geomName =
725
            featureStore.getDefaultFeatureType()
726
                .getDefaultGeometryAttributeName();
727

    
728
        IntersectsGeometryEvaluator iee =
729
            new IntersectsGeometryEvaluator(buffer, defaultSRS,
730
                featureStore.getDefaultFeatureType(), geomName);
731

    
732
        queryByGeometry.setFilter(iee);
733
        queryByGeometry.setAttributeNames(null);
734
        return this.featureStore.getFeatureSet(queryByGeometry);
735
    }
736

    
737
    private Geometry getNearestGeometry(final Point point) throws GeometryOperationNotSupportedException, GeometryOperationException, DataException{
738
        double tolerance =
739
            mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS);
740
        Geometry buffer = point.buffer(tolerance);
741
        FeatureSet featureSet = getGeometryByBuffer(buffer);
742
        double min = Double.POSITIVE_INFINITY;
743
        Geometry geometry = null;
744

    
745
        DisposableIterator iterator = featureSet.fastIterator();
746
        while (iterator.hasNext()) {
747
            Feature feat = (Feature) iterator.next();
748
            double distance = point.distance(feat.getDefaultGeometry());
749
            if (distance < min){
750
                geometry = feat.getDefaultGeometry();
751
                min = distance;
752
            }
753
        }
754
        iterator.dispose();
755
        return geometry;
756
    }
757

    
758
    private Geometry getSelectedGeometry() throws DataException {
759

    
760
        Geometry selectedGeometry = null;
761
            if (this.selection != null && this.selection.getSelectedCount() == 1) {
762
                DisposableIterator it = this.selection.fastIterator();
763
                while (it.hasNext()) {
764
                    Feature feature = (Feature) it.next();
765
                    selectedGeometry = feature.getDefaultGeometry();
766
                }
767
                it.dispose();
768
            }
769
        return selectedGeometry;
770
    }
771

    
772

    
773
    public Geometry finish() throws FinishServiceException {
774
        return null;
775
    }
776

    
777
    public void finishAndStore() throws FinishServiceException {
778
        if (this.selection != null) {
779
            try {
780
                Geometry selectedGeometry = getSelectedGeometry();
781
                List<Point> vertexesList;
782
                vertexesList = getVertexesList(selectedGeometry);
783
                if(vertexesList != null){
784
                    if(selectedIndex<0){
785
                        selectedIndex = getSelectedIndex(vertexesList);
786
                    }
787
                    Geometry modifiedGeometry = null;
788
                    if (pointToMove != null) {
789
                        if (selectedIndex >= 0) {
790
                            modifiedGeometry =
791
                                this.getModifiedGeometry(selectedGeometry,
792
                                    selectedIndex, pointToMove);
793
                        }
794
                    } else if (action != null){
795
                        if(action.equalsIgnoreCase("+")){
796
                            modifiedGeometry =
797
                                this.getInsertVertexGeometry(selectedGeometry, selectedIndex);
798

    
799
                        } else if(action.equalsIgnoreCase("-")){
800
                            modifiedGeometry = this.getRemovedVertexGeometry(selectedGeometry, selectedIndex);
801

    
802
                        }
803
                    }
804
                    DisposableIterator it = null;
805

    
806
                    try {
807
                        it = selection.fastIterator();
808

    
809
                        while (it.hasNext()) {
810
                            Feature feature = (Feature) it.next();
811
                            EditableFeature editableFeature =
812
                                feature.getEditable();
813
                            editableFeature.setDefaultGeometry(modifiedGeometry);
814
                            ((EditingProviderServices) getProviderServices())
815
                                .updateFeatureInFeatureStore(
816
                                    editableFeature, featureStore);
817
                        }
818
                    } catch (BaseException e) {
819
                        throw new FinishServiceException(e);
820
                    } finally {
821
                        it.dispose();
822
                    }
823

    
824
                }
825
            } catch (BaseException e) {
826
                throw new FinishServiceException(e);
827
            }
828
        }
829

    
830
    }
831

    
832
    private int getSelectedIndex(List<Point> vertexesList) {
833
        int selectedIndex = -1;
834
        if (vertexesList != null) {
835
            int i = 0;
836
            if (selectedVertex != null) {
837
                for (Iterator<Point> iterator = vertexesList.iterator(); iterator.hasNext();) {
838
                    Point point = (Point) iterator.next();
839
                    if (selectedVertex.equals(point)) {
840
                        selectedIndex = i;
841
                        break;
842
                    }
843
                    i++;
844
                }
845
            }
846
        }
847
        return selectedIndex;
848
    }
849

    
850
    public void start() throws StartServiceException, InvalidEntryException {
851
        FeatureSelection selected = null;
852
        if (featureStore != null) {
853
            try {
854
                selected = featureStore.getFeatureSelection();
855
                long selectedCount = selected.getSelectedCount();
856
                if(selectedCount==1){
857
                    this.selection = selected;
858
                } else {
859
                    selected.deselectAll();
860
                }
861
            } catch (DataException e) {
862
                throw new StartServiceException(e);
863
            }
864
        }
865
    }
866

    
867
    public String getName() {
868
        return EditVertexEditingProviderFactory.PROVIDER_NAME;
869
    }
870

    
871
}