Revision 19384 trunk/libraries/libTopology/src/org/gvsig/topology/topologyrules/LineMustNotHaveDangles.java

View differences:

LineMustNotHaveDangles.java
51 51

  
52 52
import java.awt.geom.Rectangle2D;
53 53

  
54
import org.gvsig.fmap.core.NewFConverter;
55
import org.gvsig.jts.JtsUtil;
56
import org.gvsig.jts.SnapLineStringSelfIntersectionChecker;
54 57
import org.gvsig.topology.AbstractTopologyRule;
58
import org.gvsig.topology.Messages;
55 59
import org.gvsig.topology.Topology;
60
import org.gvsig.topology.TopologyError;
61
import org.gvsig.topology.TopologyRuleDefinitionException;
56 62

  
63
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
64
import com.iver.cit.gvsig.fmap.core.FShape;
65
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
57 66
import com.iver.cit.gvsig.fmap.core.IFeature;
67
import com.iver.cit.gvsig.fmap.core.IGeometry;
68
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
69
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
70
import com.iver.cit.gvsig.fmap.edition.ISchemaManager;
58 71
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
72
import com.vividsolutions.jts.algorithms.SnapCGAlgorithms;
73
import com.vividsolutions.jts.geom.Coordinate;
74
import com.vividsolutions.jts.geom.Envelope;
75
import com.vividsolutions.jts.geom.Geometry;
76
import com.vividsolutions.jts.geom.GeometryCollection;
77
import com.vividsolutions.jts.geom.LineString;
78
import com.vividsolutions.jts.geom.Point;
79
import com.vividsolutions.jts.geom.Polygon;
59 80

  
60 81

  
61 82
/**
......
66 87
 */
67 88
public class LineMustNotHaveDangles extends AbstractTopologyRule {
68 89

  
69
	public LineMustNotHaveDangles(FLyrVect originLyr, Topology topology) {
70
		super(topology, originLyr );
90
	String ruleName = Messages.getText("must_not_have_dangles");
91
		
92
	double clusterTol;
93
	/**
94
	 * Default constructor
95
	 *
96
	 */
97
	public LineMustNotHaveDangles(Topology topology, FLyrVect originLyr, double clusterTol){
98
		super(topology, originLyr);
99
		this.clusterTol = clusterTol;
71 100
	}
72 101
	
102
	public LineMustNotHaveDangles(FLyrVect originLyr){
103
		super(originLyr);
104
	}
105
	
73 106
	public LineMustNotHaveDangles(){}
74

  
75
	@Override
107
	
76 108
	public String getName() {
77
		// TODO Auto-generated method stub
78
		return null;
109
		return ruleName;
79 110
	}
80 111

  
81
	@Override
82
	public void checkPreconditions() {
83
		// TODO Auto-generated method stub
84
		
112
	
113
	public void checkPreconditions() throws TopologyRuleDefinitionException {
114
		//This rule doesnt apply to Point vectorial layers.
115
		try {
116
			int shapeType = this.originLyr.getShapeType();
117
			if(shapeType != FShape.LINE || shapeType != FShape.MULTI)
118
				throw new TopologyRuleDefinitionException();
119
		} catch (ReadDriverException e) {
120
			e.printStackTrace();
121
			throw new TopologyRuleDefinitionException("Error leyendo el tipo de geometria del driver",e);
122
		}	
85 123
	}
86 124

  
87
	@Override
88
	public void checkRule() {
89
		// TODO Auto-generated method stub
90
		
91
	}
92

  
93
	@Override
125
	/**
126
	 * Validates this rule with a feature of the origin layer
127
	 * @param feature feature of the origin layer this rule is checking
128
	 */
94 129
	public void validateFeature(IFeature feature) {
95
		// TODO Auto-generated method stub
96 130
		
97
	}
98

  
99
	@Override
100
	public void checkRule(Rectangle2D rect) {
101
		// TODO Auto-generated method stub
131
		IGeometry geom = feature.getGeometry();
132
		int shapeType = geom.getGeometryType();
133
		if(shapeType != FShape.LINE && 
134
		   shapeType != FShape.ARC && 
135
		   shapeType != FShape.LINE + FShape.Z)
136
			return;
102 137
		
138
		Geometry jtsGeom = geom.toJTSGeometry();
139
		
140
		process(jtsGeom, feature);
141
	} 
142
	
143
	/**
144
	 * Utility class to check if a given linestring is a dangle
145
	 * (it has unconected extremes)
146
	 * 
147
	 * @author Alvaro Zabala
148
	 *
149
	 */
150
	class DangleChecker{
151
		Point end1;
152
		boolean ends1 = false;
153
		
154
		Point end2;
155
		boolean ends2 = false;
103 156
	}
104
 
157
	
158
	
159
	private void process(Geometry geometry, IFeature feature){
160
		if(geometry instanceof GeometryCollection){
161
			GeometryCollection geomCol = (GeometryCollection) geometry;
162
			for(int i = 0; i < geomCol.getNumGeometries(); i++){
163
				Geometry geomI = geomCol.getGeometryN(i);
164
				process(geomI, feature);
165
			}
166
		}else if(geometry instanceof LineString){
167
			LineString lineString = (LineString) geometry;
168
			
169
			//first of all, we check for a closed linestring
170
			//first point equals to last point.
171
			//This would not be a dangle
172
			if(JtsUtil.isClosed(lineString, clusterTol)){
173
				return;
174
			}
175
			
176
			
177
			Point end1 = lineString.getPointN(0);
178
			Point end2 = lineString.getPointN(lineString.getNumPoints() - 1);
179
			
180
			DangleChecker checker = new DangleChecker();
181
			checker.end1 = end1;
182
			checker.end2 = end2;
183
			
184
			Rectangle2D rect = NewFConverter.
185
				convertEnvelopeToRectangle2D(lineString.getEnvelopeInternal());
186
			try {
187
				IFeatureIterator neighbours = originLyr.
188
											 getSource().
189
											 getFeatureIterator(rect, null, null, false);
190
				while(neighbours.hasNext()){
191
					
192
					IFeature neighbourFeature = neighbours.next();
193
					Geometry geom2 = neighbourFeature.getGeometry().toJTSGeometry();
194
					process2(checker, geom2);
195
				}
196
				
197
				SnapLineStringSelfIntersectionChecker selfIntChecker = 
198
					new SnapLineStringSelfIntersectionChecker(lineString, clusterTol);
199
				selfIntChecker.setLineString(lineString);
200
				
201
				if(! checker.ends1){//dangling node
202
					//we check if its is a selfintersection
203
					//(if true, its not a dangling node)
204
					boolean isSelfIntersection = false;
205
					if(selfIntChecker.hasSelfIntersections()){
206
						Coordinate[] selfs = selfIntChecker.getSelfIntersections();
207
						for(int i = 0; i < selfs.length; i++){
208
							if(SnapCGAlgorithms.snapEquals2D(checker.end1.getCoordinate(), selfs[i], clusterTol)){
209
								isSelfIntersection = true;
210
							}
211
						}//for
212
					}
213
					if(! isSelfIntersection){
214
						IGeometry errorGeom = 
215
							ShapeFactory.createPoint2D(checker.end1.getX(),
216
													   checker.end1.getY());
217
					    TopologyError topologyError = 
218
							new TopologyError(errorGeom, 
219
												this, 
220
											 feature,
221
											topology);
222
					    topologyError.setID(errorContainer.getErrorFid());
223
					    addTopologyError(topologyError);
224
					}	
225
				}
226
				
227
				if(! checker.ends2){//dangling node
228
					boolean isSelfIntersection = false;
229
					if(selfIntChecker.hasSelfIntersections()){
230
						Coordinate[] selfs = selfIntChecker.getSelfIntersections();
231
						for(int i = 0; i < selfs.length; i++){
232
							if(SnapCGAlgorithms.snapEquals2D(checker.end1.getCoordinate(), selfs[i], clusterTol)){
233
								isSelfIntersection = true;
234
							}
235
						}//for
236
					}
237
					if(! isSelfIntersection){
238
						IGeometry errorGeom = 
239
							ShapeFactory.createPoint2D(checker.end2.getX(),
240
													   checker.end2.getY());
241
					    TopologyError topologyError = 
242
							new TopologyError(errorGeom, 
243
												this, 
244
											 feature,
245
											topology);
246
					    topologyError.setID(errorContainer.getErrorFid());
247
					    addTopologyError(topologyError);
248
					}	
249
				}
250
				
251
				if(! checker.ends2 && ! checker.ends1){//dangling line
252
					GeneralPathX gp = new GeneralPathX();
253
					gp.moveTo(checker.end1.getX(), checker.end1.getY());
254
					gp.lineTo(checker.end2.getX(), checker.end2.getY());
255
					IGeometry errorGeom = ShapeFactory.createPolyline2D(gp);
256
					TopologyError topologyError = 
257
							new TopologyError(errorGeom, 
258
												this, 
259
											 feature,
260
											topology);
261
				    topologyError.setID(errorContainer.getErrorFid());
262
				    addTopologyError(topologyError);
263
				}
264
				
265
			} catch (ReadDriverException e) {
266
				e.printStackTrace();
267
				return;
268
			}
269
			
270
		}else{
271
			System.out.println("Encontrado:"+geometry.toString()+" en regla de dangles");
272
		}
273
	}
274
	
275
	
276
	private void process2(DangleChecker checker, Geometry intersectingGeom){
277
		if(intersectingGeom instanceof LineString){
278
			LineString lineString = (LineString) intersectingGeom;
279
			
280
			Envelope snapEnvelope = JtsUtil.
281
				toSnapRectangle(checker.end1.getCoordinate(), clusterTol);
282
			Geometry snapPolygon = null;
283
//			if(lineString.intersects(checker.end1)){
284
			if(lineString.getEnvelopeInternal().intersects(snapEnvelope)){
285
				snapPolygon = JtsUtil.geomFactory.toGeometry(snapEnvelope);
286
				if(lineString.intersects(snapPolygon))
287
					checker.ends1 = true;
288
			}
289
			
290
			snapEnvelope = JtsUtil.
291
				toSnapRectangle(checker.end2.getCoordinate(), clusterTol);
292
//			if(lineString.intersects(checker.end2)){
293
			if(lineString.getEnvelopeInternal().intersects(snapEnvelope)){
294
				snapPolygon = JtsUtil.geomFactory.toGeometry(snapEnvelope);
295
				if(lineString.intersects(snapPolygon))
296
					checker.ends2 = true;
297
			}
298
			
299
		}else if(intersectingGeom instanceof GeometryCollection){
300
			GeometryCollection geomCol = (GeometryCollection) intersectingGeom;
301
			for(int i = 0; i < geomCol.getNumGeometries(); i++){
302
				Geometry geomI = geomCol.getGeometryN(i);
303
				process2(checker, geomI);
304
			}
305
		}else{
306
			System.out.println("Encontrado:"+intersectingGeom.toString()+" en regla de dangles");
307
		}
308
	}
105 309
}
106 310
 

Also available in: Unified diff