Statistics
| Revision:

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

History | View | Annotate | Download (18.9 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.hardcode.gdbms.driver.exceptions.ReadDriverException;
50
import com.iver.andami.PluginServices;
51
import com.iver.cit.gvsig.fmap.core.FGeometryCollection;
52
import com.iver.cit.gvsig.fmap.core.FShape;
53
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
54
import com.iver.cit.gvsig.fmap.core.IGeometry;
55
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
56
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
57
import com.iver.cit.gvsig.fmap.edition.UtilFunctions;
58
import com.iver.cit.gvsig.gui.cad.DefaultCADTool;
59
import com.iver.cit.gvsig.gui.cad.exception.CommandException;
60
import com.iver.cit.gvsig.gui.cad.tools.smc.PolylineCADToolContext;
61
import com.iver.cit.gvsig.gui.cad.tools.smc.PolylineCADToolContext.PolylineCADToolState;
62

    
63

    
64
/**
65
 * DOCUMENT ME!
66
 *
67
 * @author Vicente Caballero Navarro
68
 */
69
public class PolylineCADTool extends DefaultCADTool {
70
        private PolylineCADToolContext _fsm;
71
    private Point2D firstPoint;
72
    private Point2D antPoint;
73
    private Point2D antantPoint;
74
    private Point2D antCenter;
75
    private Point2D antInter;
76
    private ArrayList list = new ArrayList();
77
        private boolean close=false;
78
        private GeneralPathX gpx = null;
79

    
80
    /**
81
     * Crea un nuevo PolylineCADTool.
82
     */
83
    public PolylineCADTool() {
84

    
85
    }
86

    
87
    /**
88
     * M?todo de incio, para poner el c?digo de todo lo que se requiera de una
89
     * carga previa a la utilizaci?n de la herramienta.
90
     */
91
    public void init() {
92
        _fsm = new PolylineCADToolContext(this);
93
    }
94
    public IGeometry getGeometry() {
95
                IGeometry[] geoms = (IGeometry[]) list.toArray(new IGeometry[0]);
96
                FGeometryCollection fgc = new FGeometryCollection(geoms);
97
                // No queremos guardar FGeometryCollections:
98
                GeneralPathX gp = new GeneralPathX();
99
                gp.append(fgc.getPathIterator(null, FConverter.FLATNESS), true);
100
                IGeometry newGeom = ShapeFactory.createPolyline2D(gp);
101
                return newGeom;
102
        }
103
    public void endGeometry() {
104
            if (gpx==null) {
105
                    gpx=new GeneralPathX();
106
                    IGeometry[] geoms = (IGeometry[]) list.toArray(new IGeometry[0]);
107
                    FGeometryCollection fgc = new FGeometryCollection(geoms);
108
                    // No queremos guardar FGeometryCollections:
109
                    gpx.append(fgc.getPathIterator(null,FConverter.FLATNESS), true);
110
            }
111
        try {
112
                         if (getVLE().getVEA().getShapeType()==FShape.POLYGON && !close){
113
                                 closeGeometry();
114
                         }
115
                 } catch (ReadDriverException e) {
116
                        // TODO Auto-generated catch block
117
                        e.printStackTrace();
118
                }
119

    
120
        IGeometry newGeom = null;
121
        int type=getCadToolAdapter().getActiveLayerType();
122
        if (type==FShape.POLYGON){
123
                newGeom = ShapeFactory.createPolygon2D(gpx);
124
        }else{
125
                newGeom = ShapeFactory.createPolyline2D(gpx);
126
        }
127
        addGeometry(newGeom);
128
        _fsm = new PolylineCADToolContext(this);
129
        list.clear();
130
        close=false;
131
        gpx=null;
132
        antantPoint=antCenter=antInter=antPoint=firstPoint=null;
133
    }
134
    public void closeGeometry(){
135
            if (gpx==null) {
136
                    gpx=new GeneralPathX();
137
                    IGeometry[] geoms = (IGeometry[]) list.toArray(new IGeometry[0]);
138
                    FGeometryCollection fgc = new FGeometryCollection(geoms);
139
                    // No queremos guardar FGeometryCollections:
140
                    gpx.append(fgc.getPathIterator(null,FConverter.FLATNESS), true);
141
            }
142
            close=true;
143
            gpx.closePath();
144
    }
145
    /* (non-Javadoc)
146
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, double, double)
147
     */
148
    public void transition(double x, double y, InputEvent event) {
149
        _fsm.addPoint(x, y, event);
150
    }
151

    
152
    /* (non-Javadoc)
153
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, double)
154
     */
155
    public void transition(double d) {
156
        _fsm.addValue(d);
157
    }
158

    
159
    /* (non-Javadoc)
160
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, java.lang.String)
161
     */
162
    public void transition(String s) throws CommandException {
163
        if (!super.changeCommand(s)){
164
            _fsm.addOption(s);
165
        }
166
    }
167

    
168
    /**
169
     * Equivale al transition del prototipo pero sin pasarle como par?metro el
170
     * editableFeatureSource que ya estar? creado.
171
     *
172
     * @param sel Bitset con las geometr?as que est?n seleccionadas.
173
     * @param x par?metro x del punto que se pase en esta transici?n.
174
     * @param y par?metro y del punto que se pase en esta transici?n.
175
     */
176
    public void addPoint(double x, double y,InputEvent event) {
177
        PolylineCADToolState actualState = (PolylineCADToolState) _fsm.getPreviousState();
178
        String status = actualState.getName();
179
        if (status.equals("Polyline.NextPointOrArcOrClose") || status.equals("Polyline.FirstPoint")) {
180

    
181
           if (firstPoint == null) {
182
               firstPoint = new Point2D.Double(x, y);
183
           }
184
                Point2D point = new Point2D.Double(x, y);
185

    
186
            if (antPoint != null) {
187
                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
188
                        2);
189
                elShape.moveTo(antPoint.getX(), antPoint.getY());
190
                elShape.lineTo(point.getX(), point.getY());
191
                list.add(ShapeFactory.createPolyline2D(elShape));
192

    
193
            }
194
            if (antPoint==null)
195
                    antPoint = (Point2D)firstPoint.clone();
196

    
197
            if (antPoint != null) {
198
                antantPoint = antPoint;
199
            }
200

    
201
            antPoint = point;
202
        } else if (status.equals("Polyline.NextPointOrLineOrClose")) {
203
            Point2D point = new Point2D.Double(x, y);
204
            Point2D lastp = antPoint; //(Point2D)points.get(i-1);
205

    
206
            if (antantPoint == null) {
207
                antantPoint = new Point2D.Double(lastp.getX() +
208
                        (point.getX() / 2), lastp.getY() + (point.getY() / 2));
209
            }
210

    
211
            if (((point.getY() == lastp.getY()) &&
212
                    (point.getX() < lastp.getX())) ||
213
                    ((point.getX() == lastp.getX()) &&
214
                    (point.getY() < lastp.getY()))) {
215
            } else {
216
                if (point.getX() == lastp.getX()) {
217
                    point = new Point2D.Double(point.getX() + 0.00000001,
218
                            point.getY());
219
                } else if (point.getY() == lastp.getY()) {
220
                    point = new Point2D.Double(point.getX(),
221
                            point.getY() + 0.00000001);
222
                }
223

    
224
                if (point.getX() == antantPoint.getX()) {
225
                    point = new Point2D.Double(point.getX() + 0.00000001,
226
                            point.getY());
227
                } else if (point.getY() == antantPoint.getY()) {
228
                    point = new Point2D.Double(point.getX(),
229
                            point.getY() + 0.00000001);
230
                }
231

    
232
                if (!(list.size() > 0) ||
233
                        (((IGeometry) list.get(list.size() - 1)).getGeometryType() == FShape.LINE)) {
234
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(antantPoint,
235
                            lastp, lastp);
236
                    Point2D mediop = new Point2D.Double((point.getX() +
237
                            lastp.getX()) / 2, (point.getY() + lastp.getY()) / 2);
238
                    Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp,
239
                            point, mediop);
240
                    Point2D interp = UtilFunctions.getIntersection(ps1[0],
241
                            ps1[1], ps2[0], ps2[1]);
242
                    antInter = interp;
243

    
244
                    double radio = interp.distance(lastp);
245

    
246
                    if (UtilFunctions.isLowAngle(antantPoint, lastp, interp,
247
                                point)) {
248
                        radio = -radio;
249
                    }
250

    
251
                    Point2D centerp = UtilFunctions.getPoint(interp, mediop,
252
                            radio);
253
                    antCenter = centerp;
254

    
255
                    IGeometry ig = ShapeFactory.createArc(lastp, centerp, point);
256

    
257
                    if (ig != null) {
258
                        list.add(ig);
259
                    }
260
                } else {
261
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp,
262
                            antInter, lastp);
263
                    double a1 = UtilFunctions.getAngle(ps1[0], ps1[1]);
264
                    double a2 = UtilFunctions.getAngle(ps1[1], ps1[0]);
265
                    double angle = UtilFunctions.getAngle(antCenter, lastp);
266
                    Point2D ini1 = null;
267
                    Point2D ini2 = null;
268

    
269
                    if (UtilFunctions.absoluteAngleDistance(angle, a1) > UtilFunctions.absoluteAngleDistance(
270
                                angle, a2)) {
271
                        ini1 = ps1[0];
272
                        ini2 = ps1[1];
273
                    } else {
274
                        ini1 = ps1[1];
275
                        ini2 = ps1[0];
276
                    }
277

    
278
                    Point2D unit = UtilFunctions.getUnitVector(ini1, ini2);
279
                    Point2D correct = new Point2D.Double(lastp.getX() +
280
                            unit.getX(), lastp.getY() + unit.getY());
281
                    Point2D[] ps = UtilFunctions.getPerpendicular(lastp,
282
                            correct, lastp);
283
                    Point2D mediop = new Point2D.Double((point.getX() +
284
                            lastp.getX()) / 2, (point.getY() + lastp.getY()) / 2);
285
                    Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp,
286
                            point, mediop);
287
                    Point2D interp = UtilFunctions.getIntersection(ps[0],
288
                            ps[1], ps2[0], ps2[1]);
289
                    antInter = interp;
290

    
291
                    double radio = interp.distance(lastp);
292

    
293
                    if (UtilFunctions.isLowAngle(correct, lastp, interp, point)) {
294
                        radio = -radio;
295
                    }
296

    
297
                    Point2D centerp = UtilFunctions.getPoint(interp, mediop,
298
                            radio);
299
                    antCenter = centerp;
300
                    list.add(ShapeFactory.createArc(lastp, centerp, point));
301
                }
302

    
303
                antantPoint = antPoint;
304
                antPoint = point;
305
            }
306
        }
307
    }
308

    
309
    /**
310
     * M?todo para dibujar la lo necesario para el estado en el que nos
311
     * encontremos.
312
     *
313
     * @param g Graphics sobre el que dibujar.
314
     * @param selectedGeometries BitSet con las geometr?as seleccionadas.
315
     * @param x par?metro x del punto que se pase para dibujar.
316
     * @param y par?metro x del punto que se pase para dibujar.
317
     */
318
    public void drawOperation(Graphics g, double x,
319
        double y) {
320
        PolylineCADToolState actualState = _fsm.getState();
321
        String status = actualState.getName();
322

    
323
        if (status.equals("Polyline.NextPointOrArcOrClose") || status.equals("Polyline.FirstPoint")) {
324
            for (int i = 0; i < list.size(); i++) {
325
                ((IGeometry) list.get(i)).cloneGeometry().draw((Graphics2D) g,
326
                    getCadToolAdapter().getMapControl().getViewPort(),
327
                     DefaultCADTool.geometrySelectSymbol);
328
            }
329
            if (antPoint!=null)
330
                    drawLine((Graphics2D) g, antPoint, new Point2D.Double(x, y),DefaultCADTool.geometrySelectSymbol);
331

    
332
        } else if ((status.equals("Polyline.NextPointOrLineOrClose"))) {
333
            for (int i = 0; i < list.size(); i++) {
334
                ((IGeometry) list.get(i)).cloneGeometry().draw((Graphics2D) g,
335
                    getCadToolAdapter().getMapControl().getViewPort(),
336
                     DefaultCADTool.geometrySelectSymbol);
337
            }
338

    
339
            Point2D point = new Point2D.Double(x, y);
340
            Point2D lastp = antPoint;
341

    
342
            if (!(list.size() > 0) ||
343
                    (((IGeometry) list.get(list.size() - 1)).getGeometryType() == FShape.LINE)) {
344
                if (antantPoint == null) {
345
                    drawArc(point, lastp,
346
                        new Point2D.Double(lastp.getX() + (point.getX() / 2),
347
                            lastp.getY() + (point.getY() / 2)), g);
348
                } else {
349
                    drawArc(point, lastp, antantPoint, g);
350
                }
351
            } else {
352
                if (antInter != null) {
353
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp,
354
                            antInter, lastp);
355
                    double a1 = UtilFunctions.getAngle(ps1[0], ps1[1]);
356
                    double a2 = UtilFunctions.getAngle(ps1[1], ps1[0]);
357
                    double angle = UtilFunctions.getAngle(antCenter, lastp);
358
                    Point2D ini1 = null;
359
                    Point2D ini2 = null;
360

    
361
                    if (UtilFunctions.absoluteAngleDistance(angle, a1) > UtilFunctions.absoluteAngleDistance(
362
                                angle, a2)) {
363
                        ini1 = ps1[0];
364
                        ini2 = ps1[1];
365
                    } else {
366
                        ini1 = ps1[1];
367
                        ini2 = ps1[0];
368
                    }
369

    
370
                    Point2D unit = UtilFunctions.getUnitVector(ini1, ini2);
371
                    Point2D correct = new Point2D.Double(lastp.getX() +
372
                            unit.getX(), lastp.getY() + unit.getY());
373
                    drawArc(point, lastp, correct, g);
374
                }
375
            }
376
        }
377
    }
378

    
379
    /**
380
     * Dibuja el arco sobre el graphics.
381
     *
382
     * @param point Puntero del rat?n.
383
     * @param lastp ?ltimo punto de la polilinea.
384
     * @param antp Punto antepenultimo.
385
     * @param g Graphics sobre el que se dibuja.
386
     */
387
    private void drawArc(Point2D point, Point2D lastp, Point2D antp, Graphics g) {
388
        if (((point.getY() == lastp.getY()) && (point.getX() < lastp.getX())) ||
389
                ((point.getX() == lastp.getX()) &&
390
                (point.getY() < lastp.getY()))) {
391
        } else {
392
            if (point.getX() == lastp.getX()) {
393
                point = new Point2D.Double(point.getX() + 0.00000001,
394
                        point.getY());
395
            } else if (point.getY() == lastp.getY()) {
396
                point = new Point2D.Double(point.getX(),
397
                        point.getY() + 0.00000001);
398
            }
399

    
400
            if (point.getX() == antp.getX()) {
401
                point = new Point2D.Double(point.getX() + 0.00000001,
402
                        point.getY());
403
            } else if (point.getY() == antp.getY()) {
404
                point = new Point2D.Double(point.getX(),
405
                        point.getY() + 0.00000001);
406
            }
407

    
408
            Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp, antp, lastp);
409
            Point2D mediop = new Point2D.Double((point.getX() + lastp.getX()) / 2,
410
                    (point.getY() + lastp.getY()) / 2);
411
            Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp, point, mediop);
412
            Point2D interp = UtilFunctions.getIntersection(ps1[0], ps1[1],
413
                    ps2[0], ps2[1]);
414

    
415
            double radio = interp.distance(lastp);
416

    
417
            if (UtilFunctions.isLowAngle(antp, lastp, interp, point)) {
418
                radio = -radio;
419
            }
420

    
421
            Point2D centerp = UtilFunctions.getPoint(interp, mediop, radio);
422

    
423
            drawLine((Graphics2D) g, lastp, point,DefaultCADTool.geometrySelectSymbol);
424

    
425
            IGeometry ig = ShapeFactory.createArc(lastp, centerp, point);
426

    
427
            if (ig != null) {
428
                ig.draw((Graphics2D) g,
429
                    getCadToolAdapter().getMapControl().getViewPort(),
430
                      DefaultCADTool.axisReferencesSymbol);
431
            }
432
        }
433
    }
434

    
435
    /**
436
     * Add a diferent option.
437
     *
438
     * @param sel DOCUMENT ME!
439
     * @param s Diferent option.
440
     */
441
    public void addOption(String s) {
442
            /*       PolylineCADToolState actualState = (PolylineCADToolState) _fsm.getPreviousState();
443
        String status = actualState.getName();
444

445
        if (status.equals("Polyline.NextPointOrArcOrClose")) {
446
            if (s.equals("A") || s.equals("a") || s.equals(PluginServices.getText(this,"inter_arc"))) {
447
                //Arco
448
            } else if (s.equals("C") || s.equals("c")) {
449
                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, 2);
450
                elShape.moveTo(antPoint.getX(), antPoint.getY());
451
                elShape.lineTo(firstPoint.getX(), firstPoint.getY());
452
                list.add(ShapeFactory.createPolyline2D(elShape));
453
                //closeGeometry();
454
            }
455
        } else if (status.equals("Polyline.NextPointOrLineOrClose")) {
456
            if (s.equals("N") || s.equals("n") || s.equals(PluginServices.getText(this,"inter_line"))) {
457
                //L?nea
458
            } else if (s.equals("C") || s.equals("c")) {
459
                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, 2);
460
                elShape.moveTo(antPoint.getX(), antPoint.getY());
461
                elShape.lineTo(firstPoint.getX(), firstPoint.getY());
462
                list.add(ShapeFactory.createPolyline2D(elShape));
463
                //closeGeometry();
464
            }
465
        }
466
  */
467
    }
468

    
469
    /* (non-Javadoc)
470
     * @see com.iver.cit.gvsig.gui.cad.CADTool#addvalue(double)
471
     */
472
    public void addValue(double d) {
473
    }
474

    
475
    public void cancel(){
476
        //endGeometry();
477
        list.clear();
478
        antantPoint=antCenter=antInter=antPoint=firstPoint=null;
479
    }
480

    
481
    public void end() {
482
        /* CADExtension.setCADTool("polyline");
483
        PluginServices.getMainFrame().setSelectedTool("POLYLINE"); */
484
    }
485

    
486
    public String getName() {
487
        return PluginServices.getText(this,"polyline_");
488
    }
489

    
490
    public String toString() {
491
        return "_polyline";
492
    }
493
    public boolean isApplicable(int shapeType) {
494
        switch (shapeType) {
495
        case FShape.POINT:
496
        case FShape.MULTIPOINT:
497
            return false;
498
        }
499
        return true;
500
    }
501
}