Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.editing.app / org.gvsig.editing.app.mainplugin / src / main / java / org / gvsig / editing / gui / cad / tools / EquidistanceCADTool.java @ 40557

History | View | Annotate | Download (18.3 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.editing.gui.cad.tools;
25

    
26
import java.awt.event.InputEvent;
27
import java.awt.geom.Point2D;
28
import java.util.ArrayList;
29

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

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

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

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

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

    
82
    }
83

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

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

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

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

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

    
142
            if (selection.getSize() == 0
143
                && !SelectionCADTool.isInstance(CADExtension.getCADTool(), true)) {
144
                
145
                CADExtension.setCADTool("_selection", false);
146
                ((SelectionCADTool) CADExtension.getCADTool())
147
                    .setNextTool("_Equidistance");
148
            }
149
        } catch (ReadException e) {
150
            // TODO Auto-generated catch block
151
            e.printStackTrace();
152
        } catch (DataException e) {
153
            // TODO Auto-generated catch block
154
            e.printStackTrace();
155
        }
156
    }
157

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
418
    }
419

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

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

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

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

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

    
463
}