49 |
49 |
*/
|
50 |
50 |
package org.gvsig.topology.topologyrules;
|
51 |
51 |
|
|
52 |
import java.util.ArrayList;
|
|
53 |
import java.util.Arrays;
|
|
54 |
import java.util.Iterator;
|
|
55 |
import java.util.List;
|
|
56 |
|
|
57 |
import org.gvsig.fmap.core.FGeometryUtil;
|
|
58 |
import org.gvsig.jts.JtsUtil;
|
|
59 |
import org.gvsig.jts.SnapLineStringSelfIntersectionChecker;
|
52 |
60 |
import org.gvsig.topology.AbstractTopologyRule;
|
53 |
61 |
import org.gvsig.topology.IRuleWithClusterTolerance;
|
|
62 |
import org.gvsig.topology.Messages;
|
54 |
63 |
import org.gvsig.topology.Topology;
|
|
64 |
import org.gvsig.topology.TopologyError;
|
55 |
65 |
import org.gvsig.topology.TopologyRuleDefinitionException;
|
56 |
66 |
|
|
67 |
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
|
|
68 |
import com.iver.cit.gvsig.fmap.core.FMultiPoint2D;
|
|
69 |
import com.iver.cit.gvsig.fmap.core.FShape;
|
57 |
70 |
import com.iver.cit.gvsig.fmap.core.IFeature;
|
|
71 |
import com.iver.cit.gvsig.fmap.core.IGeometry;
|
58 |
72 |
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
|
|
73 |
import com.vividsolutions.jts.geom.Coordinate;
|
|
74 |
import com.vividsolutions.jts.geom.Geometry;
|
|
75 |
import com.vividsolutions.jts.geom.GeometryCollection;
|
|
76 |
import com.vividsolutions.jts.geom.LineString;
|
|
77 |
import com.vividsolutions.jts.geom.MultiPolygon;
|
|
78 |
import com.vividsolutions.jts.geom.Polygon;
|
59 |
79 |
|
60 |
|
|
61 |
80 |
/**
|
62 |
|
*The polygons of a layer must not have self intersections
|
63 |
|
*
|
|
81 |
* The polygons of a layer must not have self intersections
|
|
82 |
*
|
64 |
83 |
*/
|
65 |
|
public class PolygonMustNotSelfIntersect
|
66 |
|
extends AbstractTopologyRule
|
67 |
|
implements IRuleWithClusterTolerance{
|
|
84 |
public class PolygonMustNotSelfIntersect extends AbstractTopologyRule implements
|
|
85 |
IRuleWithClusterTolerance {
|
68 |
86 |
|
69 |
|
public PolygonMustNotSelfIntersect(Topology topology, FLyrVect originLyr) {
|
|
87 |
private static String ruleName = Messages
|
|
88 |
.getText("polygon_must_not_self_intersect");
|
|
89 |
|
|
90 |
private double clusterTolerance;
|
|
91 |
|
|
92 |
public PolygonMustNotSelfIntersect(Topology topology, FLyrVect originLyr,
|
|
93 |
double clusterTolerance) {
|
70 |
94 |
super(topology, originLyr);
|
|
95 |
this.clusterTolerance = clusterTolerance;
|
71 |
96 |
}
|
72 |
|
|
73 |
|
public PolygonMustNotSelfIntersect(){}
|
74 |
97 |
|
|
98 |
public PolygonMustNotSelfIntersect() {
|
|
99 |
}
|
|
100 |
|
75 |
101 |
public void checkPreconditions() throws TopologyRuleDefinitionException {
|
76 |
|
// TODO Auto-generated method stub
|
77 |
|
|
|
102 |
try {
|
|
103 |
if (FGeometryUtil.getDimensions(originLyr.getShapeType()) != 2)
|
|
104 |
throw new TopologyRuleDefinitionException(
|
|
105 |
"La capa no es de poligonos o multigeometrias");
|
|
106 |
} catch (ReadDriverException e) {
|
|
107 |
throw new TopologyRuleDefinitionException(
|
|
108 |
"Error de driver al chequear las precondiciones de la regla");
|
|
109 |
}
|
78 |
110 |
}
|
79 |
111 |
|
80 |
112 |
public String getName() {
|
81 |
|
// TODO Auto-generated method stub
|
82 |
|
return null;
|
|
113 |
return ruleName;
|
83 |
114 |
}
|
84 |
115 |
|
85 |
116 |
public void validateFeature(IFeature feature) {
|
86 |
|
// TODO Auto-generated method stub
|
87 |
|
|
|
117 |
IGeometry geom = feature.getGeometry();
|
|
118 |
int shapeType = geom.getGeometryType();
|
|
119 |
if(FGeometryUtil.getDimensions(shapeType) != 2)
|
|
120 |
return;
|
|
121 |
Geometry jtsGeom = geom.toJTSGeometry();
|
|
122 |
process(jtsGeom, feature);
|
88 |
123 |
}
|
89 |
124 |
|
|
125 |
protected void process(Geometry jtsGeom, IFeature feature) {
|
|
126 |
if (jtsGeom instanceof MultiPolygon) {
|
|
127 |
MultiPolygon multi = (MultiPolygon) jtsGeom;
|
|
128 |
int numPol = multi.getNumGeometries();
|
|
129 |
for (int i = 0; i < numPol; i++) {
|
|
130 |
Polygon pol = (Polygon) multi.getGeometryN(i);
|
|
131 |
process(pol, feature);
|
|
132 |
}
|
|
133 |
} else if (jtsGeom instanceof GeometryCollection) {
|
|
134 |
MultiPolygon multi = JtsUtil
|
|
135 |
.convertToMultiPolygon((GeometryCollection) jtsGeom);
|
|
136 |
process(multi, feature);
|
|
137 |
|
|
138 |
} else if (jtsGeom instanceof Polygon) {
|
|
139 |
Polygon pol = (Polygon) jtsGeom;
|
|
140 |
List<Coordinate> selfIntersections = new ArrayList<Coordinate>();
|
|
141 |
LineString shell = pol.getExteriorRing();
|
|
142 |
SnapLineStringSelfIntersectionChecker checker = new SnapLineStringSelfIntersectionChecker(
|
|
143 |
shell, getClusterTolerance());
|
|
144 |
if (checker.hasSelfIntersections()) {
|
|
145 |
Coordinate[] selfIntersection = checker.getSelfIntersections();
|
|
146 |
selfIntersections.addAll(Arrays.asList(selfIntersection));
|
|
147 |
}
|
|
148 |
|
|
149 |
int numHoles = pol.getNumInteriorRing();
|
|
150 |
for (int i = 0; i < numHoles; i++) {
|
|
151 |
LineString hole = pol.getInteriorRingN(i);
|
|
152 |
checker = new SnapLineStringSelfIntersectionChecker(hole,
|
|
153 |
getClusterTolerance());
|
|
154 |
if (checker.hasSelfIntersections()) {
|
|
155 |
Coordinate[] selfIntersection = checker
|
|
156 |
.getSelfIntersections();
|
|
157 |
selfIntersections.addAll(Arrays.asList(selfIntersection));
|
|
158 |
}// if
|
|
159 |
}// for
|
|
160 |
|
|
161 |
if (selfIntersections.size() > 0) {
|
|
162 |
Iterator<Coordinate> coordsIt = selfIntersections.iterator();
|
|
163 |
int count = 0;
|
|
164 |
int numberOfSelfCoords = selfIntersections.size();
|
|
165 |
double[] x = new double[numberOfSelfCoords];
|
|
166 |
double[] y = new double[numberOfSelfCoords];
|
|
167 |
while (coordsIt.hasNext()) {
|
|
168 |
Coordinate coord = (Coordinate) coordsIt.next();
|
|
169 |
x[count] = coord.x;
|
|
170 |
y[count] = coord.y;
|
|
171 |
count++;
|
|
172 |
}
|
|
173 |
|
|
174 |
FMultiPoint2D multiPoint = new FMultiPoint2D(x, y);
|
|
175 |
TopologyError topologyError = new TopologyError(multiPoint,
|
|
176 |
this, feature, topology);
|
|
177 |
topologyError.setID(errorContainer.getErrorFid());
|
|
178 |
addTopologyError(topologyError);
|
|
179 |
}//if
|
|
180 |
}// if polygon
|
|
181 |
}
|
|
182 |
|
90 |
183 |
public double getClusterTolerance() {
|
91 |
|
// TODO Auto-generated method stub
|
92 |
|
return 0;
|
|
184 |
return clusterTolerance;
|
93 |
185 |
}
|
94 |
186 |
|
95 |
187 |
public void setClusterTolerance(double clusterTolerance) {
|
96 |
|
// TODO Auto-generated method stub
|
97 |
|
|
|
188 |
this.clusterTolerance = clusterTolerance;
|
98 |
189 |
}
|
99 |
190 |
|
100 |
|
public boolean acceptsOriginLyr(FLyrVect originLyr) {
|
101 |
|
// TODO Auto-generated method stub
|
102 |
|
return false;
|
|
191 |
public boolean acceptsOriginLyr(FLyrVect lyr) {
|
|
192 |
try {
|
|
193 |
return FGeometryUtil.getDimensions(lyr.getShapeType()) == 2;
|
|
194 |
} catch (ReadDriverException e) {
|
|
195 |
return false;
|
|
196 |
}
|
103 |
197 |
}
|
104 |
|
|
105 |
|
|
106 |
|
|
107 |
198 |
}
|
108 |
|
|