Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extCAD / src / com / iver / cit / gvsig / gui / cad / tools / PolylineCADTool.java @ 3997

History | View | Annotate | Download (16.7 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.gui.cad.tools;
42

    
43
import java.awt.Graphics;
44
import java.awt.Graphics2D;
45
import java.awt.geom.Point2D;
46
import java.util.ArrayList;
47

    
48
import com.iver.cit.gvsig.fmap.core.FGeometryCollection;
49
import com.iver.cit.gvsig.fmap.core.FShape;
50
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
51
import com.iver.cit.gvsig.fmap.core.IGeometry;
52
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
53
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
54
import com.iver.cit.gvsig.fmap.edition.UtilFunctions;
55
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter;
56
import com.iver.cit.gvsig.gui.cad.CADTool;
57
import com.iver.cit.gvsig.gui.cad.DefaultCADTool;
58
import com.iver.cit.gvsig.gui.cad.tools.smc.PolylineCADToolContext;
59
import com.iver.cit.gvsig.gui.cad.tools.smc.PolylineCADToolContext.PolylineCADToolState;
60

    
61

    
62
/**
63
 * DOCUMENT ME!
64
 *
65
 * @author Vicente Caballero Navarro
66
 */
67
public class PolylineCADTool extends DefaultCADTool {
68
    private PolylineCADToolContext _fsm;
69
    private Point2D firstPoint;
70
    private Point2D antPoint;
71
    private Point2D antantPoint;
72
    private Point2D antCenter;
73
    private Point2D antInter;
74
    private ArrayList list = new ArrayList();
75

    
76
    /**
77
     * Crea un nuevo PolylineCADTool.
78
     */
79
    public PolylineCADTool() {
80

    
81
    }
82

    
83
    /**
84
     * M?todo de incio, para poner el c?digo de todo lo que se requiera de una
85
     * carga previa a la utilizaci?n de la herramienta.
86
     */
87
    public void init() {
88
            _fsm = new PolylineCADToolContext(this);
89
    }
90

    
91
    public void endGeometry() {
92
            IGeometry[] geoms = (IGeometry[]) list.toArray(new IGeometry[0]);
93
        FGeometryCollection fgc = new FGeometryCollection(geoms);
94
        addGeometry(fgc);
95
        _fsm = new PolylineCADToolContext(this);
96
        list.clear();
97
        antantPoint=antCenter=antInter=antPoint=firstPoint=null;
98
    }
99
    public void closeGeometry(){
100
            GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
101
                                2);
102
                elShape.moveTo(antPoint.getX(), antPoint.getY());
103
                elShape.lineTo(firstPoint.getX(), firstPoint.getY());
104

    
105
                list.add(ShapeFactory.createPolyline2D(elShape));
106
                // list.add(ShapeFactory.createPolyline2D(elShape));
107

    
108
    }
109
    /* (non-Javadoc)
110
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, double, double)
111
     */
112
    public void transition(double x, double y) {
113
        ((PolylineCADToolContext)_fsm).addPoint(x, y);
114
    }
115

    
116
    /* (non-Javadoc)
117
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, double)
118
     */
119
    public void transition(double d) {
120
        //_fsm.addValue(sel,d);
121
    }
122

    
123
    /* (non-Javadoc)
124
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, java.lang.String)
125
     */
126
    public void transition(String s) {
127
        ((PolylineCADToolContext)_fsm).addOption(s);
128
    }
129

    
130
    /**
131
     * Equivale al transition del prototipo pero sin pasarle como par?metro el
132
     * editableFeatureSource que ya estar? creado.
133
     *
134
     * @param sel Bitset con las geometr?as que est?n seleccionadas.
135
     * @param x par?metro x del punto que se pase en esta transici?n.
136
     * @param y par?metro y del punto que se pase en esta transici?n.
137
     */
138
    public void addPoint(double x, double y) {
139
            PolylineCADToolState actualState = (PolylineCADToolState) _fsm.getPreviousState();
140
        String status = actualState.getName();
141

    
142
        if (status.equals("Polyline.FirstPoint")) {
143
            antPoint = new Point2D.Double(x, y);
144

    
145
            if (firstPoint == null) {
146
                firstPoint = (Point2D) antPoint.clone();
147
            }
148
        } else if (status.equals("Polyline.NextPointOrArcOrClose")) {
149
            Point2D point = new Point2D.Double(x, y);
150

    
151
            if (antPoint != null) {
152
                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
153
                        2);
154
                elShape.moveTo(antPoint.getX(), antPoint.getY());
155
                elShape.lineTo(point.getX(), point.getY());
156
                                list.add(ShapeFactory.createPolyline2D(elShape));
157

    
158
            }
159

    
160
            if (antPoint != null) {
161
                antantPoint = antPoint;
162
            }
163

    
164
            antPoint = point;
165
        } else if (status.equals("Polyline.NextPointOrLineOrClose")) {
166
            Point2D point = new Point2D.Double(x, y);
167
            Point2D lastp = antPoint; //(Point2D)points.get(i-1);
168

    
169
            if (antantPoint == null) {
170
                antantPoint = new Point2D.Double(lastp.getX() +
171
                        (point.getX() / 2), lastp.getY() + (point.getY() / 2));
172
            }
173

    
174
            if (((point.getY() == lastp.getY()) &&
175
                    (point.getX() < lastp.getX())) ||
176
                    ((point.getX() == lastp.getX()) &&
177
                    (point.getY() < lastp.getY()))) {
178
            } else {
179
                if (point.getX() == lastp.getX()) {
180
                    point = new Point2D.Double(point.getX() + 0.00000001,
181
                            point.getY());
182
                } else if (point.getY() == lastp.getY()) {
183
                    point = new Point2D.Double(point.getX(),
184
                            point.getY() + 0.00000001);
185
                }
186

    
187
                if (point.getX() == antantPoint.getX()) {
188
                    point = new Point2D.Double(point.getX() + 0.00000001,
189
                            point.getY());
190
                } else if (point.getY() == antantPoint.getY()) {
191
                    point = new Point2D.Double(point.getX(),
192
                            point.getY() + 0.00000001);
193
                }
194

    
195
                if (!(list.size() > 0) ||
196
                        (((IGeometry) list.get(list.size() - 1)).getGeometryType() == FShape.LINE)) {
197
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(antantPoint,
198
                            lastp, lastp);
199
                    Point2D mediop = new Point2D.Double((point.getX() +
200
                            lastp.getX()) / 2, (point.getY() + lastp.getY()) / 2);
201
                    Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp,
202
                            point, mediop);
203
                    Point2D interp = UtilFunctions.getIntersection(ps1[0],
204
                            ps1[1], ps2[0], ps2[1]);
205
                    antInter = interp;
206

    
207
                    double radio = interp.distance(lastp);
208

    
209
                    if (UtilFunctions.isLowAngle(antantPoint, lastp, interp,
210
                                point)) {
211
                        radio = -radio;
212
                    }
213

    
214
                    Point2D centerp = UtilFunctions.getPoint(interp, mediop,
215
                            radio);
216
                    antCenter = centerp;
217

    
218
                    IGeometry ig = ShapeFactory.createArc(lastp, centerp, point);
219

    
220
                    if (ig != null) {
221
                        list.add(ig);
222
                    }
223
                } else {
224
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp,
225
                            antInter, lastp);
226
                    double a1 = UtilFunctions.getAngle(ps1[0], ps1[1]);
227
                    double a2 = UtilFunctions.getAngle(ps1[1], ps1[0]);
228
                    double angle = UtilFunctions.getAngle(antCenter, lastp);
229
                    Point2D ini1 = null;
230
                    Point2D ini2 = null;
231

    
232
                    if (UtilFunctions.absoluteAngleDistance(angle, a1) > UtilFunctions.absoluteAngleDistance(
233
                                angle, a2)) {
234
                        ini1 = ps1[0];
235
                        ini2 = ps1[1];
236
                    } else {
237
                        ini1 = ps1[1];
238
                        ini2 = ps1[0];
239
                    }
240

    
241
                    Point2D unit = UtilFunctions.getUnitVector(ini1, ini2);
242
                    Point2D correct = new Point2D.Double(lastp.getX() +
243
                            unit.getX(), lastp.getY() + unit.getY());
244
                    Point2D[] ps = UtilFunctions.getPerpendicular(lastp,
245
                            correct, lastp);
246
                    Point2D mediop = new Point2D.Double((point.getX() +
247
                            lastp.getX()) / 2, (point.getY() + lastp.getY()) / 2);
248
                    Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp,
249
                            point, mediop);
250
                    Point2D interp = UtilFunctions.getIntersection(ps[0],
251
                            ps[1], ps2[0], ps2[1]);
252
                    antInter = interp;
253

    
254
                    double radio = interp.distance(lastp);
255

    
256
                    if (UtilFunctions.isLowAngle(correct, lastp, interp, point)) {
257
                        radio = -radio;
258
                    }
259

    
260
                    Point2D centerp = UtilFunctions.getPoint(interp, mediop,
261
                            radio);
262
                    antCenter = centerp;
263
                    list.add(ShapeFactory.createArc(lastp, centerp, point));
264
                }
265

    
266
                antantPoint = antPoint;
267
                antPoint = point;
268
            }
269
        }
270
    }
271

    
272
    /**
273
     * M?todo para dibujar la lo necesario para el estado en el que nos
274
     * encontremos.
275
     *
276
     * @param g Graphics sobre el que dibujar.
277
     * @param selectedGeometries BitSet con las geometr?as seleccionadas.
278
     * @param x par?metro x del punto que se pase para dibujar.
279
     * @param y par?metro x del punto que se pase para dibujar.
280
     */
281
    public void drawOperation(Graphics g, double x,
282
        double y) {
283
        PolylineCADToolState actualState = ((PolylineCADToolContext)_fsm).getState();
284
        String status = actualState.getName();
285

    
286
        if (status.equals("Polyline.NextPointOrArcOrClose")) {
287
            for (int i = 0; i < list.size(); i++) {
288
                ((IGeometry) list.get(i)).cloneGeometry().draw((Graphics2D) g,
289
                    getCadToolAdapter().getMapControl().getViewPort(),
290
                    CADTool.drawingSymbol);
291
            }
292

    
293
            drawLine((Graphics2D) g, antPoint, new Point2D.Double(x, y));
294
        } else if ((status.equals("Polyline.NextPointOrLineOrClose"))) {
295
            for (int i = 0; i < list.size(); i++) {
296
                ((IGeometry) list.get(i)).cloneGeometry().draw((Graphics2D) g,
297
                    getCadToolAdapter().getMapControl().getViewPort(),
298
                    CADTool.drawingSymbol);
299
            }
300

    
301
            Point2D point = new Point2D.Double(x, y);
302
            Point2D lastp = antPoint;
303

    
304
            if (!(list.size() > 0) ||
305
                    (((IGeometry) list.get(list.size() - 1)).getGeometryType() == FShape.LINE)) {
306
                if (antantPoint == null) {
307
                    drawArc(point, lastp,
308
                        new Point2D.Double(lastp.getX() + (point.getX() / 2),
309
                            lastp.getY() + (point.getY() / 2)), g);
310
                } else {
311
                    drawArc(point, lastp, antantPoint, g);
312
                }
313
            } else {
314
                if (antInter != null) {
315
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp,
316
                            antInter, lastp);
317
                    double a1 = UtilFunctions.getAngle(ps1[0], ps1[1]);
318
                    double a2 = UtilFunctions.getAngle(ps1[1], ps1[0]);
319
                    double angle = UtilFunctions.getAngle(antCenter, lastp);
320
                    Point2D ini1 = null;
321
                    Point2D ini2 = null;
322

    
323
                    if (UtilFunctions.absoluteAngleDistance(angle, a1) > UtilFunctions.absoluteAngleDistance(
324
                                angle, a2)) {
325
                        ini1 = ps1[0];
326
                        ini2 = ps1[1];
327
                    } else {
328
                        ini1 = ps1[1];
329
                        ini2 = ps1[0];
330
                    }
331

    
332
                    Point2D unit = UtilFunctions.getUnitVector(ini1, ini2);
333
                    Point2D correct = new Point2D.Double(lastp.getX() +
334
                            unit.getX(), lastp.getY() + unit.getY());
335
                    drawArc(point, lastp, correct, g);
336
                }
337
            }
338
        }
339
    }
340

    
341
    /**
342
     * Dibuja el arco sobre el graphics.
343
     *
344
     * @param point Puntero del rat?n.
345
     * @param lastp ?ltimo punto de la polilinea.
346
     * @param antp Punto antepenultimo.
347
     * @param g Graphics sobre el que se dibuja.
348
     */
349
    private void drawArc(Point2D point, Point2D lastp, Point2D antp, Graphics g) {
350
        if (((point.getY() == lastp.getY()) && (point.getX() < lastp.getX())) ||
351
                ((point.getX() == lastp.getX()) &&
352
                (point.getY() < lastp.getY()))) {
353
        } else {
354
            if (point.getX() == lastp.getX()) {
355
                point = new Point2D.Double(point.getX() + 0.00000001,
356
                        point.getY());
357
            } else if (point.getY() == lastp.getY()) {
358
                point = new Point2D.Double(point.getX(),
359
                        point.getY() + 0.00000001);
360
            }
361

    
362
            if (point.getX() == antp.getX()) {
363
                point = new Point2D.Double(point.getX() + 0.00000001,
364
                        point.getY());
365
            } else if (point.getY() == antp.getY()) {
366
                point = new Point2D.Double(point.getX(),
367
                        point.getY() + 0.00000001);
368
            }
369

    
370
            Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp, antp, lastp);
371
            Point2D mediop = new Point2D.Double((point.getX() + lastp.getX()) / 2,
372
                    (point.getY() + lastp.getY()) / 2);
373
            Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp, point, mediop);
374
            Point2D interp = UtilFunctions.getIntersection(ps1[0], ps1[1],
375
                    ps2[0], ps2[1]);
376

    
377
            double radio = interp.distance(lastp);
378

    
379
            if (UtilFunctions.isLowAngle(antp, lastp, interp, point)) {
380
                radio = -radio;
381
            }
382

    
383
            Point2D centerp = UtilFunctions.getPoint(interp, mediop, radio);
384

    
385
            drawLine((Graphics2D) g, lastp, point);
386

    
387
            IGeometry ig = ShapeFactory.createArc(lastp, centerp, point);
388

    
389
            if (ig != null) {
390
                ig.draw((Graphics2D) g,
391
                    getCadToolAdapter().getMapControl().getViewPort(),
392
                    CADTool.modifySymbol);
393
            }
394
        }
395
    }
396

    
397
    /**
398
     * Add a diferent option.
399
     *
400
     * @param sel DOCUMENT ME!
401
     * @param s Diferent option.
402
     */
403
    public void addOption(String s) {
404
        PolylineCADToolState actualState = (PolylineCADToolState) _fsm.getPreviousState();
405
        String status = actualState.getName();
406

    
407
        if (status.equals("Polyline.NextPointOrArcOrClose")) {
408
            if (s.equals("A") || s.equals("a")) {
409
                //Arco
410
            } else if (s.equals("C") || s.equals("c")) {
411
                    GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, 2);
412
                elShape.moveTo(antPoint.getX(), antPoint.getY());
413
                elShape.lineTo(firstPoint.getX(), firstPoint.getY());
414
                list.add(ShapeFactory.createPolyline2D(elShape));
415
                    //closeGeometry();
416
            }
417
        } else if (status.equals("Polyline.NextPointOrLineOrClose")) {
418
            if (s.equals("N") || s.equals("n")) {
419
                //L?nea
420
            } else if (s.equals("C") || s.equals("c")) {
421
                    GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, 2);
422
                elShape.moveTo(antPoint.getX(), antPoint.getY());
423
                elShape.lineTo(firstPoint.getX(), firstPoint.getY());
424
                list.add(ShapeFactory.createPolyline2D(elShape));
425
                //closeGeometry();
426
            }
427
        }
428
    }
429

    
430
    /* (non-Javadoc)
431
     * @see com.iver.cit.gvsig.gui.cad.CADTool#addvalue(double)
432
     */
433
    public void addValue(double d) {
434
    }
435

    
436
    public void cancel(){
437
            list.clear();
438
            antantPoint=antCenter=antInter=antPoint=firstPoint=null;
439
    }
440
}