Statistics
| Revision:

root / branches / pilotoDWG / applications / appgvSIG / src / com / iver / cit / gvsig / gui / cad / tools / PolyLineCadTool.java @ 2288

History | View | Annotate | Download (13.6 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 com.iver.cit.gvsig.fmap.core.FGeometryCollection;
44
import com.iver.cit.gvsig.fmap.core.FShape;
45
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
46
import com.iver.cit.gvsig.fmap.core.IGeometry;
47
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
48
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
49
import com.iver.cit.gvsig.fmap.edition.EditableFeatureSource;
50
import com.iver.cit.gvsig.fmap.edition.cad.Status;
51
import com.iver.cit.gvsig.fmap.edition.cad.TrigonometricalFunctions;
52
import com.iver.cit.gvsig.fmap.layers.FBitSet;
53
import com.iver.cit.gvsig.gui.cad.CadTool;
54
import com.iver.cit.gvsig.gui.cad.automaton.Polilinea;
55

    
56
import com.iver.fsac.Automaton;
57

    
58
import java.awt.Graphics;
59
import java.awt.Graphics2D;
60
import java.awt.geom.Point2D;
61

    
62
import java.io.IOException;
63

    
64
import java.util.ArrayList;
65

    
66

    
67
/**
68
 * CadTool para crear una polilinea formada por lineas y arcos simples que se
69
 * almacenan en una GeometryCollection.
70
 *
71
 * @author Vicente Caballero Navarro
72
 */
73
public class PolyLineCadTool extends AbstractCadTool {
74
        private static Status[] STATUS = {
75
                        new Status("Precise punto inicial(x,y):"),
76
                        new Status("Precise punto siguiente(x,y), Arco(A) o Cerrar(C)"),
77
                        new Status("Precise punto siguiente(x,y), L?nea(N) o Cerrar(C)"),
78
                        new Status("Precise punto siguiente(x,y), L?nea(N) o Cerrar(C)"),
79
                        new Status("Precise punto siguiente(x,y):"),
80
                };
81
        private Polilinea polylineStatus = new Polilinea();
82
        private int antStatus = 0;
83
        private Point2D antCenter;
84
        private Point2D antInter;
85
        private ArrayList list = new ArrayList();
86
        private Point2D antPoint;
87
        private Point2D antantPoint;
88
        private Point2D firstPoint;
89

    
90
        /**
91
         * @see com.iver.cit.gvsig.fmap.edition.cad.CadTool#transition(java.lang.String,
92
         *                 com.iver.cit.gvsig.fmap.edition.EditableFeatureSource,
93
         *                 com.iver.cit.gvsig.fmap.layers.FBitSet, double[])
94
         */
95
        public int transition(String text, EditableFeatureSource editingSource,
96
                FBitSet selectedGeometries, double[] values) {
97
                int ret = polylineStatus.transition(text);
98

    
99
                int status = polylineStatus.getStatus();
100

    
101
                if (status == 0) {
102
                        antStatus = status;
103
                } else if (status == 1) {
104
                        if (values.length != 0) {
105
                                Point2D point = new Point2D.Double(values[0], values[1]);
106

    
107
                                if (firstPoint == null) {
108
                                        firstPoint = point;
109
                                }
110

    
111
                                if (antPoint != null) {
112
                                        GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
113
                                                        2);
114
                                        elShape.moveTo(antPoint.getX(), antPoint.getY());
115
                                        elShape.lineTo(point.getX(), point.getY());
116
                                        list.add(ShapeFactory.createPolyline2D(elShape));
117
                                }
118

    
119
                                if (antPoint != null) {
120
                                        antantPoint = antPoint;
121
                                }
122

    
123
                                antPoint = point;
124
                        }
125

    
126
                        antStatus = status;
127
                } else if (status == 2) {
128
                } else if (status == 3) {
129
                        Point2D point = new Point2D.Double(values[0], values[1]);
130
                        Point2D lastp = antPoint; //(Point2D)points.get(i-1);
131

    
132
                        if (antantPoint == null) {
133
                                antantPoint = new Point2D.Double(lastp.getX() +
134
                                                (point.getX() / 2), lastp.getY() + (point.getY() / 2));
135
                        }
136

    
137
                        if (((point.getY() == lastp.getY()) &&
138
                                        (point.getX() < lastp.getX())) ||
139
                                        ((point.getX() == lastp.getX()) &&
140
                                        (point.getY() < lastp.getY()))) {
141
                        } else {
142
                                if (point.getX() == lastp.getX()) {
143
                                        point = new Point2D.Double(point.getX() + 0.00000001,
144
                                                        point.getY());
145
                                } else if (point.getY() == lastp.getY()) {
146
                                        point = new Point2D.Double(point.getX(),
147
                                                        point.getY() + 0.00000001);
148
                                }
149

    
150
                                if (point.getX() == antantPoint.getX()) {
151
                                        point = new Point2D.Double(point.getX() + 0.00000001,
152
                                                        point.getY());
153
                                } else if (point.getY() == antantPoint.getY()) {
154
                                        point = new Point2D.Double(point.getX(),
155
                                                        point.getY() + 0.00000001);
156
                                }
157

    
158
                                if (!(list.size() > 0) ||
159
                                                (((IGeometry) list.get(list.size() - 1)).getGeometryType() == FShape.LINE)) {
160
                                        Point2D[] ps1 = TrigonometricalFunctions.getPerpendicular(antantPoint,
161
                                                        lastp, lastp);
162
                                        Point2D mediop = new Point2D.Double((point.getX() +
163
                                                        lastp.getX()) / 2, (point.getY() + lastp.getY()) / 2);
164
                                        Point2D[] ps2 = TrigonometricalFunctions.getPerpendicular(lastp,
165
                                                        point, mediop);
166
                                        Point2D interp = TrigonometricalFunctions.getIntersection(ps1[0],
167
                                                        ps1[1], ps2[0], ps2[1]);
168
                                        antInter = interp;
169

    
170
                                        double radio = interp.distance(lastp);
171

    
172
                                        if (TrigonometricalFunctions.isLowAngle(antantPoint, lastp,
173
                                                                interp, point)) {
174
                                                radio = -radio;
175
                                        }
176

    
177
                                        Point2D centerp = TrigonometricalFunctions.getPoint(interp,
178
                                                        mediop, radio);
179
                                        antCenter = centerp;
180

    
181
                                        IGeometry ig = ShapeFactory.createArc(lastp, centerp, point);
182

    
183
                                        if (ig != null) {
184
                                                list.add(ig);
185
                                        }
186
                                } else {
187
                                        Point2D[] ps1 = TrigonometricalFunctions.getPerpendicular(lastp,
188
                                                        antInter, lastp);
189
                                        double a1 = TrigonometricalFunctions.getAngle(ps1[0], ps1[1]);
190
                                        double a2 = TrigonometricalFunctions.getAngle(ps1[1], ps1[0]);
191
                                        double angle = TrigonometricalFunctions.getAngle(antCenter,
192
                                                        lastp);
193
                                        Point2D ini1 = null;
194
                                        Point2D ini2 = null;
195

    
196
                                        if (TrigonometricalFunctions.absoluteAngleDistance(angle, a1) > TrigonometricalFunctions.absoluteAngleDistance(
197
                                                                angle, a2)) {
198
                                                ini1 = ps1[0];
199
                                                ini2 = ps1[1];
200
                                        } else {
201
                                                ini1 = ps1[1];
202
                                                ini2 = ps1[0];
203
                                        }
204

    
205
                                        Point2D unit = TrigonometricalFunctions.getUnitVector(ini1,
206
                                                        ini2);
207
                                        Point2D correct = new Point2D.Double(lastp.getX() +
208
                                                        unit.getX(), lastp.getY() + unit.getY());
209

    
210
                                        Point2D[] ps = TrigonometricalFunctions.getPerpendicular(lastp,
211
                                                        correct, lastp);
212
                                        Point2D mediop = new Point2D.Double((point.getX() +
213
                                                        lastp.getX()) / 2, (point.getY() + lastp.getY()) / 2);
214
                                        Point2D[] ps2 = TrigonometricalFunctions.getPerpendicular(lastp,
215
                                                        point, mediop);
216
                                        Point2D interp = TrigonometricalFunctions.getIntersection(ps[0],
217
                                                        ps[1], ps2[0], ps2[1]);
218
                                        antInter = interp;
219

    
220
                                        double radio = interp.distance(lastp);
221

    
222
                                        if (TrigonometricalFunctions.isLowAngle(correct, lastp,
223
                                                                interp, point)) {
224
                                                radio = -radio;
225
                                        }
226

    
227
                                        Point2D centerp = TrigonometricalFunctions.getPoint(interp,
228
                                                        mediop, radio);
229
                                        antCenter = centerp;
230
                                        list.add(ShapeFactory.createArc(lastp, centerp, point));
231
                                }
232

    
233
                                antantPoint = antPoint;
234
                                antPoint = point;
235
                                antStatus = status;
236
                        }
237
                } else if (status == 4) {
238
                        GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
239
                                        2);
240
                        elShape.moveTo(antPoint.getX(), antPoint.getY());
241
                        elShape.lineTo(firstPoint.getX(), firstPoint.getY());
242
                        
243
                        list.add(ShapeFactory.createPolyline2D(elShape));
244
                        list.add(ShapeFactory.createPolyline2D(elShape));
245

    
246
                        IGeometry[] geoms = (IGeometry[]) list.toArray(new IGeometry[0]);
247
                        FGeometryCollection fgc = new FGeometryCollection(geoms);
248

    
249
                        try {
250
                                editingSource.addGeometry(fgc);
251
                        } catch (DriverIOException e1) {
252
                                e1.printStackTrace();
253
                        } catch (IOException e1) {
254
                                e1.printStackTrace();
255
                        }
256

    
257
                        ret = ret | polylineStatus.transition("cancel");
258
                        antStatus = status;
259
                } else if (status == 5) {
260
                        IGeometry[] geoms = (IGeometry[]) list.toArray(new IGeometry[0]);
261

    
262
                        if (geoms.length > 0) {
263
                                FGeometryCollection fgc = new FGeometryCollection(geoms);
264

    
265
                                try {
266
                                        editingSource.addGeometry(fgc);
267
                                } catch (DriverIOException e1) {
268
                                        e1.printStackTrace();
269
                                } catch (IOException e1) {
270
                                        e1.printStackTrace();
271
                                }
272
                        }
273

    
274
                        ret = ret | polylineStatus.transition("cancel");
275
                        antStatus = status;
276
                }
277

    
278
                return ret;
279
        }
280

    
281
        /*private GeneralPathX getGeneralPath(Point2D[] paux){
282
           int numPoints=paux.length;
283
           GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, 0);
284
           elShape.moveTo(paux[0].getX(), paux[0].getY());
285
           for (i = 1; i < numPoints; i++) {
286
                   Point2D p = paux[i];
287
                   elShape.lineTo(p.getX(), p.getY());
288
           }
289
           return elShape;
290
           }
291
         */
292

    
293
        /**
294
         * @see com.iver.cit.gvsig.fmap.edition.cad.CadTool#drawOperation(java.awt.Graphics,
295
         *                 com.iver.cit.gvsig.fmap.edition.EditableFeatureSource,
296
         *                 com.iver.cit.gvsig.fmap.layers.FBitSet, double, double)
297
         */
298
        public void drawOperation(Graphics g, EditableFeatureSource efs,
299
                FBitSet selectedGeometries, double x, double y) {
300
                int status = polylineStatus.getStatus();
301

    
302
                if (status == 1) {
303
                        for (int i = 0; i < list.size(); i++) {
304
                                ((IGeometry) list.get(i)).cloneGeometry().draw((Graphics2D) g,
305
                                        getCadToolAdapter().getMapControl().getViewPort(),
306
                                        CadTool.modifySymbol);
307
                        }
308

    
309
                        drawLine((Graphics2D) g, antPoint, new Point2D.Double(x, y));
310
                } else if ((status == 2) || (status == 3)) {
311
                        for (int i = 0; i < list.size(); i++) {
312
                                ((IGeometry) list.get(i)).cloneGeometry().draw((Graphics2D) g,
313
                                        getCadToolAdapter().getMapControl().getViewPort(),
314
                                        CadTool.modifySymbol);
315
                        }
316

    
317
                        Point2D point = new Point2D.Double(x, y);
318
                        Point2D lastp = antPoint;
319

    
320
                        if (!(list.size() > 0) ||
321
                                        (((IGeometry) list.get(list.size() - 1)).getGeometryType() == FShape.LINE)) {
322
                                if (antantPoint == null) {
323
                                        drawArc(point, lastp,
324
                                                new Point2D.Double(lastp.getX() + (point.getX() / 2),
325
                                                        lastp.getY() + (point.getY() / 2)), g);
326
                                } else {
327
                                        drawArc(point, lastp, antantPoint, g);
328
                                }
329
                        } else {
330
                                if (antInter != null) {
331
                                        Point2D[] ps1 = TrigonometricalFunctions.getPerpendicular(lastp,
332
                                                        antInter, lastp);
333
                                        double a1 = TrigonometricalFunctions.getAngle(ps1[0], ps1[1]);
334
                                        double a2 = TrigonometricalFunctions.getAngle(ps1[1], ps1[0]);
335
                                        double angle = TrigonometricalFunctions.getAngle(antCenter,
336
                                                        lastp);
337
                                        Point2D ini1 = null;
338
                                        Point2D ini2 = null;
339

    
340
                                        if (TrigonometricalFunctions.absoluteAngleDistance(angle, a1) > TrigonometricalFunctions.absoluteAngleDistance(
341
                                                                angle, a2)) {
342
                                                ini1 = ps1[0];
343
                                                ini2 = ps1[1];
344
                                        } else {
345
                                                ini1 = ps1[1];
346
                                                ini2 = ps1[0];
347
                                        }
348

    
349
                                        Point2D unit = TrigonometricalFunctions.getUnitVector(ini1,
350
                                                        ini2);
351
                                        Point2D correct = new Point2D.Double(lastp.getX() +
352
                                                        unit.getX(), lastp.getY() + unit.getY());
353
                                        drawArc(point, lastp, correct, g);
354
                                }
355
                        }
356
                }
357
        }
358

    
359
        /**
360
         * @see com.iver.cit.gvsig.fmap.edition.cad.CadTool#getQuestion()
361
         */
362
        public String getQuestion() {
363
                if (polylineStatus.getStatus() == -1) {
364
                        polylineStatus.initialize();
365
                }
366

    
367
                return STATUS[polylineStatus.getStatus()].getQuestion();
368
        }
369

    
370
        /**
371
         * @see com.iver.cit.gvsig.fmap.edition.cad.CadTool#initializeStatus()
372
         */
373
        public void initializeStatus() {
374
                polylineStatus.initialize();
375
                list.clear();
376
                antantPoint = antPoint = firstPoint = null;
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 = TrigonometricalFunctions.getPerpendicular(lastp,
409
                                        antp, lastp);
410
                        Point2D mediop = new Point2D.Double((point.getX() + lastp.getX()) / 2,
411
                                        (point.getY() + lastp.getY()) / 2);
412
                        Point2D[] ps2 = TrigonometricalFunctions.getPerpendicular(lastp,
413
                                        point, mediop);
414
                        Point2D interp = TrigonometricalFunctions.getIntersection(ps1[0],
415
                                        ps1[1], ps2[0], ps2[1]);
416

    
417
                        double radio = interp.distance(lastp);
418

    
419
                        if (TrigonometricalFunctions.isLowAngle(antp, lastp, interp, point)) {
420
                                radio = -radio;
421
                        }
422

    
423
                        Point2D centerp = TrigonometricalFunctions.getPoint(interp, mediop,
424
                                        radio);
425

    
426
                        drawLine((Graphics2D) g, lastp, point);
427

    
428
                        IGeometry ig = ShapeFactory.createArc(lastp, centerp, point);
429

    
430
                        if (ig != null) {
431
                                ig.draw((Graphics2D) g,
432
                                        getCadToolAdapter().getMapControl().getViewPort(),
433
                                        CadTool.modifySymbol);
434
                        }
435
                }
436
        }
437

    
438
        /**
439
         * @see com.iver.cit.gvsig.gui.cad.CadTool#getAutomaton()
440
         */
441
        public Automaton getAutomaton() {
442
                return polylineStatus;
443
        }
444

    
445
        /**
446
         * @see com.iver.cit.gvsig.gui.cad.CadTool#getName()
447
         */
448
        public String getName() {
449
                return "POLIL?NEA";
450
        }
451
}