Revision 13707

View differences:

trunk/libraries/libTopology/src-test/org/gvsig/topology/SnapAndCrackTest.java
1
/*
2
 * Created on 10-sep-2007
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
/* CVS MESSAGES:
45
 *
46
 * $Id$
47
 * $Log$
48
 * Revision 1.1  2007-09-14 17:34:46  azabala
49
 * first version in cvs
50
 *
51
 *
52
 */
53
package org.gvsig.topology;
54

  
55
import org.gvsig.jts.GeometryCracker;
56
import org.gvsig.jts.GeometrySnapper;
57
import org.gvsig.jts.LineStringSplitter;
58

  
59
import com.vividsolutions.jts.geom.Coordinate;
60
import com.vividsolutions.jts.geom.Geometry;
61
import com.vividsolutions.jts.geom.GeometryCollection;
62
import com.vividsolutions.jts.geom.GeometryFactory;
63
import com.vividsolutions.jts.geom.LineString;
64
import com.vividsolutions.jts.geom.Polygon;
65
import com.vividsolutions.jts.geom.PrecisionModel;
66
import com.vividsolutions.jts.io.ParseException;
67
import com.vividsolutions.jts.io.WKTReader;
68
import com.vividsolutions.jts.precision.EnhancedPrecisionOp;
69

  
70
import junit.framework.TestCase;
71

  
72
/**
73
 * Unit tests for GeometryCrack and GeometrySnap classes.
74
 * 
75
 * @author azabala
76
 * 
77
 */
78
public class SnapAndCrackTest extends TestCase {
79

  
80
	PrecisionModel pm;
81

  
82
	GeometryFactory factory;
83

  
84
	WKTReader wktReader;
85

  
86
	protected void setUp() throws Exception {
87
		super.setUp();
88
		pm = new PrecisionModel(10000);
89
		factory = new GeometryFactory(pm);
90
		wktReader = new WKTReader(factory);
91
	}
92

  
93
	protected void tearDown() throws Exception {
94
		super.tearDown();
95
		pm = null;
96
		factory = null;
97
		wktReader = null;
98
	}
99

  
100
	public void testCrackTwoPolygons() throws ParseException {
101
		String pol1txt = "POLYGON ((320 160, 320 120, 360 120, 360 160, 320 160))";
102
		String pol2txt = "POLYGON ((360 160, 360 140, 360 120, 400 120, 400 140, 400 160, 360 160))";
103
		Polygon geo1 = (Polygon) wktReader.read(pol1txt);
104
		Polygon geo2 = (Polygon) wktReader.read(pol2txt);
105

  
106
		// GeometryCracker cracker = new GeometryCracker(0.1d);
107

  
108
		LineString cracked1 = (LineString) GeometryCracker.crack(geo1.getExteriorRing(), 
109
																geo2.getExteriorRing(), 
110
																	0.1d);
111

  
112
		System.out.println(cracked1.toText());
113
	}
114
	
115
	public void testCrackTwoIntersectingLinesWithPseudonodes() throws ParseException{
116
		
117
		//a) Two linestrings that intersects in points that are not nodes (pseudonodes)
118
		String a = "LINESTRING (300 120, 360 140, 480 160, 420 100)";
119
		String b = "LINESTRING (320 140, 360 100, 420 180, 480 100, 400 120)";
120
		LineString linA = (LineString) wktReader.read(a);
121
		LineString linB = (LineString) wktReader.read(b);
122
		
123
		GeometryCracker cracker = new GeometryCracker(0.1);
124
		Geometry[] geoms = {linA, linB};
125
		Geometry[] cracked = cracker.crack(geoms);
126
		
127
		System.out.println(cracked[0].toText());
128
		System.out.println(cracked[1].toText());
129
		
130
		//Crack and Snap only affect to Vertices (it doesnt compute intersections)
131
		assertTrue(a.equalsIgnoreCase(cracked[0].toText()));
132
		assertTrue(b.equalsIgnoreCase(cracked[1].toText()));
133
		
134
		
135
		//a1) We split these two lines in their intersections (MustNotHavePseudonodes rule)
136
		Geometry intersections = EnhancedPrecisionOp.intersection(linA, linB);
137
		Coordinate[] intersectionPoints = intersections.getCoordinates();
138
		LineStringSplitter splitter = new LineStringSplitter();
139
		LineString[] linASplittedA = splitter.splitSimple(linA, intersectionPoints);
140
		LineString[] linBSplittedB = splitter.splitSimple(linB, intersectionPoints);
141
		assertTrue(linASplittedA.length == 6);
142
		assertTrue(linBSplittedB.length == 6);
143
		assertTrue(intersectionPoints.length == 5);
144
		
145
		//in this point, LineStringSplitter could return splitted linestring with
146
		//numerical precision problems. To avoid this, we could snap them.
147
		
148
		GeometrySnapper snapper = new GeometrySnapper(0.01d);
149
		Geometry[] aa = snapper.snap(linASplittedA);
150
		Geometry[] bb = snapper.snap(linBSplittedB);
151
		
152
		//FIXME
153
		//Instead of use Union for the test, use LineStringSewer
154
		
155
		Geometry splittedUnion = aa[0];
156
		for(int i = 1; i < aa.length; i++){
157
			splittedUnion = splittedUnion.union(aa[i]);
158
		}
159
//		assertTrue(splittedUnion.equalsExact(linA));
160
		
161
		splittedUnion = bb[0];
162
		for(int i = 1; i < bb.length; i++){
163
			splittedUnion = splittedUnion.union(bb[i]);
164
		}
165
//		assertTrue(splittedUnion.equals(linB));
166
		
167
		
168
		//b) Two intersecting lines with vertices that must be cracked and snapped
169
		
170
		//b1) vertex 320,180.001 must be cracked in first geometry
171
		// FIXME When were going to crack a vertex...?why dont apply the line equation y=mx+b
172
		//to avoid the pick 300 180, 320 180.001 360 180
173
		
174
		//b2) In 360,120 both lines intersects (this only will be detected in OverlayOp)
175
		//FIXME This is a real intersection. In the next test use a snap intersection
176
		
177
		// b3) In 380.01 99.99 we must crack first geometry
178
		
179
		// b4) 420.01 100.001 must be snapped
180
		
181
		//conclusion: to clean a topology we must: a) snap b) crack c) compute intersections
182
		
183
		a = "LINESTRING (300 180, 360 180, 360 100, 420 100)";
184
		b = "LINESTRING (320 180.001, 320 120, 380 120, 380.01 99.99, 400 180, 480 180, 420.01 100.001)";
185
		snapper = new GeometrySnapper(0.08);
186
		Geometry aG = wktReader.read(a);
187
		Geometry bG = wktReader.read(b);
188
		Geometry[] newgeoms = {aG,bG};
189
		Geometry[] snapped = snapper.snap(newgeoms);
190
		
191
		cracker = new GeometryCracker(0.08);
192
		snapped = cracker.crack(snapped);
193
		
194
		for(int i = 0; i < snapped.length; i++){
195
			LineString ls1 = (LineString) snapped[i];
196
			for(int j = 0; j < snapped.length; j++){
197
				if(i == j)
198
					continue;
199
				LineString ls2 = (LineString) snapped[i];
200
				//AQUI NO USAMOS SNAP. 
201
				Coordinate[] inters = EnhancedPrecisionOp.intersection(ls1, ls2).getCoordinates();
202
				LineString[] result1 = splitter.splitSimple(ls1, inters);
203
				Geometry multi1 = factory.createGeometryCollection(result1);
204
				LineString[] result2 = splitter.splitSimple(ls2, inters);
205
				Geometry multi2 = factory.createGeometryCollection(result2);
206
				multi2.toText();
207
				//Esto funciona porque son solo dos. Para hacerlo con muchas lineas, hay que mantener
208
				//para cada lineString una lista con todas las intersecciones, con independencia
209
				//de con que geomeetrias sea.. (USAR PARA ESTO EL PREPAREDGEOMETRY DE JTS)
210
			}//for
211
		}//for
212
		
213
		
214
		
215
		
216
	}
217

  
218
}
0 219

  
trunk/libraries/libTopology/src/org/gvsig/jts/SnapLineStringSelfIntersectionChecker.java
1
/*
2
 * Created on 12-sep-2007
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
/* CVS MESSAGES:
45
*
46
* $Id$
47
* $Log$
48
* Revision 1.1  2007-09-14 17:35:52  azabala
49
* first version in cvs
50
*
51
*
52
*/
53
package org.gvsig.jts;
54

  
55
import java.util.ArrayList;
56
import java.util.Iterator;
57
import java.util.List;
58

  
59
import com.iver.cit.gvsig.util.SnappingCoordinateMap;
60
import com.vividsolutions.jts.algorithm.LineIntersector;
61
import com.vividsolutions.jts.geom.Coordinate;
62
import com.vividsolutions.jts.geom.LineString;
63
import com.vividsolutions.jts.geomgraph.Edge;
64
import com.vividsolutions.jts.geomgraph.EdgeIntersectionList;
65
import com.vividsolutions.jts.geomgraph.SnappingGeometryGraph;
66
import com.vividsolutions.jts.geomgraph.SnapEdgeIntersectionList.SnapEdgeIntersectNode;
67
import com.vividsolutions.jts.geomgraph.index.SegmentIntersector;
68
import com.vividsolutions.jts.geomgraph.index.SnapSimpleMCSweepLineIntersector;
69
import com.vividsolutions.jts.operation.overlay.SnapLineIntersector;
70

  
71
public class SnapLineStringSelfIntersectionChecker extends
72
		LineStringSelfIntersectionChecker {
73

  
74
	public SnapLineStringSelfIntersectionChecker(LineString lineString,
75
			double snapTolerance) {
76
		super(lineString, snapTolerance);
77
		this.graph = new SnappingGeometryGraph(snapTolerance,0, lineString);
78
	}
79

  
80
	
81
	public SnapLineStringSelfIntersectionChecker(LineString lineString) {
82
		this(lineString, DEFAULT_SNAP_TOLERANCE);
83
	}
84

  
85
	
86
	protected void initialize() {
87
		ArrayList selfIntersectionsList = new ArrayList();
88
		SnappingCoordinateMap selfIntersectionsMap = new SnappingCoordinateMap(
89
				snapTolerance);
90
		List edges = computeSelfNodesWithSnap();
91
		Iterator i = edges.iterator();
92
		while (i.hasNext()) {// for each edge graph
93
			Edge e = (Edge) i.next();
94
			EdgeIntersectionList eiList = e.getEdgeIntersectionList();
95
			for (Iterator eiIt = eiList.iterator(); eiIt.hasNext();) {
96
				Object obj =  eiIt.next();
97
				SnapEdgeIntersectNode ei = (SnapEdgeIntersectNode) obj;
98
				if (!isProper(ei.getCoordinate())) {
99
					if (!selfIntersectionsMap.containsKey(ei.getCoordinate())) {
100
						selfIntersectionsList.add(ei.getCoordinate());
101
						selfIntersectionsMap.put(ei.getCoordinate(), ei.getCoordinate());
102
					}//if
103
				}//if
104
			}// for
105
		}// while
106
		int numSelfIntersections = selfIntersectionsList.size();
107
		if (numSelfIntersections > 0) {
108
			selfIntersections = new Coordinate[numSelfIntersections];
109
			selfIntersectionsList.toArray(selfIntersections);
110
		}
111
	}
112

  
113

  
114
	
115
	
116
	private List computeSelfNodesWithSnap() {
117
		LineIntersector li = new SnapLineIntersector(snapTolerance);
118
		SegmentIntersector si = new SegmentIntersector(li, true, false);
119
		SnapSimpleMCSweepLineIntersector esi = new SnapSimpleMCSweepLineIntersector();
120
		List edges = new ArrayList();
121
		Iterator edgesIt = graph.getEdgeIterator();
122
		while (edgesIt.hasNext()) {
123
			edges.add(edgesIt.next());
124
		}
125
		esi.computeIntersections(edges, si, true);
126
		return edges;
127
	}
128
	
129

  
130
	
131

  
132
//	public Geometry[] clean() {
133
//		if (!hasInitialized) {
134
//			initialize();
135
//			hasInitialized = true;
136
//		}// if
137
//		if (selfIntersections == null && selfIntersections.length < 1)
138
//			return new Geometry[] { lineString };
139
//		else
140
//			return LineStringSplitter.removeSelfIntersections(lineString,
141
//					selfIntersections, snapTolerance);
142
//	}
143

  
144
}
145

  
0 146

  

Also available in: Unified diff