Statistics
| Revision:

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

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

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

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

    
68
    protected SelectionCADToolContext _fsm;
69

    
70
    protected Point2D firstPoint;
71

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

    
82
    protected boolean multipleSelection = false;
83

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
539
    }
540

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

    
546
    @Override
547
    protected int[] getSupportedGeometryTypes() {
548
        return null;
549
    }
550
}