Statistics
| Revision:

root / trunk / libraries / libTopology / src / org / gvsig / topology / topologyrules / PolygonMustNotSelfIntersect.java @ 19651

History | View | Annotate | Download (6.06 KB)

1
/*
2
 * Created on 07-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
 *
49
 */
50
package org.gvsig.topology.topologyrules;
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;
60
import org.gvsig.topology.AbstractTopologyRule;
61
import org.gvsig.topology.IRuleWithClusterTolerance;
62
import org.gvsig.topology.Messages;
63
import org.gvsig.topology.Topology;
64
import org.gvsig.topology.TopologyError;
65
import org.gvsig.topology.TopologyRuleDefinitionException;
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;
70
import com.iver.cit.gvsig.fmap.core.IFeature;
71
import com.iver.cit.gvsig.fmap.core.IGeometry;
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;
79

    
80
/**
81
 * The polygons of a layer must not have self intersections
82
 * 
83
 */
84
public class PolygonMustNotSelfIntersect extends AbstractTopologyRule implements
85
                IRuleWithClusterTolerance {
86

    
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) {
94
                super(topology, originLyr);
95
                this.clusterTolerance = clusterTolerance;
96
        }
97

    
98
        public PolygonMustNotSelfIntersect() {
99
        }
100

    
101
        public void checkPreconditions() throws TopologyRuleDefinitionException {
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
                }
110
        }
111

    
112
        public String getName() {
113
                return ruleName;
114
        }
115

    
116
        public void validateFeature(IFeature feature) {
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);
123
        }
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

    
183
        public double getClusterTolerance() {
184
                return clusterTolerance;
185
        }
186

    
187
        public void setClusterTolerance(double clusterTolerance) {
188
                this.clusterTolerance = clusterTolerance;
189
        }
190

    
191
        public boolean acceptsOriginLyr(FLyrVect lyr) {
192
                try {
193
                        return FGeometryUtil.getDimensions(lyr.getShapeType()) == 2;
194
                } catch (ReadDriverException e) {
195
                        return false;
196
                }
197
        }
198
}