Statistics
| Revision:

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

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

    
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

    
34
import org.gvsig.andami.PluginServices;
35
import org.gvsig.andami.messages.NotificationManager;
36
import org.gvsig.editing.CADExtension;
37
import org.gvsig.editing.gui.cad.exception.CommandException;
38
import org.gvsig.editing.gui.cad.tools.smc.ComplexSelectionCADToolContext;
39
import org.gvsig.editing.gui.cad.tools.smc.ComplexSelectionCADToolContext.ComplexSelectionCADToolState;
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.Feature;
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.handler.Handler;
48
import org.gvsig.fmap.geom.primitive.Curve;
49
import org.gvsig.fmap.geom.primitive.GeneralPathX;
50
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
51
import org.gvsig.fmap.geom.primitive.Surface;
52
import org.gvsig.fmap.mapcontrol.MapControl;
53
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
54

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

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

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

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

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

    
84
        setType("");
85
    }
86

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

    
119
            } else
120
                if (status.equals("Selection.WithSelectedFeatures")) {
121

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

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

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

    
171
    public long selectWithPolygon(Geometry polygon) {
172
        VectorialLayerEdited vle = getVLE();
173
        PluginServices.getMDIManager().setWaitCursor();
174

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

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

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

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

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

    
283
    /**
284
     * Draw method to draw a geometry with handlers
285
     * 
286
     * @param mapControlDrawer
287
     *            object used to draw.
288
     * @param x
289
     *            selected x coordinate.
290
     * @param y
291
     *            selected y coordinate.
292
     * @param selectedHandlers
293
     *            the selected handlers
294
     */
295
    private void drawWithHandlers(MapControlDrawer mapControlDrawer, double x,
296
        double y, ArrayList selectedHandlers) {
297
        // Movemos los handlers que hemos seleccionado
298
        // previamente dentro del m?todo select()
299
        double xPrev = 0;
300
        double yPrev = 0;
301
        for (int k = 0; k < selectedHandlers.size(); k++) {
302
            Handler h = (Handler) selectedHandlers.get(k);
303
            xPrev = h.getPoint().getX();
304
            yPrev = h.getPoint().getY();
305
            h.set(x, y);
306
        }
307
        // Y una vez movidos los v?rtices (handles)
308
        // redibujamos la nueva geometr?a.
309
        for (int i = 0; i < rowselectedHandlers.size(); i++) {
310
            Feature rowEd = (Feature) rowselectedHandlers.get(i);
311
            Geometry geom = (rowEd.getDefaultGeometry()).cloneGeometry();
312
            mapControlDrawer.setColor(Color.gray);
313
            mapControlDrawer.draw(geom,
314
                mapControlManager.getAxisReferenceSymbol());
315
        }
316
        for (int k = 0; k < selectedHandlers.size(); k++) {
317
            Handler h = (Handler) selectedHandlers.get(k);
318
            h.set(xPrev, yPrev);
319
        }
320
    }
321

    
322
    /**
323
     * Draw method for the second point of the "circle" option
324
     * 
325
     * @param mapControlDrawer
326
     *            object used to draw.
327
     * @param x
328
     *            selected x coordinate.
329
     * @param y
330
     *            selected y coordinate.
331
     */
332
    private void drawSecondPointCircle(MapControlDrawer mapControlDrawer,
333
        double x, double y) {
334
        Geometry circle = createCircle(firstPoint, new Point2D.Double(x, y));
335
        GeneralPathX gpx = new GeneralPathX();
336
        gpx.append(circle.getInternalShape().getPathIterator(null), true);
337
        Geometry circleSel = createCurve(gpx);
338
        // Draw the circle
339
        mapControlDrawer.draw(circleSel,
340
            mapControlManager.getGeometrySelectionSymbol());
341
    }
342

    
343
    /**
344
     * Add a diferent option.
345
     * 
346
     * @param sel
347
     *            DOCUMENT ME!
348
     * @param s
349
     *            Diferent option.
350
     */
351
    public void addOption(String s) {
352
        ComplexSelectionCADToolState actualState =
353
            (ComplexSelectionCADToolState) _fsm.getPreviousState();
354
        String status = actualState.getName();
355
        LOG.info("PREVIOUSSTATE =" + status);
356
        LOG.info("STATUS ACTUAL = " + _fsm.getTransition());
357
        if (s.equals(PluginServices.getText(this, "cancel"))) {
358
            init();
359
            try {
360
                clearSelection();
361
            } catch (DataException e) {
362
                LOG.error("Error canceling the selection", e);
363
            }
364
            return;
365
        } else
366
            if (s.equals(PluginServices.getText(this, "select_all"))) {
367
                // The selct all is made in the context
368
                init();
369
                return;
370
            }
371
        if (status.equals("Selection.FirstPoint")) {
372
            setType(s);
373
            return;
374
        } else
375
            if (status.equals("Selection.NextPointPolygon")) {
376
                if (s.equals(PluginServices.getText(this, "end_polygon"))
377
                    || s.equalsIgnoreCase(PluginServices.getText(this,
378
                        "ComplexSelectionCADTool.end"))) {
379
                    selectCurrentSurface();
380
                    return;
381
                }
382
            }
383
        init();
384
    }
385

    
386
    public long selectCurrentSurface() {
387
        Geometry surface =
388
            createOrientablePrimitive(null, Geometry.TYPES.SURFACE);
389
        GeneralPathX gpx = new GeneralPathX();
390
        gpx.append(surface.getPathIterator(null), true);
391
        if (gpx.isCCW()) {
392
            gpx.flip();
393
            surface = createSurface(gpx);
394
        }
395
        pointsPolygon.clear();
396
        return selectWithPolygon(surface);
397
    }
398

    
399
    public long selectAll() {
400
        VectorialLayerEdited vle = getVLE();
401
        PluginServices.getMDIManager().setWaitCursor();
402
        vle.selectAll();
403
        long countSelection = 0;
404
        try {
405
            countSelection =
406
                ((FeatureSelection) vle.getFeatureStore().getSelection())
407
                    .getSize();
408
        } catch (ReadException e) {
409
            LOG.error("Error reading the store", e);
410
        } catch (DataException e) {
411
            LOG.error("Error reading the store", e);
412
        }
413
        PluginServices.getMDIManager().restoreCursor();
414
        if (countSelection > 0) {
415
            nextState = "Selection.WithSelectedFeatures";
416
        } else {
417
            nextState = "Selection.FirstPoint";
418
        }
419
        end();
420
        return countSelection;
421
    }
422

    
423
    private OrientablePrimitive createOrientablePrimitive(Point2D p,
424
        int geometryType) {
425
        Point2D[] points = (Point2D[]) pointsPolygon.toArray(new Point2D[0]);
426
        OrientablePrimitive orientablePrimitive =
427
            createOrientablePrimitive(geometryType);
428

    
429
        for (int i = 0; i < points.length; i++) {
430
            if (i == 0) {
431
                orientablePrimitive.addMoveToVertex(createPoint(
432
                    points[i].getX(), points[i].getY()));
433
            } else {
434
                orientablePrimitive.addVertex(createPoint(points[i].getX(),
435
                    points[i].getY()));
436
            }
437
        }
438
        if (p != null) {
439
            orientablePrimitive.addVertex(createPoint(p.getX(), p.getY()));
440
        }
441
        orientablePrimitive.closePrimitive();
442
        return orientablePrimitive;
443
    }
444

    
445
    public void addValue(double d) {
446

    
447
    }
448

    
449
    public void end() {
450
        if (!getNextTool().equals("complex_selection")) {
451
            CADExtension.setCADTool(getNextTool(), false);
452
        }
453
    }
454

    
455
    public String getName() {
456
        return PluginServices.getText(this, "complex_selection_");
457
    }
458

    
459
    public boolean selectFeatures(double x, double y, InputEvent event) {
460
        ComplexSelectionCADToolState actualState = _fsm.getState();
461

    
462
        String status = actualState.getName();
463
        VectorialLayerEdited vle = getVLE();
464

    
465
        if ((status.equals("Selection.FirstPoint"))
466
            || (status.equals("Selection.WithSelectedFeatures"))) {
467
            PluginServices.getMDIManager().setWaitCursor();
468
            firstPoint = new Point2D.Double(x, y);
469
            vle.selectWithPoint(x, y, multipleSelection);
470
            PluginServices.getMDIManager().restoreCursor();
471
        }
472
        long countSelection = 0;
473
        try {
474
            countSelection =
475
                ((FeatureSelection) vle.getFeatureStore().getSelection())
476
                    .getSize();
477
        } catch (ReadException e) {
478
            LOG.error("Error reading the store", e);
479
        } catch (DataException e) {
480
            LOG.error("Error reading the store", e);
481
        }
482
        if (countSelection > 0) {
483
            nextState = "Selection.WithSelectedFeatures";
484
            return true;
485
        } else {
486
            {
487
                nextState = "Selection.SecondPoint";
488
                return true;
489
            }
490
        }
491
    }
492

    
493
    public String getType() {
494
        return type;
495
    }
496

    
497
    public void setType(String type) {
498
        if (type.equalsIgnoreCase(PluginServices.getText(this,
499
            "ComplexSelectionCADTool.outrectangle"))) {
500
            this.type = PluginServices.getText(this, "out_rectangle");
501
        } else
502
            if (type.equalsIgnoreCase(PluginServices.getText(this,
503
                "ComplexSelectionCADTool.intropolygon"))) {
504
                this.type = PluginServices.getText(this, "inside_polygon");
505
            } else
506
                if (type.equalsIgnoreCase(PluginServices.getText(this,
507
                    "ComplexSelectionCADTool.crosspolygon"))) {
508
                    this.type = PluginServices.getText(this, "cross_polygon");
509
                } else
510
                    if (type.equalsIgnoreCase(PluginServices.getText(this,
511
                        "ComplexSelectionCADTool.outpolygon"))) {
512
                        this.type = PluginServices.getText(this, "out_polygon");
513
                    } else
514
                        if (type.equalsIgnoreCase(PluginServices.getText(this,
515
                            "ComplexSelectionCADTool.introcircle"))) {
516
                            this.type =
517
                                PluginServices.getText(this, "inside_circle");
518
                        } else
519
                            if (type.equalsIgnoreCase(PluginServices.getText(
520
                                this, "ComplexSelectionCADTool.crosscircle"))) {
521
                                this.type =
522
                                    PluginServices
523
                                        .getText(this, "cross_circle");
524
                            } else
525
                                if (type.equalsIgnoreCase(PluginServices
526
                                    .getText(this,
527
                                        "ComplexSelectionCADTool.outcircle"))) {
528
                                    this.type =
529
                                        PluginServices.getText(this,
530
                                            "out_circle");
531
                                } else
532
                                    if (type.equals(PluginServices.getText(
533
                                        this, "select_all"))) {
534
                                        selectAll();
535
                                        init();
536
                                    } else {
537
                                        this.type = type;
538
                                    }
539
        pointsPolygon.clear();
540
    }
541

    
542
    public void transition(double x, double y, InputEvent event) {
543
        LOG.info("TRANSITION FROM STATE " + _fsm.getState() + " x= " + x
544
            + " y=" + y);
545
        try {
546
            _fsm.addPoint(x, y, event);
547
        } catch (Exception e) {
548
            init();
549
        }
550
        LOG.info("CURRENT STATE: " + getStatus());
551
    }
552

    
553
    public String getStatus() {
554
        try {
555
            ComplexSelectionCADToolState actualState =
556
                (ComplexSelectionCADToolState) _fsm.getPreviousState();
557
            String status = actualState.getName();
558

    
559
            return status;
560
        } catch (NullPointerException e) {
561
            return "Selection.FirstPoint";
562
        }
563
    }
564

    
565
    public void transition(String s) throws CommandException {
566
        if (!super.changeCommand(s)) {
567

    
568
            _fsm.addOption(s);
569

    
570
        }
571
    }
572

    
573
    public void transition(double d) {
574
        _fsm.addValue(d);
575
    }
576

    
577
    public String toString() {
578
        return "_complex_selection";
579
    }
580

    
581
    public String getNextState() {
582
        return nextState;
583
    }
584
}