Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / extEditing / src / org / gvsig / editing / gui / cad / tools / SelectionCADTool.java @ 39573

History | View | Annotate | Download (19.6 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.Color;
25
import java.awt.event.InputEvent;
26
import java.awt.geom.Point2D;
27
import java.util.ArrayList;
28

    
29
import org.cresques.cts.ICoordTrans;
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

    
33
import org.gvsig.andami.PluginServices;
34
import org.gvsig.andami.messages.NotificationManager;
35
import org.gvsig.editing.CADExtension;
36
import org.gvsig.editing.gui.cad.CADTool;
37
import org.gvsig.editing.gui.cad.DefaultCADTool;
38
import org.gvsig.editing.gui.cad.exception.CommandException;
39
import org.gvsig.editing.gui.cad.tools.smc.SelectionCADToolContext;
40
import org.gvsig.editing.gui.cad.tools.smc.SelectionCADToolContext.SelectionCADToolState;
41
import org.gvsig.editing.layers.VectorialLayerEdited;
42
import org.gvsig.fmap.dal.exception.DataException;
43
import org.gvsig.fmap.dal.exception.ReadException;
44
import org.gvsig.fmap.dal.feature.EditableFeature;
45
import org.gvsig.fmap.dal.feature.Feature;
46
import org.gvsig.fmap.dal.feature.FeatureSet;
47
import org.gvsig.fmap.dal.feature.FeatureStore;
48
import org.gvsig.fmap.dal.feature.exception.NeedEditingModeException;
49
import org.gvsig.fmap.geom.Geometry;
50
import org.gvsig.fmap.geom.handler.Handler;
51
import org.gvsig.fmap.geom.primitive.Curve;
52
import org.gvsig.fmap.geom.type.GeometryType;
53
import org.gvsig.fmap.mapcontext.MapContext;
54
import org.gvsig.fmap.mapcontext.ViewPort;
55
import org.gvsig.fmap.mapcontext.layers.FLayer;
56
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
57
import org.gvsig.tools.dispose.DisposableIterator;
58

    
59
/**
60
 * DOCUMENT ME!
61
 * 
62
 * @author Vicente Caballero Navarro
63
 */
64
public class SelectionCADTool extends DefaultCADTool {
65

    
66
    private static final Logger LOG = LoggerFactory
67
        .getLogger(SelectionCADTool.class);
68

    
69
    protected SelectionCADToolContext _fsm;
70

    
71
    protected Point2D firstPoint;
72

    
73
    protected String nextState;
74
    
75
    // These two arrays are used to save the current selected features and
76
    // geometries. The selected geometries contains an instance of the
77
    // geometry that can be reprojected.
78
    protected ArrayList selectedGeometries = new ArrayList();
79
    protected ArrayList selectedFeatures = new ArrayList(); 
80
    
81
    protected String type = PluginServices.getText(this, "simple");
82

    
83
    protected boolean multipleSelection = false;
84

    
85
    /**
86
     * M?todo de incio, para poner el c?digo de todo lo que se requiera de una
87
     * carga previa a la utilizaci?n de la herramienta.
88
     */
89
    public void init() {
90
        _fsm = new SelectionCADToolContext(this);
91
        setNextTool("selection");
92
        setType(PluginServices.getText(this, "simple"));
93
    }
94

    
95
    public void transition(double x, double y, InputEvent event) {
96
        LOG.debug("TRANSICION DESDE ESTADO {}", _fsm.getState() + " x= " + x
97
            + " y=" + y);
98
        try {
99
            _fsm.addPoint(x, y, event);
100
        } catch (Exception e) {
101
            init();
102
            PluginServices.getMDIManager().restoreCursor();
103
        }
104
        LOG.debug("ESTADO ACTUAL: ", getStatus());
105
    }
106

    
107
    public void transition(double d) {
108
        _fsm.addValue(d);
109
    }
110

    
111
    public void transition(String s) throws CommandException {
112
        if (!super.changeCommand(s)) {
113
            _fsm.addOption(s);
114
        }
115
    }
116

    
117
    public String getNextState() {
118
        return nextState;
119
    }
120

    
121
    protected void pointDoubleClick(MapContext map) throws ReadException {
122
        FLayer[] actives = map.getLayers().getActives();
123
    }
124

    
125
    /**
126
     * Equivale al transition del prototipo pero sin pasarle como par? metro el
127
     * editableFeatureSource que ya estar? creado.
128
     * 
129
     * @param selection
130
     *            Bitset con las geometr?as que est?n seleccionadas.
131
     * @param x
132
     *            par?metro x del punto que se pase en esta transici?n.
133
     * @param y
134
     *            par?metro y del punto que se pase en esta transici?n.
135
     */
136
    public void addPoint(double x, double y, InputEvent event) {
137
        SelectionCADToolState actualState =
138
            (SelectionCADToolState) _fsm.getPreviousState();
139
        String status = actualState.getName();
140
        LOG.debug("PREVIOUSSTATE = {}", status);
141
        VectorialLayerEdited vle = getVLE();
142
        try {
143
            LOG.debug("STATUS ACTUAL = {}", _fsm.getTransition());
144
            if (status.equals("Selection.FirstPoint")) {
145
                firstPoint = new Point2D.Double(x, y);
146
            } else
147
                if (status.equals("Selection.SecondPoint")) {
148
                } else
149
                    if (status.equals("Selection.WithFeatures")) {
150
                    } else
151
                        if (status.equals("Selection.WithHandlers")) {
152
                            addPointWithHandlers(x, y, vle.getFeatureStore(),
153
                                vle.getSelectedHandler());
154
                        }
155
        } catch (DataException e) {
156
            LOG.error("Error reding the store", e);
157
        }
158
    }
159

    
160
    /**
161
     * AddPoint method for the WithHandlers option
162
     * 
163
     * @param x
164
     *            selected x coordinate.
165
     * @param y
166
     *            selected y coordinate.
167
     * @param featureStore
168
     *            the selected feature store.
169
     * @param selectedHandlers
170
     *            the selected handlers
171
     */
172
    protected void addPointWithHandlers(double x, double y,
173
        FeatureStore featureStore, ArrayList selectedHandlers) {
174
        String description = PluginServices.getText(this, "move_handlers");
175
        DisposableIterator iterator = null;
176
        try {
177
            featureStore.beginEditingGroup(description);
178
            ICoordTrans coordTrans = getVLE().getLayer().getCoordTrans();
179
            for (int i=0 ; i<selectedFeatures.size() ; i++){
180
                Feature feature = (Feature) selectedFeatures.get(i);
181
                
182
                Geometry changing_geometry = (Geometry)selectedGeometries.get(i);
183
                Geometry old_geometry = changing_geometry.cloneGeometry();
184
                
185
                // Draw the moved geometry. It has been reprojected in the
186
                // select handler method
187
                for (int k = 0; k < selectedHandlers.size(); k++) {
188
                    Handler h = (Handler) selectedHandlers.get(k);
189
                    h.set(x, y);
190
                }                            
191
                             
192
                //If the layer is reprojected, It is necessary
193
                //to reproject the geometry
194
                if (coordTrans != null) {
195
                    changing_geometry = changing_geometry.cloneGeometry();
196
                    changing_geometry.reProject(coordTrans.getInverted());
197
                    // ==========================
198
                    // this is already an independent clone
199
                    old_geometry.reProject(coordTrans.getInverted());
200
                }              
201
                
202
                // restore old geometry in feature
203
                // this is because selectedGeometries and
204
                // selectedFeature point
205
                // at the same geometries at least sometimes
206
                EditableFeature eFeature = feature.getEditable();
207
                eFeature.setDefaultGeometry(old_geometry);
208
                
209
                Feature old_geom_feature = eFeature.getNotEditableCopy();
210
                
211
                // set new (old remains as source for undoing)
212
                eFeature = old_geom_feature.getEditable();
213
                eFeature.setDefaultGeometry(changing_geometry);
214
                
215
                
216
                featureStore.update(eFeature);
217
            }
218

    
219
            firstPoint = new Point2D.Double(x, y);
220

    
221
            featureStore.endEditingGroup();
222
        } catch (DataException e1) {
223
            LOG.error("Error reading the store", e1);
224
        } finally {
225
            if (iterator != null) {
226
                iterator.dispose();
227
            }
228
        }
229
    }
230

    
231
    /**
232
     * Receives second point
233
     * 
234
     * @param x
235
     * @param y
236
     * @return numFeatures selected
237
     */
238
    public long selectWithSecondPoint(double x, double y, InputEvent event) {
239
        VectorialLayerEdited vle = getVLE();
240
        PluginServices.getMDIManager().setWaitCursor();
241
        vle.selectWithSecondPoint(x, y);
242
        FeatureSet selection = null;
243
        try {
244
            selection = (FeatureSet) vle.getFeatureStore().getSelection();
245
            PluginServices.getMDIManager().restoreCursor();
246
            long countSel = selection.getSize();
247
            if (countSel > 0) {
248
                nextState = "Selection.WithSelectedFeatures";
249
            } else {
250
                nextState = "Selection.FirstPoint";
251
            }
252
            return countSel;
253
        } catch (ReadException e) {
254
            e.printStackTrace();
255
            return 0;
256
        } catch (DataException e) {
257
            e.printStackTrace();
258
            return 0;
259
        }
260
    }
261

    
262
    /**
263
     * M?todo para dibujar la lo necesario para el estado en el que nos
264
     * encontremos.
265
     * 
266
     * @param g
267
     *            Graphics sobre el que dibujar.
268
     * @param selectedGeometries
269
     *            BitSet con las geometr?as seleccionadas.
270
     * @param x
271
     *            par?metro x del punto que se pase para dibujar.
272
     * @param y
273
     *            par?metro x del punto que se pase para dibujar.
274
     */
275
    public void drawOperation(MapControlDrawer renderer, double x, double y) {
276
        SelectionCADToolState actualState = _fsm.getState();
277
        String status = actualState.getName();
278
        VectorialLayerEdited vle = getVLE();
279
        if (vle == null) {
280
            return;
281
        }
282
        ArrayList selectedHandler = vle.getSelectedHandler();
283
        ViewPort vp = vle.getLayer().getMapContext().getViewPort();
284
        if (status.equals("Selection.SecondPoint")) {
285
            // Dibuja el rect?ngulo de selecci?n
286
            Curve curve = createCurve();
287
            curve.addMoveToVertex(createPoint(firstPoint.getX(),
288
                firstPoint.getY()));
289
            curve.addVertex(createPoint(x, firstPoint.getY()));
290
            curve.addVertex(createPoint(x, y));
291
            curve.addVertex(createPoint(firstPoint.getX(), y));
292
            curve.addVertex(createPoint(firstPoint.getX(), firstPoint.getY()));
293

    
294
            renderer
295
                .draw(curve, mapControlManager.getGeometrySelectionSymbol());
296

    
297
            return;
298
        } else
299
            //If there is a handler to move...
300
            if (status.equals("Selection.WithHandlers")) {
301
                drawWithHandlers(renderer, x, y, selectedHandler);
302
            }
303
    }
304
    
305
    /**
306
     * Draw method to draw a geometry with handlers
307
     * 
308
     * @param mapControlDrawer
309
     *            object used to draw.
310
     * @param x
311
     *            selected x coordinate.
312
     * @param y
313
     *            selected y coordinate.
314
     * @param selectedHandlers
315
     *            the selected handlers
316
     */
317
    protected void drawWithHandlers(MapControlDrawer mapControlDrawer, double x,
318
        double y, ArrayList selectedHandlers) {
319
        // Moving the handlers that have been selected
320
        // in the selectHandlers method
321
        double xPrev = 0;
322
        double yPrev = 0;
323
        for (int k = 0; k < selectedHandlers.size(); k++) {
324
            Handler h = (Handler) selectedHandlers.get(k);
325
            xPrev = h.getPoint().getX();
326
            yPrev = h.getPoint().getY();
327
            h.set(x, y);
328
        }
329
       
330
        // Draw the moved geometry. It has been reprojected in the
331
        // select handler method
332
        for (int i = 0; i < selectedGeometries.size(); i++) {
333
            Geometry geom = (Geometry) selectedGeometries.get(i);
334

    
335
            mapControlDrawer.setColor(Color.gray);
336
            mapControlDrawer.draw(geom,
337
                mapControlManager.getAxisReferenceSymbol());
338
        }
339
        for (int k = 0; k < selectedHandlers.size(); k++) {
340
            Handler h = (Handler) selectedHandlers.get(k);
341
            h.set(xPrev, yPrev);
342
        } 
343
    }
344

    
345
    /**
346
     * Add a diferent option.
347
     * 
348
     * @param sel
349
     *            DOCUMENT ME!
350
     * @param s
351
     *            Diferent option.
352
     */
353
    public void addOption(String s) {
354
        SelectionCADToolState actualState =
355
            (SelectionCADToolState) _fsm.getPreviousState();
356
        String status = actualState.getName();
357
        LOG.debug("PREVIOUSSTATE = {}", status);
358
        LOG.debug("STATUS ACTUAL = {}", _fsm.getTransition());
359
        if (s.equals(PluginServices.getText(this, "cancel"))) {
360
            init();
361
            return;
362
        }
363
        if (status.equals("Selection.FirstPoint")) {
364
            setType(s);
365
            return;
366
        }
367
        init();
368
    }
369

    
370
    /*
371
     * (non-Javadoc)
372
     * 
373
     * @see com.iver.cit.gvsig.gui.cad.CADTool#addvalue(double)
374
     */
375
    public void addValue(double d) {
376
    }
377

    
378
    public String getStatus() {
379
        try {
380
            SelectionCADToolState actualState =
381
                (SelectionCADToolState) _fsm.getPreviousState();
382
            String status = actualState.getName();
383

    
384
            return status;
385
        } catch (NullPointerException e) {
386
            return "Selection.FirstPoint";
387
        }
388
    }
389

    
390
    public void end() {
391
        if (!getNextTool().equals("selection")) {
392
            CADExtension.setCADTool(getNextTool(), false);
393
        }
394
    }
395

    
396
    public String getName() {
397
        return PluginServices.getText(this, "selection_");
398
    }
399

    
400
    public boolean selectFeatures(double x, double y, InputEvent event) {
401
        SelectionCADToolState actualState = _fsm.getState();
402

    
403
        String status = actualState.getName();
404
        VectorialLayerEdited vle = getVLE();
405
        multipleSelection = event.isControlDown();
406

    
407
        if ((status.equals("Selection.FirstPoint"))
408
            || (status.equals("Selection.WithSelectedFeatures"))) {
409
            PluginServices.getMDIManager().setWaitCursor();
410
            firstPoint = new Point2D.Double(x, y);
411
            try {
412
                vle.getFeatureStore().beginEditingGroup(getName());
413
                vle.selectWithPoint(x, y, multipleSelection);
414
                vle.getFeatureStore().endEditingGroup();
415
            } catch (NeedEditingModeException e) {
416
                NotificationManager.showMessageError(getName(), e);
417
            } catch (ReadException e) {
418
                NotificationManager.showMessageError(getName(), e);
419
            }
420
            PluginServices.getMDIManager().restoreCursor();
421
        }
422
        FeatureSet selection = null;
423
        try {
424
            selection = (FeatureSet) vle.getFeatureStore().getSelection();
425
            long countSel = selection.getSize();
426
            if (countSel > 0) {
427
                nextState = "Selection.WithSelectedFeatures";
428
                return true;
429
            } else {
430
                {
431
                    nextState = "Selection.SecondPoint";
432
                    return true;
433
                }
434
            }
435
        } catch (ReadException e) {
436
            LOG.error("Error selecting the features", e);
437
            return false;
438
        } catch (DataException e) {
439
            LOG.error("Error selecting the features", e);
440
            return false;
441
        }
442
    }
443

    
444
    public int selectHandlers(double x, double y, InputEvent event) {
445
        Point2D auxPoint = new Point2D.Double(x, y);
446

    
447
        VectorialLayerEdited vle = getVLE();
448
        
449
        //Gets the current selected handlers 
450
        ArrayList selectedHandler = vle.getSelectedHandler();
451
        FeatureSet selection = null;
452
        DisposableIterator iterator = null;
453
        try {
454
            selection = (FeatureSet) vle.getFeatureStore().getSelection();
455

    
456
            long countSel = selection.getSize();
457
            LOG.debug("DENTRO DE selectHandlers. selectedRow.size = {}",
458
                countSel);
459
            selectedHandler.clear();
460

    
461
            //Clear the previous selection
462
            clearCurrentSelection();
463
            
464
            // Se comprueba si se pincha en una gemometr?a
465
            PluginServices.getMDIManager().setWaitCursor();
466

    
467
            double tam =
468
                getCadToolAdapter().getMapControl().getViewPort()
469
                    .toMapDistance(mapControlManager.getTolerance());
470

    
471
            Handler[] handlers = null;
472
            
473
            
474
            selectedGeometries.clear();
475
            iterator = selection.fastIterator();
476
            ICoordTrans coordTrans = getVLE().getLayer().getCoordTrans();
477
            while (iterator.hasNext()) {
478
                Feature feature = (Feature) iterator.next();
479
                
480
                //If the layer is reprojected, the tolerance is not applicable. It is necessary
481
                //to reproject the geometry
482
                Geometry geometry = feature.getDefaultGeometry();
483
                if (coordTrans != null){
484
                    geometry = geometry.cloneGeometry();
485
                    geometry.reProject(coordTrans);
486
                }
487
                
488
                handlers = geometry.getHandlers(Geometry.SELECTHANDLER);
489

    
490
                // y miramos los handlers de cada entidad seleccionada
491
                double min = tam;
492

    
493
                for (int j = 0; j < handlers.length; j++) {
494
                    Point2D handlerPoint = handlers[j].getPoint();
495
                    double distance = auxPoint.distance(handlerPoint);
496
                    if (distance <= min) {
497
                        min = distance;
498
                        selectedHandler.add(handlers[j]);
499
                        selectedGeometries.add(geometry);
500
                        selectedFeatures.add(feature);
501
                    }
502
                }
503
            }
504
            PluginServices.getMDIManager().restoreCursor();
505
        } catch (DataException e) {
506
            LOG.error("Error reading the store", e);
507
        } finally {
508
            if (iterator != null) {
509
                iterator.dispose();
510
            }
511
        }
512

    
513
        return selectedHandler.size();
514
    }
515
    
516
    protected void clearCurrentSelection(){
517
        selectedFeatures.clear();
518
        selectedGeometries.clear();
519
    }
520

    
521
    public String getType() {
522
        return type;
523
    }
524

    
525
    public void setType(String type) {
526
        if (type.equals("S") || type.equals("s")) {
527
            this.type = PluginServices.getText(this, "simple");
528
        } else {
529
            this.type = type;
530
        }
531
    }
532

    
533
    public String toString() {
534
        return "_selection";
535
    }
536

    
537
    public void multipleSelection(boolean b) {
538
        multipleSelection = b;
539

    
540
    }
541

    
542
    @Override
543
    public boolean isApplicable(GeometryType geometryType) {
544
        return true;
545
    }
546

    
547
    @Override
548
    protected int[] getSupportedGeometryTypes() {
549
        return null;
550
    }
551
    
552
    /**
553
     * Tells whether the tool provided is an instance of this class
554
     * 
555
     * @param tool
556
     * @param exactly_this requires that the object is an instance of
557
     * this class and not an instance of a subclass
558
     *  
559
     * @return 
560
     */
561
    public static boolean isInstance(CADTool tool, boolean exactly_this) {
562
        
563
        if (exactly_this) {
564
            return tool.getClass() == SelectionCADTool.class;
565
        } else {
566
            return (tool instanceof SelectionCADTool);
567
        }
568
        
569
    }
570
}