Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2061 / applications / appgvSIG / src / org / gvsig / app / project / documents / view / toolListeners / snapping / snappers / IntersectionPointSnapper.java @ 39427

History | View | Annotate | Download (4.76 KB)

1 29598 jpiera
package org.gvsig.app.project.documents.view.toolListeners.snapping.snappers;
2 23642 vcaballero
3 38895 jldominguez
import java.awt.geom.PathIterator;
4 23642 vcaballero
import java.awt.geom.Point2D;
5 29683 jpiera
import java.util.List;
6 23642 vcaballero
7 36371 jpiera
import org.slf4j.Logger;
8
import org.slf4j.LoggerFactory;
9
10 23642 vcaballero
import org.gvsig.fmap.geom.Geometry;
11 36371 jpiera
import org.gvsig.fmap.geom.operation.GeometryOperationException;
12
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
13 30212 vcaballero
import org.gvsig.fmap.geom.primitive.Curve;
14 30349 jpiera
import org.gvsig.fmap.mapcontrol.PrimitivesDrawer;
15 23642 vcaballero
import org.gvsig.fmap.mapcontrol.tools.snapping.snappers.ISnapperGeometriesVectorial;
16 30349 jpiera
import org.gvsig.fmap.mapcontrol.tools.snapping.snappers.impl.AbstractSnapper;
17 38226 jldominguez
import org.gvsig.i18n.Messages;
18 23642 vcaballero
19
20
/**
21
 * Intersection point snapper.
22
 *
23
 * @author Vicente Caballero Navarro
24
 */
25
public class IntersectionPointSnapper extends AbstractSnapper
26
    implements ISnapperGeometriesVectorial {
27 36371 jpiera
    private static final Logger LOG = LoggerFactory.getLogger(IntersectionPointSnapper.class);
28
29
        private static int maxPointsGeom = 1000;
30 35614 jpiera
        private List<Geometry> geometries;
31 39053 jldominguez
        private static long lastLogTime = 0;
32 23642 vcaballero
33
    public Point2D getSnapPoint(Point2D point, Geometry geom,
34
        double tolerance, Point2D lastPointEntered) {
35 30212 vcaballero
            if (!(geom instanceof Curve)){
36
                    return null;
37 23642 vcaballero
            }
38
            Point2D result = null;
39
40
        if (geometries == null) {
41
            return null;
42
        }
43
44 35614 jpiera
        for (int i = 0; i < geometries.size(); i++) {
45
                Point2D r = intersects(geom, geometries.get(i), point, tolerance);
46 23642 vcaballero
47
            if (r != null) {
48
                result = r;
49
            }
50
        }
51
52
        return result;
53
    }
54
55 36371 jpiera
    private Point2D intersects(Geometry geometry1, Geometry geometry2, Point2D point,
56 30212 vcaballero
            double tolerance) {
57 36371 jpiera
58 35619 jpiera
            //If there is a topology error don't intersects
59 36371 jpiera
            if ((geometry1 == null) || (geometry2 == null)){
60 35619 jpiera
                return null;
61
            }
62 38895 jldominguez
63
            if (hasMoreThanVertices(geometry1, maxPointsGeom)
64
                || hasMoreThanVertices(geometry2, maxPointsGeom)) {
65
66
                return null;
67 30313 vcaballero
            }
68 38895 jldominguez
69 36371 jpiera
            Geometry geometry;
70
        try {
71
            geometry = geometry1.intersection(geometry2);
72
            if ((geometry != null) && (geometry.getType() == Geometry.TYPES.POINT)){
73
                return geometry.getHandlers(Geometry.SELECTHANDLER)[0].getPoint();
74
            }
75
        } catch (GeometryOperationNotSupportedException e) {
76 39053 jldominguez
            LOG.error("Unable to intersect these geometries", e);
77 36371 jpiera
        } catch (GeometryOperationException e) {
78 39053 jldominguez
            LOG.error("Unable to intersect these geometries", e);
79
        } catch (Exception e) {
80
            /*
81
             * Sometimes there is a JTS TopologyException.
82
             * The cause is unknown because it's difficult to
83
             * reproduce, but probably caused by extremely similar
84
             * geometries. This is unlikely to cause functionality
85
             * problems, so we'll only log it once every 5 seconds
86
             * (otherwise the user can see performance issues because
87
             * this exception is thrown many times in those strange
88
             * cases)
89
             */
90
            long curr_time = System.currentTimeMillis();
91
            // This ensures not more than one log every 5 seconds
92
            if (curr_time - lastLogTime > 5000) {
93
                LOG.info("Error while intersecting.", e);
94
                lastLogTime = curr_time;
95
            }
96 36371 jpiera
        }
97
98 30212 vcaballero
            return null;
99
    }
100 36371 jpiera
101 30349 jpiera
    public void draw(PrimitivesDrawer primitivesDrawer, Point2D pPixels) {
102
            primitivesDrawer.setColor(getColor());
103 23642 vcaballero
104
        int half = getSizePixels() / 2;
105
        int x1 = (int) (pPixels.getX() - half);
106
        int x2 = (int) (pPixels.getX() + half);
107
        int y1 = (int) (pPixels.getY() - half);
108
        int y2 = (int) (pPixels.getY() + half);
109
110 30349 jpiera
        primitivesDrawer.drawLine(x1, y1, x2, y2);
111
        primitivesDrawer.drawLine(x1, y2, x2, y1);
112 23642 vcaballero
    }
113 36371 jpiera
114 23642 vcaballero
    public String getToolTipText() {
115 38226 jldominguez
        return Messages.getText("Intersection_point");
116 23642 vcaballero
    }
117 29683 jpiera
118
        public void setGeometries(List geoms) {
119 35614 jpiera
            this.geometries = geoms;
120 29683 jpiera
        }
121 38895 jldominguez
122
123
124
        /**
125
     * Tells whether geometry has more than n vertices using its path
126
     * iterator
127
     * @param geom
128
     * @param n
129
     * @return
130
     */
131
    private static boolean hasMoreThanVertices(Geometry geom, int n) {
132
133
        PathIterator piter = geom.getPathIterator(null);
134
        if (piter == null) {
135
            return false;
136
        }
137
138
        if (n < 1) {
139
            return true;
140
        }
141
142
        int cnt = n;
143
        while (!piter.isDone()) {
144
            piter.next();
145
            cnt--;
146
            if (cnt == 0) {
147
                return true;
148
            }
149
        }
150
        return false;
151
    }
152 23642 vcaballero
}