Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGeoprocessingExtensions / src / com / iver / cit / gvsig / topology / lineclean / fmap / LineCleanVisitor.java @ 9182

History | View | Annotate | Download (26.3 KB)

1
/*
2
 * Created on 10-oct-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: LineCleanVisitor.java 9182 2006-12-04 19:43:54Z azabala $
47
 * $Log$
48
 * Revision 1.1  2006-12-04 19:42:23  azabala
49
 * *** empty log message ***
50
 *
51
 * Revision 1.7  2006/11/14 18:34:16  azabala
52
 * *** empty log message ***
53
 *
54
 * Revision 1.6  2006/11/14 18:01:09  azabala
55
 * removed system.out.println
56
 *
57
 * Revision 1.5  2006/11/13 20:41:08  azabala
58
 * *** empty log message ***
59
 *
60
 * Revision 1.4  2006/10/19 16:06:48  azabala
61
 * *** empty log message ***
62
 *
63
 * Revision 1.3  2006/10/17 18:27:24  azabala
64
 * *** empty log message ***
65
 *
66
 * Revision 1.1  2006/10/10 18:50:17  azabala
67
 * First version in CVS
68
 *
69
 *
70
 */
71
package com.iver.cit.gvsig.topology.lineclean.fmap;
72

    
73
import java.util.ArrayList;
74
import java.util.Arrays;
75
import java.util.Collections;
76
import java.util.Comparator;
77
import java.util.Iterator;
78

    
79
import com.hardcode.gdbms.engine.data.driver.DriverException;
80
import com.hardcode.gdbms.engine.values.Value;
81
import com.hardcode.gdbms.engine.values.ValueFactory;
82
import com.iver.cit.gvsig.fmap.core.IFeature;
83
import com.iver.cit.gvsig.fmap.core.IGeometry;
84
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
85
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
86
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
87
import com.iver.cit.gvsig.fmap.edition.EditionException;
88
import com.iver.cit.gvsig.fmap.layers.FBitSet;
89
import com.iver.cit.gvsig.fmap.layers.FLayer;
90
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
91
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
92
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
93
import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData;
94
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
95
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
96
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
97
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
98
import com.iver.cit.gvsig.geoprocess.core.fmap.FeatureFactory;
99
import com.iver.cit.gvsig.geoprocess.core.fmap.FeaturePersisterProcessor2;
100
import com.iver.cit.gvsig.geoprocess.core.fmap.FeatureProcessor;
101
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes;
102
import com.iver.cit.gvsig.util.SnappingCoordinateMap;
103
import com.vividsolutions.jts.geom.Coordinate;
104
import com.vividsolutions.jts.geom.Geometry;
105
import com.vividsolutions.jts.geom.GeometryCollection;
106
import com.vividsolutions.jts.geom.GeometryFactory;
107
import com.vividsolutions.jts.geom.LineString;
108
import com.vividsolutions.jts.geom.MultiLineString;
109
import com.vividsolutions.jts.geom.MultiPoint;
110
import com.vividsolutions.jts.geom.Point;
111
import com.vividsolutions.jts.geom.Polygon;
112
import com.vividsolutions.jts.geomgraph.Node;
113
import com.vividsolutions.jts.geomgraph.NodeFactory;
114
import com.vividsolutions.jts.geomgraph.SnappingNodeMap;
115
import com.vividsolutions.jts.linearref.LengthIndexedLine;
116
import com.vividsolutions.jts.linearref.LinearLocation;
117
import com.vividsolutions.jts.linearref.LocationIndexedLine;
118
import com.vividsolutions.jts.operation.overlay.SnappingOverlayOperation;
119

    
120
/**
121
 * <p>
122
 * This visitor operates with features whose geometries are lines. <br>
123
 * For each visited feature, it looks for features in its proximity (spatial
124
 * query). If these features hasnt been processed, it intersects the visited
125
 * feature with all of the neighbour features. If intersection points are not
126
 * nodes (end points), it ignores them. split the
127
 * </p>
128
 * 
129
 * @author azabala
130
 */
131
public class LineCleanVisitor implements FeatureVisitor {
132

    
133
        /**
134
         * Recordset of the layer we are working with
135
         */
136
        protected SelectableDataSource recordset;
137

    
138
        /**
139
         * Layer which we are cleaning
140
         */
141
        protected FLyrVect layerToClean;
142

    
143
        /**
144
         * marks if we are going to clean only layer selection
145
         */
146
        protected boolean cleanOnlySelection;
147

    
148
        /*
149
         * TODO Meter esto en preferencias
150
         */
151
        public final static double DEFAULT_SNAP = 0.1;
152

    
153
        protected double snapTolerance = DEFAULT_SNAP;
154

    
155
        /**
156
         * It marks all processed features (to ignore them in future intersections)
157
         */
158
        protected FBitSet processedFeatures;
159

    
160
        /**
161
         * Strategy of the layer we are working with.
162
         */
163
        protected Strategy strategy;
164

    
165
        /**
166
         * Saves features resulting of cleaning process
167
         */
168
        protected FeatureProcessor featureProcessor;
169

    
170
        protected ILayerDefinition layerDefinition;
171
        
172
        
173
        /**
174
         * Saves pseudonodes found
175
         * */
176
        protected FeatureProcessor intersectProcessor;
177
        protected ILayerDefinition intersectDefinition;
178
        
179
        
180
        /**
181
         * Counter of new features
182
         */
183
        int fid = 0;
184
        
185
        /**
186
         * It caches all written pseudonodes, to avoid 
187
         * writing the same pseudonode twice.
188
         * 
189
         * */
190
        SnappingCoordinateMap snapCoordMap;
191
        
192
        /**
193
         * Constructor.
194
         * @param processor
195
         * @param intersectsProcessor
196
         * @param cleanOnlySelection
197
         * @param layerDefinition
198
         * @param intersectDefinition
199
         * @param firstLayer
200
         * @param source
201
         * @param snapCoordMap
202
         */
203
        public LineCleanVisitor(FeatureProcessor processor,
204
                        FeaturePersisterProcessor2 intersectsProcessor, 
205
                                                                        boolean cleanOnlySelection, 
206
                                                                        ILayerDefinition layerDefinition, 
207
                                                                        ILayerDefinition intersectDefinition, 
208
                                                                        FLyrVect firstLayer, 
209
                                                                        SelectableDataSource source,
210
                                                                        SnappingCoordinateMap snapCoordMap) {
211
                this.featureProcessor = processor;
212
                this.cleanOnlySelection = cleanOnlySelection;
213
                processedFeatures = new FBitSet();
214
                this.layerDefinition = layerDefinition;
215
                this.intersectProcessor = intersectsProcessor;
216
                this.intersectDefinition = intersectDefinition;
217
                this.layerToClean = firstLayer;
218
                this.recordset = source;
219
                this.strategy = StrategyManager.getStrategy(layerToClean);
220
                this.snapCoordMap = snapCoordMap;
221
        }
222

    
223
        public void setLayerDefinition(ILayerDefinition layerDefinition) {
224
                this.layerDefinition = layerDefinition;
225
        }
226

    
227
        private boolean checkForLineGeometry(Geometry geometry) {
228
                if (geometry instanceof LineString)
229
                        return true;
230
                if (geometry instanceof MultiLineString)
231
                        return true;
232
                if (geometry instanceof GeometryCollection) {
233
                        GeometryCollection col = (GeometryCollection) geometry;
234
                        for (int i = 0; i < col.getNumGeometries(); i++) {
235
                                if (!checkForLineGeometry(col.getGeometryN(i)))
236
                                        return false;
237
                        }
238
                        return true;
239
                }
240
                return false;
241
        }
242

    
243
        public void visit(IGeometry g, final int index) throws VisitException {
244
                // first, we check it isnt a null geometry and the geometry type
245
                // is correct
246
                if (g == null)
247
                        return;
248
                int geometryType = g.getGeometryType();
249
                if (geometryType != XTypes.ARC && geometryType != XTypes.LINE
250
                                && geometryType != XTypes.MULTI)
251
                        return;
252

    
253
                // after that, if we are going to clean only selected features, we
254
                // check if this feature is selected
255
                if (cleanOnlySelection) {
256
                        try {
257
                                if (!layerToClean.getRecordset().getSelection().get(index))
258
                                        return;
259
                        } catch (com.iver.cit.gvsig.fmap.DriverException e) {
260
                                throw new VisitException(
261
                                                "Error verificando seleccion en CLEAN", e);
262
                        }
263
                }// if cleanOnly
264

    
265
                final Geometry jtsGeo = g.toJTSGeometry();
266

    
267
                
268
                // we check if jts geometry is a line (or a line collection)
269
                if (!checkForLineGeometry(jtsGeo))
270
                        return;
271

    
272
                final SnappingNodeMap nodes = new SnappingNodeMap(new NodeFactory(),
273
                                snapTolerance);
274
                /*
275
                 * Se nos plantea una problematica. Tenemos dos features: A y B, y he
276
                 * calculado la interseccion de A y B. Ahora, hay dos alternativas: -a)
277
                 * nunca mas calcular esta intersecci?n, pero almacenar su resultado en
278
                 * SnappingNodeMap. As?, en una segunda pasada, con todos los "Nodos"
279
                 * calculados, podr?amos fragmentar las lineas de forma individual.
280
                 * PROBLEMA: SnappingNodeMap ir?a creciendo, almacenando todos los nodos
281
                 * de una capa....(si se apoya sobre un IndexedShpDriver, no tendr?a por
282
                 * qu?)
283
                 * 
284
                 * 
285
                 * -b) Calcular la intersecci?n en los dos sentidos: A int B, y luego al
286
                 * procesar B, B int A. En este caso, pasamos ol?mpicamente del bitset
287
                 * 
288
                 * De momento, por simplicidad, seguimos la alternativa -b)
289
                 */
290

    
291
                final boolean onlySelection = cleanOnlySelection;
292
                try {
293
                        strategy.process(new FeatureVisitor() {
294
                                
295
                                
296
                                SnappingOverlayOperation overlayOp = null;
297

    
298
                                /**
299
                                 * From a given geometry, it returns its nodes (coordinate for a
300
                                 * point, extreme coordinates for a line, first coordinate for a
301
                                 * polygon)
302
                                 */
303
                                private Coordinate[] getNodesFor(Geometry processedGeometry) {
304
                                        Coordinate[] geomNodes = null;
305
                                        if (processedGeometry instanceof LineString) {
306
                                                LineString line = (LineString) processedGeometry;
307
                                                geomNodes = new Coordinate[2];
308
                                                geomNodes[0] = line.getCoordinateN(0);
309
                                                geomNodes[1] = line
310
                                                                .getCoordinateN(line.getNumPoints() - 1);
311
                                        } else if (processedGeometry instanceof MultiLineString) {
312
                                                MultiLineString lines = (MultiLineString) processedGeometry;
313
                                                int numLines = lines.getNumGeometries();
314
                                                geomNodes = new Coordinate[2 * numLines];
315
                                                int index = 0;
316
                                                for (int i = 0; i < numLines; i++) {
317
                                                        LineString line = (LineString) lines
318
                                                                        .getGeometryN(i);
319
                                                        geomNodes[index] = line.getCoordinateN(0);
320
                                                        index++;
321
                                                        geomNodes[index] = line.getCoordinateN(line
322
                                                                        .getNumPoints() - 1);
323
                                                        index++;
324
                                                }
325
                                        } else if (processedGeometry instanceof GeometryCollection) {
326
                                                GeometryCollection col = (GeometryCollection) processedGeometry;
327
                                                ArrayList coordinates = new ArrayList();
328
                                                for (int i = 0; i < col.getNumGeometries(); i++) {
329
                                                        Geometry geom = col.getGeometryN(i);
330
                                                        Coordinate[] newNodes = getNodesFor(geom);
331
                                                        coordinates.addAll(Arrays.asList(newNodes));
332
                                                }
333
                                        }
334
//                                        else {
335
//                                                System.out
336
//                                                                .println("Este proceso solo debe trabajar con lineas");
337
//                                                System.out.println(processedGeometry.getGeometryType());
338
//                                        }
339
                                        return geomNodes;
340
                                }
341

    
342
                                /**
343
                                 * Checks if a coordinate is on a node of a given set of nodes
344
                                 * 
345
                                 * @param coord
346
                                 * @param nodes
347
                                 * @return
348
                                 */
349
                                private boolean checkIsNode(Coordinate coord, Coordinate[] nodes) {
350
                                        for (int i = 0; i < nodes.length; i++) {
351
                                                if (coord.distance(nodes[i]) <= snapTolerance)
352
                                                        return true;
353
                                        }
354
                                        return false;
355
                                }
356

    
357
                                /**
358
                                 * From a given geometry, and the intersection of this geometry
359
                                 * with another geometry, it creates a new node with these
360
                                 * intersections if its points are not coincident with the nodes
361
                                 * of the original goemetry.
362
                                 * 
363
                                 */
364
                                private void processIntersections(com.vividsolutions.jts.geomgraph.SnappingNodeMap nodes,
365
                                                Geometry processedGeometry, Geometry intersections, int fid1, int fid2) {
366

    
367
                                        Coordinate[] geomNodes = getNodesFor(processedGeometry);
368
                                        if (intersections instanceof Point) {
369
                                                Point p = (Point) intersections;
370
                                                Coordinate coord = p.getCoordinate();
371
                                                if (!checkIsNode(coord, geomNodes)){
372
                                                        nodes.addNode(coord);
373
                                                        
374
                                                        /*
375
                                                         * We are computing intersections twice: A intersection B
376
                                                         * and B intersection A. This is simpler than manage caches.
377
                                                         * With this logic, we avoid to write the same pseudonode twice
378
                                                         * 
379
                                                         * */
380
                                                        if(snapCoordMap.containsKey(coord))
381
                                                                return;
382
                                                        else{
383
                                                                snapCoordMap.put(coord, coord);
384
                                                                IFeature feature = createIntersectFeature(coord, fid1, fid2);
385
                                                                intersectProcessor.processFeature(feature);
386
                                                        }
387
                                                }         
388
                                        } else if (intersections instanceof MultiPoint) {
389
                                                MultiPoint points = (MultiPoint) intersections;
390
                                                for (int i = 0; i < points.getNumGeometries(); i++) {
391
                                                        Coordinate coord = ((Point) points.getGeometryN(i))
392
                                                                        .getCoordinate();
393
                                                        if (!checkIsNode(coord, geomNodes)){
394
                                                                nodes.addNode(coord);
395
                                                                if(snapCoordMap.containsKey(coord))
396
                                                                        return;
397
                                                                else{
398
                                                                        snapCoordMap.put(coord, coord);
399
                                                                        IFeature feature = createIntersectFeature(coord, fid1, fid2);
400
                                                                        intersectProcessor.processFeature(feature);
401
                                                                }
402
                                                        }        
403
                                                }
404
                                        } else if (intersections instanceof LineString) {
405
                                                LineString line = (LineString) intersections;
406
                                                int numPoints = line.getCoordinates().length;
407
                                                Coordinate coord1 = line.getCoordinateN(0);
408
                                                Coordinate coord2 = line.getCoordinateN(numPoints - 1);
409
                                                if (!checkIsNode(coord1, geomNodes)){
410
                                                        nodes.addNode(coord1);
411
                                                        if(snapCoordMap.containsKey(coord1))
412
                                                                return;
413
                                                        else{
414
                                                                snapCoordMap.put(coord1, coord1);
415
                                                                IFeature feature = createIntersectFeature(coord1, fid1, fid2);
416
                                                                intersectProcessor.processFeature(feature);
417
                                                        }
418
                                                }        
419
                                                if (!checkIsNode(coord2, geomNodes)){
420
                                                        nodes.addNode(coord2);
421
                                                        if(snapCoordMap.containsKey(coord2))
422
                                                                return;
423
                                                        else{
424
                                                                snapCoordMap.put(coord2, coord2);
425
                                                                IFeature feature = createIntersectFeature(coord2, fid1, fid2);
426
                                                                intersectProcessor.processFeature(feature);
427
                                                        }
428
                                                }        
429
                                        } else if (intersections instanceof GeometryCollection) {
430
                                                GeometryCollection col = (GeometryCollection) intersections;
431
                                                for (int i = 0; i < col.getNumGeometries(); i++) {
432

    
433
                                                        // El tema est? en que aqu? el calculo de los nodos
434
                                                        // de la geometria intersectada se repite cada vez
435
                                                        // revisar, pues MultiLineString puede ser un
436
                                                        // resultado habitual
437
                                                        processIntersections(nodes, processedGeometry, col
438
                                                                        .getGeometryN(i), fid1, fid2);
439
                                                }
440
                                        }
441
//                                        else if (intersections instanceof Polygon) {
442
//                                                System.out
443
//                                                                .println("Un poligono interseccion de 2 lineas???");
444
//                                        }// else
445

    
446
                                }
447

    
448
                                public void visit(IGeometry g2, int indexOverlay)
449
                                                throws VisitException {
450

    
451
                                        if (g2 == null)
452
                                                return;
453

    
454
                                        if (index == indexOverlay)
455
                                                return;
456

    
457
                                        if (onlySelection) {
458
                                                try {
459
                                                        if (!layerToClean.getRecordset().getSelection()
460
                                                                        .get(indexOverlay))
461
                                                                return;
462
                                                } catch (com.iver.cit.gvsig.fmap.DriverException e) {
463
                                                        throw new VisitException(
464
                                                                        "Error verificando seleccion en clean", e);
465
                                                }// geometry g is not selected
466
                                        }// if onlySelection
467

    
468
                                        int geometryType = g2.getGeometryType();
469
                                        if (geometryType != XTypes.ARC
470
                                                        && geometryType != XTypes.LINE
471
                                                        && geometryType != XTypes.MULTI)
472
                                                return;
473

    
474
                                        /*
475
                                         * TODO De momento no vamos a tener en cuenta que la
476
                                         * interseccion ya ha sido calculada... (Ver comentario al
477
                                         * instanciar SnappingNodeMap) // ya ha sido tratado
478
                                         * if(processedFeatures.get(indexOverlay)) return;
479
                                         */
480
                                        Geometry jtsGeo2 = g2.toJTSGeometry();
481
                                        if (!checkForLineGeometry(jtsGeo2))
482
                                                return;
483

    
484
                                        if(overlayOp == null)
485
                                                overlayOp = new SnappingOverlayOperation(jtsGeo, jtsGeo2, snapTolerance);        
486
                                        else{
487
                                                overlayOp.setSecondGeometry(jtsGeo2);
488
                                        }
489
                                        
490
                                        Geometry intersections = overlayOp.
491
                                                getResultGeometry(SnappingOverlayOperation.INTERSECTION);
492
                                                
493
                                        processIntersections(nodes, jtsGeo, intersections, index, indexOverlay);
494

    
495
                                        // IFeature cleanedFeature;
496
                                        // try {
497
                                        // cleanedFeature = createFeature(newGeoJts,
498
                                        // index, indexOverlay);
499
                                        // } catch (DriverException e) {
500
                                        // throw new VisitException(
501
                                        // "Error al crear el feature resultante del CLEAN");
502
                                        // }
503
                                        // featureProcessor.processFeature(cleanedFeature);
504

    
505
                                }
506

    
507
                                public String getProcessDescription() {
508
                                        return "Computing intersections of a polygon with its adjacents";
509
                                }
510

    
511
                                public void stop(FLayer layer) {
512
                                }
513

    
514
                                public boolean start(FLayer layer) {
515
                                        return true;
516
                                }
517
                        }, g.getBounds2D());
518

    
519
                        // At this point, nodes variable (SnappingNodeMap)
520
                        // has all intersections of the visited feature with the rest of
521
                        // features of the layer
522

    
523
                        // It computes linear distance of a point on the given jtsGeo linear
524
                        // geometry
525
                        LengthIndexedLine lengthLine = new LengthIndexedLine(jtsGeo);
526
                        Iterator nodesIt = nodes.iterator();
527
                        ArrayList nodeIntersections = new ArrayList();
528
                        while (nodesIt.hasNext()) {
529
                                Node node = (Node) nodesIt.next();
530
                                Coordinate coord = node.getCoordinate();
531
                                double lengthOfNode = lengthLine.indexOf(coord);
532
                                LineIntersection inters = new LineIntersection();
533
                                inters.coordinate = coord;
534
                                inters.lenght = lengthOfNode;
535
                                nodeIntersections.add(inters);
536
                        }
537

    
538
                        if (nodeIntersections.size() > 0) {
539
                                //        We sort the intersections by distance along the line (dynamic
540
                                // segmentation)
541
                                Collections.sort(nodeIntersections, new Comparator() {
542
                                        public int compare(Object arg0, Object arg1) {
543
                                                LineIntersection l1 = (LineIntersection) arg0;
544
                                                LineIntersection l2 = (LineIntersection) arg1;
545
                                                if (l1.lenght > l2.lenght)
546
                                                        return 1;
547
                                                else if (l1.lenght < l2.lenght)
548
                                                        return -1;
549
                                                else
550
                                                        return 0;
551
                                        }
552
                                });
553

    
554
                                LinearLocation lastLocation = null;
555
                                LineIntersection lastIntersection = null;
556
                                LocationIndexedLine indexedLine = new LocationIndexedLine(
557
                                                jtsGeo);
558
                                for (int i = 0; i < nodeIntersections.size(); i++) {
559
                                        Geometry solution = null;
560
                                        LineIntersection li = (LineIntersection) nodeIntersections
561
                                                        .get(i);
562
                                        
563
                                        LinearLocation location = indexedLine
564
                                                        .indexOf(li.coordinate);
565
                                        if (lastLocation == null) {
566
                                                LinearLocation from = new LinearLocation(0, 0d);
567
                                                solution = splitLineString(jtsGeo, from, location,
568
                                                                null, li);
569
                                                lastLocation = location;
570
                                                lastIntersection = li;
571
                                                /*
572
                                                 * Construimos una linea desde el primer punto hasta el
573
                                                 * punto contenido en LineIntersection, con todos los
574
                                                 * puntos intermedios de la linea.
575
                                                 * 
576
                                                 * 
577
                                                 * 
578
                                                 */
579
                                        } else {
580
                                                // Construimos una linea entre lastIntersection y la
581
                                                // intersection
582
                                                // actual
583
                                                LinearLocation locationFrom = lastLocation;
584
                                                solution = splitLineString(jtsGeo, locationFrom,
585
                                                                location, lastIntersection, li);
586
                                                lastLocation = location;
587
                                                lastIntersection = li;
588

    
589
                                        }
590

    
591
                                        
592
                                                IFeature feature = createFeature(solution, index);
593
                                                featureProcessor.processFeature(feature);
594
                                                // TODO Podriamos guardar los puntos de interseccion
595
                                                // para
596
                                                // mostrar al usuario que puntos eran pseudonodos
597
                                }// for
598
                                
599
                                //a?adimos el ultimo segmento
600
                                Coordinate[] geomCoords = jtsGeo.getCoordinates();
601
                                ArrayList coordinates = new ArrayList();
602
                                coordinates.add(lastIntersection.coordinate);
603
                                int startIndex = lastLocation.getSegmentIndex() + 1;
604
                                for (int i = startIndex; i < geomCoords.length; i++) {
605
                                        coordinates.add(geomCoords[i]);
606
                                }
607
                                Coordinate[] solutionCoords = new Coordinate[coordinates.size()];
608
                                coordinates.toArray(solutionCoords);
609
                                IFeature lastFeature = createFeature(new GeometryFactory().
610
                                                                                 createLineString(solutionCoords), 
611
                                                                                 index);
612
                                featureProcessor.processFeature(lastFeature);
613
                                
614
                                
615
                        } else {
616
                                IFeature feature = createFeature(g, index);
617
                                featureProcessor.processFeature(feature);
618
                        }
619

    
620
                } catch (com.iver.cit.gvsig.fmap.DriverException e) {
621
                        throw new VisitException(
622
                                        "Error buscando los overlays que intersectan con un feature");
623
                } catch (DriverException e) {
624
                        // TODO Auto-generated catch block
625
                        e.printStackTrace();
626
                }
627
        }
628

    
629
        private Geometry splitLineString(Geometry linearGeometry,
630
                        LinearLocation from, LinearLocation to, LineIntersection fromInt,
631
                        LineIntersection toInt) {
632
                Coordinate[] geomCoords = linearGeometry.getCoordinates();
633
                ArrayList coordinates = new ArrayList();
634
                if (fromInt != null)
635
                        coordinates.add(fromInt.coordinate);
636
                int startIndex = from.getSegmentIndex();
637
                /*
638
                 * segmentIndex siempre referencia al punto inmediatamente anterior del
639
                 * lineString. Nos interesa sumar 1, a no ser que sea el primer punto
640
                 * del linestring
641
                 */
642
                if (startIndex != 0)
643
                        startIndex++;
644
                
645
                for (int i = startIndex; i <= to.getSegmentIndex(); i++) {
646
                        coordinates.add(geomCoords[i]);
647
                }
648
                coordinates.add(toInt.coordinate);
649
                Coordinate[] solutionCoords = new Coordinate[coordinates.size()];
650
                coordinates.toArray(solutionCoords);
651
                return new GeometryFactory().createLineString(solutionCoords);
652

    
653
        }
654

    
655
        class LineIntersection {
656
                Coordinate coordinate;
657

    
658
                double lenght;
659
        }
660

    
661
        public String getProcessDescription() {
662
                return "Cleaning lines of a vectorial line layer";
663
        }
664

    
665
        public void stop(FLayer layer) {
666
                this.featureProcessor.finish();
667
                this.intersectProcessor.finish();
668
        }
669

    
670
        public boolean start(FLayer layer) {
671
                if (layer instanceof AlphanumericData && layer instanceof VectorialData) {
672
                        try {
673
                                layerToClean = (FLyrVect) layer;
674
                                recordset = ((AlphanumericData) layer).getRecordset();
675
                                strategy = StrategyManager.getStrategy(layerToClean);
676
                                featureProcessor.start();
677
                                intersectProcessor.start();
678
                        } catch (com.iver.cit.gvsig.fmap.DriverException e) {
679
                                return false;
680
                        } catch (EditionException e) {
681
                                return false;
682
                        }
683
                        return true;
684
                }
685
                return false;
686
        }
687

    
688
        private IFeature createFeature(Geometry jtsGeometry, int firstLayerIndex)
689
                        throws DriverException {
690
                IFeature solution = null;
691
                IGeometry cleanedGeometry = FConverter.jts_to_igeometry(jtsGeometry);
692
                FieldDescription[] fields = layerDefinition.getFieldsDesc();
693
                int numFields = fields.length;
694
                Value[] featureAttr = new Value[fields.length];
695
                for (int indexField = 0; indexField < numFields; indexField++) {
696
                        // for each field of firstRs
697
                        String fieldName = recordset.getFieldName(indexField);
698
                        for (int j = 0; j < fields.length; j++) {
699
                                if (fieldName.equalsIgnoreCase(fields[j].getFieldName())) {
700
                                        featureAttr[j] = recordset.getFieldValue(firstLayerIndex,
701
                                                        indexField);
702
                                        break;
703
                                }// if
704
                        }// for
705
                }// for
706
                // now we put null values
707
                for (int i = 0; i < featureAttr.length; i++) {
708
                        if (featureAttr[i] == null)
709
                                featureAttr[i] = ValueFactory.createNullValue();
710
                }
711
                solution = FeatureFactory.createFeature(featureAttr, cleanedGeometry);
712
                return solution;
713
        }
714
        
715
        
716
        
717
        private IFeature createIntersectFeature(Coordinate coord,  int fid1, int fid2){
718
                IFeature solution = null;
719
                Point point = FConverter.geomFactory.createPoint(coord);
720
                IGeometry cleanedGeometry = FConverter.jts_to_igeometry(point);
721
                Value[] values = new Value[2];
722
                values[0] = ValueFactory.createValue(fid1);
723
                values[1] = ValueFactory.createValue(fid2);
724
                solution = FeatureFactory.createFeature(values, cleanedGeometry);
725
                return solution;
726
        }
727

    
728
        private IFeature createFeature(IGeometry g, int firstLayerIndex)
729
                        throws DriverException {
730
                IFeature solution = null;
731
                FieldDescription[] fields = layerDefinition.getFieldsDesc();
732
                int numFields = fields.length;
733
                Value[] featureAttr = new Value[fields.length];
734
                for (int indexField = 0; indexField < numFields; indexField++) {
735
                        // for each field of firstRs
736
                        String fieldName = recordset.getFieldName(indexField);
737
                        for (int j = 0; j < fields.length; j++) {
738
                                if (fieldName.equalsIgnoreCase(fields[j].getFieldName())) {
739
                                        featureAttr[j] = recordset.getFieldValue(firstLayerIndex,
740
                                                        indexField);
741
                                        break;
742
                                }// if
743
                        }// for
744
                }// for
745
                // now we put null values
746
                for (int i = 0; i < featureAttr.length; i++) {
747
                        if (featureAttr[i] == null)
748
                                featureAttr[i] = ValueFactory.createNullValue();
749
                }
750
                solution = FeatureFactory.createFeature(featureAttr, g);
751
                return solution;
752
        }
753

    
754
//        public static void main(String[] args) {
755
//                DriverManager dm = new DriverManager();
756
//                dm.setValidation(new DriverValidation() {
757
//                        public boolean validate(Driver d) {
758
//                                return ((d instanceof ObjectDriver)
759
//                                                || (d instanceof FileDriver) || (d instanceof DBDriver));
760
//                        }
761
//                });
762
//                dm.loadDrivers(new File(
763
//                                "../_fwAndami/gvSIG/extensiones/com.iver.cit.gvsig/drivers"));
764
//                LayerFactory
765
//                                .setDriversPath("../_fwAndami/gvSIG/extensiones/com.iver.cit.gvsig/drivers");
766
//
767
//                // Setup del factory de DataSources
768
//                DataSourceFactory dsf = LayerFactory.getDataSourceFactory();
769
//                dsf.setDriverManager(dm);
770
//
771
//                // Setup de las tablas
772
//                // dsf.addFileDataSource("gdbms dbf driver", "nodes", "c:/nodes.dbf");
773
//                // dsf.addFileDataSource("gdbms dbf driver", "edges", "c:/edges.dbf");
774
//
775
//                IProjection prj = CRSFactory.getCRS("EPSG:23030");
776
//                File shpFile = new File("C:/JUMP/datos/cauces_gv.shp");
777
//                try {
778
//                        FLyrVect lyr = (FLyrVect) LayerFactory.createLayer("Ejes",
779
//                                        "gvSIG shp driver", shpFile, prj);
780
//                        System.out.println(lyr.getSource().getShapeCount());
781
//
782
//                        LayerDefinition definition = new LayerDefinition();
783
//                        FieldDescription cauNom = new FieldDescription();
784
//                        cauNom.setFieldName("CAUNOM");
785
//                        cauNom.setFieldType(XTypes.CHAR);
786
//                        cauNom.setFieldLength(10);
787
//                        cauNom.setFieldDecimalCount(0);
788
//                        definition.setFieldsDesc(new FieldDescription[]{cauNom});
789
//                        definition.setShapeType(XTypes.LINE);
790
//                        
791
//                        
792
//                        
793
//                        
794
////                        LineCleanVisitor visitor = new LineCleanVisitor(
795
////                                        new FeatureProcessor() {
796
////
797
////                                                public void processFeature(IRow feature) {
798
////                                                        // TODO Auto-generated method stub
799
////
800
////                                                }
801
////
802
////                                                public void finish() {
803
////                                                        // TODO Auto-generated method stub
804
////
805
////                                                }
806
////
807
////                                                public void start() throws EditionException {
808
////                                                        // TODO Auto-generated method stub
809
////
810
////                                                }
811
////                                        }, false, definition);
812
//                        Strategy str = StrategyManager.getStrategy(lyr);
813
////                        str.process(visitor);
814
//
815
////                } catch (com.iver.cit.gvsig.fmap.DriverException e) {
816
////                        // TODO Auto-generated catch block
817
////                        e.printStackTrace();
818
////                } catch (DriverIOException e) {
819
////                        // TODO Auto-generated catch block
820
////                        e.printStackTrace();
821
////                } catch (VisitException e) {
822
////                        // TODO Auto-generated catch block
823
////                        e.printStackTrace();
824
////                }
825
//        }
826

    
827
}