Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.editing.app / org.gvsig.editing.app.mainplugin / src / main / java / org / gvsig / editing / gui / cad / tools / ComplexSelectionCADTool.java @ 40557

History | View | Annotate | Download (19.2 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.editing.gui.cad.tools;
25

    
26
import java.awt.event.InputEvent;
27
import java.awt.event.MouseEvent;
28
import java.awt.geom.Point2D;
29
import java.util.ArrayList;
30
import java.util.List;
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.editing.CADExtension;
38
import org.gvsig.editing.gui.cad.exception.CommandException;
39
import org.gvsig.editing.gui.cad.tools.smc.ComplexSelectionCADToolContext;
40
import org.gvsig.editing.gui.cad.tools.smc.ComplexSelectionCADToolContext.ComplexSelectionCADToolState;
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.FeatureSelection;
45
import org.gvsig.fmap.dal.feature.FeatureStore;
46
import org.gvsig.fmap.geom.Geometry;
47
import org.gvsig.fmap.geom.primitive.Curve;
48
import org.gvsig.fmap.geom.primitive.GeneralPathX;
49
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
50
import org.gvsig.fmap.geom.primitive.Surface;
51
import org.gvsig.fmap.mapcontrol.MapControl;
52
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
53

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

    
62
    private static final Logger LOG = LoggerFactory
63
        .getLogger(ComplexSelectionCADTool.class);
64

    
65
    protected ComplexSelectionCADToolContext _fsm;
66
    protected List pointsPolygon = new ArrayList();
67

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

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

    
83
        setType("");
84
    }
85

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

    
117
        } else if (status.equals("Selection.WithSelectedFeatures")) {
118

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
403
    public void addValue(double d) {
404

    
405
    }
406

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

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

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

    
420
        String status = actualState.getName();
421
        VectorialLayerEdited vle = getVLE();
422

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

    
451
    public String getType() {
452
        return type;
453
    }
454

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

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

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

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

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

    
526
            _fsm.addOption(s);
527

    
528
        }
529
    }
530

    
531
    public void transition(double d) {
532
        _fsm.addValue(d);
533
    }
534

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

    
539
    public String getNextState() {
540
        return nextState;
541
    }
542
}