Statistics
| Revision:

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

History | View | Annotate | Download (16.8 KB)

1 3765 caballero
/* 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 3782 caballero
package com.iver.cit.gvsig.gui.cad.tools;
42
43 3832 caballero
import java.awt.Graphics;
44
import java.awt.Graphics2D;
45 4313 fjp
import java.awt.event.InputEvent;
46 3832 caballero
import java.awt.geom.Point2D;
47
import java.util.ArrayList;
48
49 3782 caballero
import com.iver.cit.gvsig.fmap.core.FGeometryCollection;
50
import com.iver.cit.gvsig.fmap.core.FShape;
51
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
52
import com.iver.cit.gvsig.fmap.core.IGeometry;
53
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
54
import com.iver.cit.gvsig.fmap.edition.UtilFunctions;
55
import com.iver.cit.gvsig.gui.cad.CADTool;
56 3832 caballero
import com.iver.cit.gvsig.gui.cad.DefaultCADTool;
57 3782 caballero
import com.iver.cit.gvsig.gui.cad.tools.smc.PolylineCADToolContext;
58
import com.iver.cit.gvsig.gui.cad.tools.smc.PolylineCADToolContext.PolylineCADToolState;
59
60
61
/**
62
 * DOCUMENT ME!
63
 *
64
 * @author Vicente Caballero Navarro
65
 */
66 3765 caballero
public class PolylineCADTool extends DefaultCADTool {
67
    private PolylineCADToolContext _fsm;
68
    private Point2D firstPoint;
69
    private Point2D antPoint;
70
    private Point2D antantPoint;
71
    private Point2D antCenter;
72 3782 caballero
    private Point2D antInter;
73
    private ArrayList list = new ArrayList();
74
75
    /**
76 3765 caballero
     * Crea un nuevo PolylineCADTool.
77
     */
78
    public PolylineCADTool() {
79 3883 caballero
80 3765 caballero
    }
81
82
    /**
83
     * M?todo de incio, para poner el c?digo de todo lo que se requiera de una
84
     * carga previa a la utilizaci?n de la herramienta.
85
     */
86
    public void init() {
87 3883 caballero
            _fsm = new PolylineCADToolContext(this);
88 3765 caballero
    }
89
90 3883 caballero
    public void endGeometry() {
91 3846 caballero
            IGeometry[] geoms = (IGeometry[]) list.toArray(new IGeometry[0]);
92
        FGeometryCollection fgc = new FGeometryCollection(geoms);
93
        addGeometry(fgc);
94 3782 caballero
        _fsm = new PolylineCADToolContext(this);
95 3883 caballero
        list.clear();
96
        antantPoint=antCenter=antInter=antPoint=firstPoint=null;
97 3765 caballero
    }
98 3883 caballero
    public void closeGeometry(){
99
            GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
100
                                2);
101
                elShape.moveTo(antPoint.getX(), antPoint.getY());
102
                elShape.lineTo(firstPoint.getX(), firstPoint.getY());
103 3765 caballero
104 3883 caballero
                list.add(ShapeFactory.createPolyline2D(elShape));
105 3997 fjp
                // list.add(ShapeFactory.createPolyline2D(elShape));
106 3883 caballero
107
    }
108 3765 caballero
    /* (non-Javadoc)
109 3782 caballero
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, double, double)
110
     */
111 4313 fjp
    public void transition(double x, double y, InputEvent event) {
112 4324 caballero
        _fsm.addPoint(x, y, event);
113 3765 caballero
    }
114
115
    /* (non-Javadoc)
116 3782 caballero
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, double)
117
     */
118 3832 caballero
    public void transition(double d) {
119 3782 caballero
        //_fsm.addValue(sel,d);
120
    }
121 3765 caballero
122 3782 caballero
    /* (non-Javadoc)
123
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, java.lang.String)
124
     */
125 3832 caballero
    public void transition(String s) {
126 4324 caballero
        _fsm.addOption(s);
127 3782 caballero
    }
128
129 3765 caballero
    /**
130
     * Equivale al transition del prototipo pero sin pasarle como par?metro el
131
     * editableFeatureSource que ya estar? creado.
132
     *
133
     * @param sel Bitset con las geometr?as que est?n seleccionadas.
134
     * @param x par?metro x del punto que se pase en esta transici?n.
135
     * @param y par?metro y del punto que se pase en esta transici?n.
136
     */
137 4365 caballero
    public void addPoint(double x, double y,InputEvent event) {
138 3883 caballero
            PolylineCADToolState actualState = (PolylineCADToolState) _fsm.getPreviousState();
139 3765 caballero
        String status = actualState.getName();
140 3782 caballero
141 3978 caballero
        if (status.equals("Polyline.FirstPoint")) {
142 3765 caballero
            antPoint = new Point2D.Double(x, y);
143 3782 caballero
144
            if (firstPoint == null) {
145
                firstPoint = (Point2D) antPoint.clone();
146
            }
147 3978 caballero
        } else if (status.equals("Polyline.NextPointOrArcOrClose")) {
148 3782 caballero
            Point2D point = new Point2D.Double(x, y);
149 3765 caballero
150 3782 caballero
            if (antPoint != null) {
151
                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
152
                        2);
153
                elShape.moveTo(antPoint.getX(), antPoint.getY());
154
                elShape.lineTo(point.getX(), point.getY());
155 3952 fjp
                                list.add(ShapeFactory.createPolyline2D(elShape));
156 3978 caballero
157 3782 caballero
            }
158 3765 caballero
159 3782 caballero
            if (antPoint != null) {
160
                antantPoint = antPoint;
161
            }
162 3765 caballero
163 3782 caballero
            antPoint = point;
164 3978 caballero
        } else if (status.equals("Polyline.NextPointOrLineOrClose")) {
165 3782 caballero
            Point2D point = new Point2D.Double(x, y);
166
            Point2D lastp = antPoint; //(Point2D)points.get(i-1);
167 3765 caballero
168 3782 caballero
            if (antantPoint == null) {
169
                antantPoint = new Point2D.Double(lastp.getX() +
170
                        (point.getX() / 2), lastp.getY() + (point.getY() / 2));
171
            }
172 3765 caballero
173 3782 caballero
            if (((point.getY() == lastp.getY()) &&
174
                    (point.getX() < lastp.getX())) ||
175
                    ((point.getX() == lastp.getX()) &&
176
                    (point.getY() < lastp.getY()))) {
177
            } else {
178
                if (point.getX() == lastp.getX()) {
179
                    point = new Point2D.Double(point.getX() + 0.00000001,
180
                            point.getY());
181
                } else if (point.getY() == lastp.getY()) {
182
                    point = new Point2D.Double(point.getX(),
183
                            point.getY() + 0.00000001);
184
                }
185 3765 caballero
186 3782 caballero
                if (point.getX() == antantPoint.getX()) {
187
                    point = new Point2D.Double(point.getX() + 0.00000001,
188
                            point.getY());
189
                } else if (point.getY() == antantPoint.getY()) {
190
                    point = new Point2D.Double(point.getX(),
191
                            point.getY() + 0.00000001);
192
                }
193 3765 caballero
194 3782 caballero
                if (!(list.size() > 0) ||
195
                        (((IGeometry) list.get(list.size() - 1)).getGeometryType() == FShape.LINE)) {
196
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(antantPoint,
197
                            lastp, lastp);
198
                    Point2D mediop = new Point2D.Double((point.getX() +
199
                            lastp.getX()) / 2, (point.getY() + lastp.getY()) / 2);
200
                    Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp,
201
                            point, mediop);
202
                    Point2D interp = UtilFunctions.getIntersection(ps1[0],
203
                            ps1[1], ps2[0], ps2[1]);
204
                    antInter = interp;
205 3765 caballero
206 3782 caballero
                    double radio = interp.distance(lastp);
207 3765 caballero
208 3782 caballero
                    if (UtilFunctions.isLowAngle(antantPoint, lastp, interp,
209
                                point)) {
210
                        radio = -radio;
211
                    }
212 3765 caballero
213 3782 caballero
                    Point2D centerp = UtilFunctions.getPoint(interp, mediop,
214
                            radio);
215
                    antCenter = centerp;
216 3765 caballero
217 3782 caballero
                    IGeometry ig = ShapeFactory.createArc(lastp, centerp, point);
218 3765 caballero
219 3782 caballero
                    if (ig != null) {
220
                        list.add(ig);
221
                    }
222
                } else {
223
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp,
224
                            antInter, lastp);
225
                    double a1 = UtilFunctions.getAngle(ps1[0], ps1[1]);
226
                    double a2 = UtilFunctions.getAngle(ps1[1], ps1[0]);
227
                    double angle = UtilFunctions.getAngle(antCenter, lastp);
228
                    Point2D ini1 = null;
229
                    Point2D ini2 = null;
230 3765 caballero
231 3782 caballero
                    if (UtilFunctions.absoluteAngleDistance(angle, a1) > UtilFunctions.absoluteAngleDistance(
232
                                angle, a2)) {
233
                        ini1 = ps1[0];
234
                        ini2 = ps1[1];
235
                    } else {
236
                        ini1 = ps1[1];
237
                        ini2 = ps1[0];
238
                    }
239 3765 caballero
240 3782 caballero
                    Point2D unit = UtilFunctions.getUnitVector(ini1, ini2);
241
                    Point2D correct = new Point2D.Double(lastp.getX() +
242
                            unit.getX(), lastp.getY() + unit.getY());
243
                    Point2D[] ps = UtilFunctions.getPerpendicular(lastp,
244
                            correct, lastp);
245
                    Point2D mediop = new Point2D.Double((point.getX() +
246
                            lastp.getX()) / 2, (point.getY() + lastp.getY()) / 2);
247
                    Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp,
248
                            point, mediop);
249
                    Point2D interp = UtilFunctions.getIntersection(ps[0],
250
                            ps[1], ps2[0], ps2[1]);
251
                    antInter = interp;
252 3765 caballero
253 3782 caballero
                    double radio = interp.distance(lastp);
254 3765 caballero
255 3782 caballero
                    if (UtilFunctions.isLowAngle(correct, lastp, interp, point)) {
256
                        radio = -radio;
257
                    }
258 3765 caballero
259 3782 caballero
                    Point2D centerp = UtilFunctions.getPoint(interp, mediop,
260
                            radio);
261
                    antCenter = centerp;
262
                    list.add(ShapeFactory.createArc(lastp, centerp, point));
263
                }
264 3765 caballero
265 3782 caballero
                antantPoint = antPoint;
266
                antPoint = point;
267
            }
268 3765 caballero
        }
269
    }
270
271
    /**
272
     * M?todo para dibujar la lo necesario para el estado en el que nos
273
     * encontremos.
274
     *
275
     * @param g Graphics sobre el que dibujar.
276
     * @param selectedGeometries BitSet con las geometr?as seleccionadas.
277
     * @param x par?metro x del punto que se pase para dibujar.
278
     * @param y par?metro x del punto que se pase para dibujar.
279
     */
280 3832 caballero
    public void drawOperation(Graphics g, double x,
281 3765 caballero
        double y) {
282 3883 caballero
        PolylineCADToolState actualState = ((PolylineCADToolContext)_fsm).getState();
283 3765 caballero
        String status = actualState.getName();
284
285 3978 caballero
        if (status.equals("Polyline.NextPointOrArcOrClose")) {
286 3782 caballero
            for (int i = 0; i < list.size(); i++) {
287
                ((IGeometry) list.get(i)).cloneGeometry().draw((Graphics2D) g,
288
                    getCadToolAdapter().getMapControl().getViewPort(),
289 3997 fjp
                    CADTool.drawingSymbol);
290 3782 caballero
            }
291 3765 caballero
292 3782 caballero
            drawLine((Graphics2D) g, antPoint, new Point2D.Double(x, y));
293 3978 caballero
        } else if ((status.equals("Polyline.NextPointOrLineOrClose"))) {
294 3782 caballero
            for (int i = 0; i < list.size(); i++) {
295
                ((IGeometry) list.get(i)).cloneGeometry().draw((Graphics2D) g,
296
                    getCadToolAdapter().getMapControl().getViewPort(),
297 3997 fjp
                    CADTool.drawingSymbol);
298 3782 caballero
            }
299 3765 caballero
300 3782 caballero
            Point2D point = new Point2D.Double(x, y);
301
            Point2D lastp = antPoint;
302 3765 caballero
303 3782 caballero
            if (!(list.size() > 0) ||
304
                    (((IGeometry) list.get(list.size() - 1)).getGeometryType() == FShape.LINE)) {
305
                if (antantPoint == null) {
306
                    drawArc(point, lastp,
307
                        new Point2D.Double(lastp.getX() + (point.getX() / 2),
308
                            lastp.getY() + (point.getY() / 2)), g);
309
                } else {
310
                    drawArc(point, lastp, antantPoint, g);
311
                }
312
            } else {
313
                if (antInter != null) {
314
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp,
315
                            antInter, lastp);
316
                    double a1 = UtilFunctions.getAngle(ps1[0], ps1[1]);
317
                    double a2 = UtilFunctions.getAngle(ps1[1], ps1[0]);
318
                    double angle = UtilFunctions.getAngle(antCenter, lastp);
319
                    Point2D ini1 = null;
320
                    Point2D ini2 = null;
321 3765 caballero
322 3782 caballero
                    if (UtilFunctions.absoluteAngleDistance(angle, a1) > UtilFunctions.absoluteAngleDistance(
323
                                angle, a2)) {
324
                        ini1 = ps1[0];
325
                        ini2 = ps1[1];
326
                    } else {
327
                        ini1 = ps1[1];
328
                        ini2 = ps1[0];
329
                    }
330 3765 caballero
331 3782 caballero
                    Point2D unit = UtilFunctions.getUnitVector(ini1, ini2);
332
                    Point2D correct = new Point2D.Double(lastp.getX() +
333
                            unit.getX(), lastp.getY() + unit.getY());
334
                    drawArc(point, lastp, correct, g);
335
                }
336
            }
337
        }
338 3765 caballero
    }
339 3782 caballero
340 3765 caballero
    /**
341 3782 caballero
     * Dibuja el arco sobre el graphics.
342
     *
343
     * @param point Puntero del rat?n.
344
     * @param lastp ?ltimo punto de la polilinea.
345
     * @param antp Punto antepenultimo.
346
     * @param g Graphics sobre el que se dibuja.
347
     */
348
    private void drawArc(Point2D point, Point2D lastp, Point2D antp, Graphics g) {
349
        if (((point.getY() == lastp.getY()) && (point.getX() < lastp.getX())) ||
350
                ((point.getX() == lastp.getX()) &&
351
                (point.getY() < lastp.getY()))) {
352
        } else {
353
            if (point.getX() == lastp.getX()) {
354
                point = new Point2D.Double(point.getX() + 0.00000001,
355
                        point.getY());
356
            } else if (point.getY() == lastp.getY()) {
357
                point = new Point2D.Double(point.getX(),
358
                        point.getY() + 0.00000001);
359
            }
360 3765 caballero
361 3782 caballero
            if (point.getX() == antp.getX()) {
362
                point = new Point2D.Double(point.getX() + 0.00000001,
363
                        point.getY());
364
            } else if (point.getY() == antp.getY()) {
365
                point = new Point2D.Double(point.getX(),
366
                        point.getY() + 0.00000001);
367
            }
368 3765 caballero
369 3782 caballero
            Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp, antp, lastp);
370
            Point2D mediop = new Point2D.Double((point.getX() + lastp.getX()) / 2,
371
                    (point.getY() + lastp.getY()) / 2);
372
            Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp, point, mediop);
373
            Point2D interp = UtilFunctions.getIntersection(ps1[0], ps1[1],
374
                    ps2[0], ps2[1]);
375 3765 caballero
376 3782 caballero
            double radio = interp.distance(lastp);
377 3765 caballero
378 3782 caballero
            if (UtilFunctions.isLowAngle(antp, lastp, interp, point)) {
379
                radio = -radio;
380
            }
381 3765 caballero
382 3782 caballero
            Point2D centerp = UtilFunctions.getPoint(interp, mediop, radio);
383 3765 caballero
384 3782 caballero
            drawLine((Graphics2D) g, lastp, point);
385 3765 caballero
386 3782 caballero
            IGeometry ig = ShapeFactory.createArc(lastp, centerp, point);
387 3765 caballero
388 3782 caballero
            if (ig != null) {
389
                ig.draw((Graphics2D) g,
390
                    getCadToolAdapter().getMapControl().getViewPort(),
391
                    CADTool.modifySymbol);
392
            }
393
        }
394 3765 caballero
    }
395
396
    /**
397
     * Add a diferent option.
398
     *
399 3782 caballero
     * @param sel DOCUMENT ME!
400 3765 caballero
     * @param s Diferent option.
401
     */
402 3832 caballero
    public void addOption(String s) {
403 3782 caballero
        PolylineCADToolState actualState = (PolylineCADToolState) _fsm.getPreviousState();
404 3765 caballero
        String status = actualState.getName();
405 3782 caballero
406 3978 caballero
        if (status.equals("Polyline.NextPointOrArcOrClose")) {
407 3782 caballero
            if (s.equals("A") || s.equals("a")) {
408
                //Arco
409
            } else if (s.equals("C") || s.equals("c")) {
410 3846 caballero
                    GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, 2);
411
                elShape.moveTo(antPoint.getX(), antPoint.getY());
412
                elShape.lineTo(firstPoint.getX(), firstPoint.getY());
413
                list.add(ShapeFactory.createPolyline2D(elShape));
414
                    //closeGeometry();
415 3765 caballero
            }
416 3978 caballero
        } else if (status.equals("Polyline.NextPointOrLineOrClose")) {
417 3782 caballero
            if (s.equals("N") || s.equals("n")) {
418
                //L?nea
419
            } else if (s.equals("C") || s.equals("c")) {
420 3846 caballero
                    GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, 2);
421
                elShape.moveTo(antPoint.getX(), antPoint.getY());
422
                elShape.lineTo(firstPoint.getX(), firstPoint.getY());
423
                list.add(ShapeFactory.createPolyline2D(elShape));
424
                //closeGeometry();
425 3782 caballero
            }
426 3765 caballero
        }
427
    }
428
429
    /* (non-Javadoc)
430
     * @see com.iver.cit.gvsig.gui.cad.CADTool#addvalue(double)
431
     */
432 3832 caballero
    public void addValue(double d) {
433 3765 caballero
    }
434 3883 caballero
435
    public void cancel(){
436 4434 caballero
            endGeometry();
437 3883 caballero
            list.clear();
438
            antantPoint=antCenter=antInter=antPoint=firstPoint=null;
439
    }
440 4002 fjp
441
        public void end() {
442
                /* CADExtension.setCADTool("polyline");
443
            PluginServices.getMainFrame().setSelectedTool("POLYLINE"); */
444
        }
445 4118 caballero
446
        public String getName() {
447
                return "POLILINEA";
448
        }
449 3765 caballero
}