Statistics
| Revision:

root / branches / v10 / extensions / extGraph_predes / src / com / iver / cit / gvsig / topology / lineclean / fmap / LineCleanVisitor.java @ 12565

History | View | Annotate | Download (27 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 12565 2007-07-12 12:20:51Z azabala $
47
 * $Log$
48
 * Revision 1.7.2.1  2007-07-12 12:20:51  azabala
49
 * bug solved
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
                        boolean rightGeometry = true;
526
                        if (nodes.values().size() > 0) {
527
                                
528
                                LengthIndexedLine lengthLine = new LengthIndexedLine(jtsGeo);
529
                                Iterator nodesIt = nodes.iterator();
530
                                ArrayList nodeIntersections = new ArrayList();
531
                                while (nodesIt.hasNext()) {
532
                                        Node node = (Node) nodesIt.next();
533
                                        Coordinate coord = node.getCoordinate();
534
                                        double lengthOfNode = lengthLine.indexOf(coord);
535
                                        LineIntersection inters = new LineIntersection();
536
                                        inters.coordinate = coord;
537
                                        inters.lenght = lengthOfNode;
538
                                        nodeIntersections.add(inters);
539
                                }
540
                                
541
                                if (nodeIntersections.size() > 0) {
542
                                        // We sort the intersections by distance along the line
543
                                        // (dynamic
544
                                        // segmentation)
545
                                        rightGeometry = false;
546
                                        Collections.sort(nodeIntersections, new Comparator() {
547
                                                public int compare(Object arg0, Object arg1) {
548
                                                        LineIntersection l1 = (LineIntersection) arg0;
549
                                                        LineIntersection l2 = (LineIntersection) arg1;
550
                                                        if (l1.lenght > l2.lenght)
551
                                                                return 1;
552
                                                        else if (l1.lenght < l2.lenght)
553
                                                                return -1;
554
                                                        else
555
                                                                return 0;
556
                                                }
557
                                        });
558

    
559
                                        LinearLocation lastLocation = null;
560
                                        LineIntersection lastIntersection = null;
561
                                        LocationIndexedLine indexedLine = new LocationIndexedLine(
562
                                                        jtsGeo);
563
                                        for (int i = 0; i < nodeIntersections.size(); i++) {
564
                                                Geometry solution = null;
565
                                                LineIntersection li = (LineIntersection) nodeIntersections
566
                                                                .get(i);
567

    
568
                                                LinearLocation location = indexedLine
569
                                                                .indexOf(li.coordinate);// es posible que esto
570
                                                                                                                // est? mal por no
571
                                                                                                                // pasarle una longitud.
572
                                                                                                                // REVISAR
573
                                                if (lastLocation == null) {
574
                                                        LinearLocation from = new LinearLocation(0, 0d);
575
                                                        
576
//                                                        solution = splitLineString(jtsGeo, from, location,
577
//                                                                        null, li);
578
//                                                        
579
                                                        
580
                                                        solution = indexedLine.extractLine(from, location);
581
                                                        
582
                                                        
583
                                                        lastLocation = location;
584
                                                        lastIntersection = li;
585
                                                        /*
586
                                                         * Construimos una linea desde el primer punto hasta
587
                                                         * el punto contenido en LineIntersection, con todos
588
                                                         * los puntos intermedios de la linea.
589
                                                         * 
590
                                                         * 
591
                                                         * 
592
                                                         */
593
                                                } else {
594
                                                        // Construimos una linea entre lastIntersection y la
595
                                                        // intersection
596
                                                        // actual
597
                                                        LinearLocation locationFrom = lastLocation;
598
                                                        
599
//                                                        solution = splitLineString(jtsGeo, locationFrom,
600
//                                                                        location, lastIntersection, li);
601
                                                        
602
                                                        solution = indexedLine.extractLine(locationFrom, location);
603
                                                        lastLocation = location;
604
                                                        lastIntersection = li;
605

    
606
                                                }
607

    
608
                                                IFeature feature = createFeature(solution, index);
609
                                                featureProcessor.processFeature(feature);
610
                                                // TODO Podriamos guardar los puntos de interseccion
611
                                                // para
612
                                                // mostrar al usuario que puntos eran pseudonodos
613
                                        }// for
614

    
615
                                        // a?adimos el ultimo segmento
616
//                                        Coordinate[] geomCoords = jtsGeo.getCoordinates();
617
//                                        ArrayList coordinates = new ArrayList();
618
//                                        coordinates.add(lastIntersection.coordinate);
619
//                                        int startIndex = lastLocation.getSegmentIndex() + 1;
620
//                                        for (int i = startIndex; i < geomCoords.length; i++) {
621
//                                                coordinates.add(geomCoords[i]);
622
//                                        }
623
//                                        Coordinate[] solutionCoords = new Coordinate[coordinates
624
//                                                        .size()];
625
//                                        coordinates.toArray(solutionCoords);
626
//                                        IFeature lastFeature = createFeature(new GeometryFactory()
627
//                                                        .createLineString(solutionCoords), index);
628
                                        LinearLocation endLocation = new LinearLocation();
629
                                        endLocation.setToEnd(jtsGeo);
630
                                        Geometry geo = indexedLine.extractLine(lastLocation, endLocation);
631
                                        IFeature lastFeature = createFeature(geo, index);
632
                                        featureProcessor.processFeature(lastFeature);
633

    
634
                                }
635
                        } 
636
                        if(rightGeometry){
637
                                IFeature feature = createFeature(g, index);
638
                                featureProcessor.processFeature(feature);
639
                        }
640

    
641

    
642
                } catch (com.iver.cit.gvsig.fmap.DriverException e) {
643
                        throw new VisitException(
644
                                        "Error buscando los overlays que intersectan con un feature");
645
                } catch (DriverException e) {
646
                        // TODO Auto-generated catch block
647
                        e.printStackTrace();
648
                }
649
        }
650

    
651
        private Geometry splitLineString(Geometry linearGeometry,
652
                        LinearLocation from, LinearLocation to, LineIntersection fromInt,
653
                        LineIntersection toInt) {
654
                Coordinate[] geomCoords = linearGeometry.getCoordinates();
655
                ArrayList coordinates = new ArrayList();
656
                if (fromInt != null)
657
                        coordinates.add(fromInt.coordinate);
658
                int startIndex = from.getSegmentIndex();
659
                /*
660
                 * segmentIndex siempre referencia al punto inmediatamente anterior del
661
                 * lineString. Nos interesa sumar 1, a no ser que sea el primer punto
662
                 * del linestring
663
                 */
664
                if (startIndex != 0)
665
                        startIndex++;
666
                
667
                for (int i = startIndex; i <= to.getSegmentIndex(); i++) {
668
                        coordinates.add(geomCoords[i]);
669
                }
670
                coordinates.add(toInt.coordinate);
671
                Coordinate[] solutionCoords = new Coordinate[coordinates.size()];
672
                coordinates.toArray(solutionCoords);
673
                return new GeometryFactory().createLineString(solutionCoords);
674

    
675
        }
676

    
677
        class LineIntersection {
678
                Coordinate coordinate;
679

    
680
                double lenght;
681
        }
682

    
683
        public String getProcessDescription() {
684
                return "Cleaning lines of a vectorial line layer";
685
        }
686

    
687
        public void stop(FLayer layer) {
688
                this.featureProcessor.finish();
689
                this.intersectProcessor.finish();
690
        }
691

    
692
        public boolean start(FLayer layer) {
693
                if (layer instanceof AlphanumericData && layer instanceof VectorialData) {
694
                        try {
695
                                layerToClean = (FLyrVect) layer;
696
                                recordset = ((AlphanumericData) layer).getRecordset();
697
                                strategy = StrategyManager.getStrategy(layerToClean);
698
                                featureProcessor.start();
699
                                intersectProcessor.start();
700
                        } catch (com.iver.cit.gvsig.fmap.DriverException e) {
701
                                return false;
702
                        } catch (EditionException e) {
703
                                return false;
704
                        }
705
                        return true;
706
                }
707
                return false;
708
        }
709

    
710
        private IFeature createFeature(Geometry jtsGeometry, int firstLayerIndex)
711
                        throws DriverException {
712
                IFeature solution = null;
713
                IGeometry cleanedGeometry = FConverter.jts_to_igeometry(jtsGeometry);
714
                FieldDescription[] fields = layerDefinition.getFieldsDesc();
715
                int numFields = fields.length;
716
                Value[] featureAttr = new Value[fields.length];
717
                for (int indexField = 0; indexField < numFields; indexField++) {
718
                        // for each field of firstRs
719
                        String fieldName = recordset.getFieldName(indexField);
720
                        for (int j = 0; j < fields.length; j++) {
721
                                if (fieldName.equalsIgnoreCase(fields[j].getFieldName())) {
722
                                        featureAttr[j] = recordset.getFieldValue(firstLayerIndex,
723
                                                        indexField);
724
                                        break;
725
                                }// if
726
                        }// for
727
                }// for
728
                // now we put null values
729
                for (int i = 0; i < featureAttr.length; i++) {
730
                        if (featureAttr[i] == null)
731
                                featureAttr[i] = ValueFactory.createNullValue();
732
                }
733
                solution = FeatureFactory.createFeature(featureAttr, cleanedGeometry);
734
                return solution;
735
        }
736
        
737
        
738
        
739
        private IFeature createIntersectFeature(Coordinate coord,  int fid1, int fid2){
740
                IFeature solution = null;
741
                Point point = FConverter.geomFactory.createPoint(coord);
742
                IGeometry cleanedGeometry = FConverter.jts_to_igeometry(point);
743
                Value[] values = new Value[2];
744
                values[0] = ValueFactory.createValue(fid1);
745
                values[1] = ValueFactory.createValue(fid2);
746
                solution = FeatureFactory.createFeature(values, cleanedGeometry);
747
                return solution;
748
        }
749

    
750
        private IFeature createFeature(IGeometry g, int firstLayerIndex)
751
                        throws DriverException {
752
                IFeature solution = null;
753
                FieldDescription[] fields = layerDefinition.getFieldsDesc();
754
                int numFields = fields.length;
755
                Value[] featureAttr = new Value[fields.length];
756
                for (int indexField = 0; indexField < numFields; indexField++) {
757
                        // for each field of firstRs
758
                        String fieldName = recordset.getFieldName(indexField);
759
                        for (int j = 0; j < fields.length; j++) {
760
                                if (fieldName.equalsIgnoreCase(fields[j].getFieldName())) {
761
                                        featureAttr[j] = recordset.getFieldValue(firstLayerIndex,
762
                                                        indexField);
763
                                        break;
764
                                }// if
765
                        }// for
766
                }// for
767
                // now we put null values
768
                for (int i = 0; i < featureAttr.length; i++) {
769
                        if (featureAttr[i] == null)
770
                                featureAttr[i] = ValueFactory.createNullValue();
771
                }
772
                solution = FeatureFactory.createFeature(featureAttr, g);
773
                return solution;
774
        }
775

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

    
849
}