Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / extEditing / src / org / gvsig / editing / gui / cad / tools / PolylineCADTool.java @ 30788

History | View | Annotate | Download (20.1 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 org.gvsig.editing.gui.cad.tools;
42

    
43
import java.awt.Image;
44
import java.awt.event.InputEvent;
45
import java.awt.event.MouseEvent;
46
import java.awt.geom.Point2D;
47
import java.util.ArrayList;
48

    
49
import org.gvsig.andami.PluginServices;
50
import org.gvsig.andami.messages.NotificationManager;
51
import org.gvsig.editing.gui.cad.DefaultCADTool;
52
import org.gvsig.editing.gui.cad.exception.CommandException;
53
import org.gvsig.editing.gui.cad.tools.smc.PolylineCADToolContext;
54
import org.gvsig.editing.gui.cad.tools.smc.PolylineCADToolContext.PolylineCADToolState;
55
import org.gvsig.editing.layers.VectorialLayerEdited;
56
import org.gvsig.fmap.dal.exception.ReadException;
57
import org.gvsig.fmap.geom.Geometry;
58
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
59
import org.gvsig.fmap.geom.handler.Handler;
60
import org.gvsig.fmap.geom.operation.Draw;
61
import org.gvsig.fmap.geom.operation.GeometryOperationException;
62
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
63
import org.gvsig.fmap.geom.primitive.Curve;
64
import org.gvsig.fmap.geom.primitive.GeneralPathX;
65
import org.gvsig.fmap.geom.util.Converter;
66
import org.gvsig.fmap.geom.util.UtilFunctions;
67
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
68
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
69

    
70

    
71

    
72
/**
73
 * DOCUMENT ME!
74
 *
75
 * @author Vicente Caballero Navarro
76
 */
77
public class PolylineCADTool extends DefaultCADTool {
78
        protected PolylineCADToolContext _fsm;
79
        protected Point2D firstPoint;
80
        protected Point2D antPoint;
81
        protected Point2D antantPoint;
82
        protected Point2D antCenter;
83
        protected Point2D antInter;
84
        protected ArrayList list = new ArrayList();
85
        protected boolean close=false;
86
        protected GeneralPathX gpx = null;
87

    
88
    /**
89
     * Crea un nuevo PolylineCADTool.
90
     */
91
    public PolylineCADTool() {
92

    
93
    }
94

    
95
    /**
96
     * M?todo de incio, para poner el c?digo de todo lo que se requiera de una
97
     * carga previa a la utilizaci?n de la herramienta.
98
     */
99
    public void init() {
100
        _fsm = new PolylineCADToolContext(this);
101
    }
102
    public Geometry getGeometry() {
103
                Geometry[] geoms = (Geometry[]) list.toArray(new Geometry[0]);
104
                MultiPrimitive fgc = createMultiPrimitive(geoms);
105
                // No queremos guardar FGeometryCollections:
106
                GeneralPathX gp = new GeneralPathX();
107
                gp.append(fgc.getPathIterator(null, geomManager.getFlatness()), true);
108
                Geometry newGeom = createCurve(gp);
109
                return newGeom;
110
        }
111
    public int getLinesCount() {
112
            return list.size();
113
    }
114
    public boolean isPolygonLayer(){
115
            try {
116
                        return (((FLyrVect)getVLE().getLayer()).getShapeType()==Geometry.TYPES.SURFACE);
117
                } catch (ReadException e) {
118
                        return false;
119
                }
120
    }
121
    public void endGeometry() {
122
            if (gpx==null) {
123
                    gpx=new GeneralPathX();
124
                    Geometry[] geoms = (Geometry[]) list.toArray(new Geometry[0]);
125
                    MultiPrimitive fgc = createMultiPrimitive(geoms);
126
                    // No queremos guardar FGeometryCollections:
127
                    gpx.append(fgc.getPathIterator(null, geomManager.getFlatness()), true);
128
            }
129
        try {
130
                         if (((FLyrVect)getVLE().getLayer()).getShapeType()==Geometry.TYPES.SURFACE && !close){
131
                                 closeGeometry();
132
                         }
133
                 } catch (ReadException e) {
134
                         NotificationManager.addError(e.getMessage(),e);
135
                }
136

    
137
        Geometry newGeom = null;
138
        int type=getCadToolAdapter().getActiveLayerType();
139
        if (type==Geometry.TYPES.SURFACE){
140
                newGeom = createSurface(gpx);
141
        }else{
142
                newGeom = createCurve(gpx);
143
        }
144
        insertAndSelectGeometry(newGeom);
145
        _fsm = new PolylineCADToolContext(this);
146
        list.clear();
147
        clearTemporalCache();
148
        close=false;
149
        gpx=null;
150
        antantPoint=antCenter=antInter=antPoint=firstPoint=null;
151
    }
152
    public void closeGeometry(){
153
            if (gpx==null) {
154
                    gpx=new GeneralPathX();
155
                    Geometry[] geoms = (Geometry[]) list.toArray(new Geometry[0]);
156
                    MultiPrimitive fgc = createMultiPrimitive(geoms);
157
                    // No queremos guardar FGeometryCollections:
158
                    gpx.append(fgc.getPathIterator(null, geomManager.getFlatness()), true);
159
            }
160
            close=true;
161
            gpx.closePath();
162
    }
163
    /* (non-Javadoc)
164
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, double, double)
165
     */
166
    public void transition(double x, double y, InputEvent event) {
167
        _fsm.addPoint(x, y, event);
168
    }
169

    
170
    /* (non-Javadoc)
171
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, double)
172
     */
173
    public void transition(double d) {
174
        _fsm.addValue(d);
175
    }
176

    
177
    /* (non-Javadoc)
178
     * @see com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap.layers.FBitSet, java.lang.String)
179
     */
180
    public void transition(String s) throws CommandException {
181
        if (!super.changeCommand(s)){
182
            _fsm.addOption(s);
183
        }
184
    }
185

    
186
    /**
187
     * Equivale al transition del prototipo pero sin pasarle como par?metro el
188
     * editableFeatureSource que ya estar? creado.
189
     *
190
     * @param sel Bitset con las geometr?as que est?n seleccionadas.
191
     * @param x par?metro x del punto que se pase en esta transici?n.
192
     * @param y par?metro y del punto que se pase en esta transici?n.
193
     */
194
    public void addPoint(double x, double y,InputEvent event) {
195
        PolylineCADToolState actualState = (PolylineCADToolState) _fsm.getPreviousState();
196
        String status = actualState.getName();
197
        if (status.equals("Polyline.NextPointOrArcOrClose") || status.equals("Polyline.FirstPoint")) {
198

    
199
           if (firstPoint == null) {
200
               firstPoint = new Point2D.Double(x, y);
201
           }
202
                Point2D point = new Point2D.Double(x, y);
203

    
204
                if (antPoint != null && (antPoint.getX()!=point.getX() || antPoint.getY()!=point.getY())) {
205
                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
206
                        2);
207
                elShape.moveTo(antPoint.getX(), antPoint.getY());
208
                elShape.lineTo(point.getX(), point.getY());
209
                Geometry geom= createCurve(elShape);
210
                list.add(geom);
211
                addTemporalCache(geom);
212
            }
213
            if (antPoint==null)
214
                    antPoint = (Point2D)firstPoint.clone();
215

    
216
            if (antPoint != null) {
217
                antantPoint = antPoint;
218
            }
219

    
220
            antPoint = point;
221
        } else if (status.equals("Polyline.NextPointOrLineOrClose")) {
222
            Point2D point = new Point2D.Double(x, y);
223
            Point2D lastp = antPoint; //(Point2D)points.get(i-1);
224

    
225
            if (antantPoint == null) {
226
                antantPoint = new Point2D.Double(lastp.getX() +
227
                        (point.getX() / 2), lastp.getY() + (point.getY() / 2));
228
            }
229

    
230
            if (((point.getY() == lastp.getY()) &&
231
                    (point.getX() < lastp.getX())) ||
232
                    ((point.getX() == lastp.getX()) &&
233
                    (point.getY() < lastp.getY()))) {
234
            } else {
235
                if (point.getX() == lastp.getX()) {
236
                    point = new Point2D.Double(point.getX() + 0.00000001,
237
                            point.getY());
238
                } else if (point.getY() == lastp.getY()) {
239
                    point = new Point2D.Double(point.getX(),
240
                            point.getY() + 0.00000001);
241
                }
242

    
243
                if (point.getX() == antantPoint.getX()) {
244
                    point = new Point2D.Double(point.getX() + 0.00000001,
245
                            point.getY());
246
                } else if (point.getY() == antantPoint.getY()) {
247
                    point = new Point2D.Double(point.getX(),
248
                            point.getY() + 0.00000001);
249
                }
250

    
251
                if (!(list.size() > 0) ||
252
                        (((Geometry) list.get(list.size() - 1)).getType() == Geometry.TYPES.CURVE)) {
253
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(antantPoint,
254
                            lastp, lastp);
255
                    Point2D mediop = new Point2D.Double((point.getX() +
256
                            lastp.getX()) / 2, (point.getY() + lastp.getY()) / 2);
257
                    Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp,
258
                            point, mediop);
259
                    Point2D interp = UtilFunctions.getIntersection(ps1[0],
260
                            ps1[1], ps2[0], ps2[1]);
261
                    antInter = interp;
262

    
263
                    double radio = interp.distance(lastp);
264

    
265
                    if (UtilFunctions.isLowAngle(antantPoint, lastp, interp,
266
                                point)) {
267
                        radio = -radio;
268
                    }
269

    
270
                    Point2D centerp = UtilFunctions.getPoint(interp, mediop,
271
                            radio);
272
                    antCenter = centerp;
273

    
274
                    Geometry ig = createArc(lastp, centerp, point);
275

    
276
                    if (ig != null) {
277
                        list.add(ig);
278
                        addTemporalCache(ig);
279
                    }
280
                } else {
281
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp,
282
                            antInter, lastp);
283
                    double a1 = UtilFunctions.getAngle(ps1[0], ps1[1]);
284
                    double a2 = UtilFunctions.getAngle(ps1[1], ps1[0]);
285
                    double angle = UtilFunctions.getAngle(antCenter, lastp);
286
                    Point2D ini1 = null;
287
                    Point2D ini2 = null;
288

    
289
                    if (UtilFunctions.absoluteAngleDistance(angle, a1) > UtilFunctions.absoluteAngleDistance(
290
                                angle, a2)) {
291
                        ini1 = ps1[0];
292
                        ini2 = ps1[1];
293
                    } else {
294
                        ini1 = ps1[1];
295
                        ini2 = ps1[0];
296
                    }
297

    
298
                    Point2D unit = UtilFunctions.getUnitVector(ini1, ini2);
299
                    Point2D correct = new Point2D.Double(lastp.getX() +
300
                            unit.getX(), lastp.getY() + unit.getY());
301
                    Point2D[] ps = UtilFunctions.getPerpendicular(lastp,
302
                            correct, lastp);
303
                    Point2D mediop = new Point2D.Double((point.getX() +
304
                            lastp.getX()) / 2, (point.getY() + lastp.getY()) / 2);
305
                    Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp,
306
                            point, mediop);
307
                    Point2D interp = UtilFunctions.getIntersection(ps[0],
308
                            ps[1], ps2[0], ps2[1]);
309
                    antInter = interp;
310

    
311
                    double radio = interp.distance(lastp);
312

    
313
                    if (UtilFunctions.isLowAngle(correct, lastp, interp, point)) {
314
                        radio = -radio;
315
                    }
316

    
317
                    Point2D centerp = UtilFunctions.getPoint(interp, mediop,
318
                            radio);
319
                    antCenter = centerp;
320
                    Geometry geom=createArc(lastp, centerp, point);
321
                    list.add(geom);
322
                    addTemporalCache(geom);
323
                }
324

    
325
                antantPoint = antPoint;
326
                antPoint = point;
327
            }
328
        }
329
    }
330

    
331
    /**
332
     * M?todo para dibujar la lo necesario para el estado en el que nos
333
     * encontremos.
334
     *
335
     * @param g Graphics sobre el que dibujar.
336
     * @param selectedGeometries BitSet con las geometr?as seleccionadas.
337
     * @param x par?metro x del punto que se pase para dibujar.
338
     * @param y par?metro x del punto que se pase para dibujar.
339
     */
340
    public void drawOperation(MapControlDrawer renderer, double x,
341
        double y) {
342
        PolylineCADToolState actualState = _fsm.getState();
343
        String status = actualState.getName();
344

    
345
        if (status.equals("Polyline.NextPointOrArcOrClose") || status.equals("Polyline.FirstPoint")) {
346
            for (int i = 0; i < list.size(); i++) {
347
                    renderer.draw((Geometry) list.get(i), mapControlManager.getGeometrySelectionSymbol());
348
            }
349
            if (antPoint!=null)
350
                    renderer.drawLine(antPoint, new Point2D.Double(x, y), mapControlManager.getGeometrySelectionSymbol());
351

    
352
        } else if ((status.equals("Polyline.NextPointOrLineOrClose"))) {
353
            for (int i = 0; i < list.size(); i++) {
354
                    renderer.draw((Geometry) list.get(i), mapControlManager.getGeometrySelectionSymbol());
355
            }
356

    
357
            Point2D point = new Point2D.Double(x, y);
358
            Point2D lastp = antPoint;
359

    
360
            if (!(list.size() > 0) ||
361
                    (((Geometry) list.get(list.size() - 1)).getType() == Geometry.TYPES.CURVE)) {
362
                if (antantPoint == null) {
363
                    drawArc(point, lastp,
364
                        new Point2D.Double(lastp.getX() + (point.getX() / 2),
365
                            lastp.getY() + (point.getY() / 2)), renderer);
366
                } else {
367
                    drawArc(point, lastp, antantPoint, renderer);
368
                }
369
            } else {
370
                if (antInter != null) {
371
                    Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp,
372
                            antInter, lastp);
373
                    double a1 = UtilFunctions.getAngle(ps1[0], ps1[1]);
374
                    double a2 = UtilFunctions.getAngle(ps1[1], ps1[0]);
375
                    double angle = UtilFunctions.getAngle(antCenter, lastp);
376
                    Point2D ini1 = null;
377
                    Point2D ini2 = null;
378

    
379
                    if (UtilFunctions.absoluteAngleDistance(angle, a1) > UtilFunctions.absoluteAngleDistance(
380
                                angle, a2)) {
381
                        ini1 = ps1[0];
382
                        ini2 = ps1[1];
383
                    } else {
384
                        ini1 = ps1[1];
385
                        ini2 = ps1[0];
386
                    }
387

    
388
                    Point2D unit = UtilFunctions.getUnitVector(ini1, ini2);
389
                    Point2D correct = new Point2D.Double(lastp.getX() +
390
                            unit.getX(), lastp.getY() + unit.getY());
391
                    drawArc(point, lastp, correct, renderer);
392
                }
393
            }
394
        }
395
        try {
396
                        if (((FLyrVect)getVLE().getLayer()).getShapeType()==Geometry.TYPES.SURFACE && !list.isEmpty()){
397
                                Handler handler1=((Geometry) list.get(0)).getHandlers(Geometry.SELECTHANDLER)[0];
398
                                GeneralPathX gpx=new GeneralPathX();
399
                                gpx.moveTo(x,y);
400
                                Point2D p1=handler1.getPoint();
401
                                gpx.lineTo(p1.getX(),p1.getY());
402
                           Curve curve = createCurve(gpx);
403
                    renderer.draw(curve, mapControlManager.getGeometrySelectionSymbol());                
404
                        }                        
405
                } catch (ReadException e) {
406
                        e.printStackTrace();
407
                }
408
    }
409

    
410
    /**
411
     * Dibuja el arco sobre el graphics.
412
     *
413
     * @param point Puntero del rat?n.
414
     * @param lastp ?ltimo punto de la polilinea.
415
     * @param antp Punto antepenultimo.
416
     * @param g Graphics sobre el que se dibuja.
417
     */
418
    private void drawArc(Point2D point, Point2D lastp, Point2D antp, MapControlDrawer renderer) {
419
        if (((point.getY() == lastp.getY()) && (point.getX() < lastp.getX())) ||
420
                ((point.getX() == lastp.getX()) &&
421
                (point.getY() < lastp.getY()))) {
422
        } else {
423
            if (point.getX() == lastp.getX()) {
424
                point = new Point2D.Double(point.getX() + 0.00000001,
425
                        point.getY());
426
            } else if (point.getY() == lastp.getY()) {
427
                point = new Point2D.Double(point.getX(),
428
                        point.getY() + 0.00000001);
429
            }
430

    
431
            if (point.getX() == antp.getX()) {
432
                point = new Point2D.Double(point.getX() + 0.00000001,
433
                        point.getY());
434
            } else if (point.getY() == antp.getY()) {
435
                point = new Point2D.Double(point.getX(),
436
                        point.getY() + 0.00000001);
437
            }
438

    
439
            Point2D[] ps1 = UtilFunctions.getPerpendicular(lastp, antp, lastp);
440
            Point2D mediop = new Point2D.Double((point.getX() + lastp.getX()) / 2,
441
                    (point.getY() + lastp.getY()) / 2);
442
            Point2D[] ps2 = UtilFunctions.getPerpendicular(lastp, point, mediop);
443
            Point2D interp = UtilFunctions.getIntersection(ps1[0], ps1[1],
444
                    ps2[0], ps2[1]);
445

    
446
            double radio = interp.distance(lastp);
447

    
448
            if (UtilFunctions.isLowAngle(antp, lastp, interp, point)) {
449
                radio = -radio;
450
            }
451

    
452
            Point2D centerp = UtilFunctions.getPoint(interp, mediop, radio);
453
            renderer.drawLine(lastp, point, mapControlManager.getGeometrySelectionSymbol());
454

    
455
            Geometry ig = createArc(lastp, centerp, point);
456

    
457
            if (ig != null) {
458
                    renderer.draw(ig, mapControlManager.getGeometrySelectionSymbol());         
459
            }
460
        }
461
    }
462

    
463
    /**
464
     * Add a diferent option.
465
     *
466
     * @param sel DOCUMENT ME!
467
     * @param s Diferent option.
468
     */
469
    public void addOption(String s) {
470
            /*       PolylineCADToolState actualState = (PolylineCADToolState) _fsm.getPreviousState();
471
        String status = actualState.getName();
472

473
        if (status.equals("Polyline.NextPointOrArcOrClose")) {
474
            if (s.equals("A") || s.equals("a") || s.equals(PluginServices.getText(this,"inter_arc"))) {
475
                //Arco
476
            } else if (s.equals("C") || s.equals("c")) {
477
                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, 2);
478
                elShape.moveTo(antPoint.getX(), antPoint.getY());
479
                elShape.lineTo(firstPoint.getX(), firstPoint.getY());
480
                list.add(ShapeFactory.createPolyline2D(elShape));
481
                //closeGeometry();
482
            }
483
        } else if (status.equals("Polyline.NextPointOrLineOrClose")) {
484
            if (s.equals("N") || s.equals("n") || s.equals(PluginServices.getText(this,"inter_line"))) {
485
                //L?nea
486
            } else if (s.equals("C") || s.equals("c")) {
487
                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, 2);
488
                elShape.moveTo(antPoint.getX(), antPoint.getY());
489
                elShape.lineTo(firstPoint.getX(), firstPoint.getY());
490
                list.add(ShapeFactory.createPolyline2D(elShape));
491
                //closeGeometry();
492
            }
493
        }
494
  */
495
    }
496

    
497
    /* (non-Javadoc)
498
     * @see com.iver.cit.gvsig.gui.cad.CADTool#addvalue(double)
499
     */
500
    public void addValue(double d) {
501
    }
502

    
503
    public void cancel(){
504
        //endGeometry();
505
        list.clear();
506
        clearTemporalCache();
507
        antantPoint=antCenter=antInter=antPoint=firstPoint=null;
508
    }
509

    
510
    public void end() {
511
        /* CADExtension.setCADTool("polyline");
512
        PluginServices.getMainFrame().setSelectedTool("POLYLINE"); */
513
    }
514

    
515
    public String getName() {
516
        return PluginServices.getText(this,"polyline_");
517
    }
518

    
519
    public String toString() {
520
        return "_polyline";
521
    }
522
    public boolean isApplicable(int shapeType) {
523
        switch (shapeType) {
524
        case Geometry.TYPES.POINT:
525
        case Geometry.TYPES.MULTIPOINT:
526
            return false;
527
        }
528
        return true;
529
    }
530

    
531
        public void endTransition(double x, double y, MouseEvent event) {
532
                _fsm.endPoint(x, y, event);
533
        }
534
}