Statistics
| Revision:

root / trunk / extensions / extCAD / src / com / iver / cit / gvsig / TopologyExtension.java @ 6945

History | View | Annotate | Download (9.03 KB)

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

    
43
import java.awt.Color;
44
import java.util.ArrayList;
45
import java.util.Collection;
46
import java.util.Iterator;
47

    
48
import com.iver.andami.PluginServices;
49
import com.iver.andami.messages.NotificationManager;
50
import com.iver.andami.plugins.Extension;
51
import com.iver.andami.ui.mdiManager.IWindow;
52
import com.iver.cit.gvsig.fmap.DriverException;
53
import com.iver.cit.gvsig.fmap.MapControl;
54
import com.iver.cit.gvsig.fmap.core.FPoint2D;
55
import com.iver.cit.gvsig.fmap.core.FShape;
56
import com.iver.cit.gvsig.fmap.core.IGeometry;
57
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
58
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
59
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
60
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
61
import com.iver.cit.gvsig.fmap.layers.FBitSet;
62
import com.iver.cit.gvsig.fmap.layers.FLayer;
63
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
64
import com.iver.cit.gvsig.fmap.layers.GraphicLayer;
65
import com.iver.cit.gvsig.fmap.rendering.FGraphic;
66
import com.iver.cit.gvsig.gui.View;
67
import com.vividsolutions.jts.geom.Coordinate;
68
import com.vividsolutions.jts.geom.CoordinateArrays;
69
import com.vividsolutions.jts.geom.Geometry;
70
import com.vividsolutions.jts.geom.LineString;
71
import com.vividsolutions.jts.geom.Polygon;
72
import com.vividsolutions.jts.operation.polygonize.Polygonizer;
73
import com.vividsolutions.jts.planargraph.Node;
74
import com.vividsolutions.jts.planargraph.NodeMap;
75

    
76
/**
77
 * @author fjp
78
 * Primera prueba acerca de la creaci?n de pol?gonos a partir de una
79
 * capa de l?neas
80
 *
81
 */
82
public class TopologyExtension extends Extension {
83
        
84
        
85
        private class MyNode extends Node
86
        {
87
                public MyNode(Coordinate pt) {
88
                        super(pt);
89
                        occurrences = 1;
90
                }
91

    
92
                int occurrences;
93

    
94
                public int getOccurrences() {
95
                        return occurrences;
96
                }
97

    
98
                public void setOccurrences(int occurrences) {
99
                        this.occurrences = occurrences;
100
                }
101
                
102
        }
103
        
104
        /**
105
         * @see com.iver.andami.plugins.IExtension#initialize()
106
         */
107
        public void initialize() {
108
        }
109

    
110
        /**
111
         * @see com.iver.andami.plugins.IExtension#execute(java.lang.String)
112
         */
113
        public void execute(String s) {
114
                View v = (View) PluginServices.getMDIManager().getActiveWindow();
115
                MapControl mc = v.getMapControl();
116
                FLayer[] actives = mc.getMapContext().getLayers().getActives();
117
                for (int i = 0; i < actives.length; i++) {
118
                        if (actives[i] instanceof FLyrVect) {
119
                                FLyrVect lv = (FLyrVect) actives[i];
120
                                if (s.compareTo("CLEAN") == 0)                                        
121
                                        doClean(lv);
122
                                if (s.compareTo("SHOW_ERRORS") == 0)
123
                                        try {
124
                                                doShowNodeErrors(lv);
125
                                        } catch (DriverException e) {
126
                                                e.printStackTrace();
127
                                                NotificationManager.addError(e);
128
                                        } catch (DriverIOException e) {
129
                                                e.printStackTrace();
130
                                                NotificationManager.addError(e);
131
                                        }
132
                                
133
                        }
134
                }
135
                
136

    
137
        }
138

    
139

    
140
        /**
141
         * @param lv FLayerVect de l?neas para convertir a pol?gonos.
142
         */
143
        private void doClean(FLyrVect lv) {
144
                Polygonizer polygonizer = new Polygonizer();
145
                
146
                View v = (View) PluginServices.getMDIManager().getActiveWindow();
147
                MapControl mc = v.getMapControl();
148

    
149
                
150
                try {
151
                        FBitSet bitSet = lv.getRecordset().getSelection();
152
                        
153
                        // First, we need to do "noding"
154
                        // TODO: This step must be optional
155
                        ArrayList lineStrings = new ArrayList();
156
                        for(int i=bitSet.nextSetBit(0); i>=0; i=bitSet.nextSetBit(i+1)) {
157
                                IGeometry g = lv.getSource().getShape(i);
158
                                lineStrings.add(g.toJTSGeometry());                                 
159
                        }
160

    
161
                        Geometry nodedLineStrings = (Geometry) lineStrings.get(0);
162
                        for (int i = 1; i < lineStrings.size(); i++) {
163
                                nodedLineStrings = nodedLineStrings.union((Geometry)lineStrings.get(i));
164
                        }
165
                        
166
                        // FIN noding 
167
                        
168

    
169
                        polygonizer.add(nodedLineStrings);                                 
170
                        Collection polygons = polygonizer.getPolygons();
171
                        Iterator it = polygons.iterator();
172
                        GraphicLayer graphicLayer = mc.getMapContext().getGraphicsLayer();
173
                        int idSymbolPol = graphicLayer.addSymbol(new FSymbol(FShape.POLYGON));
174
                        int idSymbolCutEdge = graphicLayer.addSymbol(new FSymbol(FShape.LINE, Color.BLUE));
175
                        int idSymbolDangle = graphicLayer.addSymbol(new FSymbol(FShape.LINE, Color.RED));
176
                        while (it.hasNext())
177
                        {
178
                                Polygon pol = (Polygon) it.next();
179
                                IGeometry gAux = FConverter.jts_to_igeometry(pol);
180
                                FGraphic graphic = new FGraphic(gAux, idSymbolPol);
181
                                graphicLayer.addGraphic(graphic);
182
                        }
183
                        
184
                        // LINEAS QUE PARTEN POLIGONOS
185
                        Collection cutEdges = polygonizer.getCutEdges(); 
186
                        it = cutEdges.iterator(); 
187
                        while (it.hasNext())
188
                        {
189
                                LineString lin = (LineString) it.next();
190
                                IGeometry gAux = FConverter.jts_to_igeometry(lin);
191
                                FGraphic graphic = new FGraphic(gAux, idSymbolCutEdge);
192
                                graphicLayer.addGraphic(graphic);
193
                        }
194
                        
195
                        // LINEAS COLGANTES, QUE NO FORMAN POLIGONO
196
                        Collection dangles = polygonizer.getDangles(); 
197
                        it = dangles.iterator(); 
198
                        while (it.hasNext())
199
                        {
200
                                LineString lin = (LineString) it.next();
201
                                IGeometry gAux = FConverter.jts_to_igeometry(lin);
202
                                FGraphic graphic = new FGraphic(gAux, idSymbolDangle);
203
                                graphicLayer.addGraphic(graphic);
204
                        }
205
                        
206
                        
207
                        mc.drawGraphics();
208
                } catch (DriverException e) {
209
                        e.printStackTrace();
210
                        NotificationManager.addError(e);
211
                } catch (DriverIOException e) {
212
                        e.printStackTrace();
213
                        NotificationManager.addError(e);
214
                }
215
                
216
        }
217
        
218
        /**
219
         * We search for origin-endpoints in LineString. Each one will
220
         * generate a Node. We also fill a map Node-numOccurrences.
221
         * Dangle and Fuzzy nodes will be those that have an occurrence
222
         * count = 1. (Node with degree cero in graph's language)
223
         * @param lyr
224
         * @throws DriverException 
225
         * @throws DriverIOException 
226
         */
227
        private void doShowNodeErrors(FLyrVect lv) throws DriverException, DriverIOException
228
        {
229
                View v = (View) PluginServices.getMDIManager().getActiveWindow();
230
                MapControl mc = v.getMapControl();
231

    
232
//                ArrayList nodeErrors = new ArrayList();
233
                NodeMap nodeMap = new NodeMap();
234
                FBitSet bitSet = lv.getRecordset().getSelection();
235
                
236
                for(int i=bitSet.nextSetBit(0); i>=0; i=bitSet.nextSetBit(i+1)) {
237
                        IGeometry g = lv.getSource().getShape(i);
238
                        Geometry jtsG = g.toJTSGeometry();
239
                        Coordinate[] coords = jtsG.getCoordinates();
240
                    if (jtsG.isEmpty()) 
241
                            continue;
242
                    Coordinate[] linePts = CoordinateArrays.removeRepeatedPoints(coords);
243
                    Coordinate startPt = linePts[0];
244
                    Coordinate endPt = linePts[linePts.length - 1];
245

    
246
                    MyNode nStart = (MyNode) nodeMap.find(startPt);
247
                    MyNode nEnd = (MyNode) nodeMap.find(endPt);
248
                    if (nStart == null)
249
                    {
250
                            nStart = new MyNode(startPt);
251
                            nodeMap.add(nStart);
252
                    }
253
                    else
254
                            nStart.setOccurrences(nStart.getOccurrences()+1);
255
                    if (nEnd == null)
256
                    {
257
                            nEnd = new MyNode(endPt);
258
                            nodeMap.add(nEnd);
259
                    }
260
                    else
261
                            nEnd.setOccurrences(nEnd.getOccurrences()+1);
262

    
263
                }
264
                
265
                // Ahora recorremos todos los nodos y los que solo hayan sido
266
                // a?adidos una vez, son dangle o fuzzy.
267
                // TODO: Poner una tolerancia para que las coordinate cercanas
268
                // formen un solo nodo.
269
                GraphicLayer graphicLayer = mc.getMapContext().getGraphicsLayer();
270
                int idSymbolPoint = graphicLayer.addSymbol(new FSymbol(FShape.POINT));
271
                
272
                Iterator it = nodeMap.iterator();
273
                while (it.hasNext())
274
                {
275
                        MyNode node = (MyNode) it.next();
276
                        if (node.getOccurrences() == 1)
277
                        {                                
278
                                FPoint2D p = FConverter.coordinate2FPoint2D(node.getCoordinate());
279
                                IGeometry gAux = ShapeFactory.createPoint2D(p);
280
                                FGraphic graphic = new FGraphic(gAux, idSymbolPoint);
281
                                graphicLayer.addGraphic(graphic);
282

    
283
                                
284
                        }
285
                }
286
                mc.drawGraphics();
287
        }
288
        
289

    
290
        /**
291
         * @see com.iver.andami.plugins.IExtension#isEnabled()
292
         */
293
        public boolean isEnabled() {
294
                View v = (View) PluginServices.getMDIManager().getActiveWindow();
295
                MapControl mc = v.getMapControl();
296
                if (mc.getMapContext().getLayers().getActives().length > 0)
297
                        return true;
298
                return false;
299
        }
300

    
301
        /**
302
         * @see com.iver.andami.plugins.IExtension#isVisible()
303
         */
304
        public boolean isVisible() {
305
                IWindow v = PluginServices.getMDIManager().getActiveWindow();
306
                if (v instanceof View)
307
                        return true;
308
                return false;
309
        }
310

    
311
}
312

    
313