Statistics
| Revision:

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

History | View | Annotate | Download (18.4 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
 * MA  02110-1301, USA.
20
 * 
21
 */
22
package org.gvsig.editing.gui.cad.tools;
23

    
24
import java.awt.event.InputEvent;
25
import java.awt.geom.Point2D;
26
import java.util.ArrayList;
27

    
28
import com.vividsolutions.jts.algorithm.CGAlgorithms;
29
import com.vividsolutions.jts.geom.Coordinate;
30
import com.vividsolutions.jts.geom.GeometryFactory;
31
import com.vividsolutions.jts.geom.LineString;
32
import com.vividsolutions.jts.geom.LinearRing;
33
import com.vividsolutions.jts.geom.Point;
34
import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
35

    
36
import org.gvsig.andami.PluginServices;
37
import org.gvsig.editing.CADExtension;
38
import org.gvsig.editing.gui.cad.DefaultCADTool;
39
import org.gvsig.editing.gui.cad.exception.CommandException;
40
import org.gvsig.editing.gui.cad.tools.smc.EquidistanceCADToolContext;
41
import org.gvsig.editing.gui.cad.tools.smc.EquidistanceCADToolContext.EquidistanceCADToolState;
42
import org.gvsig.editing.layers.VectorialLayerEdited;
43
import org.gvsig.fmap.dal.exception.DataException;
44
import org.gvsig.fmap.dal.exception.ReadException;
45
import org.gvsig.fmap.dal.feature.Feature;
46
import org.gvsig.fmap.dal.feature.FeatureSelection;
47
import org.gvsig.fmap.dal.feature.FeatureSet;
48
import org.gvsig.fmap.dal.feature.FeatureStore;
49
import org.gvsig.fmap.geom.Geometry;
50
import org.gvsig.fmap.geom.exception.CreateGeometryException;
51
import org.gvsig.fmap.geom.operation.GeometryOperationException;
52
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
53
import org.gvsig.fmap.geom.operation.tojts.ToJTS;
54
import org.gvsig.fmap.geom.util.Converter;
55
import org.gvsig.fmap.geom.util.UtilFunctions;
56
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
57
import org.gvsig.tools.dispose.DisposableIterator;
58

    
59
/**
60
 * Herramienta para crear una geometr?a equidistante a otra.
61
 * 
62
 * @author Vicente Caballero Navarro
63
 */
64
public class EquidistanceCADTool extends DefaultCADTool {
65

    
66
    private EquidistanceCADToolContext _fsm;
67
    private Point2D firstPoint = new Point2D.Double(800000, 4500000);
68
    private Point2D secondPoint = new Point2D.Double(810000, 4500000);
69
    private double distance = 10;
70
    private double distancePos = java.lang.Double.MAX_VALUE;
71
    private LineString distanceLine;
72

    
73
    /**
74
     * M?todo de inicio, para poner el c?digo de todo lo que se requiera de una
75
     * carga previa a la utilizaci?n de la herramienta.
76
     */
77
    public void init() {
78
        _fsm = new EquidistanceCADToolContext(this);
79

    
80
    }
81

    
82
    private Coordinate[] getParallel(Point2D[] points, double distance) {
83
        Point2D[] pper = new Point2D[2];
84
        double angle =
85
            Math.toRadians(90) + UtilFunctions.getAngle(points[0], points[1]);
86
        pper[0] = UtilFunctions.getPoint(points[0], angle, distance);
87
        pper[1] = UtilFunctions.getPoint(points[1], angle, distance);
88
        Coordinate[] result = new Coordinate[2];
89
        result[0] = new Coordinate(pper[0].getX(), pper[0].getY());
90
        result[1] = new Coordinate(pper[1].getX(), pper[1].getY());
91
        return result;
92
    }
93

    
94
    /*
95
     * (non-Javadoc)
96
     * 
97
     * @see
98
     * com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap
99
     * .layers.FBitSet,
100
     * double, double)
101
     */
102
    public void transition(double x, double y, InputEvent event) {
103
        _fsm.addPoint(x, y, event);
104
    }
105

    
106
    /*
107
     * (non-Javadoc)
108
     * 
109
     * @see
110
     * com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap
111
     * .layers.FBitSet,
112
     * double)
113
     */
114
    public void transition(double d) {
115
        _fsm.addValue(d);
116
    }
117

    
118
    /*
119
     * (non-Javadoc)
120
     * 
121
     * @see
122
     * com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap
123
     * .layers.FBitSet,
124
     * java.lang.String)
125
     */
126
    public void transition(String s) throws CommandException {
127
        if (!super.changeCommand(s)) {
128
            _fsm.addOption(s);
129
        }
130
    }
131

    
132
    /**
133
     * DOCUMENT ME!
134
     */
135
    public void selection() {
136
        FeatureSet selection = null;
137
        try {
138
            selection = (FeatureSet) getVLE().getFeatureStore().getSelection();
139

    
140
            if (selection.getSize() == 0
141
                && !CADExtension
142
                    .getCADTool()
143
                    .getClass()
144
                    .getName()
145
                    .equals("com.iver.cit.gvsig.gui.cad.tools.SelectionCADTool")) {
146
                CADExtension.setCADTool("_selection", false);
147
                ((SelectionCADTool) CADExtension.getCADTool())
148
                    .setNextTool("_Equidistance");
149
            }
150
        } catch (ReadException e) {
151
            // TODO Auto-generated catch block
152
            e.printStackTrace();
153
        } catch (DataException e) {
154
            // TODO Auto-generated catch block
155
            e.printStackTrace();
156
        }
157
    }
158

    
159
    /**
160
     * Equivale al transition del prototipo pero sin pasarle como par?metro el
161
     * editableFeatureSource que ya estar? creado.
162
     * 
163
     * @param x
164
     *            par?metro x del punto que se pase en esta transici?n.
165
     * @param y
166
     *            par?metro y del punto que se pase en esta transici?n.
167
     */
168
    public void addPoint(double x, double y, InputEvent event) {
169
        EquidistanceCADToolState actualState =
170
            (EquidistanceCADToolState) _fsm.getPreviousState();
171
        String status = actualState.getName();
172
        if (status.equals("Equidistance.Distance")) {
173
            firstPoint = new Point2D.Double(x, y);
174
        } else
175
            if (status.equals("Equidistance.SecondPointDistance")) {
176
                secondPoint = new Point2D.Double(x, y);
177
                distance = secondPoint.distance(firstPoint);
178
            } else
179
                if (status.equals("Equidistance.Position")) {
180
                    VectorialLayerEdited vle = getVLE();
181
                    FeatureStore featureStore = null;
182
                    try {
183
                        featureStore = vle.getFeatureStore();
184
                    } catch (ReadException e) {
185
                        // TODO Auto-generated catch block
186
                        e.printStackTrace();
187
                    }
188
                    ArrayList selectedRowAux = new ArrayList();
189
                    DisposableIterator iterator = null;
190
                    try {
191
                        iterator =
192
                            ((FeatureSelection) featureStore.getSelection())
193
                                .iterator();
194

    
195
                        PluginServices.getMDIManager().setWaitCursor();
196
                        featureStore.beginEditingGroup(getName());
197
                        while (iterator.hasNext()) {
198
                            Feature feature = (Feature) iterator.next();
199
                            Geometry geometry =
200
                                compute(feature, new Point2D.Double(x, y));
201
                            insertAndSelectGeometry(geometry);
202
                        }
203

    
204
                        featureStore.endEditingGroup();
205
                    } catch (DataException e) {
206
                        // TODO Auto-generated catch block
207
                        e.printStackTrace();
208
                    } catch (CreateGeometryException e) {
209
                        // TODO Auto-generated catch block
210
                        e.printStackTrace();
211
                    } finally {
212
                        if (iterator != null) {
213
                            iterator.dispose();
214
                        }
215
                    }
216
                    PluginServices.getMDIManager().restoreCursor();
217
                }
218
    }
219

    
220
    private Geometry compute(Feature fea, Point2D position)
221
        throws CreateGeometryException {
222
        Geometry geometry = (fea.getDefaultGeometry()).cloneGeometry();
223
        int typeGeometry = geometry.getType();
224
        com.vividsolutions.jts.geom.Geometry g = null;
225
        try {
226
            g =
227
                (com.vividsolutions.jts.geom.Geometry) geometry
228
                    .invokeOperation(ToJTS.CODE, null);
229
        } catch (GeometryOperationNotSupportedException e) {
230
            // TODO Auto-generated catch block
231
            e.printStackTrace();
232
        } catch (GeometryOperationException e) {
233
            // TODO Auto-generated catch block
234
            e.printStackTrace();
235
        }
236

    
237
        // com.vividsolutions.jts.geom.Geometry g = geometry.toJTSGeometry();
238
        GeometryFactory factory = g.getFactory();
239
        Coordinate[] c2 = new Coordinate[2];
240
        com.vividsolutions.jts.geom.Geometry g2 = null;
241
        Coordinate coordinatePosition =
242
            new Coordinate(position.getX(), position.getY());
243
        Point pPos = factory.createPoint(coordinatePosition);
244
        switch (typeGeometry) {
245
        case CURVE:
246

    
247
            LineString lR = factory.createLineString(g.getCoordinates());
248
            g = TopologyPreservingSimplifier.simplify(lR, 10d);
249
            com.vividsolutions.jts.geom.Geometry gLine = g.getGeometryN(0);
250
            Coordinate[] coordinatesLine = gLine.getCoordinates();
251
            int numPointsLine = gLine.getNumPoints();
252
            if (numPointsLine < 1) {
253
                return null;
254
            }
255
            LineString[] lineStrings = new LineString[numPointsLine - 1];
256

    
257
            for (int j = 1; j < numPointsLine; j = j + 1) {
258
                c2[0] = coordinatesLine[j - 1];
259
                c2[1] = coordinatesLine[j];
260
                LineString lS = factory.createLineString(c2);
261
                if (lS.distance(pPos) < distancePos) {
262
                    distancePos = lS.distance(pPos);
263
                    distanceLine = (LineString) factory.createGeometry(lS);
264
                }
265
            }
266
            setDistanceLine(coordinatePosition);
267

    
268
            for (int j = 1; j < numPointsLine; j = j + 1) {
269
                c2[0] = coordinatesLine[j - 1];
270
                c2[1] = coordinatesLine[j];
271
                Point2D[] points = new Point2D[2];
272
                points[0] = new Point2D.Double(c2[0].x, c2[0].y);
273
                points[1] = new Point2D.Double(c2[1].x, c2[1].y);
274
                lineStrings[j - 1] =
275
                    factory.createLineString(getParallel(points, distance));
276
            }
277

    
278
            for (int i = 0; i < lineStrings.length - 1; i++) {
279
                Coordinate coord = lineStrings[i].getCoordinateN(0);
280
                Point2D p1 = new Point2D.Double(coord.x, coord.y);
281
                coord = lineStrings[i].getCoordinateN(1);
282
                Point2D p2 = new Point2D.Double(coord.x, coord.y);
283
                coord = lineStrings[i + 1].getCoordinateN(0);
284
                Point2D p3 = new Point2D.Double(coord.x, coord.y);
285
                coord = lineStrings[i + 1].getCoordinateN(1);
286
                Point2D p4 = new Point2D.Double(coord.x, coord.y);
287
                Point2D intersection =
288
                    UtilFunctions.getIntersection(p1, p2, p3, p4);
289
                Coordinate[] coords1 = new Coordinate[2];
290
                coords1[0] = lineStrings[i].getCoordinateN(0);
291
                coords1[1] =
292
                    new Coordinate(intersection.getX(), intersection.getY());
293
                lineStrings[i] = factory.createLineString(coords1);
294
                Coordinate[] coords2 = new Coordinate[2];
295
                coords2[0] = coords1[1];
296
                coords2[1] = lineStrings[i + 1].getCoordinateN(1);
297
                lineStrings[i + 1] = factory.createLineString(coords2);
298
            }
299
            g2 = factory.createMultiLineString(lineStrings);
300
            return Converter.jtsToGeometry(g2);
301
        case SURFACE:
302
        case CIRCLE:
303
        case ELLIPSE:
304
            g = TopologyPreservingSimplifier.simplify(g, 10d);
305
            com.vividsolutions.jts.geom.Geometry gPolygon = g.getGeometryN(0);
306
            setDistancePolygon(gPolygon, pPos);
307
            Coordinate[] coordinates = gPolygon.getCoordinates();
308
            int numPointsPolygon = gPolygon.getNumPoints();
309
            if (numPointsPolygon < 2) {
310
                return null;
311
            }
312
            LineString[] polygonStrings = new LineString[numPointsPolygon];
313
            for (int j = 1; j < numPointsPolygon; j = j + 1) {
314
                c2[0] = coordinates[j - 1];
315
                c2[1] = coordinates[j];
316
                Point2D[] points = new Point2D[2];
317
                points[0] = new Point2D.Double(c2[0].x, c2[0].y);
318
                points[1] = new Point2D.Double(c2[1].x, c2[1].y);
319
                polygonStrings[j - 1] =
320
                    factory.createLineString(getParallel(points, distance));
321
            }
322
            for (int i = 0; i < polygonStrings.length - 2; i++) {
323
                Coordinate coord = polygonStrings[i].getCoordinateN(0);
324
                Point2D p1 = new Point2D.Double(coord.x, coord.y);
325
                coord = polygonStrings[i].getCoordinateN(1);
326
                Point2D p2 = new Point2D.Double(coord.x, coord.y);
327
                coord = polygonStrings[i + 1].getCoordinateN(0);
328
                Point2D p3 = new Point2D.Double(coord.x, coord.y);
329
                coord = polygonStrings[i + 1].getCoordinateN(1);
330
                Point2D p4 = new Point2D.Double(coord.x, coord.y);
331
                Point2D intersection =
332
                    UtilFunctions.getIntersection(p1, p2, p3, p4);
333
                Coordinate[] coords1 = new Coordinate[2];
334
                coords1[0] = polygonStrings[i].getCoordinateN(0);
335
                coords1[1] =
336
                    new Coordinate(intersection.getX(), intersection.getY());
337
                polygonStrings[i] = factory.createLineString(coords1);
338
                Coordinate[] coords2 = new Coordinate[2];
339
                coords2[0] = coords1[1];
340
                coords2[1] = polygonStrings[i + 1].getCoordinateN(1);
341
                polygonStrings[i + 1] = factory.createLineString(coords2);
342
            }
343

    
344
            Coordinate coord = polygonStrings[0].getCoordinateN(0);
345
            Point2D p1 = new Point2D.Double(coord.x, coord.y);
346
            coord = polygonStrings[0].getCoordinateN(1);
347
            Point2D p2 = new Point2D.Double(coord.x, coord.y);
348
            coord = polygonStrings[polygonStrings.length - 2].getCoordinateN(0);
349
            Point2D p3 = new Point2D.Double(coord.x, coord.y);
350
            coord = polygonStrings[polygonStrings.length - 2].getCoordinateN(1);
351
            Point2D p4 = new Point2D.Double(coord.x, coord.y);
352

    
353
            Point2D intersection =
354
                UtilFunctions.getIntersection(p1, p2, p3, p4);
355
            Coordinate[] coords1 = new Coordinate[2];
356
            coords1[0] =
357
                polygonStrings[polygonStrings.length - 2].getCoordinateN(1);
358
            coords1[1] =
359
                new Coordinate(intersection.getX(), intersection.getY());
360
            polygonStrings[polygonStrings.length - 1] =
361
                factory.createLineString(coords1);
362
            Coordinate[] coords2 = new Coordinate[2];
363
            coords2[0] = coords1[1];
364
            coords2[1] = polygonStrings[0].getCoordinateN(1);
365
            polygonStrings[0] = factory.createLineString(coords2);
366
            com.vividsolutions.jts.geom.Geometry geometryCollection =
367
                factory.createGeometryCollection(polygonStrings);
368
            LinearRing linearRing =
369
                factory.createLinearRing(geometryCollection.getCoordinates());
370
            LinearRing[] holes = new LinearRing[1];
371
            holes[0] = factory.createLinearRing(new Coordinate[0]);
372
            g2 = factory.createPolygon(linearRing, holes);
373
            return Converter.jtsToGeometry(g2);
374

    
375
        default:
376
            break;
377
        }
378
        return null;
379
    }
380

    
381
    private void setDistanceLine(Coordinate position) {
382
        Coordinate pStart = distanceLine.getCoordinateN(0);
383
        Coordinate pEnd =
384
            distanceLine.getCoordinateN(distanceLine.getNumPoints() - 1);
385
        int pos = CGAlgorithms.computeOrientation(pStart, pEnd, position);
386
        if (pos > 0) {
387
            distance = Math.abs(distance);
388
        } else {
389
            distance = -Math.abs(distance);
390
        }
391
        distancePos = java.lang.Double.MAX_VALUE;
392
        distanceLine = null;
393
    }
394

    
395
    private void setDistancePolygon(
396
        com.vividsolutions.jts.geom.Geometry polygon,
397
        com.vividsolutions.jts.geom.Geometry position) {
398
        boolean intersects = polygon.intersects(position);
399
        if (intersects) {
400
            distance = -Math.abs(distance);
401
        } else {
402
            distance = Math.abs(distance);
403
        }
404
    }
405

    
406
    /**
407
     * M?todo para dibujar la lo necesario para el estado en el que nos
408
     * encontremos.
409
     * 
410
     * @param g
411
     *            Graphics sobre el que dibujar.
412
     * @param x
413
     *            par?metro x del punto que se pase para dibujar.
414
     * @param y
415
     *            par?metro x del punto que se pase para dibujar.
416
     */
417
    public void drawOperation(MapControlDrawer renderer, double x, double y) {
418

    
419
    }
420

    
421
    /**
422
     * Add a diferent option.
423
     * 
424
     * @param s
425
     *            Diferent option.
426
     */
427
    public void addOption(String s) {
428
        // EquidistanceCADToolState actualState = (EquidistanceCADToolState)
429
        // _fsm
430
        // .getPreviousState();
431
        // String status = actualState.getName();
432
        // if (status.equals("Equidistance.Distance")) {
433
        // distance=java.lang.Double.parseDouble(s);
434
        // }
435
    }
436

    
437
    /*
438
     * (non-Javadoc)
439
     * 
440
     * @see com.iver.cit.gvsig.gui.cad.CADTool#addvalue(double)
441
     */
442
    public void addValue(double d) {
443
        EquidistanceCADToolState actualState =
444
            (EquidistanceCADToolState) _fsm.getPreviousState();
445
        String status = actualState.getName();
446
        if (status.equals("Equidistance.Distance")) {
447
            distance = d;
448
        }
449
    }
450

    
451
    public String getName() {
452
        return PluginServices.getText(this, "Equidistance_");
453
    }
454

    
455
    public String toString() {
456
        return "_Equidistance";
457
    }
458

    
459
    @Override
460
    protected int[] getSupportedGeometryTypes() {
461
        return new int[] { CURVE, CIRCLE, ELLIPSE, SURFACE };
462
    }
463

    
464
}