Statistics
| Revision:

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

History | View | Annotate | Download (19.7 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.IEditionManager;
37
import org.gvsig.editing.gui.cad.CADTool;
38
import org.gvsig.editing.gui.cad.DefaultCADTool;
39
import org.gvsig.editing.gui.cad.exception.CommandException;
40
import org.gvsig.editing.gui.cad.tools.smc.SelectionCADToolContext;
41
import org.gvsig.editing.gui.cad.tools.smc.SelectionCADToolContext.SelectionCADToolState;
42
import org.gvsig.editing.layers.VectorialLayerEdited;
43
import org.gvsig.fmap.dal.exception.DataException;
44
import org.gvsig.fmap.dal.exception.ReadException;
45
import org.gvsig.fmap.dal.feature.EditableFeature;
46
import org.gvsig.fmap.dal.feature.Feature;
47
import org.gvsig.fmap.dal.feature.FeatureSet;
48
import org.gvsig.fmap.dal.feature.FeatureStore;
49
import org.gvsig.fmap.dal.feature.exception.NeedEditingModeException;
50
import org.gvsig.fmap.geom.Geometry;
51
import org.gvsig.fmap.geom.handler.Handler;
52
import org.gvsig.fmap.geom.primitive.Curve;
53
import org.gvsig.fmap.geom.type.GeometryType;
54
import org.gvsig.fmap.mapcontext.MapContext;
55
import org.gvsig.fmap.mapcontext.ViewPort;
56
import org.gvsig.fmap.mapcontext.layers.FLayer;
57
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
58
import org.gvsig.tools.dispose.DisposableIterator;
59

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

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

    
70
    protected SelectionCADToolContext _fsm;
71

    
72
    protected Point2D firstPoint;
73

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

    
84
    protected boolean multipleSelection = false;
85

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

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

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

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

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

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

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

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

    
221
            firstPoint = new Point2D.Double(x, y);
222

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

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

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

    
296
            renderer
297
                .draw(curve, mapControlManager.getGeometrySelectionSymbol());
298

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
469
            double tam =
470
                getCadToolAdapter().getMapControl().getViewPort()
471
                    .toMapDistance(mapControlManager.getTolerance());
472

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

    
492
                // y miramos los handlers de cada entidad seleccionada
493
                double min = tam;
494

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

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

    
523
    public String getType() {
524
        return type;
525
    }
526

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

    
535
    public String toString() {
536
        return "_selection";
537
    }
538

    
539
    public void multipleSelection(boolean b) {
540
        multipleSelection = b;
541

    
542
    }
543

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

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