Statistics
| Revision:

root / trunk / libraries / libTopology / src / org / gvsig / topology / topologyrules / jtsisvalidrules / PolygonMustHaveConnectedInterior.java @ 23036

History | View | Annotate | Download (7.22 KB)

1
/*
2
 * Created on 10-abr-2006
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
package org.gvsig.topology.topologyrules.jtsisvalidrules;
50

    
51
import java.awt.Color;
52
import java.util.ArrayList;
53
import java.util.List;
54

    
55
import org.gvsig.fmap.core.FGeometryUtil;
56
import org.gvsig.jts.JtsUtil;
57
import org.gvsig.topology.AbstractTopologyRule;
58
import org.gvsig.topology.ITopologyErrorFix;
59
import org.gvsig.topology.Messages;
60
import org.gvsig.topology.Topology;
61
import org.gvsig.topology.TopologyRuleDefinitionException;
62
import org.gvsig.topology.WrongLyrForTopologyException;
63
import org.gvsig.topology.topologyrules.JtsValidRule;
64

    
65
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
66
import com.iver.cit.gvsig.fmap.core.FPoint2D;
67
import com.iver.cit.gvsig.fmap.core.FShape;
68
import com.iver.cit.gvsig.fmap.core.IFeature;
69
import com.iver.cit.gvsig.fmap.core.IGeometry;
70
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
71
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
72
import com.iver.cit.gvsig.fmap.core.symbols.MultiShapeSymbol;
73
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
74
import com.vividsolutions.jts.geom.Coordinate;
75
import com.vividsolutions.jts.geom.Geometry;
76
import com.vividsolutions.jts.geom.GeometryCollection;
77
import com.vividsolutions.jts.geom.MultiPolygon;
78
import com.vividsolutions.jts.geom.Polygon;
79
import com.vividsolutions.jts.geom.TopologyException;
80
import com.vividsolutions.jts.geomgraph.GeometryGraph;
81
import com.vividsolutions.jts.operation.valid.ConnectedInteriorTester;
82

    
83
/**
84
 * 
85
 * Esta regla chequea que los holes de un pol?gono, que por definicion pueden
86
 * tocarse entre s? en un punto as? como con el borde exterior hagan que el interior
87
 * del poligono est? inconexo.
88
 * 
89
 * 
90
 * 
91
 * @author Alvaro Zabala
92
 *
93
 */
94
public class PolygonMustHaveConnectedInterior extends AbstractTopologyRule {
95
        
96
        private static String RULE_NAME = Messages.getText("POLYGON_MUST_NOT_HAVE_INTERSECTED_RINGS");
97
        
98
        private static List<ITopologyErrorFix> automaticErrorFixes = new ArrayList<ITopologyErrorFix>();
99
        
100

    
101
        private static final Color DEFAULT_ERROR_COLOR = Color.BLACK;
102

    
103
        private static final MultiShapeSymbol DEFAULT_ERROR_SYMBOL = 
104
                (MultiShapeSymbol) SymbologyFactory.createDefaultSymbolByShapeType(FShape.MULTI, 
105
                                                                                        DEFAULT_ERROR_COLOR);
106
        static{
107
                DEFAULT_ERROR_SYMBOL.setDescription(RULE_NAME);
108
                DEFAULT_ERROR_SYMBOL.setSize(2);
109
        }
110

    
111

    
112
        private MultiShapeSymbol errorSymbol;
113
        
114
        
115
        JtsValidRule parentRule;
116
        
117
        public PolygonMustHaveConnectedInterior(Topology topology,
118
                        FLyrVect originLyr) {
119
                super(topology, originLyr);
120
        }
121
        
122
        public PolygonMustHaveConnectedInterior(FLyrVect originLyr) {
123
                super(originLyr);
124
        }
125
        
126
        public PolygonMustHaveConnectedInterior(){}
127
        
128

    
129
        public String getName() {
130
                return RULE_NAME;
131
        }
132

    
133
        public void checkPreconditions() throws TopologyRuleDefinitionException {
134
                int shapeType;
135
                try {
136
                        shapeType = this.originLyr.getShapeType();
137
                        int numDimensions = FGeometryUtil.getDimensions(shapeType);
138
                        if(numDimensions != 2)
139
                                throw new WrongLyrForTopologyException("MustNotHaveHoles solo aplica sobre capas de dimension 2");
140
                } catch (ReadDriverException e) {
141
                        throw new TopologyRuleDefinitionException(
142
                                        "Error al tratar de verificar el tipo de geometria");
143
                }
144
        }
145

    
146
        public void validateFeature(IFeature feature) {
147
                Geometry jtsGeo = feature.getGeometry().toJTSGeometry();
148
                if (jtsGeo instanceof Polygon) {
149
                        GeometryGraph graph = new GeometryGraph(0, jtsGeo);
150
                        checkConnectedInteriors(graph, feature);
151
                } else if (jtsGeo instanceof MultiPolygon) {
152
                        MultiPolygon multiPoly = (MultiPolygon) jtsGeo;
153
                        for (int i = 0; i < multiPoly.getNumGeometries(); i++) {
154
                                Polygon polygon = (Polygon) multiPoly.getGeometryN(i);
155
                                GeometryGraph graph = new GeometryGraph(0, polygon);
156
                                checkConnectedInteriors(graph, feature);
157
                        }
158
                } else if (jtsGeo instanceof GeometryCollection) {
159
                        MultiPolygon multiPoly = JtsUtil
160
                                        .convertToMultiPolygon((GeometryCollection) jtsGeo);
161
                        for (int i = 0; i < multiPoly.getNumGeometries(); i++) {
162
                                Polygon polygon = (Polygon) multiPoly.getGeometryN(i);
163
                                GeometryGraph graph = new GeometryGraph(0, polygon);
164
                                checkConnectedInteriors(graph, feature);
165
                        }//for
166
                }
167

    
168
        }
169

    
170
        private void checkConnectedInteriors(GeometryGraph graph, IFeature feature) {
171
                ConnectedInteriorTester cit = new ConnectedInteriorTester(graph);
172
                try{
173
                        if (!cit.isInteriorsConnected()){
174
                                Coordinate coord = cit.getCoordinate();
175
                                FPoint2D pt = new FPoint2D(coord.x, coord.y);
176
                                IGeometry geometry = ShapeFactory.createGeometry(pt);
177
                                AbstractTopologyRule violatedRule = null;
178
                                if(this.parentRule != null)
179
                                        violatedRule = parentRule;
180
                                else
181
                                        violatedRule = this;
182
                                JtsValidTopologyError error = 
183
                                        new JtsValidTopologyError(geometry, violatedRule, feature, topology);
184
                                addTopologyError(error);
185
                        }
186
                }catch(TopologyException e){
187
                        //In unit tests JTS has throwed this exception POLYGON ((440 260, 500 300, 660 300, 600 200, 440 260, 440 260), (440 260, 600 200, 660 300, 500 300, 440 260))
188
                        e.printStackTrace();
189
                        AbstractTopologyRule violatedRule = null;
190
                        if(this.parentRule != null)
191
                                violatedRule = parentRule;
192
                        else
193
                                violatedRule = this;
194
                        JtsValidTopologyError error = 
195
                                new JtsValidTopologyError(feature.getGeometry(), violatedRule, feature, topology);
196
                        addTopologyError(error);
197
                        
198
                }
199
        }
200

    
201
        public JtsValidRule getParentRule() {
202
                return parentRule;
203
        }
204

    
205
        public void setParentRule(JtsValidRule parentRule) {
206
                this.parentRule = parentRule;
207
        }
208
        
209
        public boolean acceptsOriginLyr(FLyrVect lyr) {
210
                try {
211
                        return FGeometryUtil.getDimensions(lyr.getShapeType()) == 2;
212
                } catch (ReadDriverException e) {
213
                        e.printStackTrace();
214
                        return false;
215
                }
216
        }
217

    
218
        public List<ITopologyErrorFix> getAutomaticErrorFixes() {
219
                return automaticErrorFixes;
220
        }
221

    
222
        public MultiShapeSymbol getDefaultErrorSymbol() {
223
                return DEFAULT_ERROR_SYMBOL;
224
        }
225

    
226
        public MultiShapeSymbol getErrorSymbol() {
227
                return errorSymbol;
228
        }
229
}