Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / project / documents / view / toolListeners / snapping / snappers / IntersectionPointSnapper.java @ 40558

History | View | Annotate | Download (5.72 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.app.project.documents.view.toolListeners.snapping.snappers;
25

    
26
import java.awt.geom.PathIterator;
27
import java.awt.geom.Point2D;
28
import java.util.List;
29

    
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

    
33
import org.gvsig.fmap.geom.Geometry;
34
import org.gvsig.fmap.geom.operation.GeometryOperationException;
35
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
36
import org.gvsig.fmap.geom.primitive.Curve;
37
import org.gvsig.fmap.mapcontrol.PrimitivesDrawer;
38
import org.gvsig.fmap.mapcontrol.tools.snapping.snappers.ISnapperGeometriesVectorial;
39
import org.gvsig.fmap.mapcontrol.tools.snapping.snappers.impl.AbstractSnapper;
40
import org.gvsig.i18n.Messages;
41

    
42

    
43
/**
44
 * Intersection point snapper.
45
 *
46
 * @author Vicente Caballero Navarro
47
 */
48
public class IntersectionPointSnapper extends AbstractSnapper
49
    implements ISnapperGeometriesVectorial {
50
    private static final Logger LOG = LoggerFactory.getLogger(IntersectionPointSnapper.class);
51
    
52
        private static int maxPointsGeom = 1000;
53
        private List<Geometry> geometries;
54
        private static long lastLogTime = 0;
55

    
56
    public Point2D getSnapPoint(Point2D point, Geometry geom,
57
        double tolerance, Point2D lastPointEntered) {
58
            if (!(geom instanceof Curve)){
59
                    return null;
60
            }
61
            Point2D result = null;
62

    
63
        if (geometries == null) {
64
            return null;
65
        }
66

    
67
        for (int i = 0; i < geometries.size(); i++) {
68
                Point2D r = intersects(geom, geometries.get(i), point, tolerance);
69

    
70
            if (r != null) {
71
                result = r;
72
            }
73
        }
74

    
75
        return result;
76
    }
77

    
78
    private Point2D intersects(Geometry geometry1, Geometry geometry2, Point2D point,
79
            double tolerance) {
80
            
81
            //If there is a topology error don't intersects
82
            if ((geometry1 == null) || (geometry2 == null)){
83
                return null;
84
            }
85

    
86
            if (hasMoreThanVertices(geometry1, maxPointsGeom)
87
                || hasMoreThanVertices(geometry2, maxPointsGeom)) {
88
                
89
                return null;
90
            }
91
                
92
            Geometry geometry;
93
        try {
94
            geometry = geometry1.intersection(geometry2);
95
            if ((geometry != null) && (geometry.getType() == Geometry.TYPES.POINT)){
96
                return geometry.getHandlers(Geometry.SELECTHANDLER)[0].getPoint();
97
            }
98
        } catch (GeometryOperationNotSupportedException e) {
99
            LOG.error("Unable to intersect these geometries", e);
100
        } catch (GeometryOperationException e) {
101
            LOG.error("Unable to intersect these geometries", e);
102
        } catch (Exception e) {
103
            /*
104
             * Sometimes there is a JTS TopologyException.
105
             * The cause is unknown because it's difficult to
106
             * reproduce, but probably caused by extremely similar
107
             * geometries. This is unlikely to cause functionality
108
             * problems, so we'll only log it once every 5 seconds
109
             * (otherwise the user can see performance issues because
110
             * this exception is thrown many times in those strange
111
             * cases) 
112
             */
113
            long curr_time = System.currentTimeMillis();
114
            // This ensures not more than one log every 5 seconds
115
            if (curr_time - lastLogTime > 5000) {
116
                LOG.info("Error while intersecting.", e);
117
                lastLogTime = curr_time;
118
            }
119
        }    
120
            
121
            return null;
122
    }
123

    
124
    public void draw(PrimitivesDrawer primitivesDrawer, Point2D pPixels) {
125
            primitivesDrawer.setColor(getColor());
126

    
127
        int half = getSizePixels() / 2;
128
        int x1 = (int) (pPixels.getX() - half);
129
        int x2 = (int) (pPixels.getX() + half);
130
        int y1 = (int) (pPixels.getY() - half);
131
        int y2 = (int) (pPixels.getY() + half);
132

    
133
        primitivesDrawer.drawLine(x1, y1, x2, y2);
134
        primitivesDrawer.drawLine(x1, y2, x2, y1);
135
    }
136

    
137
    public String getToolTipText() {
138
        return Messages.getText("Intersection_point");
139
    }
140

    
141
        public void setGeometries(List geoms) {
142
            this.geometries = geoms;                
143
        }
144
        
145
        
146
           
147
        /**
148
     * Tells whether geometry has more than n vertices using its path
149
     * iterator
150
     * @param geom
151
     * @param n
152
     * @return
153
     */
154
    private static boolean hasMoreThanVertices(Geometry geom, int n) {
155
        
156
        PathIterator piter = geom.getPathIterator(null);
157
        if (piter == null) {
158
            return false;
159
        }
160
        
161
        if (n < 1) {
162
            return true;
163
        }
164

    
165
        int cnt = n;
166
        while (!piter.isDone()) {
167
            piter.next();
168
            cnt--;
169
            if (cnt == 0) {
170
                return true;
171
            }
172
        }
173
        return false;
174
    }
175
}