Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2060 / extensions / extEditing / src / org / gvsig / editing / gui / cad / tools / EditVertexCADTool.java @ 39348

History | View | Annotate | Download (30.3 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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
 */
22
package org.gvsig.editing.gui.cad.tools;
23

    
24
import java.awt.Component;
25
import java.awt.event.InputEvent;
26
import java.awt.geom.PathIterator;
27
import java.awt.geom.Point2D;
28
import java.awt.geom.Rectangle2D;
29

    
30
import javax.swing.JOptionPane;
31

    
32
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34

    
35
import org.gvsig.andami.PluginServices;
36
import org.gvsig.andami.messages.NotificationManager;
37
import org.gvsig.app.ApplicationLocator;
38
import org.gvsig.editing.CADExtension;
39
import org.gvsig.editing.gui.cad.DefaultCADTool;
40
import org.gvsig.editing.gui.cad.exception.CommandException;
41
import org.gvsig.editing.gui.cad.tools.smc.EditVertexCADToolContext;
42
import org.gvsig.editing.gui.cad.tools.smc.EditVertexCADToolContext.EditVertexCADToolState;
43
import org.gvsig.editing.layers.VectorialLayerEdited;
44
import org.gvsig.fmap.dal.exception.DataException;
45
import org.gvsig.fmap.dal.exception.ReadException;
46
import org.gvsig.fmap.dal.feature.EditableFeature;
47
import org.gvsig.fmap.dal.feature.Feature;
48
import org.gvsig.fmap.dal.feature.FeatureSelection;
49
import org.gvsig.fmap.dal.feature.FeatureSet;
50
import org.gvsig.fmap.dal.feature.FeatureStore;
51
import org.gvsig.fmap.dal.feature.exception.CreateGeometryException;
52
import org.gvsig.fmap.geom.Geometry;
53
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
54
import org.gvsig.fmap.geom.handler.Handler;
55
import org.gvsig.fmap.geom.operation.GeometryOperationException;
56
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
57
import org.gvsig.fmap.geom.primitive.GeneralPathX;
58
import org.gvsig.fmap.geom.primitive.Primitive;
59
import org.gvsig.fmap.mapcontext.ViewPort;
60
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
61
import org.gvsig.tools.dispose.DisposableIterator;
62
import org.gvsig.tools.dispose.DisposeUtils;
63

    
64
/**
65
 * DOCUMENT ME!
66
 * 
67
 * @author Vicente Caballero Navarro
68
 */
69
public class EditVertexCADTool extends DefaultCADTool {
70

    
71
    protected EditVertexCADToolContext _fsm;
72
    protected int numSelect = 0;
73
    protected int numHandlers;
74
    protected boolean addVertex = false;
75
    
76
    private static Logger logger =
77
        LoggerFactory.getLogger(EditVertexCADTool.class);
78

    
79
    /**
80
     * M?todo de incio, para poner el c?digo de todo lo que se requiera de una
81
     * carga previa a la utilizaci?n de la herramienta.
82
     */
83
    public void init() {
84
        _fsm = new EditVertexCADToolContext(this);
85
    }
86

    
87
    /*
88
     * (non-Javadoc)
89
     * 
90
     * @see
91
     * com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap
92
     * .layers.FBitSet, double, double)
93
     */
94
    public void transition(double x, double y, InputEvent event) {
95
        _fsm.addPoint(x, y, event);
96
    }
97

    
98
    /*
99
     * (non-Javadoc)
100
     * 
101
     * @see
102
     * com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap
103
     * .layers.FBitSet, double)
104
     */
105
    public void transition(double d) {
106
        _fsm.addValue(d);
107
    }
108

    
109
    /*
110
     * (non-Javadoc)
111
     * 
112
     * @see
113
     * com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap
114
     * .layers.FBitSet, java.lang.String)
115
     */
116
    public void transition(String s) throws CommandException {
117
        if (!super.changeCommand(s)) {
118
            _fsm.addOption(s);
119
        }
120
    }
121

    
122
    /**
123
     * DOCUMENT ME!
124
     */
125
    public void selection() {
126
        FeatureSet selection = null;
127
        try {
128
            selection = (FeatureSet) getVLE().getFeatureStore().getSelection();
129

    
130
            if (selection.getSize() == 0
131
                && !CADExtension
132
                    .getCADTool()
133
                    .getClass()
134
                    .getName()
135
                    .equals("com.iver.cit.gvsig.gui.cad.tools.SelectionCADTool")) {
136
                CADExtension.setCADTool("_selection", false);
137
                ((SelectionCADTool) CADExtension.getCADTool())
138
                    .setNextTool("_editvertex");
139
            }
140
        } catch (ReadException e) {
141
            // TODO Auto-generated catch block
142
            e.printStackTrace();
143
        } catch (DataException e) {
144
            // TODO Auto-generated catch block
145
            e.printStackTrace();
146
        }
147
    }
148

    
149
    /**
150
     * Equivale al transition del prototipo pero sin pasarle como par?metro el
151
     * editableFeatureSource que ya estar? creado.
152
     * 
153
     * @param x
154
     *            par?metro x del punto que se pase en esta transici?n.
155
     * @param y
156
     *            par?metro y del punto que se pase en esta transici?n.
157
     */
158
    public void addPoint(double x, double y, InputEvent event) {
159
        selectHandler(x, y);
160
        addVertex = false;
161
    }
162

    
163
    private Geometry getSelectedGeometry() {
164
        FeatureSet selection = null;
165
        DisposableIterator iterator = null;
166
        try {
167
            selection = (FeatureSet) getVLE().getFeatureStore().getSelection();
168

    
169
            Feature feature = null;
170
            Geometry ig = null;
171
            if (selection.getSize() == 1) {
172
                iterator = selection.iterator();
173
                feature = (Feature) iterator.next();
174
                ig = (feature.getDefaultGeometry()).cloneGeometry();
175
                return ig;
176
            }
177
        } catch (ReadException e) {
178
            // TODO Auto-generated catch block
179
            e.printStackTrace();
180
        } catch (DataException e) {
181
            // TODO Auto-generated catch block
182
            e.printStackTrace();
183
        } finally {
184
            DisposeUtils.dispose(iterator);
185
        }
186

    
187
        return null;
188
    }
189

    
190
    /**
191
     * M?todo para dibujar la lo necesario para el estado en el que nos
192
     * encontremos.
193
     * 
194
     * @param g
195
     *            Graphics sobre el que dibujar.
196
     * @param x
197
     *            par?metro x del punto que se pase para dibujar.
198
     * @param y
199
     *            par?metro x del punto que se pase para dibujar.
200
     */
201
    public void drawOperation(MapControlDrawer renderer, double x, double y) {
202
        drawVertex(renderer, getCadToolAdapter().getMapControl().getViewPort());
203
    }
204

    
205
    /**
206
     * Add a diferent option.
207
     * 
208
     * @param s
209
     *            Diferent option.
210
     */
211
    public void addOption(String s) {
212
        EditVertexCADToolState actualState =
213
            (EditVertexCADToolState) _fsm.getPreviousState();
214
        String status = actualState.getName();
215
        VectorialLayerEdited vle = getVLE();
216
        FeatureStore featureStore = null;
217
        DisposableIterator iterator = null;
218
        try {
219
            featureStore = vle.getFeatureStore();
220

    
221
            FeatureSet selection = (FeatureSet) featureStore.getSelection();
222
            Feature feature = null;
223
            Geometry ig = null;
224
            Handler[] handlers = null;
225
            if (selection.getSize() == 1) {
226
                iterator = selection.iterator();
227
                feature = (Feature) iterator.next();
228
                ig = (feature.getDefaultGeometry()).cloneGeometry();
229
                handlers = ig.getHandlers(Geometry.SELECTHANDLER);
230
                numHandlers = handlers.length;
231
                if (numHandlers == 0) {
232
                    try {
233
                        featureStore.delete(feature);
234
                    } catch (ReadException e) {
235
                        NotificationManager.addError(e.getMessage(), e);
236
                    } catch (DataException e) {
237
                        NotificationManager.addError(e.getMessage(), e);
238
                    }
239
                }
240
            } else {
241
                JOptionPane.showMessageDialog((Component) PluginServices
242
                    .getMainFrame(), PluginServices.getText(this,
243
                    "hay_mas_de_una_geometria_seleccionada"));
244
            }
245

    
246
            int diff = 1;// En el caso de ser pol?gono.
247
            /*
248
            if (ig instanceof MultiPrimitive) {
249
                diff = 2;
250
            }
251
            */
252

    
253
            if (status.equals("EditVertex.SelectVertexOrDelete")) {
254
                if (s.equalsIgnoreCase(PluginServices.getText(this,
255
                    "EditVertexCADTool.nextvertex"))
256
                    || s.equals(PluginServices.getText(this, "next"))) {
257
                    
258
                    numSelect = numSelect + diff;
259
                    if (numSelect > (numHandlers - 1)) {
260
                        numSelect = numSelect - (numHandlers);
261
                    }
262
                    
263
                } else
264
                    if (s.equalsIgnoreCase(PluginServices.getText(this,
265
                        "EditVertexCADTool.previousvertex"))
266
                        || s.equals(PluginServices.getText(this, "previous"))) {
267

    
268
                        numSelect = numSelect - diff;
269
                        if (numSelect < 0) {
270
                            numSelect = numHandlers - 1 + (numSelect + 1);
271
                        }
272

    
273
                    } else
274
                        if (s.equalsIgnoreCase(PluginServices.getText(this,
275
                            "EditVertexCADTool.delvertex"))
276
                            || s.equals(PluginServices.getText(this, "del"))) {
277
                            if (handlers != null) {
278
                                Geometry newGeometry = null;
279
                                if (ig instanceof MultiPrimitive) {
280
                                    newGeometry =
281
                                        removeVertexGC((MultiPrimitive) ig,
282
                                            handlers[numSelect]);
283
                                } else {
284
                                    newGeometry =
285
                                        removeVertex(ig, handlers[numSelect]);
286
                                }
287
                                try {
288
                                    EditableFeature eFeature =
289
                                        feature.getEditable();
290
                                    eFeature.setGeometry(featureStore
291
                                        .getDefaultFeatureType()
292
                                        .getDefaultGeometryAttributeName(),
293
                                        newGeometry);
294
                                    featureStore.update(eFeature);
295

    
296
                                } catch (ReadException e) {
297
                                    NotificationManager.addError(
298
                                        e.getMessage(), e);
299
                                } catch (DataException e) {
300
                                    // TODO Auto-generated catch block
301
                                    e.printStackTrace();
302
                                }
303
                            }
304
                        } else
305
                            if (s.equalsIgnoreCase(PluginServices.getText(this,
306
                                "EditVertexCADTool.addvertex"))
307
                                || s.equals(PluginServices.getText(this, "add"))) {
308
                                addVertex = true;
309
                            }
310
            }
311
        } catch (Exception e1) {
312
            
313
            ApplicationLocator.getManager().message(
314
                e1.getMessage(), JOptionPane.ERROR_MESSAGE);
315
            logger.info("Error in add option.", e1);
316
        } finally {
317
            if (iterator != null) {
318
                iterator.dispose();
319
            }
320
        }
321
    }
322

    
323
    private void drawVertex(MapControlDrawer renderer, ViewPort vp) {
324
        VectorialLayerEdited vle = getVLE();
325
        DisposableIterator iterator = null;
326
        try {
327
            iterator =
328
                ((FeatureSelection) vle.getFeatureStore().getSelection())
329
                    .iterator();
330
            while (iterator.hasNext()) {
331
                Feature feature = (Feature) iterator.next();
332

    
333
                Geometry ig = (feature.getDefaultGeometry()).cloneGeometry();
334
                // renderer.draw(ig,
335
                // mapControlManager.getGeometrySelectionSymbol());
336

    
337
                Handler[] handlers = ig.getHandlers(Geometry.SELECTHANDLER);
338
                if (numSelect >= handlers.length) {
339
                    numSelect = 0;
340
                }
341
                if (handlers.length == 0)
342
                    continue;
343
                renderer.drawHandler(handlers[numSelect],
344
                    vp.getAffineTransform());
345
            }
346
        } catch (DataException e) {
347
            // TODO Auto-generated catch block
348
            e.printStackTrace();
349
        } finally {
350
            if (iterator != null) {
351
                iterator.dispose();
352
            }
353
        }
354
    }
355

    
356
    /*
357
     * (non-Javadoc)
358
     * 
359
     * @see com.iver.cit.gvsig.gui.cad.CADTool#addvalue(double)
360
     */
361
    public void addValue(double d) {
362
    }
363

    
364
    private Geometry removeVertex(Geometry gp, Handler hand) {
365
        GeneralPathX newGp = new GeneralPathX();
366
        double[] theData = new double[6];
367

    
368
        PathIterator theIterator;
369
        int theType;
370
        int numParts = 0;
371

    
372
        Point2D ptSrc = new Point2D.Double();
373
        boolean bFirst = false;
374

    
375
        theIterator = gp.getPathIterator(null, geomManager.getFlatness());
376
        int numSegmentsAdded = 0;
377
        while (!theIterator.isDone()) {
378
            theType = theIterator.currentSegment(theData);
379
            if (bFirst) {
380
                newGp.moveTo(theData[0], theData[1]);
381
                numSegmentsAdded++;
382
                bFirst = false;
383
                theIterator.next();
384
                continue;
385
            }
386
            switch (theType) {
387

    
388
            case PathIterator.SEG_MOVETO:
389
                numParts++;
390
                ptSrc.setLocation(theData[0], theData[1]);
391
                if (ptSrc.equals(hand.getPoint())) {
392
                    numParts--;
393
                    bFirst = true;
394
                    break;
395
                }
396
                newGp.moveTo(ptSrc.getX(), ptSrc.getY());
397
                numSegmentsAdded++;
398
                bFirst = false;
399
                break;
400

    
401
            case PathIterator.SEG_LINETO:
402
                ptSrc.setLocation(theData[0], theData[1]);
403
                if (ptSrc.equals(hand.getPoint())) {
404
                    break;
405
                }
406
                newGp.lineTo(ptSrc.getX(), ptSrc.getY());
407
                bFirst = false;
408
                numSegmentsAdded++;
409
                break;
410

    
411
            case PathIterator.SEG_QUADTO:
412
                newGp.quadTo(theData[0], theData[1], theData[2], theData[3]);
413
                numSegmentsAdded++;
414
                break;
415

    
416
            case PathIterator.SEG_CUBICTO:
417
                newGp.curveTo(theData[0], theData[1], theData[2], theData[3],
418
                    theData[4], theData[5]);
419
                numSegmentsAdded++;
420
                break;
421

    
422
            case PathIterator.SEG_CLOSE:
423
                if (numSegmentsAdded < 3) {
424
                    newGp.lineTo(theData[0], theData[1]);
425
                }
426
                newGp.closePath();
427

    
428
                break;
429
            } // end switch
430

    
431
            theIterator.next();
432
        } // end while loop
433
        Geometry shp = null;
434
        switch (gp.getType()) {
435
        case Geometry.TYPES.POINT: // Tipo punto
436
            shp = createPoint(ptSrc.getX(), ptSrc.getY());
437
            break;
438

    
439
        case Geometry.TYPES.CURVE:
440
            shp = createCurve(newGp);
441
            break;
442
        case Geometry.TYPES.SURFACE:
443
            shp = createSurface(newGp);
444
            break;
445
        }
446
        Geometry ig = shp;
447
        int dif = 1;// En el caso de ser pol?gono.
448
        numSelect = numSelect - dif;
449
        if (numSelect < 0) {
450
            numSelect = numHandlers - 1 + (numSelect + 1);
451
        }
452
        return ig;
453
    }
454

    
455
    private Geometry removeVertexGC(MultiPrimitive gc, Handler handler)
456
        throws GeometryOperationNotSupportedException,
457
        GeometryOperationException, CreateGeometryException {
458

    
459
        Primitive prim = null;
460
        int np = gc.getPrimitivesNumber();
461
        
462
        for (int i = 0; i < np; i++) {
463
            prim = gc.getPrimitiveAt(i);
464
            Handler[] hh = prim.getHandlers(Geometry.SELECTHANDLER);
465
            int nh = hh.length;
466
            for (int j=0; j<nh; j++) {
467
                if (hh[j].equalsPoint(handler)) {
468
                    /*
469
                     * Find the first primitive which has a handler
470
                     * matching received handler
471
                     */
472
                    Geometry resp = this.removeVertex(prim, handler);
473
                    for (int k=0; k<np; k++) {
474
                        if (k != i) {
475
                            resp = resp.union(gc.getPrimitiveAt(k));
476
                        }
477
                    }
478
                    return resp;
479
                }
480
            }
481
        }
482
        throw new CreateGeometryException(
483
            new Exception("Unable to remove vertex"));
484
        /*
485
            Geometry[] geoms = new Geometry[gc.getPrimitivesNumber()];
486
            for( int i=0; i<gc.getPrimitivesNumber(); i++) {
487
                    geoms[i] = gc.getPrimitiveAt(i);
488
            }
489
            
490
        ArrayList geomsAux = new ArrayList();
491
        int pos = -1;
492
        for (int i = 0; i < geoms.length; i++) {
493
            Handler[] handlers = geoms[i].getHandlers(Geometry.SELECTHANDLER);
494
            for (int j = 0; j < handlers.length; j++) {
495
                if (handlers[j].equalsPoint(handler)) {
496
                    geomsAux.add(geoms[i]);
497
                    if (pos == -1) {
498
                        pos = i;
499
                    }
500
                }
501
            }
502
        }
503
        int numGeomsAux = geomsAux.size();
504
        GeneralPathX gpx = new GeneralPathX();
505
        for (int i = 0; i < numGeomsAux; i++) {
506
            Handler[] handlers =
507
                ((Geometry) geomsAux.get(i))
508
                    .getHandlers(Geometry.SELECTHANDLER);
509
            if (numGeomsAux == 2) {
510
                for (int j = 0; j < handlers.length; j++) {
511
                    if (handlers[j].equalsPoint(handler)) {
512
                        if (j == (handlers.length - 1)) {
513
                            Point2D ph = handlers[0].getPoint();
514
                            gpx.moveTo(ph.getX(), ph.getY());
515
                        } else {
516
                            Point2D ph =
517
                                handlers[handlers.length - 1].getPoint();
518
                            gpx.lineTo(ph.getX(), ph.getY());
519
                        }
520
                    }
521
                }
522
            }
523

524
        }
525
        ArrayList newGeoms = new ArrayList();
526
        for (int i = 0; i < pos; i++) {
527
            newGeoms.add(geoms[i]);
528
        }
529
        newGeoms.add(createCurve(gpx));
530
        for (int i = pos + numGeomsAux; i < geoms.length; i++) {
531
            newGeoms.add(geoms[i]);
532
        }
533

534
        return createMultiPrimitive((Geometry[]) newGeoms
535
            .toArray(new Geometry[0]));
536
            */
537
    }
538

    
539
    private Geometry addVertex(Geometry geome, Point2D p, Rectangle2D rect) {
540
        Geometry geometryCloned = geome.cloneGeometry();
541
        Geometry geom1 = null;
542
        GeneralPathX gpxAux;
543
        boolean finish = false;
544
        // FGeometry geom2=null;
545

    
546
        // if (geometryCloned.getGeometryType() == FShape.POLYGON){
547
        // ///////////////
548

    
549
        GeneralPathX newGp = new GeneralPathX();
550
        double[] theData = new double[6];
551

    
552
        PathIterator theIterator;
553
        int theType;
554
        int numParts = 0;
555
        Point2D pLast = new Point2D.Double();
556
        Point2D pAnt = new Point2D.Double();
557
        Point2D firstPoint = null;
558
        theIterator = geome.getPathIterator(null, geomManager.getFlatness()); // ,
559
                                                                              // flatness);
560
        int numSegmentsAdded = 0;
561
        while (!theIterator.isDone()) {
562
            theType = theIterator.currentSegment(theData);
563
            switch (theType) {
564
            case PathIterator.SEG_MOVETO:
565
                pLast.setLocation(theData[0], theData[1]);
566
                if (numParts == 0) {
567
                    firstPoint = (Point2D) pLast.clone();
568
                }
569
                numParts++;
570

    
571
                gpxAux = new GeneralPathX();
572
                gpxAux.moveTo(pAnt.getX(), pAnt.getY());
573
                gpxAux.lineTo(pLast.getX(), pLast.getY());
574
                geom1 = createCurve(gpxAux);
575
                if (geom1.intersects(rect)) {
576
                    finish = true;
577
                    newGp.moveTo(pLast.getX(), pLast.getY());
578
                    // newGp.lineTo(pLast.getX(),pLast.getY());
579
                } else {
580
                    newGp.moveTo(pLast.getX(), pLast.getY());
581
                }
582
                pAnt.setLocation(pLast.getX(), pLast.getY());
583
                numSegmentsAdded++;
584
                break;
585

    
586
            case PathIterator.SEG_LINETO:
587
                pLast.setLocation(theData[0], theData[1]);
588
                gpxAux = new GeneralPathX();
589
                gpxAux.moveTo(pAnt.getX(), pAnt.getY());
590
                gpxAux.lineTo(pLast.getX(), pLast.getY());
591
                geom1 = createCurve(gpxAux);
592
                if (geom1.intersects(rect)) {
593
                    newGp.lineTo(p.getX(), p.getY());
594
                    newGp.lineTo(pLast.getX(), pLast.getY());
595
                } else {
596
                    newGp.lineTo(pLast.getX(), pLast.getY());
597
                }
598
                pAnt.setLocation(pLast.getX(), pLast.getY());
599
                numSegmentsAdded++;
600
                break;
601

    
602
            case PathIterator.SEG_QUADTO:
603
                newGp.quadTo(theData[0], theData[1], theData[2], theData[3]);
604
                numSegmentsAdded++;
605
                break;
606

    
607
            case PathIterator.SEG_CUBICTO:
608
                newGp.curveTo(theData[0], theData[1], theData[2], theData[3],
609
                    theData[4], theData[5]);
610
                numSegmentsAdded++;
611
                break;
612

    
613
            case PathIterator.SEG_CLOSE:
614
                // if (numSegmentsAdded < 3){
615
                gpxAux = new GeneralPathX();
616
                gpxAux.moveTo(pAnt.getX(), pAnt.getY());
617
                gpxAux.lineTo(firstPoint.getX(), firstPoint.getY());
618
                geom1 = createCurve(gpxAux);
619
                if (geom1.intersects(rect) || finish) {
620
                    newGp.lineTo(p.getX(), p.getY());
621
                    // newGp.lineTo(pLast.getX(), pLast.getY());
622
                } else {
623
                    newGp.lineTo(pLast.getX(), pLast.getY());
624
                }
625
                // }
626
                newGp.closePath();
627
                break;
628
            } // end switch
629

    
630
            theIterator.next();
631
        } // end while loop
632
        Geometry shp = null;
633
        switch (geometryCloned.getType()) {
634
        case POINT: // Tipo punto
635
            shp = createPoint(pLast.getX(), pLast.getY());
636
            break;
637

    
638
        case CURVE:
639
            shp = createCurve(newGp);
640
            break;
641
        case SURFACE:
642
        case CIRCLE:
643
        case ELLIPSE:
644
            shp = createSurface(newGp);
645
            break;
646
        }
647
        return shp;
648
    }
649

    
650
    private Geometry addVertexGC(
651
        MultiPrimitive mpri,
652
        Point2D p,
653
        Rectangle2D rect)
654
            throws GeometryOperationNotSupportedException,
655
            GeometryOperationException, CreateGeometryException
656
            {
657
        
658
        int n = mpri.getPrimitivesNumber();
659
        Primitive item = null;
660
        for (int i=0; i<n; i++) {
661
            item = mpri.getPrimitiveAt(i);
662
            if (item.intersects(rect)) {
663
                /*
664
                 * Only the first primitive that intersects
665
                 * with rect will be treated
666
                 */
667
                Geometry newg = this.addVertex(item, p, rect);
668
                for (int k=0; k<n; k++) {
669
                    if (k != i) {
670
                        newg = newg.union(mpri.getPrimitiveAt(k));
671
                    }
672
                    return newg;
673
                }
674
            }
675
        }
676
        throw new CreateGeometryException(
677
            new Exception("Unable to add vertex"));
678

    
679
        /*
680
            Geometry[] geoms = new Geometry[gc.getPrimitivesNumber()];
681
            for( int i=0; i<gc.getPrimitivesNumber(); i++) {
682
                    geoms[i] = gc.getPrimitiveAt(i);
683
            }
684
          
685
        int pos = -1;
686
        for (int i = 0; i < geoms.length; i++) {
687
            if (geoms[i].intersects(rect)) {
688
                pos = i;
689
            }
690
        }
691
        ArrayList newGeoms = new ArrayList();
692
        for (int i = 0; i < pos; i++) {
693
            newGeoms.add(geoms[i]);
694
        }
695
        if (pos != -1) {
696
            GeneralPathX gpx1 = new GeneralPathX();
697
            GeneralPathX gpx2 = new GeneralPathX();
698
            Handler[] handlers = geoms[pos].getHandlers(Geometry.SELECTHANDLER);
699
            Point2D p1 = handlers[0].getPoint();
700
            Point2D p2 = p;
701
            Point2D p3 = handlers[handlers.length - 1].getPoint();
702
            gpx1.moveTo(p1.getX(), p1.getY());
703
            gpx1.lineTo(p2.getX(), p2.getY());
704
            gpx2.moveTo(p2.getX(), p2.getY());
705
            gpx2.lineTo(p3.getX(), p3.getY());
706
            newGeoms.add(createCurve(gpx1));
707
            newGeoms.add(createCurve(gpx2));
708
            for (int i = pos + 1; i < geoms.length; i++) {
709
                newGeoms.add(geoms[i]);
710
            }
711
            return createMultiPrimitive((Geometry[]) newGeoms
712
                .toArray(new Geometry[0]));
713
        } else {
714
            return null;
715
        }
716
        */
717
    }
718

    
719
    public String getName() {
720
        return PluginServices.getText(this, "edit_vertex_");
721
    }
722

    
723
    private void selectHandler(double x, double y) {
724
        Point2D firstPoint = new Point2D.Double(x, y);
725
        VectorialLayerEdited vle = getVLE();
726
        FeatureStore featureStore = null;
727
        DisposableIterator iterator = null;
728
        DisposableIterator selectedIterator = null;
729

    
730
        try {
731
            featureStore = vle.getFeatureStore();
732

    
733
            iterator =
734
                ((FeatureSelection) featureStore.getSelection()).iterator();
735
            double tam =
736
                getCadToolAdapter().getMapControl().getViewPort()
737
                    .toMapDistance(mapControlManager.getTolerance());
738
            Rectangle2D rect =
739
                new Rectangle2D.Double(firstPoint.getX() - tam,
740
                    firstPoint.getY() - tam, tam * 2, tam * 2);
741
            while (iterator.hasNext()) {
742
                Feature feature = (Feature) iterator.next();
743

    
744
                boolean isSelectedHandler = false;
745
                Geometry geometry = getSelectedGeometry();
746
                if (geometry != null) {
747
                    Handler[] handlers =
748
                        geometry.getHandlers(Geometry.SELECTHANDLER);
749
                    for (int h = 0; h < handlers.length; h++) {
750
                        if (handlers[h].getPoint().distance(firstPoint) < tam) {
751
                            numSelect = h;
752
                            isSelectedHandler = true;
753
                            break;
754
                        }
755
                    }
756

    
757
                    if (!isSelectedHandler) {
758
                        boolean isSelectedGeometry = false;
759
                        if (geometry.intersects(rect)) { // , 0.1)){
760
                            isSelectedGeometry = true;
761
                        }
762
                        if (isSelectedGeometry && addVertex) {
763
                            try {
764
                                selectedIterator =
765
                                    featureStore.getFeatureSelection()
766
                                        .iterator();
767
                                Feature feat =
768
                                    (Feature) selectedIterator.next();
769
                                Point2D posVertex = new Point2D.Double(x, y);
770
                                Geometry geom1 =
771
                                    (feat.getDefaultGeometry()).cloneGeometry();
772
                                Geometry geom = null;
773
                                if (geom1 instanceof MultiPrimitive) {
774
                                    geom =
775
                                        addVertexGC((MultiPrimitive) geom1,
776
                                            posVertex, rect);
777
                                } else {
778
                                    geom = addVertex(geom1, posVertex, rect);
779
                                }
780
                                if (geom != null) {
781
                                    EditableFeature eFeature =
782
                                        feature.getEditable();
783
                                    eFeature.setGeometry(featureStore
784
                                        .getDefaultFeatureType()
785
                                        .getDefaultGeometryAttributeName(),
786
                                        geom);
787
                                    featureStore.update(eFeature);
788
                                    Handler[] newHandlers =
789
                                        geom.getHandlers(Geometry.SELECTHANDLER);
790
                                    for (int h = 0; h < newHandlers.length; h++) {
791
                                        if (newHandlers[h].getPoint().distance(
792
                                            posVertex) < tam) {
793
                                            numSelect = h;
794
                                            isSelectedHandler = true;
795
                                        }
796
                                    }
797

    
798
                                    // clearSelection();
799
                                }
800
                            } finally {
801
                                if (selectedIterator != null) {
802
                                    selectedIterator.dispose();
803
                                }
804
                            }
805
                        }
806
                    }
807
                }
808
            }
809

    
810
        } catch (Exception e) {
811
            
812
            ApplicationLocator.getManager().message(
813
                e.getMessage(), JOptionPane.ERROR_MESSAGE);
814
            logger.info("Error in select handler.", e);
815
        } finally {
816
            if (iterator != null) {
817
                iterator.dispose();
818
            }
819
        }
820

    
821
    }
822

    
823
    public String toString() {
824
        return "_editvertex";
825
    }
826

    
827
    @Override
828
    protected int[] getSupportedGeometryTypes() {
829
        return new int[] { POINT, MULTIPOINT, CURVE, MULTICURVE, CIRCLE,
830
            ELLIPSE, SURFACE, MULTISURFACE };
831
    }
832

    
833
}