Statistics
| Revision:

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

History | View | Annotate | Download (4.76 KB)

1
package org.gvsig.app.project.documents.view.toolListeners.snapping.snappers;
2

    
3
import java.awt.geom.PathIterator;
4
import java.awt.geom.Point2D;
5
import java.util.List;
6

    
7
import org.slf4j.Logger;
8
import org.slf4j.LoggerFactory;
9

    
10
import org.gvsig.fmap.geom.Geometry;
11
import org.gvsig.fmap.geom.operation.GeometryOperationException;
12
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
13
import org.gvsig.fmap.geom.primitive.Curve;
14
import org.gvsig.fmap.mapcontrol.PrimitivesDrawer;
15
import org.gvsig.fmap.mapcontrol.tools.snapping.snappers.ISnapperGeometriesVectorial;
16
import org.gvsig.fmap.mapcontrol.tools.snapping.snappers.impl.AbstractSnapper;
17
import org.gvsig.i18n.Messages;
18

    
19

    
20
/**
21
 * Intersection point snapper.
22
 *
23
 * @author Vicente Caballero Navarro
24
 */
25
public class IntersectionPointSnapper extends AbstractSnapper
26
    implements ISnapperGeometriesVectorial {
27
    private static final Logger LOG = LoggerFactory.getLogger(IntersectionPointSnapper.class);
28
    
29
        private static int maxPointsGeom = 1000;
30
        private List<Geometry> geometries;
31
        private static long lastLogTime = 0;
32

    
33
    public Point2D getSnapPoint(Point2D point, Geometry geom,
34
        double tolerance, Point2D lastPointEntered) {
35
            if (!(geom instanceof Curve)){
36
                    return null;
37
            }
38
            Point2D result = null;
39

    
40
        if (geometries == null) {
41
            return null;
42
        }
43

    
44
        for (int i = 0; i < geometries.size(); i++) {
45
                Point2D r = intersects(geom, geometries.get(i), point, tolerance);
46

    
47
            if (r != null) {
48
                result = r;
49
            }
50
        }
51

    
52
        return result;
53
    }
54

    
55
    private Point2D intersects(Geometry geometry1, Geometry geometry2, Point2D point,
56
            double tolerance) {
57
            
58
            //If there is a topology error don't intersects
59
            if ((geometry1 == null) || (geometry2 == null)){
60
                return null;
61
            }
62

    
63
            if (hasMoreThanVertices(geometry1, maxPointsGeom)
64
                || hasMoreThanVertices(geometry2, maxPointsGeom)) {
65
                
66
                return null;
67
            }
68
                
69
            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
            LOG.error("Unable to intersect these geometries", e);
77
        } catch (GeometryOperationException e) {
78
            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
        }    
97
            
98
            return null;
99
    }
100

    
101
    public void draw(PrimitivesDrawer primitivesDrawer, Point2D pPixels) {
102
            primitivesDrawer.setColor(getColor());
103

    
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
        primitivesDrawer.drawLine(x1, y1, x2, y2);
111
        primitivesDrawer.drawLine(x1, y2, x2, y1);
112
    }
113

    
114
    public String getToolTipText() {
115
        return Messages.getText("Intersection_point");
116
    }
117

    
118
        public void setGeometries(List geoms) {
119
            this.geometries = geoms;                
120
        }
121
        
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
}