Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / extEditing / src / org / gvsig / editing / gui / cad / tools / ComplexSelectionCADTool.java @ 38539

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

    
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.exception.CommandException;
37
import org.gvsig.editing.gui.cad.tools.smc.ComplexSelectionCADToolContext;
38
import org.gvsig.editing.gui.cad.tools.smc.ComplexSelectionCADToolContext.ComplexSelectionCADToolState;
39
import org.gvsig.editing.layers.VectorialLayerEdited;
40
import org.gvsig.fmap.dal.exception.DataException;
41
import org.gvsig.fmap.dal.exception.ReadException;
42
import org.gvsig.fmap.dal.feature.FeatureSelection;
43
import org.gvsig.fmap.dal.feature.FeatureStore;
44
import org.gvsig.fmap.geom.Geometry;
45
import org.gvsig.fmap.geom.primitive.Curve;
46
import org.gvsig.fmap.geom.primitive.GeneralPathX;
47
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
48
import org.gvsig.fmap.geom.primitive.Surface;
49
import org.gvsig.fmap.mapcontrol.MapControl;
50
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
51

    
52
/**
53
 * DOCUMENT ME!
54
 * 
55
 * @author Vicente Caballero Navarro
56
 */
57
@SuppressWarnings({ "rawtypes", "unchecked" })
58
public class ComplexSelectionCADTool extends SelectionCADTool {
59

    
60
    private static final Logger LOG = LoggerFactory
61
        .getLogger(ComplexSelectionCADTool.class);
62

    
63
    protected ComplexSelectionCADToolContext _fsm;
64
    protected List pointsPolygon = new ArrayList();
65

    
66
    /**
67
     * Crea un nuevo ComplexSelectionCADTool.
68
     */
69
    public ComplexSelectionCADTool() {
70
        type = "";
71
    }
72

    
73
    /**
74
     * M?todo de incio, para poner el c?digo de todo lo que se requiera de una
75
     * carga previa a la utilizaci?n de la herramienta.
76
     */
77
    public void init() {
78
        _fsm = new ComplexSelectionCADToolContext(this);
79
        setNextTool("complex_selection");
80

    
81
        setType("");
82
    }
83

    
84
    /**
85
     * Equivale al transition del prototipo pero sin pasarle como par? metro el
86
     * editableFeatureSource que ya estar? creado.
87
     * 
88
     * @param selection
89
     *            Bitset con las geometr?as que est?n seleccionadas.
90
     * @param x
91
     *            par?metro x del punto que se pase en esta transici?n.
92
     * @param y
93
     *            par?metro y del punto que se pase en esta transici?n.
94
     */
95
    public void addPoint(double x, double y, InputEvent event) {
96
        if (event != null && ((MouseEvent) event).getClickCount() == 2) {
97
            try {
98
                pointDoubleClick(((MapControl) event.getComponent())
99
                    .getMapContext());
100
            } catch (ReadException e) {
101
                NotificationManager.addError(e.getMessage(), e);
102
            }
103
            return;
104
        }
105
        ComplexSelectionCADToolState actualState =
106
            (ComplexSelectionCADToolState) _fsm.getPreviousState();
107
        String status = actualState.getName();
108
        LOG.info("PREVIOUSSTATE =" + status);
109
        LOG.info("STATUS ACTUAL = " + _fsm.getTransition());
110
        if (status.equals("Selection.FirstPoint")) {
111
            firstPoint = new Point2D.Double(x, y);
112
            pointsPolygon.add(firstPoint);
113
        } else if (status.equals("Selection.SecondPoint")) {
114

    
115
        } else if (status.equals("Selection.WithSelectedFeatures")) {
116

    
117
        } else if (status.equals("Selection.WithHandlers")) {
118
            FeatureStore featureStore = null;
119
            try {
120
                VectorialLayerEdited vle = getVLE();
121
                featureStore = vle.getFeatureStore();
122
                addPointWithHandlers(x, y, featureStore,
123
                    vle.getSelectedHandler());
124
            } catch (ReadException e) {
125
                LOG.error("Error getting the feature store");
126
            }
127
        } else if (status.equals("Selection.NextPointPolygon")) {
128
            pointsPolygon.add(new Point2D.Double(x, y));
129
        } else if (status.equals("Selection.SecondPointCircle")) {
130
            selectWithCircle(x, y, event);
131
        }
132
    }
133

    
134
    /**
135
     * Receives second point
136
     * 
137
     * @param x
138
     * @param y
139
     * @return numFeatures selected
140
     */
141
    public long selectWithSecondPointOutRectangle(double x, double y,
142
        InputEvent event) {
143
        Point2D lastPoint = new Point2D.Double(x, y);
144
        Surface surface = createSurface();
145
        surface.addMoveToVertex(createPoint(firstPoint.getX(),
146
            firstPoint.getY()));
147
        surface.addVertex(createPoint(lastPoint.getX(), firstPoint.getY()));
148
        surface.addVertex(createPoint(lastPoint.getX(), lastPoint.getY()));
149
        surface.addVertex(createPoint(firstPoint.getX(), lastPoint.getY()));
150
        surface.closePrimitive();
151
        return selectWithPolygon(surface);
152
    }
153

    
154
    /**
155
     * Receives second point
156
     * 
157
     * @param x
158
     * @param y
159
     * @return numFeatures selected
160
     */
161
    public long selectWithCircle(double x, double y, InputEvent event) {
162
        Geometry circle = createCircle(firstPoint, new Point2D.Double(x, y));
163
        return selectWithPolygon(circle);
164
    }
165

    
166
    public long selectWithPolygon(Geometry polygon) {
167
        VectorialLayerEdited vle = getVLE();
168
        PluginServices.getMDIManager().setWaitCursor();
169

    
170
        if (getType().equals(PluginServices.getText(this, "inside_circle"))
171
            || getType().equals(PluginServices.getText(this, "inside_polygon"))) {
172
            vle.selectContainsSurface(polygon);
173
        } else
174
            if (getType().equals(PluginServices.getText(this, "cross_circle"))
175
                || getType().equals(
176
                    PluginServices.getText(this, "cross_polygon"))) {
177
                vle.selectIntersectsSurface(polygon);
178
            } else
179
                if (getType()
180
                    .equals(PluginServices.getText(this, "out_circle"))
181
                    || getType().equals(
182
                        PluginServices.getText(this, "out_polygon"))
183
                    || getType().equals(
184
                        PluginServices.getText(this, "out_rectangle"))) {
185
                    vle.selectOutPolygon(polygon);
186
                }
187
        long countSelection = 0;
188
        try {
189
            countSelection =
190
                ((FeatureSelection) vle.getFeatureStore().getSelection())
191
                    .getSize();
192
        } catch (ReadException e) {
193
            LOG.error("Error reading the store", e);
194
        } catch (DataException e) {
195
            LOG.error("Error reading the store", e);
196
        }
197
        PluginServices.getMDIManager().restoreCursor();
198
        if (countSelection > 0) {
199
            nextState = "Selection.WithSelectedFeatures";
200
            end();
201
        } else {
202
            nextState = "Selection.FirstPoint";
203
        }
204
        return countSelection;
205
    }
206

    
207
    /**
208
     * M?todo para dibujar la lo necesario para el estado en el que nos
209
     * encontremos.
210
     * 
211
     * @param g
212
     *            Graphics sobre el que dibujar.
213
     * @param selectedGeometries
214
     *            BitSet con las geometr?as seleccionadas.
215
     * @param x
216
     *            par?metro x del punto que se pase para dibujar.
217
     * @param y
218
     *            par?metro x del punto que se pase para dibujar.
219
     */
220
    public void drawOperation(MapControlDrawer renderer, double x, double y) {
221
        ComplexSelectionCADToolState actualState = _fsm.getState();
222
        String status = actualState.getName();
223

    
224
        if (status.equals("Selection.SecondPoint")
225
            || status.equals("Selection.SecondPointOutRectangle")) {
226
            drawRectangle(renderer, x, y);
227
        } else
228
            if (status.equals("Selection.SecondPointCircle")) {
229
                drawSecondPointCircle(renderer, x, y);
230
            } else
231
                if (status.equals("Selection.NextPointPolygon")) {
232
                    drawNextPointPolygon(renderer, x, y);
233
                } else
234
                    if (status.equals("Selection.WithHandlers")) {
235
                        VectorialLayerEdited vle = getVLE();
236
                        drawWithHandlers(renderer, x, y,
237
                            vle.getSelectedHandler());
238
                    }
239
    }
240

    
241
    /**
242
     * Draw method for the nexp point of a polygon.
243
     * 
244
     * @param mapControlDrawer
245
     *            object used to draw.
246
     * @param x
247
     *            selected x coordinate.
248
     * @param y
249
     *            selected y coordinate.
250
     */
251
    private void drawNextPointPolygon(MapControlDrawer mapControlDrawer,
252
        double x, double y) {
253
        // Dibuja el pol?gono de selecci?n
254
        Geometry curve =
255
            createOrientablePrimitive(new Point2D.Double(x, y),
256
                Geometry.TYPES.CURVE);
257
        mapControlDrawer.draw(curve,
258
            mapControlManager.getGeometrySelectionSymbol());
259
    }
260

    
261
    /**
262
     * Draw method for the second point of a "rectangle".
263
     * 
264
     * @param mapControlDrawer
265
     *            object used to draw.
266
     * @param x
267
     *            selected x coordinate.
268
     * @param y
269
     *            selected y coordinate.
270
     */
271
    private void drawRectangle(MapControlDrawer mapControlDrawer, double x,
272
        double y) {
273
        Curve curve =
274
            createEnvelopeLikeCurve(firstPoint, new Point2D.Double(x, y));
275
        mapControlDrawer.draw(curve);
276
    }
277

    
278
    /**
279
     * Draw method for the second point of the "circle" option
280
     * 
281
     * @param mapControlDrawer
282
     *            object used to draw.
283
     * @param x
284
     *            selected x coordinate.
285
     * @param y
286
     *            selected y coordinate.
287
     */
288
    private void drawSecondPointCircle(MapControlDrawer mapControlDrawer,
289
        double x, double y) {
290
        Geometry circle = createCircle(firstPoint, new Point2D.Double(x, y));
291
        GeneralPathX gpx = new GeneralPathX();
292
        gpx.append(circle.getInternalShape().getPathIterator(null), true);
293
        Geometry circleSel = createCurve(gpx);
294
        // Draw the circle
295
        mapControlDrawer.draw(circleSel,
296
            mapControlManager.getGeometrySelectionSymbol());
297
    }
298

    
299
    /**
300
     * Add a diferent option.
301
     * 
302
     * @param sel
303
     *            DOCUMENT ME!
304
     * @param s
305
     *            Diferent option.
306
     */
307
    public void addOption(String s) {
308
        ComplexSelectionCADToolState actualState =
309
            (ComplexSelectionCADToolState) _fsm.getPreviousState();
310
        String status = actualState.getName();
311
        LOG.info("PREVIOUSSTATE =" + status);
312
        LOG.info("STATUS ACTUAL = " + _fsm.getTransition());
313
        if (s.equals(PluginServices.getText(this, "cancel"))) {
314
            init();
315
            try {
316
                clearSelection();
317
            } catch (DataException e) {
318
                LOG.error("Error canceling the selection", e);
319
            }
320
            return;
321
        } else
322
            if (s.equals(PluginServices.getText(this, "select_all"))) {
323
                // The selct all is made in the context
324
                init();
325
                return;
326
            }
327
        if (status.equals("Selection.FirstPoint")) {
328
            setType(s);
329
            return;
330
        } else
331
            if (status.equals("Selection.NextPointPolygon")) {
332
                if (s.equals(PluginServices.getText(this, "end_polygon"))
333
                    || s.equalsIgnoreCase(PluginServices.getText(this,
334
                        "ComplexSelectionCADTool.end"))) {
335
                    selectCurrentSurface();
336
                    return;
337
                }
338
            }
339
        init();
340
    }
341

    
342
    public long selectCurrentSurface() {
343
        Geometry surface =
344
            createOrientablePrimitive(null, Geometry.TYPES.SURFACE);
345
        GeneralPathX gpx = new GeneralPathX();
346
        gpx.append(surface.getPathIterator(null), true);
347
        if (gpx.isCCW()) {
348
            gpx.flip();
349
            surface = createSurface(gpx);
350
        }
351
        pointsPolygon.clear();
352
        return selectWithPolygon(surface);
353
    }
354

    
355
    public long selectAll() {
356
        VectorialLayerEdited vle = getVLE();
357
        PluginServices.getMDIManager().setWaitCursor();
358
        vle.selectAll();
359
        long countSelection = 0;
360
        try {
361
            countSelection =
362
                ((FeatureSelection) vle.getFeatureStore().getSelection())
363
                    .getSize();
364
        } catch (ReadException e) {
365
            LOG.error("Error reading the store", e);
366
        } catch (DataException e) {
367
            LOG.error("Error reading the store", e);
368
        }
369
        PluginServices.getMDIManager().restoreCursor();
370
        if (countSelection > 0) {
371
            nextState = "Selection.WithSelectedFeatures";
372
        } else {
373
            nextState = "Selection.FirstPoint";
374
        }
375
        end();
376
        return countSelection;
377
    }
378

    
379
    private OrientablePrimitive createOrientablePrimitive(Point2D p,
380
        int geometryType) {
381
        Point2D[] points = (Point2D[]) pointsPolygon.toArray(new Point2D[0]);
382
        OrientablePrimitive orientablePrimitive =
383
            createOrientablePrimitive(geometryType);
384

    
385
        for (int i = 0; i < points.length; i++) {
386
            if (i == 0) {
387
                orientablePrimitive.addMoveToVertex(createPoint(
388
                    points[i].getX(), points[i].getY()));
389
            } else {
390
                orientablePrimitive.addVertex(createPoint(points[i].getX(),
391
                    points[i].getY()));
392
            }
393
        }
394
        if (p != null) {
395
            orientablePrimitive.addVertex(createPoint(p.getX(), p.getY()));
396
        }
397
        orientablePrimitive.closePrimitive();
398
        return orientablePrimitive;
399
    }
400

    
401
    public void addValue(double d) {
402

    
403
    }
404

    
405
    public void end() {
406
        if (!getNextTool().equals("complex_selection")) {
407
            CADExtension.setCADTool(getNextTool(), false);
408
        }
409
    }
410

    
411
    public String getName() {
412
        return PluginServices.getText(this, "complex_selection_");
413
    }
414

    
415
    public boolean selectFeatures(double x, double y, InputEvent event) {
416
        ComplexSelectionCADToolState actualState = _fsm.getState();
417

    
418
        String status = actualState.getName();
419
        VectorialLayerEdited vle = getVLE();
420

    
421
        if ((status.equals("Selection.FirstPoint"))
422
            || (status.equals("Selection.WithSelectedFeatures"))) {
423
            PluginServices.getMDIManager().setWaitCursor();
424
            firstPoint = new Point2D.Double(x, y);
425
            vle.selectWithPoint(x, y, multipleSelection);
426
            PluginServices.getMDIManager().restoreCursor();
427
        }
428
        long countSelection = 0;
429
        try {
430
            countSelection =
431
                ((FeatureSelection) vle.getFeatureStore().getSelection())
432
                    .getSize();
433
        } catch (ReadException e) {
434
            LOG.error("Error reading the store", e);
435
        } catch (DataException e) {
436
            LOG.error("Error reading the store", e);
437
        }
438
        if (countSelection > 0) {
439
            nextState = "Selection.WithSelectedFeatures";
440
            return true;
441
        } else {
442
            {
443
                nextState = "Selection.SecondPoint";
444
                return true;
445
            }
446
        }
447
    }
448

    
449
    public String getType() {
450
        return type;
451
    }
452

    
453
    public void setType(String type) {
454
        if (type.equalsIgnoreCase(PluginServices.getText(this,
455
            "ComplexSelectionCADTool.outrectangle"))) {
456
            this.type = PluginServices.getText(this, "out_rectangle");
457
        } else
458
            if (type.equalsIgnoreCase(PluginServices.getText(this,
459
                "ComplexSelectionCADTool.intropolygon"))) {
460
                this.type = PluginServices.getText(this, "inside_polygon");
461
            } else
462
                if (type.equalsIgnoreCase(PluginServices.getText(this,
463
                    "ComplexSelectionCADTool.crosspolygon"))) {
464
                    this.type = PluginServices.getText(this, "cross_polygon");
465
                } else
466
                    if (type.equalsIgnoreCase(PluginServices.getText(this,
467
                        "ComplexSelectionCADTool.outpolygon"))) {
468
                        this.type = PluginServices.getText(this, "out_polygon");
469
                    } else
470
                        if (type.equalsIgnoreCase(PluginServices.getText(this,
471
                            "ComplexSelectionCADTool.introcircle"))) {
472
                            this.type =
473
                                PluginServices.getText(this, "inside_circle");
474
                        } else
475
                            if (type.equalsIgnoreCase(PluginServices.getText(
476
                                this, "ComplexSelectionCADTool.crosscircle"))) {
477
                                this.type =
478
                                    PluginServices
479
                                        .getText(this, "cross_circle");
480
                            } else
481
                                if (type.equalsIgnoreCase(PluginServices
482
                                    .getText(this,
483
                                        "ComplexSelectionCADTool.outcircle"))) {
484
                                    this.type =
485
                                        PluginServices.getText(this,
486
                                            "out_circle");
487
                                } else
488
                                    if (type.equals(PluginServices.getText(
489
                                        this, "select_all"))) {
490
                                        selectAll();
491
                                        init();
492
                                    } else {
493
                                        this.type = type;
494
                                    }
495
        pointsPolygon.clear();
496
    }
497

    
498
    public void transition(double x, double y, InputEvent event) {
499
        LOG.info("TRANSITION FROM STATE " + _fsm.getState() + " x= " + x
500
            + " y=" + y);
501
        try {
502
            _fsm.addPoint(x, y, event);
503
        } catch (Exception e) {
504
            init();
505
        }
506
        LOG.info("CURRENT STATE: " + getStatus());
507
    }
508

    
509
    public String getStatus() {
510
        try {
511
            ComplexSelectionCADToolState actualState =
512
                (ComplexSelectionCADToolState) _fsm.getPreviousState();
513
            String status = actualState.getName();
514

    
515
            return status;
516
        } catch (NullPointerException e) {
517
            return "Selection.FirstPoint";
518
        }
519
    }
520

    
521
    public void transition(String s) throws CommandException {
522
        if (!super.changeCommand(s)) {
523

    
524
            _fsm.addOption(s);
525

    
526
        }
527
    }
528

    
529
    public void transition(double d) {
530
        _fsm.addValue(d);
531
    }
532

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

    
537
    public String getNextState() {
538
        return nextState;
539
    }
540
}