Statistics
| Revision:

gvsig-lrs / org.gvsig.lrs / trunk / org.gvsig.lrs / org.gvsig.lrs.lib / org.gvsig.lrs.lib.impl / src / main / java / org / gvsig / lrs / lib / impl / LrsCreateRouteAlgorithm.java @ 6

History | View | Annotate | Download (26.4 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2015 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.lrs.lib.impl;
24

    
25
import java.util.ArrayList;
26
import java.util.HashMap;
27
import java.util.Iterator;
28
import java.util.List;
29
import java.util.Map;
30

    
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

    
34
import org.gvsig.fmap.dal.exception.DataException;
35
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
37
import org.gvsig.fmap.dal.feature.FeatureReference;
38
import org.gvsig.fmap.dal.feature.FeatureSelection;
39
import org.gvsig.fmap.dal.feature.FeatureStore;
40
import org.gvsig.fmap.geom.Geometry;
41
import org.gvsig.fmap.geom.GeometryLocator;
42
import org.gvsig.fmap.geom.GeometryManager;
43
import org.gvsig.fmap.geom.aggregate.MultiLine;
44
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
45
import org.gvsig.fmap.geom.exception.CreateGeometryException;
46
import org.gvsig.fmap.geom.operation.GeometryOperationException;
47
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
48
import org.gvsig.fmap.geom.primitive.Envelope;
49
import org.gvsig.fmap.geom.primitive.Line;
50
import org.gvsig.fmap.geom.primitive.Point;
51
import org.gvsig.lrs.lib.api.LrsAlgorithm;
52
import org.gvsig.lrs.lib.api.LrsAlgorithmParams;
53
import org.gvsig.lrs.lib.api.LrsCoordinatesPriority;
54
import org.gvsig.lrs.lib.api.LrsCreateRouteAlgorithmParams;
55
import org.gvsig.lrs.lib.api.LrsSourceOfMeasures;
56
import org.gvsig.tools.exception.BaseException;
57
import org.gvsig.tools.service.Manager;
58
import org.gvsig.tools.task.SimpleTaskStatus;
59
import org.gvsig.tools.visitor.VisitCanceledException;
60
import org.gvsig.tools.visitor.Visitor;
61

    
62
/**
63
 * @author fdiaz
64
 *
65
 */
66
public class LrsCreateRouteAlgorithm implements LrsAlgorithm {
67

    
68
    private static final Logger logger = LoggerFactory.getLogger(LrsCreateRouteAlgorithm.class);
69

    
70
    private LrsCreateRouteAlgorithmParams parameters;
71

    
72

    
73
    /**
74
     *
75
     */
76
    public LrsCreateRouteAlgorithm(LrsCreateRouteAlgorithmParams parameters) {
77
        this.parameters = parameters;
78

    
79
    }
80

    
81
    /*
82
     * (non-Javadoc)
83
     *
84
     * @see org.gvsig.tools.service.Service#getManager()
85
     */
86
    public Manager getManager() {
87
        return null;
88
    }
89

    
90
    /*
91
     * (non-Javadoc)
92
     *
93
     * @see org.gvsig.lrs.lib.api.LrsAlgorithm#getParams()
94
     */
95
    public  LrsAlgorithmParams getParams() {
96
        return this.parameters;
97
    }
98

    
99
    /*
100
     * (non-Javadoc)
101
     * @see org.gvsig.lrs.lib.api.LrsAlgorithm#execute(org.gvsig.tools.task.SimpleTaskStatus)
102
     */
103
    public void execute(SimpleTaskStatus taskStatus) {
104
        FeatureStore outputFeatureStore = parameters.getOutputFeatoreStore();
105
        FeatureStore sourceFeatureStore = parameters.getSourceFeatureStore();
106
        FeatureAttributeDescriptor idRouteField = parameters.getIdRouteField();
107
        LrsCoordinatesPriority coordinatePriority = parameters.getCoordinatePriority();
108
        LrsSourceOfMeasures sourceOfMeasures = parameters.getSourceOfMeasures();
109
        FeatureAttributeDescriptor fromMeasureField = parameters.getFromMeasureField();
110
        FeatureAttributeDescriptor toMeasureField = parameters.getToMeasureField();
111
        double measureFactor = parameters.getMeasureFactor();
112
        double measureOffset = parameters.getMeasureOffset();
113
        boolean ignoreSpatialGaps = parameters.ignoreSpatialGaps();
114

    
115
        logger.info(parameters.toString());
116

    
117
        taskStatus.setTitle(parameters.getName());
118
        taskStatus.message("Grouping features");
119

    
120
        taskStatus.setRangeOfValues(0, 1000-1);
121

    
122
        for (int i = 0; i < 1000; i++) {
123
            logger.info(new StringBuilder().append(i).toString());
124
            taskStatus.setCurValue(i);
125
//            if (i == 50000) {
126
//                logger.info(new StringBuilder().append(i / 0).toString());
127
//            }
128
        }
129

    
130
        taskStatus.terminate();
131

    
132

    
133
//        FeatureSelection selection;
134
//        try {
135
//            outputFeatureStore.edit(FeatureStore.MODE_FULLEDIT);
136
//            selection = sourceFeatureStore.getFeatureSelection();
137
//            if (selection == null || selection.isEmpty()) {
138
//                selection = sourceFeatureStore.createFeatureSelection();
139
//                selection.selectAll();
140
//            }
141
//            taskStatus.message("Grouping features");
142
//            Map<Object, List<FeatureReference>> groupedReferences = getGroupedReferences(selection, idRouteField);
143
//
144
//            taskStatus.message("Creating routes");
145
//
146
//            Set<Object> keys = groupedReferences.keySet();
147
//            taskStatus.setRangeOfValues(0, keys.size());
148
//            int i=0;
149
//            for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
150
//                taskStatus.setCurValue(i++);
151
//                Object key = (Object) iterator.next();
152
//                EditableFeature newFeature = outputFeatureStore.createNewFeature(true);
153
//                newFeature.set(idRouteField.getName(), key);
154
//
155
//                List<FeatureReference> references = groupedReferences.get(key);
156
//                Geometry route = createRoute(references, coordinatePriority, sourceOfMeasures, fromMeasureField, toMeasureField, measureFactor, measureOffset, ignoreSpatialGaps);
157
//                route = calibrateRoute(route);
158
//                newFeature.setDefaultGeometry(route);
159
//                outputFeatureStore.update(newFeature);
160
//            }
161
//            outputFeatureStore.finishEditing();
162
//            taskStatus.terminate();
163
//
164
//        } catch (DataException e) {
165
//            // TODO Auto-generated catch block
166
//            e.printStackTrace();
167
//        } catch (BaseException e) {
168
//            // TODO Auto-generated catch block
169
//            e.printStackTrace();
170
//        }
171
    }
172

    
173
    /**
174
     * @param route
175
     * @return
176
     */
177
    private Geometry calibrateRoute(Geometry route) {
178
        // TODO Auto-generated method stub
179
        return route;
180
    }
181

    
182
    private Map<Object, List<FeatureReference>> getGroupedReferences(FeatureSelection selection, final FeatureAttributeDescriptor idRouteField) throws BaseException {
183
        final Map<Object, List<FeatureReference>> refs = new HashMap<Object, List<FeatureReference>>();
184
        selection.accept(new Visitor() {
185

    
186
            public void visit(Object obj) throws VisitCanceledException, BaseException {
187
                Feature feature = (Feature) obj;
188
                Object id = feature.getFeature(idRouteField.getName());
189
                FeatureReference reference = feature.getReference();
190
                List<FeatureReference> references = refs.get(id);
191
                if (references == null) {
192
                    references = new ArrayList<FeatureReference>();
193
                }
194
                references.add(reference);
195
                refs.put(id, references);
196
            }
197
        });
198
        return refs;
199
    }
200

    
201
    private MultiLine createRoute(List<FeatureReference> references, LrsCoordinatesPriority coordinatePriority, LrsSourceOfMeasures sourceOfMeasures, FeatureAttributeDescriptor fromMeasureField,FeatureAttributeDescriptor toMeasureField, double measureFactor, double measureOffset, boolean ignoreSpatialGaps) throws CreateGeometryException, DataException, CreateEnvelopeException, GeometryOperationNotSupportedException, GeometryOperationException{
202

    
203
        Envelope envelope = getEnvelope(references);
204
        Point p = getOriginPointAccordingPriorityCoordinates(envelope, coordinatePriority);
205
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
206

    
207
        //FIXME: cuando est? esto tendr? que ser GEOM2DM o incluso GEOM3DM
208
        MultiLine route = geometryManager.createMultiLine(Geometry.SUBTYPES.GEOM2D);
209
        double m = 0;
210
        Point previousVertex = null;
211
        List<FeatureReference> orderedReferences = getOrderedReferences(references, (Point)p.cloneGeometry());
212
        for (Iterator iterator = orderedReferences.iterator(); iterator.hasNext();) {
213
            FeatureReference featureReference = (FeatureReference) iterator.next();
214
            Feature feature = featureReference.getFeature();
215
            Geometry geometry = feature.getDefaultGeometry();
216
            if (geometry instanceof Line) {
217
                Line line = (Line) geometry;
218
                Point firstVertex = line.getVertex(0);
219
                Point lastVertex = line.getVertex(line.getNumVertices() - 1);
220
                boolean ascendantOrder = isAscendantOrder(p, firstVertex, lastVertex);
221
                //FIXME: cuando est? disponible esto deber? ser GEOM2DM (?o incluso GEOM3DM?)
222
                Line tramo = geometryManager.createLine(Geometry.SUBTYPES.GEOM3D);
223
                double lineLength = getLineLength(line);
224
                for(int i=0; i<line.getNumVertices(); i++){
225
                    Point vertex = getNextVertex(line, ascendantOrder, i);
226

    
227
                    switch (sourceOfMeasures) {
228
                    case ONE_FIELD:
229
                        m = calculateMByOneField(m, previousVertex, i, vertex, feature.getDouble(fromMeasureField.getName()), lineLength, measureFactor, measureOffset, ignoreSpatialGaps);
230
                        break;
231
                    case TWO_FIELDS:
232
                        m = calculateMByTwoField(m, previousVertex, i, vertex, feature.getDouble(fromMeasureField.getName()), feature.getDouble(toMeasureField.getName()), lineLength, measureFactor, measureOffset);
233
                        break;
234
                    case LENGTH:
235
                    default:
236
                        m = calculateMByLength(m, previousVertex, i, vertex, ignoreSpatialGaps, measureFactor, measureOffset);
237
                        break;
238
                    }
239
                    // FIXME: cuando est? disponible esto deber? ser GEOM2DM (?o incluso GEOM3DM?)
240
                    Point mvertex = geometryManager.createPoint(vertex.getX(), vertex.getY(), Geometry.SUBTYPES.GEOM3D);
241
                    mvertex.setCoordinateAt(2, m);
242
                    tramo.addVertex(mvertex);
243
                    previousVertex = vertex;
244
                    p = vertex;
245
                }
246
                route.addPrimitive(tramo);
247
            } else if (geometry instanceof MultiLine) {
248
                MultiLine multiLine = (MultiLine)geometry;
249
                double multiLineLength = getMultiLineLength(multiLine);
250
                MultiLine orderedMultiLine = getOrderedMultiLine(multiLine, previousVertex, coordinatePriority);
251
                for (int j = 0; j < orderedMultiLine.getPrimitivesNumber(); j++) {
252
                    Line line = (Line) orderedMultiLine.getPrimitiveAt(j);
253
                    Point firstVertex = line.getVertex(0);
254
                    Point lastVertex = line.getVertex(line.getNumVertices() - 1);
255
                    boolean ascendantOrder = isAscendantOrder(p, firstVertex, lastVertex);
256
                    //FIXME: cuando est? disponible esto deber? ser GEOM2DM (?o incluso GEOM3DM?)
257
                    Line tramo = geometryManager.createLine(Geometry.SUBTYPES.GEOM3D);
258
                    for(int i=0; i<line.getNumVertices(); i++){
259
                        Point vertex = getNextVertex(line, ascendantOrder, i);
260
                        switch (sourceOfMeasures) {
261
                        case ONE_FIELD:
262
                            m = calculateMByOneField(m, previousVertex, i, vertex, feature.getDouble(toMeasureField.getName()), multiLineLength, multiLineLength, multiLineLength, ascendantOrder);
263
                            break;
264
                        case TWO_FIELDS:
265
                            //Este caso tal vez no se d? nunca, pero por si acaso
266
                            m = calculateMByTwoField(m, previousVertex, i, vertex, feature.getDouble(fromMeasureField.getName()), feature.getDouble(toMeasureField.getName()), multiLineLength, measureFactor, measureOffset);
267
                            break;
268
                        case LENGTH:
269
                        default:
270
                            m = calculateMByLength(m, previousVertex, i, vertex, ignoreSpatialGaps, measureFactor, measureOffset);
271
                            break;
272
                        }
273

    
274
                        // FIXME: cuando est? disponible esto deber? ser GEOM2DM (?o incluso GEOM3DM?)
275
                        Point mvertex = geometryManager.createPoint(vertex.getX(), vertex.getY(), Geometry.SUBTYPES.GEOM3D);
276
                        mvertex.setCoordinateAt(2, m);
277
                        tramo.addVertex(mvertex);
278
                        previousVertex = vertex;
279
                        p = vertex;
280
                    }
281
                    route.addPrimitive(tramo);
282
                }
283
            }
284
        }
285

    
286

    
287

    
288

    
289
        return route;
290
    }
291

    
292
    /**
293
     * @param multiLine
294
     * @param previousVertex
295
     * @param coordinatePriority2
296
     * @return
297
     * @throws CreateGeometryException
298
     * @throws GeometryOperationException
299
     * @throws GeometryOperationNotSupportedException
300
     */
301
    private MultiLine getOrderedMultiLine(MultiLine multiLine, Point previousVertex, LrsCoordinatesPriority coordinatePriority) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
302
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
303
        MultiLine orderedMultiLine = geometryManager.createMultiLine(multiLine.getGeometryType().getSubType());
304
        Point p = null;
305
        if(previousVertex!=null){
306
            previousVertex.cloneGeometry();
307
        } else {
308
            Envelope envelope = multiLine.getEnvelope();
309
            p = getOriginPointAccordingPriorityCoordinates(envelope, coordinatePriority);
310
        }
311

    
312
        Point newPoint = (Point) p.cloneGeometry();
313
        Integer nearestPrimitive = null;
314
        double nearestDistance = Double.POSITIVE_INFINITY;
315
        List<Integer> addedPrimitives = new ArrayList<Integer>();
316
        boolean changed = true;
317
        while (changed) {
318
            changed = false;
319
            nearestDistance = Double.POSITIVE_INFINITY;
320

    
321
            for (int i = 0; i < multiLine.getPrimitivesNumber(); i++) {
322
                if(!addedPrimitives.contains(i)){
323
                    Line line = (Line)multiLine.getPrimitiveAt(i);
324
                    Point firstVertex = line.getVertex(0);
325
                    Point lastVertex = line.getVertex(line.getNumVertices() - 1);
326
                    double distanceFirstVertex = p.distance(firstVertex);
327
                    double distanceLastVertex = p.distance(lastVertex);
328
                    double distance = Math.min(distanceFirstVertex, distanceLastVertex);
329
                    if (distance < nearestDistance) {
330
                        if(distanceFirstVertex<distanceLastVertex){
331
                            newPoint = lastVertex;
332
                        } else {
333

    
334
                        }
335
                        nearestPrimitive = i;
336
                        nearestDistance = distance;
337
                        changed = true;
338
                    }
339

    
340
                }
341
            }
342
            if (changed) {
343
                addedPrimitives.add(nearestPrimitive);
344
                p = (Point) newPoint.cloneGeometry();
345
            }
346
        }
347
        p = (Point) previousVertex.cloneGeometry();
348
        for (Iterator iterator = addedPrimitives.iterator(); iterator.hasNext();) {
349
            Integer integer = (Integer) iterator.next();
350
            Line line = (Line)multiLine.getPrimitiveAt(integer);
351
            Line auxLine;
352
            if(isAscendantOrder(p, line.getVertex(0), line.getVertex(line.getNumVertices()-1))){
353
                auxLine = (Line) line.cloneGeometry();
354
            } else {
355
                auxLine = geometryManager.createLine(line.getGeometryType().getSubType());
356
                for (int i = line.getNumVertices(); i >=0 ; --i) {
357
                    auxLine.addVertex(line.getVertex(i));
358
                }
359
            }
360
            orderedMultiLine.addPrimitive(auxLine);
361
        }
362
        return orderedMultiLine;
363
    }
364

    
365
    private Point getOriginPointAccordingPriorityCoordinates(Envelope envelope, LrsCoordinatesPriority coordinatePriority) throws CreateGeometryException {
366
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
367
        Point p;
368
        //FIXME: OJO con el significado de coordinatePriority
369
        switch (coordinatePriority) {
370
        case DOWN_LEFT:
371
            p = geometryManager.createPoint(envelope.getMinimum(0), envelope.getMaximum(1), Geometry.SUBTYPES.GEOM2D);
372
            break;
373
        case UP_RIGHT:
374
            p = geometryManager.createPoint(envelope.getMinimum(0), envelope.getMinimum(1), Geometry.SUBTYPES.GEOM2D);
375
            break;
376
        case DOWN_RIGHT:
377
            p = geometryManager.createPoint(envelope.getMaximum(0), envelope.getMaximum(1), Geometry.SUBTYPES.GEOM2D);
378
            break;
379
        case UP_LEFT:
380
        default:
381
            p = geometryManager.createPoint(envelope.getMaximum(0), envelope.getMinimum(1), Geometry.SUBTYPES.GEOM2D);
382
            break;
383
        }
384
        return p;
385
    }
386

    
387
    /**
388
     * @param line
389
     * @return lenght
390
     * @throws GeometryOperationException
391
     * @throws GeometryOperationNotSupportedException
392
     */
393
    private double getLineLength(Line line) throws GeometryOperationNotSupportedException, GeometryOperationException {
394
        double lenght = 0;
395
        Point previousVertex = null;
396
        for(int i=0; i<line.getNumVertices(); i++){
397
            Point vertex = line.getVertex(i);
398
            if(previousVertex!=null){
399
                lenght+=previousVertex.distance(vertex);
400
            }
401
            previousVertex = vertex;
402
        }
403
        return lenght;
404
    }
405

    
406
    /**
407
     * @param multiLine
408
     * @return lenght
409
     * @throws GeometryOperationException
410
     * @throws GeometryOperationNotSupportedException
411
     */
412
    private double getMultiLineLength(MultiLine multiLine) throws GeometryOperationNotSupportedException, GeometryOperationException{
413
        double lenght = 0;
414
        for (int j = 0; j < multiLine.getPrimitivesNumber(); j++) {
415
            Line line = (Line) multiLine.getPrimitiveAt(j);
416
            Point previousVertex = null;
417
            for(int i=0; i<line.getNumVertices(); i++){
418
                Point vertex = line.getVertex(i);
419
                if(previousVertex!=null){
420
                    lenght+=previousVertex.distance(vertex);
421
                }
422
                previousVertex = vertex;
423
            }
424
        }
425
        return lenght;
426
    }
427

    
428
    private double calculateM(double m, Point previousVertex, int i, Point vertex, Double from, Double to, boolean ignoreSpatialGaps, double measureFactor, double measureOffset)
429
        throws GeometryOperationNotSupportedException, GeometryOperationException {
430
        if (i == 0) {
431
            if (previousVertex != null && !ignoreSpatialGaps) {
432
                m += (previousVertex.distance(vertex)*measureFactor)+measureOffset;
433
            }
434
        } else {
435
            if(previousVertex!=null){
436
                m += (previousVertex.distance(vertex)*measureFactor)+measureOffset;
437
            }
438
        }
439
        return m;
440
    }
441

    
442
    private double calculateMByLength(double m, Point previousVertex, int i, Point vertex, boolean ignoreSpatialGaps, double measureFactor, double measureOffset)
443
        throws GeometryOperationNotSupportedException, GeometryOperationException {
444
        if (i == 0) {
445
            if (previousVertex != null && !ignoreSpatialGaps) {
446
                m += (previousVertex.distance(vertex)*measureFactor)+measureOffset;
447
            }
448
        } else {
449
            if(previousVertex!=null){
450
                m += (previousVertex.distance(vertex)*measureFactor)+measureOffset;
451
            }
452
        }
453
        return m;
454
    }
455

    
456
    private double calculateMByOneField(double m, Point previousVertex, int i, Point vertex, Double length, double totalGeometricLength, double measureFactor, double measureOffset, boolean ignoreSpatialGaps)
457
        throws GeometryOperationNotSupportedException, GeometryOperationException {
458
        if (i == 0) {
459
            if (previousVertex != null && !ignoreSpatialGaps) {
460
                m += (previousVertex.distance(vertex)*length/totalGeometricLength*measureFactor)+measureOffset;
461
            }
462
        } else {
463
            if(previousVertex!=null){
464
                m += (previousVertex.distance(vertex)*length/totalGeometricLength*measureFactor)+measureOffset;
465
            }
466
        }
467
        return m;
468
    }
469

    
470
    private double calculateMByTwoField(double m, Point previousVertex, int i, Point vertex, Double from, Double to, double totalGeometricLength, double measureFactor, double measureOffset)
471
        throws GeometryOperationNotSupportedException, GeometryOperationException {
472
        if (i == 0) {
473
            m = from;
474
        } else {
475
            if(previousVertex!=null){
476
                m += (previousVertex.distance(vertex)*(to-from)/totalGeometricLength*measureFactor)+measureOffset;
477
            }
478
        }
479
        return m;
480
    }
481

    
482
    private Point getNextVertex(Line line, boolean ascendantOrder, int i) {
483
        Point vertex = null;
484
        if(ascendantOrder){
485
            vertex = line.getVertex(i);
486
        } else {
487
            vertex = line.getVertex(line.getNumVertices()-i);
488
        }
489
        return vertex;
490
    }
491

    
492
    private boolean isAscendantOrder(Point p, Point firstVertex, Point lastVertex)
493
        throws GeometryOperationNotSupportedException, GeometryOperationException {
494
        double distanceFirstVertex = p.distance(firstVertex);
495
        double distanceLastVertex = p.distance(lastVertex);
496
        boolean ascendantOrder = (distanceFirstVertex<=distanceLastVertex);
497
        return ascendantOrder;
498
    }
499

    
500
    private List<FeatureReference> getOrderedReferences(List<FeatureReference> references, Point point)
501
        throws CreateEnvelopeException, DataException, CreateGeometryException, GeometryOperationNotSupportedException,
502
        GeometryOperationException {
503

    
504
        Point p = (Point) point.cloneGeometry();
505
        List<FeatureReference> orderedReferences = new ArrayList<FeatureReference>();
506

    
507
        FeatureReference nearestFeatureReference = null;
508
        double nearestDistance = Double.POSITIVE_INFINITY;
509
        boolean changed = true;
510
        Point newPoint = (Point) p.cloneGeometry();
511

    
512
        while (changed) {
513
            changed = false;
514
            nearestDistance = Double.POSITIVE_INFINITY;
515
            for (Iterator iterator = references.iterator(); iterator.hasNext();) {
516
                FeatureReference featureReference = (FeatureReference) iterator.next();
517
                if (!orderedReferences.contains(featureReference)) {
518
                    Geometry geometry = featureReference.getFeature().getDefaultGeometry();
519
                    if (geometry instanceof Line) {
520
                        Line line = (Line) geometry;
521
                        Point firstVertex = line.getVertex(0);
522
                        Point lastVertex = line.getVertex(line.getNumVertices() - 1);
523
                        double distanceFirstVertex = p.distance(firstVertex);
524
                        double distanceLastVertex = p.distance(lastVertex);
525
                        double distance = Math.min(distanceFirstVertex, distanceLastVertex);
526
                        if (distance < nearestDistance) {
527
                            if(distanceFirstVertex<distanceLastVertex){
528
                                newPoint = lastVertex;
529
                            }
530
                            nearestFeatureReference = featureReference;
531
                            nearestDistance = distance;
532
                            changed = true;
533
                        }
534
                    } else if (geometry instanceof MultiLine) {
535
                        MultiLine multiLine = (MultiLine) geometry;
536
                        for(int i=0; i<multiLine.getPrimitivesNumber(); i++){
537
                            Line line = (Line)multiLine.getPrimitiveAt(i);
538
                            Point firstVertex = line.getVertex(0);
539
                            Point lastVertex = line.getVertex(line.getNumVertices() - 1);
540
                            double distanceFirstVertex = p.distance(firstVertex);
541
                            double distanceLastVertex = p.distance(lastVertex);
542
                            double distance = Math.min(distanceFirstVertex, distanceLastVertex);
543
                            if (distance < nearestDistance) {
544
                                if(distanceFirstVertex<distanceLastVertex){
545
                                    newPoint = lastVertex;
546
                                }
547
                                nearestFeatureReference = featureReference;
548
                                nearestDistance = distance;
549
                                changed = true;
550
                                break;
551
                            }
552
                        }
553
                    }
554
                }
555
            }
556
            if (changed) {
557
                orderedReferences.add(nearestFeatureReference);
558
                p = (Point) newPoint.cloneGeometry();
559
            }
560
        }
561
        return orderedReferences;
562
    }
563

    
564
    private Envelope getEnvelope(List<FeatureReference> references) throws CreateEnvelopeException, DataException{
565
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
566
        Envelope envelope = geometryManager.createEnvelope(Geometry.SUBTYPES.GEOM2D);
567
        for (Iterator iterator = references.iterator(); iterator.hasNext();) {
568
            FeatureReference featureReference = (FeatureReference) iterator.next();
569
            Geometry geometry = featureReference.getFeature().getDefaultGeometry();
570
            envelope.add(geometry.getEnvelope());
571
        }
572
        return envelope;
573
    }
574

    
575
    /* (non-Javadoc)
576
     * @see org.gvsig.lrs.lib.api.LrsAlgorithm#setParams(org.gvsig.lrs.lib.api.LrsAlgorithmParams)
577
     */
578
    public void setParams(LrsAlgorithmParams params) throws IllegalArgumentException {
579
        if(!(params instanceof LrsCreateRouteAlgorithmParams)){
580
            throw new IllegalArgumentException("params should be LrsCreateRouteAlgorithmParams type.");
581
        }
582
        // TODO Auto-generated method stub
583

    
584
    }
585

    
586
}