Statistics
| Revision:

root / trunk / extensions / extCAD / src / com / iver / cit / gvsig / gui / cad / tools / PolylineCADTool.java @ 4365

History | View | Annotate | Download (16.8 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.event.InputEvent;
46
import java.awt.geom.Point2D;
47
import java.util.ArrayList;
48

    
49
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
import com.iver.cit.gvsig.gui.cad.DefaultCADTool;
57
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
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
    private Point2D antInter;
73
    private ArrayList list = new ArrayList();
74

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

    
80
    }
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
            _fsm = new PolylineCADToolContext(this);
88
    }
89

    
90
    public void endGeometry() {
91
            IGeometry[] geoms = (IGeometry[]) list.toArray(new IGeometry[0]);
92
        FGeometryCollection fgc = new FGeometryCollection(geoms);
93
        addGeometry(fgc);
94
        _fsm = new PolylineCADToolContext(this);
95
        list.clear();
96
        antantPoint=antCenter=antInter=antPoint=firstPoint=null;
97
    }
98
    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

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

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

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

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

    
129
    /**
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
    public void addPoint(double x, double y,InputEvent event) {
138
            PolylineCADToolState actualState = (PolylineCADToolState) _fsm.getPreviousState();
139
        String status = actualState.getName();
140

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

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

    
150
            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
                                list.add(ShapeFactory.createPolyline2D(elShape));
156

    
157
            }
158

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

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

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

    
173
            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

    
186
                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

    
194
                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

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

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

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

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

    
219
                    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

    
231
                    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

    
240
                    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

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

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

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

    
265
                antantPoint = antPoint;
266
                antPoint = point;
267
            }
268
        }
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
    public void drawOperation(Graphics g, double x,
281
        double y) {
282
        PolylineCADToolState actualState = ((PolylineCADToolContext)_fsm).getState();
283
        String status = actualState.getName();
284

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

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

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

    
303
            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

    
322
                    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

    
331
                    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
    }
339

    
340
    /**
341
     * 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

    
361
            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

    
369
            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

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

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

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

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

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

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

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

    
406
        if (status.equals("Polyline.NextPointOrArcOrClose")) {
407
            if (s.equals("A") || s.equals("a")) {
408
                //Arco
409
            } else if (s.equals("C") || s.equals("c")) {
410
                    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
            }
416
        } else if (status.equals("Polyline.NextPointOrLineOrClose")) {
417
            if (s.equals("N") || s.equals("n")) {
418
                //L?nea
419
            } else if (s.equals("C") || s.equals("c")) {
420
                    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
            }
426
        }
427
    }
428

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

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

    
440
        public void end() {
441
                /* CADExtension.setCADTool("polyline");
442
            PluginServices.getMainFrame().setSelectedTool("POLYLINE"); */
443
        }
444

    
445
        public String getName() {
446
                return "POLILINEA";
447
        }
448
}