Revision 267

View differences:

org.gvsig.lrs/tags/org.gvsig.lrs-1.0.39/org.gvsig.lrs.lib/org.gvsig.lrs.lib.impl/src/main/java/org/gvsig/lrs/lib/impl/LrsAlgorithmUtils.java
1
/*
2
 * Copyright 2015 DiSiD Technologies S.L.L. All rights reserved.
3
 *
4
 * Project  : DiSiD org.gvsig.lrs.lib.impl
5
 * SVN Id   : $Id$
6
 */
7
package org.gvsig.lrs.lib.impl;
8

  
9
import java.io.File;
10
import java.util.ArrayList;
11
import java.util.List;
12

  
13
import org.gvsig.fmap.dal.DALLocator;
14
import org.gvsig.fmap.dal.DataManager;
15
import org.gvsig.fmap.dal.DataServerExplorer;
16
import org.gvsig.fmap.dal.DataServerExplorerParameters;
17
import org.gvsig.fmap.dal.DataStore;
18
import org.gvsig.fmap.dal.DataTypes;
19
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
20
import org.gvsig.fmap.dal.feature.EditableFeatureType;
21
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
22
import org.gvsig.fmap.dal.feature.FeatureStore;
23
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
24
import org.gvsig.fmap.dal.store.shp.SHPNewStoreParameters;
25
import org.gvsig.fmap.geom.Geometry;
26
import org.gvsig.fmap.geom.GeometryLocator;
27
import org.gvsig.fmap.geom.GeometryManager;
28
import org.gvsig.fmap.geom.aggregate.MultiLine;
29
import org.gvsig.fmap.geom.exception.CreateGeometryException;
30
import org.gvsig.fmap.geom.operation.GeometryOperationException;
31
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
32
import org.gvsig.fmap.geom.primitive.Line;
33
import org.gvsig.fmap.geom.primitive.Point;
34
import org.gvsig.fmap.geom.type.GeometryType;
35
import org.gvsig.lrs.lib.api.exceptions.LrsCreateRouteException;
36
import org.gvsig.tools.dataTypes.DataType;
37
import org.gvsig.tools.locator.LocatorException;
38

  
39
/**
40
 * @author fdiaz
41
 *
42
 */
43
public class LrsAlgorithmUtils {
44

  
45
    static protected FeatureStore createNewDataStore(NewFeatureStoreParameters newFeatureStoreParameters,
46
        FeatureAttributeDescriptor idRouteField) throws Exception {
47
        return createNewDataStore(newFeatureStoreParameters, idRouteField, Geometry.TYPES.MULTILINE);
48
    }
49

  
50
    static protected FeatureStore createNewDataStore(NewFeatureStoreParameters newFeatureStoreParameters,
51
        FeatureAttributeDescriptor idRouteField, int type) throws Exception {
52
        try {
53
            SHPNewStoreParameters shapeStoreParams = (SHPNewStoreParameters) newFeatureStoreParameters;
54
            File file = shapeStoreParams.getFile();
55
            String filePath = file.getPath().substring(0, file.getPath().lastIndexOf(File.separator));
56

  
57
            DataManager dataManager = DALLocator.getDataManager();
58
            DataServerExplorerParameters serverParams =
59
                dataManager.createServerExplorerParameters("FilesystemExplorer");
60
            serverParams.setDynValue("initialpath", filePath);
61
            DataServerExplorer serverExplorer =
62
                dataManager.openServerExplorer(serverParams.getExplorerName(), serverParams);
63

  
64
            EditableFeatureType featureType = (EditableFeatureType) shapeStoreParams.getDefaultFeatureType();
65
            featureType.add(idRouteField.getName(), idRouteField.getType(), idRouteField.getSize());
66
            EditableFeatureAttributeDescriptor geometryField = featureType.add("Geometry", DataTypes.GEOMETRY);
67
            GeometryType geometryType =
68
                GeometryLocator.getGeometryManager().getGeometryType(type, Geometry.SUBTYPES.GEOM2DM);
69
            geometryField.setGeometryType(geometryType);
70

  
71
            featureType.setDefaultGeometryAttributeName("Geometry");
72

  
73
            shapeStoreParams.setDefaultFeatureType(featureType);
74
            serverExplorer.add("Shape", shapeStoreParams, true);
75

  
76
            DataStore store = dataManager.createStore(shapeStoreParams);
77

  
78
            return (FeatureStore) store;
79

  
80
        } catch (Exception e) {
81
            throw new LrsCreateRouteException("Error creating new dataStore", e);
82
        }
83
    }
84

  
85
    static protected Double getAsDouble(Object obj, DataType dataType) {
86
        if (obj == null || dataType == null) {
87
            return null;
88
        }
89
        Double result = Double.NaN;
90
        if (dataType.equals(DataTypes.DOUBLE)) {
91
            result = (Double) obj;
92
        } else if (dataType.isNumeric()) {
93
            result = Double.valueOf(String.valueOf(obj));
94
        }
95
        return result;
96
    }
97

  
98
    static List<Point> getPointsWithM(Geometry geom, double m) throws CreateGeometryException, LocatorException {
99

  
100
        List<Point> points = new ArrayList<Point>();
101

  
102
        if (geom instanceof Line) {
103
            Line line = (Line) geom;
104
            for (int i = 0; i < line.getNumVertices() - 1; i++) {
105
                Point currentVertex = line.getVertex(i);
106
                Point nextVertex = line.getVertex(i + 1);
107
                Point point = getPointWithMBetweenTwoMPoints(m, currentVertex, nextVertex);
108
                if (point != null && !points.contains(point)) {
109
                    points.add(point);
110
                }
111
            }
112
        } else if (geom instanceof MultiLine) {
113
            MultiLine multiLine = (MultiLine) geom;
114
            for (int p = 0; p < multiLine.getPrimitivesNumber(); p++) {
115
                Line line = (Line) multiLine.getPrimitiveAt(p);
116
                for (int i = 0; i < line.getNumVertices() - 1; i++) {
117
                    Point point = getPointWithMBetweenTwoMPoints(m, line.getVertex(i), line.getVertex(i + 1));
118
                    if (point != null && !points.contains(point)) {
119
                        points.add(point);
120
                    }
121
                }
122
            }
123
        }
124
        return points;
125
    }
126

  
127
    private static boolean isInRange(double v, double r1, double r2) {
128
        if (r1 < r2) {
129
            return v >= r1 && v <= r2;
130
        } else if (r1 > r2) {
131
            return v >= r2 && v <= r1;
132
        } else {
133
            return v == r1;
134
        }
135
    }
136

  
137
    static MultiLine getLinesBetweenTwoM(Geometry geom, double m1, double m2) throws CreateGeometryException,
138
        LocatorException {
139
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
140

  
141
        MultiLine lines = null;
142
        if (geom instanceof Line) {
143
            lines = getLinesBetweenTwoM((Line) geom, m1, m2);
144
        } else if (geom instanceof MultiLine) {
145
            lines = (MultiLine) geomManager.create(Geometry.TYPES.MULTILINE, geom.getGeometryType().getSubType());
146
            MultiLine multiLine = (MultiLine) geom;
147
            for (int i = 0; i < multiLine.getPrimitivesNumber(); i++) {
148
                MultiLine auxMultiLine = getLinesBetweenTwoM(multiLine.getPrimitiveAt(i), m1, m2);
149
                for (int j = 0; j < auxMultiLine.getPrimitivesNumber(); j++) {
150
                    lines.addPrimitive(auxMultiLine.getPrimitiveAt(j));
151
                }
152
            }
153
        }
154
        return lines;
155
    }
156

  
157
    static private MultiLine getLinesBetweenTwoM(Line line, double m1, double m2) throws CreateGeometryException {
158
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
159
        MultiLine lines = (MultiLine) geomManager.create(Geometry.TYPES.MULTILINE, line.getGeometryType().getSubType());
160
        Line auxLine = (Line) geomManager.create(Geometry.TYPES.LINE, line.getGeometryType().getSubType());
161

  
162
        boolean inSegment = false;
163
        if (line.getNumVertices() > 0) {
164
            int ivertex = 0;
165
            Point previousVertex = null;
166
            while (ivertex < line.getNumVertices()) {
167
                if (!inSegment) { // NO ESTAMOS EN UN SEGMENTO VALIDO
168
                    Point vertex = line.getVertex(ivertex);
169
                    double m = vertex.getCoordinateAt(vertex.getDimension() - 1);
170
                    if (isInRange(m, m1, m2)) {
171
                        // Si la m del vertice actual entra en el rango:
172
                        if (previousVertex == null) {
173
                            // Si no hay previousVertex, este debe ser el primer
174
                            // vertice, entonces
175
                            // - a?adimos el v?rtice a la linea
176
                            // - marcamos que estamos en un segmento valido
177
                            // - nos guardamos el vertice como previousVertex
178
                            // - aumentamos el indice para coger el siguiente
179
                            // v?rtice en la pr?xima iteraci?n
180
                            auxLine.addVertex(vertex);
181
                            previousVertex = vertex;
182
                            inSegment = true;
183
                            ivertex++;
184
                        } else {
185
                            // - Calculamos qu? punto habr?a iniciado el
186
                            // segmento v?lido
187
                            double previousM = previousVertex.getCoordinateAt(previousVertex.getDimension() - 1);
188
                            // FIXME: Esta comprobaci?n se podr?a quitar
189
                            if (isInRange(m1, previousM, m) || isInRange(m2, previousM, m)) {
190
                                Point point = getPointWithMBetweenTwoMPoints(m1, previousVertex, vertex);
191
                                if (point == null) {
192
                                    point = getPointWithMBetweenTwoMPoints(m2, previousVertex, vertex);
193
                                }
194
                                if (point != null) {
195
                                    // - A?adimos el punto a la linea auxiliar
196
                                    // - Marcamos que estamos en un segmento v?lido
197
                                    // - nos guardamos el punto como previousVertex
198
                                    // - y NO aumentamos el indice
199
                                    auxLine.addVertex(point);
200
                                    inSegment = true;
201
                                    previousVertex = point;
202
                                } else {
203
                                    // Nunca deber?a pasar por aqu?
204
                                }
205
                            }
206
                        }
207
                    } else {
208
                        // Cabe la posibilidad de que entre un vertice y otro se
209
                        // entre y se salga del rango
210
                        if (previousVertex != null) {
211
                            double previousM = previousVertex.getCoordinateAt(previousVertex.getDimension() - 1);
212
                            if (isInRange(m1, previousM, m) && isInRange(m2, previousM, m)) {
213
                                Point point1 = getPointWithMBetweenTwoMPoints(m1, previousVertex, vertex);
214
                                Point point2 = getPointWithMBetweenTwoMPoints(m2, previousVertex, vertex);
215
                                auxLine.addVertex(point1);
216
                                auxLine.addVertex(point2);
217
                                lines.addPrimitive(auxLine);
218
                            }
219
                        }
220

  
221
                        // Si la m del v?rtice actual no entra en el rango:
222
                        // - nos guardamos el vertice como previousVertex
223
                        // - aumentamos el indice para coger el siguiente
224
                        // v?rtice en la pr?xima iteraci?n
225
                        previousVertex = vertex;
226
                        ivertex++;
227
                    }
228
                } else { // ESTAMOS EN UN SEGMENTO VALIDO
229
                    Point vertex = line.getVertex(ivertex);
230
                    double m = vertex.getCoordinateAt(previousVertex.getDimension() - 1);
231
                    if (isInRange(m, m1, m2)) {
232
                        // Si la m del vertice actual entra en el rango:
233
                        // - a?adimos el v?rtice a la linea
234
                        // - aumentamos el indice para coger el siguiente
235
                        // v?rtice en la pr?xima iteraci?n
236
                        auxLine.addVertex(vertex);
237
                        previousVertex = vertex;
238
                        ivertex++;
239
                    } else {
240
                        // Si la m del v?rtice actual no entra en el rango:
241
                        // - Calculamos el punto que habr?a finalizado el
242
                        // segmento v?lido entre el vertice anterior y el actual
243
                        Point point = getPointWithMBetweenTwoMPoints(m1, previousVertex, vertex);
244
                        if (point == null) {
245
                            point = getPointWithMBetweenTwoMPoints(m2, previousVertex, vertex);
246
                        }
247
                        if (point != null) {
248
                            // - A?adimos el punto a la linea auxiliar
249
                            // - a?adimos la linea y creamos una nueva
250
                            // - Marcamos que NO estamos en un segmento v?lido
251
                            // - nos guardamos el punto como previousVertex
252
                            // - y NO aumentamos el indice
253
                            auxLine.addVertex(point);
254
                            lines.addPrimitive(auxLine);
255
                            auxLine =
256
                                (Line) geomManager.create(Geometry.TYPES.LINE, line.getGeometryType().getSubType());
257
                            inSegment = false;
258
                            previousVertex = point;
259
                        } else {
260
                            // Nunca deber?a pasar por aqu?
261
                        }
262
                    }
263
                }
264
            }
265
        }
266
        if (inSegment && auxLine.getNumVertices() > 0) {
267
            lines.addPrimitive(auxLine);
268
        }
269
        return lines;
270
    }
271

  
272
    /*
273
     *
274
     */
275
    private static Point getPointWithMBetweenTwoMPoints(double m, Point p1, Point p2) throws CreateGeometryException,
276
        LocatorException {
277
        double x;
278
        double y;
279
        double m1 = p1.getCoordinateAt(p1.getDimension() - 1);
280
        double m2 = p2.getCoordinateAt(p2.getDimension() - 1);
281

  
282
        if (m1 <= m2) {
283
            if (m < m1 || m > m2) {
284
                return null;
285
            }
286
        } else {
287
            if (m < m2 || m > m1) {
288
                return null;
289
            }
290
        }
291

  
292
        double x1 = p1.getX();
293
        double x2 = p2.getX();
294
        double y1 = p1.getY();
295
        double y2 = p2.getY();
296
        if (x1 == x2) {
297
            x = x1;
298
        } else {
299
            x = ((x2 - x1) * (m - m1) / (m2 - m1)) + x1;
300
        }
301
        if (y1 == y2) {
302
            y = y1;
303
        } else {
304
            y = ((y2 - y1) * (m - m1) / (m2 - m1)) + y1;
305
        }
306

  
307
        Point point = (Point) GeometryLocator.getGeometryManager().create(p1.getGeometryType());
308
        point.setX(x);
309
        point.setY(y);
310
        point.setCoordinateAt(point.getDimension() - 1, m);
311
        return point;
312
    }
313

  
314

  
315

  
316
    /**
317
     * Returns geometry length without gaps
318
     * @param geometry
319
     * @return
320
     * @throws GeometryOperationNotSupportedException
321
     * @throws GeometryOperationException
322
     */
323
    static protected Double getGeometryLength(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException{
324
        return getGeometryLength(geometry, true);
325
    }
326

  
327
    /**
328
     * Returns geometry length without gaps with the option to not ignore spatial gaps.
329
     * @param geometry
330
     * @param ignoreSpatialGaps
331
     * @return
332
     * @throws GeometryOperationNotSupportedException
333
     * @throws GeometryOperationException
334
     */
335
    static protected Double getGeometryLength(Geometry geometry,
336
        boolean ignoreSpatialGaps)
337
            throws GeometryOperationNotSupportedException,
338
            GeometryOperationException {
339
        if (geometry instanceof Line) {
340
            Line line = (Line) geometry;
341
            return getLineLength(line);
342
        }
343
        if (geometry instanceof MultiLine) {
344
            MultiLine multiLine = (MultiLine) geometry;
345
            return getMultiLineLength(multiLine, ignoreSpatialGaps);
346
        }
347
        return Double.NaN;
348
    }
349

  
350
    /**
351
     * @param line
352
     * @return lenght
353
     * @throws GeometryOperationException
354
     * @throws GeometryOperationNotSupportedException
355
     */
356
    static protected double getLineLength(Line line)
357
        throws GeometryOperationNotSupportedException,
358
        GeometryOperationException {
359
        double lenght = 0;
360
        Point previousVertex = null;
361
        for (int i = 0; i < line.getNumVertices(); i++) {
362
            Point vertex = line.getVertex(i);
363
            if (previousVertex != null) {
364
                lenght += previousVertex.distance(vertex);
365
            }
366
            previousVertex = vertex;
367
        }
368
        return lenght;
369
    }
370

  
371
    /**
372
     * @param multiLine
373
     * @return lenght
374
     * @throws GeometryOperationException
375
     * @throws GeometryOperationNotSupportedException
376
     */
377
    static protected double getMultiLineLength(MultiLine multiLine,
378
        boolean ignoreSpatialGaps)
379
            throws GeometryOperationNotSupportedException,
380
            GeometryOperationException {
381
        double length = 0;
382
        Point previousVertex = null;
383
        for (int j = 0; j < multiLine.getPrimitivesNumber(); j++) {
384
            Line line = (Line) multiLine.getPrimitiveAt(j);
385
            if (ignoreSpatialGaps) {
386
                previousVertex = null;
387
            }
388
            for (int i = 0; i < line.getNumVertices(); i++) {
389
                Point vertex = line.getVertex(i);
390
                if (previousVertex != null) {
391
                    length += previousVertex.distance(vertex);
392
                }
393
                previousVertex = vertex;
394
            }
395
        }
396
        return length;
397
    }
398

  
399
    /**
400
     * Extracts the lines in a Line or Multiline
401
     * @param geometry
402
     * @return
403
     */
404
    static protected List<Line> extractLines(Geometry geometry){
405
        List<Line> lines=new ArrayList<Line>();
406
        if (geometry instanceof  Line){
407
            lines.add((Line) geometry);
408
        }
409
        if (geometry instanceof MultiLine){
410
            MultiLine multiline=(MultiLine)geometry;
411
            for (int i=0;i<multiline.getPrimitivesNumber();i++){
412
                lines.add((Line) multiline.getPrimitiveAt(i));
413
            }
414
        }
415
        return lines;
416
    }
417

  
418
    static protected List<Point> extractPoints(Geometry geometry){
419
        List<Point> points=new ArrayList<Point>();
420
        List<Line> lines=LrsAlgorithmUtils.extractLines(geometry);
421
        for (Line line: lines){
422
            for (int i=0;i<line.getNumVertices();i++){
423
                points.add(line.getVertex(i));
424
            }
425
        }
426
        return points;
427
    }
428

  
429

  
430
    static protected Point extractFirstPoint(Geometry geometry){
431
        Point firstPoint=null;
432
        List<Line> lines= LrsAlgorithmUtils.extractLines(geometry);
433
        if (lines!=null && !lines.isEmpty()){
434
            firstPoint=lines.get(0).getVertex(0);
435
        }
436
        return firstPoint;
437
    }
438

  
439
    static protected boolean equalPoints(Point point1, Point point2){
440
        if ( point1.getX()==point2.getX() && point1.getY()==point2.getY()){
441
            return true;
442
        }
443
        return false;
444
    }
445

  
446
    static protected Geometry insertVertex(Geometry geometry, Point vertex, int index){
447
        if (geometry instanceof Line){
448
            Line line=(Line)geometry;
449
            line.insertVertex(index, vertex);
450
        }
451
        if (geometry instanceof MultiLine){
452
            List<Line> lines=extractLines(geometry);
453
            for(Line line:lines){
454
                if (index<=line.getNumVertices()){
455
                    line.insertVertex(index, vertex);
456
                    return geometry;
457
                }else{
458
                    index-=line.getNumVertices();
459
                }
460

  
461
            }
462
        }
463
        return geometry;
464
    }
465

  
466
    /**
467
     * Reduced versi?n of straight line through two points equation to calculate M's
468
     *
469
     * @param totalLength
470
     * @param minValue
471
     * @param maxValue
472
     * @param relativeDistance
473
     * @return
474
     */
475
    static protected double calculateM(Double totalLength, Double minValue, Double maxValue, Double relativeDistance) {
476
        return LrsAlgorithmUtils.straightLineThroughTwoPointsEquation(0, totalLength, minValue, maxValue, relativeDistance);
477
    }
478

  
479
    /**
480
     * Straight line through two points equation.
481
     *
482
     * @param x1
483
     * @param x2
484
     * @param y1
485
     * @param y2
486
     * @param x
487
     * @return
488
     */
489
    static protected double straightLineThroughTwoPointsEquation(double x1, double x2, double y1, double y2, double x) {
490
        if (x2 - x1 == 0.0) {
491
            return Double.POSITIVE_INFINITY;
492
        }
493
        return ((y2 - y1) * (x - x1) / (x2 - x1)) + y1;
494
    }
495

  
496
}
org.gvsig.lrs/tags/org.gvsig.lrs-1.0.39/org.gvsig.lrs.lib/org.gvsig.lrs.lib.impl/src/main/java/org/gvsig/lrs/lib/impl/DefaultLrsEditRouteCalibrationSelectIdRouteAlgorithmParams.java
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 org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
26
import org.gvsig.fmap.dal.feature.FeatureStore;
27
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
28
import org.gvsig.lrs.lib.api.DistanceUnits;
29
import org.gvsig.lrs.lib.api.LrsCalibrateRouteAlgorithmParams;
30
import org.gvsig.lrs.lib.api.LrsEditRouteCalibrationSelectIdRouteAlgorithmParams;
31
import org.gvsig.lrs.lib.api.LrsMeasureCalculationMethods;
32

  
33

  
34
/**
35
 * @author dmartinez
36
 *
37
 */
38
public class DefaultLrsEditRouteCalibrationSelectIdRouteAlgorithmParams implements LrsEditRouteCalibrationSelectIdRouteAlgorithmParams {
39

  
40
    private FeatureAttributeDescriptor idRouteField;
41
    private final String NAME = "LrsEditRouteCalibrationSelectIdRouteAlgorithm";
42
    private final String DESCRIPTION = "Algorithm to select id route to edit calibration with linear reference system.";
43

  
44

  
45
    /* (non-Javadoc)
46
     * @see org.gvsig.lrs.lib.api.LrsAlgorithmParams#getName()
47
     */
48
    public String getName() {
49
        return NAME;
50
    }
51

  
52
    /* (non-Javadoc)
53
     * @see org.gvsig.lrs.lib.api.LrsAlgorithmParams#getDescription()
54
     */
55
    public String getDescription() {
56
        return DESCRIPTION;
57
    }
58

  
59
    /*
60
     * (non-Javadoc)
61
     * @see org.gvsig.lrs.lib.api.LrsCreateRouteAlgorithmParams#getIdRouteField()
62
     */
63
    public FeatureAttributeDescriptor getIdRouteField() {
64
        return idRouteField;
65
    }
66

  
67
    /*
68
     * (non-Javadoc)
69
     * @see org.gvsig.lrs.lib.api.LrsCreateRouteAlgorithmParams#setIdRouteField(org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor)
70
     */
71
    public void setIdRouteField(FeatureAttributeDescriptor idRouteField) {
72
        this.idRouteField = idRouteField;
73
    }
74

  
75
}
org.gvsig.lrs/tags/org.gvsig.lrs-1.0.39/org.gvsig.lrs.lib/org.gvsig.lrs.lib.impl/src/main/java/org/gvsig/lrs/lib/impl/DefaultLrsAlgorithmsManager.java
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 org.gvsig.lrs.lib.api.MeasuresCalculator;
26

  
27
import java.util.List;
28

  
29
import org.apache.commons.lang3.StringUtils;
30
import org.cresques.cts.IProjection;
31

  
32
import org.gvsig.fmap.dal.DALLocator;
33
import org.gvsig.fmap.dal.DataManager;
34
import org.gvsig.fmap.dal.DataServerExplorer;
35
import org.gvsig.fmap.dal.DataServerExplorerParameters;
36
import org.gvsig.fmap.dal.DataStoreParameters;
37
import org.gvsig.fmap.dal.exception.DataException;
38
import org.gvsig.fmap.dal.exception.InitializeException;
39
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
40
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
41
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
42
import org.gvsig.fmap.dal.feature.EditableFeatureType;
43
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
44
import org.gvsig.fmap.dal.feature.FeatureStore;
45
import org.gvsig.fmap.dal.feature.FeatureType;
46
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
47
import org.gvsig.fmap.geom.DataTypes;
48
import org.gvsig.fmap.geom.Geometry;
49
import org.gvsig.fmap.geom.GeometryLocator;
50
import org.gvsig.fmap.geom.GeometryManager;
51
import org.gvsig.fmap.geom.exception.CreateGeometryException;
52
import org.gvsig.fmap.geom.operation.GeometryOperationException;
53
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
54
import org.gvsig.fmap.geom.primitive.Line;
55
import org.gvsig.fmap.geom.primitive.Point;
56
import org.gvsig.fmap.geom.type.GeometryType;
57
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
58
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
59
import org.gvsig.lrs.lib.api.LrsAlgorithm;
60
import org.gvsig.lrs.lib.api.LrsAlgorithmParams;
61
import org.gvsig.lrs.lib.api.LrsAlgorithmsManager;
62
import org.gvsig.lrs.lib.api.LrsCalibrateRouteAlgorithmParams;
63
import org.gvsig.lrs.lib.api.LrsCreateRouteAlgorithmParams;
64
import org.gvsig.lrs.lib.api.LrsEditRouteCalibrationAlgorithmParams;
65
import org.gvsig.lrs.lib.api.LrsEditRouteCalibrationSelectIdRouteAlgorithmParams;
66
import org.gvsig.lrs.lib.api.LrsGenerateDynamicSegmentationAlgorithmParams;
67
import org.gvsig.lrs.lib.api.LrsShowMeasuresAlgorithmParams;
68
import org.gvsig.tools.dynobject.DynObject;
69
import org.gvsig.tools.locator.LocatorException;
70
import org.gvsig.tools.service.Service;
71
import org.gvsig.tools.service.ServiceException;
72

  
73

  
74
/**
75
 * @author fdiaz
76
 *
77
 */
78
public class DefaultLrsAlgorithmsManager implements LrsAlgorithmsManager {
79

  
80
    /* (non-Javadoc)
81
     * @see org.gvsig.tools.service.Manager#createServiceParameters(java.lang.String)
82
     */
83
    public DynObject createServiceParameters(String serviceName) throws ServiceException {
84
        // TODO Auto-generated method stub
85
        return null;
86
    }
87

  
88
    /* (non-Javadoc)
89
     * @see org.gvsig.tools.service.Manager#getService(org.gvsig.tools.dynobject.DynObject)
90
     */
91
    public Service getService(DynObject parameters) throws ServiceException {
92
        // TODO Auto-generated method stub
93
        return null;
94
    }
95

  
96
    /* (non-Javadoc)
97
     * @see org.gvsig.lrs.lib.api.LrsAlgorithmsManager#createLrsAlgorithm(org.gvsig.lrs.lib.api.LrsAlgorithmParams)
98
     */
99
    public LrsAlgorithm createLrsAlgorithm(LrsAlgorithmParams params) {
100
        if(params instanceof LrsCreateRouteAlgorithmParams){
101
            return new LrsCreateRouteAlgorithm((LrsCreateRouteAlgorithmParams)params);
102
        }
103
        if(params instanceof LrsCalibrateRouteAlgorithmParams){
104
            return new LrsCalibrateRouteAlgorithm((LrsCalibrateRouteAlgorithmParams)params);
105
        }
106
        if(params instanceof LrsGenerateDynamicSegmentationAlgorithmParams){
107
            return new LrsGenerateDynamicSegmentationAlgorithm((LrsGenerateDynamicSegmentationAlgorithmParams)params);
108
        }
109
        return null;
110
    }
111

  
112
    /* (non-Javadoc)
113
     * @see org.gvsig.lrs.lib.api.LrsAlgorithmsManager#createLrsCreateRouteAlgorithmParams()
114
     */
115
    public LrsCreateRouteAlgorithmParams createLrsCreateRouteAlgorithmParams() {
116
        return new DefaultLrsCreateRouteAlgorithmParams();
117
    }
118

  
119
    /* (non-Javadoc)
120
     * @see org.gvsig.lrs.lib.api.LrsAlgorithmsManager#createLrsCalibrateRouteAlgorithmParams()
121
     */
122
    public LrsCalibrateRouteAlgorithmParams createLrsCalibrateRouteAlgorithmParams() {
123
        return new DefaultLrsCalibrateRouteAlgorithmParams();
124
    }
125

  
126
    /* (non-Javadoc)
127
     * @see org.gvsig.lrs.lib.api.LrsAlgorithmsManager#createLrsEditRouteCalibrationAlgorithmParams()
128
     */
129
    public LrsEditRouteCalibrationAlgorithmParams createLrsEditRouteCalibrationAlgorithmParams() {
130
        return new DefaultLrsEditRouteCalibrationAlgorithmParams();
131
    }
132

  
133
    /* (non-Javadoc)
134
     * @see org.gvsig.lrs.lib.api.LrsAlgorithmsManager#createLrsEditRouteCalibrationSelectIdRouteAlgorithmParams()
135
     */
136
    public LrsEditRouteCalibrationSelectIdRouteAlgorithmParams createLrsEditRouteCalibrationSelectIdRouteAlgorithmParams() {
137
        return new DefaultLrsEditRouteCalibrationSelectIdRouteAlgorithmParams();
138
    }
139

  
140
    /* (non-Javadoc)
141
     * @see org.gvsig.lrs.lib.api.LrsAlgorithmsManager#createLrsShowMeasuresAlgorithmParams()
142
     */
143
    public LrsShowMeasuresAlgorithmParams createLrsShowMeasuresAlgorithmParams() {
144
        return new DefaultLrsShowMeasuresAlgorithmParams();
145
    }
146

  
147

  
148
    /* (non-Javadoc)
149
     * @see org.gvsig.lrs.lib.api.LrsAlgorithmsManager#createLrsGenerateDynamicSegmentationAlgorithmParams()
150
     */
151
    public LrsGenerateDynamicSegmentationAlgorithmParams createLrsGenerateDynamicSegmentationAlgorithmParams() {
152
        return new DefaultLrsGenerateDynamicSegmentationAlgorithmParams();
153
    }
154

  
155

  
156
    public void createNewShape(FeatureType sourceFeatureType,
157
        int outputLayerType, String outputLayerPath, IProjection projection) throws ValidateDataParametersException, DataException, GeometryTypeNotSupportedException, GeometryTypeNotValidException {
158

  
159
        DataManager dataManager = DALLocator.getDataManager();
160
        DataServerExplorerParameters eparams =
161
            dataManager.createServerExplorerParameters("FilesystemExplorer");
162
        eparams.setDynValue("initialpath", "/data");
163
        DataServerExplorer serverExplorer =
164
            dataManager.openServerExplorer(eparams.getExplorerName(), eparams);
165

  
166
        NewFeatureStoreParameters sparams =
167
            (NewFeatureStoreParameters) serverExplorer
168
                .getAddParameters("Shape");
169

  
170
        EditableFeatureType newEditableFeatureType =
171
            (EditableFeatureType) sparams.getDefaultFeatureType();
172

  
173
        // Iterate over feature type. Don't add geometry fields.
174
        for (int i = 0; i < sourceFeatureType.size(); i++) {
175
            String fieldName =
176
                sourceFeatureType.getAttributeDescriptor(i).getName();
177
            int fieldType =
178
                sourceFeatureType.getAttributeDescriptor(i).getType();
179
            if (fieldType != DataTypes.GEOMETRY) {
180
                newEditableFeatureType.add(fieldName, fieldType);
181
            }
182
        }
183

  
184
        // Add new geometry field with new geometry type
185
        FeatureAttributeDescriptor geometryAttribute =
186
            (FeatureAttributeDescriptor) sourceFeatureType
187
                .get(sourceFeatureType.getDefaultGeometryAttributeName());
188
        EditableFeatureAttributeDescriptor newGeometryAttribute =
189
            newEditableFeatureType.add(geometryAttribute.getName(),
190
                geometryAttribute.getType(), geometryAttribute.getSize());
191

  
192
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
193
        GeometryType sourceLayerGeomType =
194
            sourceFeatureType.getDefaultGeometryAttribute().getGeomType();
195
        GeometryType outputLayerGeomType =
196
            geoManager.getGeometryType(outputLayerType,
197
                sourceLayerGeomType.getSubType());
198

  
199
        newGeometryAttribute.setGeometryType(outputLayerGeomType);
200
        newGeometryAttribute.setPrecision(geometryAttribute.getPrecision());
201
        newGeometryAttribute.setDefaultValue(geometryAttribute
202
            .getDefaultValue());
203

  
204
        newEditableFeatureType
205
            .setDefaultGeometryAttributeName(geometryAttribute.getName());
206

  
207
        if(!StringUtils.endsWithIgnoreCase(outputLayerPath, ".shp")){
208
            outputLayerPath = new StringBuilder().append(outputLayerPath).append(".shp").toString();
209
        }
210

  
211
        sparams.setDynValue("geometryType", null);
212
        sparams.setDynValue("shpfile", outputLayerPath);
213
        sparams.setDynValue("CRS", projection);
214
        sparams.setDynValue("useNullGeometry", false);
215
        sparams.setDefaultFeatureType(newEditableFeatureType);
216
        sparams.validate();
217

  
218
        serverExplorer.add("Shape", sparams, true);
219
    }
220

  
221
    public FeatureStore getFeatureStore(String outputLayerPath,
222
        IProjection projection) throws InitializeException, ProviderNotRegisteredException, ValidateDataParametersException{
223

  
224
        DataManager dataManager = DALLocator.getDataManager();
225
        DataStoreParameters dataStoreParams =
226
            dataManager.createStoreParameters("Shape");
227
        dataStoreParams.setDynValue("shpfile", outputLayerPath);
228
        dataStoreParams.setDynValue("CRS", projection);
229
        dataStoreParams.setDynValue("useNullGeometry", false);
230
        dataStoreParams.validate();
231

  
232
        return (FeatureStore) dataManager.openStore("Shape", dataStoreParams);
233
    }
234

  
235
    public MeasuresCalculator createMeasuresCalculator(Geometry geometry, boolean ignoreSpatialGaps) {
236
        return new DefaultMeasuresCalculator(geometry, ignoreSpatialGaps);
237
    }
238

  
239
    @Override
240
    public Point getMPointFromGeometry(Geometry geom, double m) throws CreateGeometryException, LocatorException {
241
        List<Point> points = LrsAlgorithmUtils.getPointsWithM( geom,  m);
242
        if (points!=null && !points.isEmpty()){
243
            return points.get(0);
244
        }
245
        return null;
246
    }
247

  
248
    /**
249
     * Given a point without m in a M-Geometry, returns the point with the m-value
250
     * @param geom
251
     * @param pointNoM
252
     * @return
253
     * @throws GeometryOperationException
254
     * @throws GeometryOperationNotSupportedException
255
     * @throws CreateGeometryException
256
     */
257
    @Override
258
    public Point getMPointFromGeometry(Geometry geom, Point pointNoM) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException{
259
        final Double PRECISION = new Double(1.0e-5);
260
        final int MDIMENSION = geom.getDimension() - 1;
261

  
262
        List<Line> lines = LrsAlgorithmUtils.extractLines(geom);
263
        for (int i = 0; i < lines.size(); i++) {
264
            Line line = lines.get(i);
265

  
266
            if (line.isWithinDistance(pointNoM, PRECISION)) {
267
                for (int j = 0; j < line.getNumVertices(); j++) {
268
                    Point vertex = line.getVertex(j);
269
                    Point nextVertex;
270
                    if (j + 1 < line.getNumVertices()) {
271
                        nextVertex = line.getVertex(j + 1);
272
                    } else {
273
                        nextVertex = null;
274
                    }
275
                    //The point and the first vertex are the same
276
                    if (LrsAlgorithmUtils.equalPoints(vertex, pointNoM) || vertex.distance(pointNoM) <= PRECISION) {
277
                        Double m=vertex.getCoordinateAt(MDIMENSION);
278
                        GeometryManager geomanager = GeometryLocator.getGeometryManager();
279
                        Point mPoint = (Point) geomanager
280
                                .create(Geometry.TYPES.POINT, Geometry.SUBTYPES.GEOM2DM);
281
                        mPoint.setX(pointNoM.getX());
282
                        mPoint.setY(pointNoM.getY());
283
                        mPoint.setCoordinateAt(MDIMENSION, m);
284
                        return mPoint;
285
                    }else{
286
                        if (nextVertex != null
287
                            && !LrsAlgorithmUtils.equalPoints(nextVertex, pointNoM)
288
                            && vertex.distance(pointNoM) > PRECISION
289
                            && nextVertex.distance(pointNoM) > PRECISION) {
290

  
291
                            GeometryManager geomanager = GeometryLocator.getGeometryManager();
292
                            Line segment = (Line) geomanager
293
                                    .create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM);
294
                            segment.addVertex(vertex);
295
                            segment.addVertex(nextVertex);
296
                            if (segment.isWithinDistance(pointNoM, PRECISION)) {
297
                                double distanceFirstVertex = 0;
298
                                double distanceNextVertex = nextVertex.distance(vertex);
299
                                double distanceToFixedPoint = vertex.distance(pointNoM);
300

  
301
                                Double m = LrsAlgorithmUtils.straightLineThroughTwoPointsEquation(
302
                                    distanceFirstVertex,
303
                                    distanceNextVertex,
304
                                    vertex.getCoordinateAt(MDIMENSION),
305
                                    nextVertex.getCoordinateAt(MDIMENSION),
306
                                    distanceToFixedPoint);
307

  
308
                                Point mPoint = (Point) geomanager
309
                                        .create(Geometry.TYPES.POINT, Geometry.SUBTYPES.GEOM2DM);
310
                                mPoint.setX(pointNoM.getX());
311
                                mPoint.setY(pointNoM.getY());
312
                                mPoint.setCoordinateAt(MDIMENSION, m);
313
                                return mPoint;
314
                            }
315
                        }
316
                    }
317
                }
318
            }
319

  
320
        }
321
        return null;
322

  
323
    }
324
}
org.gvsig.lrs/tags/org.gvsig.lrs-1.0.39/org.gvsig.lrs.lib/org.gvsig.lrs.lib.impl/src/main/java/org/gvsig/lrs/lib/impl/LrsCreateRouteAlgorithm.java
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.Collections;
27
import java.util.Iterator;
28
import java.util.List;
29
import java.util.Map.Entry;
30
import java.util.SortedMap;
31
import java.util.TreeMap;
32

  
33
import org.apache.commons.lang3.mutable.MutableInt;
34
import org.slf4j.Logger;
35
import org.slf4j.LoggerFactory;
36

  
37
import org.gvsig.fmap.dal.feature.EditableFeature;
38
import org.gvsig.fmap.dal.feature.Feature;
39
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
40
import org.gvsig.fmap.dal.feature.FeatureSet;
41
import org.gvsig.fmap.dal.feature.FeatureStore;
42
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
43
import org.gvsig.fmap.geom.Geometry;
44
import org.gvsig.fmap.geom.Geometry.DIMENSIONS;
45
import org.gvsig.fmap.geom.GeometryLocator;
46
import org.gvsig.fmap.geom.GeometryManager;
47
import org.gvsig.fmap.geom.aggregate.MultiLine;
48
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
49
import org.gvsig.fmap.geom.exception.CreateGeometryException;
50
import org.gvsig.fmap.geom.operation.GeometryOperationException;
51
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
52
import org.gvsig.fmap.geom.primitive.Envelope;
53
import org.gvsig.fmap.geom.primitive.Line;
54
import org.gvsig.fmap.geom.primitive.Point;
55
import org.gvsig.lrs.lib.api.LrsAlgorithm;
56
import org.gvsig.lrs.lib.api.LrsAlgorithmParams;
57
import org.gvsig.lrs.lib.api.LrsCoordinatesPriority;
58
import org.gvsig.lrs.lib.api.LrsCreateRouteAlgorithmParams;
59
import org.gvsig.lrs.lib.api.LrsSourceOfMeasures;
60
import org.gvsig.lrs.lib.api.exceptions.LrsCreateRouteException;
61
import org.gvsig.lrs.lib.api.exceptions.LrsException;
62
import org.gvsig.tools.ToolsLocator;
63
import org.gvsig.tools.dataTypes.DataType;
64
import org.gvsig.tools.exception.BaseException;
65
import org.gvsig.tools.i18n.I18nManager;
66
import org.gvsig.tools.locator.LocatorException;
67
import org.gvsig.tools.service.Manager;
68
import org.gvsig.tools.task.SimpleTaskStatus;
69
import org.gvsig.tools.visitor.VisitCanceledException;
70
import org.gvsig.tools.visitor.Visitor;
71

  
72
/**
73
 * @author fdiaz
74
 *
75
 */
76
public class LrsCreateRouteAlgorithm implements LrsAlgorithm {
77

  
78
    private static final Logger logger = LoggerFactory.getLogger(LrsCreateRouteAlgorithm.class);
79

  
80
    private LrsCreateRouteAlgorithmParams parameters;
81

  
82
    /**
83
     *
84
     */
85
    public LrsCreateRouteAlgorithm(LrsCreateRouteAlgorithmParams parameters) {
86
        this.parameters = parameters;
87

  
88
    }
89

  
90
    /*
91
     * (non-Javadoc)
92
     *
93
     * @see org.gvsig.tools.service.Service#getManager()
94
     */
95
    public Manager getManager() {
96
        return null;
97
    }
98

  
99
    /*
100
     * (non-Javadoc)
101
     *
102
     * @see org.gvsig.lrs.lib.api.LrsAlgorithm#getParams()
103
     */
104
    public LrsAlgorithmParams getParams() {
105
        return this.parameters;
106
    }
107

  
108
    /*
109
     * (non-Javadoc)
110
     *
111
     * @see org.gvsig.lrs.lib.api.LrsAlgorithm#execute(org.gvsig.tools.task.
112
     * SimpleTaskStatus)
113
     */
114
    public void execute(SimpleTaskStatus taskStatus) throws LrsException {
115
        NewFeatureStoreParameters newFeatureStoreParameters = parameters.getNewFeatureStoreParameters();
116
        FeatureStore sourceFeatureStore = parameters.getSourceFeatureStore();
117
        FeatureAttributeDescriptor idRouteField = parameters.getIdRouteField();
118
        FeatureAttributeDescriptor fromMeasureField = parameters.getFromMeasureField();
119
        FeatureAttributeDescriptor toMeasureField = parameters.getToMeasureField();
120

  
121
        logger.info(parameters.toString());
122

  
123
        taskStatus.setTitle(parameters.getName());
124
        I18nManager i18nManager = ToolsLocator.getI18nManager();
125
        taskStatus.message(i18nManager.getTranslation("grouping_features"));
126

  
127
        try {
128
            final String routeFieldName = idRouteField.getName();
129
            final String fromFieldName;
130
            final DataType fromDataType;
131
            final DataType toDataType;
132
            if (fromMeasureField != null) {
133
                fromFieldName = fromMeasureField.getName();
134
                fromDataType = fromMeasureField.getDataType();
135
            } else {
136
                fromFieldName = null;
137
                fromDataType = null;
138
            }
139
            final String toFieldName;
140
            if (toMeasureField != null) {
141
                toFieldName = toMeasureField.getName();
142
                toDataType = toMeasureField.getDataType();
143
            } else {
144
                toFieldName = null;
145
                toDataType = null;
146
            }
147

  
148
            FeatureStore newFeatureStore =
149
                LrsAlgorithmUtils.createNewDataStore(newFeatureStoreParameters, idRouteField);
150

  
151
            FeatureSet sourceFeatures;
152
            if (sourceFeatureStore.getFeatureSelection().getSize() > 0) {
153
                sourceFeatures = sourceFeatureStore.getFeatureSelection();
154
            } else {
155
                sourceFeatures = sourceFeatureStore.getFeatureSet();
156
            }
157

  
158
            final SortedMap<String, List<MSegment>> featuresMap = new TreeMap<String, List<MSegment>>();
159
            final MutableInt contId = new MutableInt(0);
160
            sourceFeatures.accept(new Visitor() {
161

  
162
                public void visit(Object obj) throws VisitCanceledException, BaseException {
163
                    Feature feature = (Feature) obj;
164
                    String routeName = (String) feature.get(routeFieldName);
165
                    Object objFrom = null;
166
                    Object objTo = null;
167
                    if (fromFieldName != null) {
168
                        objFrom = feature.get(fromFieldName);
169
                    }
170
                    if (toFieldName != null) {
171
                        objTo = feature.get(toFieldName);
172
                    }
173
                    if (!featuresMap.containsKey(routeName)) {
174
                        featuresMap.put(routeName, new ArrayList<MSegment>());
175
                    }
176
                    List<MSegment> mList = featuresMap.get(routeName);
177
                    MSegment mSegment = new MSegment();
178
                    mSegment.geometry = feature.getDefaultGeometry().cloneGeometry();
179
                    mSegment.fromValue = LrsAlgorithmUtils.getAsDouble(objFrom, fromDataType);
180
                    mSegment.toValue = LrsAlgorithmUtils.getAsDouble(objTo, toDataType);
181
                    mSegment.id = contId.getValue();
182
                    contId.increment();
183
                    mList.add(mSegment);
184
                    featuresMap.put(routeName, mList);
185
                }
186
            });
187

  
188
            taskStatus.setRangeOfValues(0, featuresMap.size());
189
            int taskCount = 0;
190

  
191
            newFeatureStore.edit(FeatureStore.MODE_FULLEDIT);
192

  
193
            for (Entry<String, List<MSegment>> entry : featuresMap.entrySet()) {
194
                String routeName = entry.getKey();
195
                List<MSegment> mList = entry.getValue();
196

  
197
                EditableFeature newFeature = newFeatureStore.createNewFeature(true);
198
                newFeature.set(routeFieldName, routeName);
199
                Geometry route = createGeometryRoute(mList);
200
                newFeature.setDefaultGeometry(route);
201

  
202
                newFeatureStore.update(newFeature);
203

  
204
                taskCount++;
205
                taskStatus.setCurValue(taskCount);
206

  
207
            }
208
            newFeatureStore.finishEditing();
209

  
210
        } catch (Exception e1) {
211
            taskStatus.abort();
212
            throw new LrsCreateRouteException("Error creating routes", e1);
213
        }
214

  
215
        taskStatus.terminate();
216

  
217
    }
218

  
219
    private Geometry createGeometryRoute(List<MSegment> mList) throws CreateGeometryException,
220
        GeometryOperationNotSupportedException, GeometryOperationException, CreateEnvelopeException {
221
        LrsSourceOfMeasures sourceOfMeasures = parameters.getSourceOfMeasures();
222
        Geometry geometryResult = null;
223
        simplifyMultilines(mList);
224
        switch (sourceOfMeasures) {
225
        case ONE_FIELD:
226
            geometryResult = calculateGeometryByOneField(mList);
227
            break;
228
        case TWO_FIELDS:
229
            geometryResult = calculateGeometryByTwoField(mList);
230
            break;
231
        case LENGTH:
232
        default:
233
            geometryResult = calculateGeometryByLength(mList);
234
            break;
235
        }
236
        geometryResult = applyOffsetAndFactor(geometryResult);
237
        return geometryResult;
238
    }
239

  
240
    private Geometry calculateGeometryByLength(List<MSegment> mList) throws CreateGeometryException,
241
        GeometryOperationNotSupportedException, GeometryOperationException, CreateEnvelopeException {
242
        boolean ignoreSpatialGaps = parameters.ignoreSpatialGaps();
243
        for (MSegment mSegment : mList) {
244
            mSegment.fromValue = LrsAlgorithmUtils.getGeometryLength(mSegment.geometry, ignoreSpatialGaps);
245
        }
246
        return calculateGeometryByOneField(mList);
247
    }
248

  
249
    private Geometry calculateGeometryByOneField(List<MSegment> mList) throws CreateGeometryException,
250
        GeometryOperationNotSupportedException, GeometryOperationException, CreateEnvelopeException {
251
        boolean ignoreSpatialGaps = parameters.ignoreSpatialGaps();
252
        GeometryManager gmanager = GeometryLocator.getGeometryManager();
253
        try {
254
            mList = sortMList(mList);
255
        } catch (Exception e) {
256
            logger.warn("Geometries couldn't be ordered");
257
        }
258

  
259
        MultiLine auxMultiLine = (MultiLine) gmanager.create(Geometry.TYPES.MULTILINE, Geometry.SUBTYPES.GEOM2DM);
260

  
261
        Point previousPoint = null;
262
        double previousM = 0.0;
263
        for (MSegment mSegment : mList) {
264
            Geometry geom = mSegment.geometry;
265
            Double geometryLength = mSegment.getLength(ignoreSpatialGaps);
266
            if (geom instanceof Line) {
267
                Line line = (Line) geom;
268
                Line auxLine = (Line) gmanager.create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM);
269
                double distance = 0.0;
270
                double firstM = previousM;
271
                for (int i = 0; i < line.getNumVertices(); i++) {
272
                    Point vertex = line.getVertex(i);
273
                    Point point = (Point) gmanager.create(Geometry.TYPES.POINT, Geometry.SUBTYPES.GEOM2DM);
274
                    point.setX(vertex.getX());
275
                    point.setY(vertex.getY());
276
                    if (i == 0 && previousPoint != null) {
277
                        boolean gap = false;
278
                        if (areInSame2DLocation(previousPoint, vertex)) {
279
                            // Buscamos si ha sido una bifurcaci?n
280
                            Point fork = getPossibleFork(auxMultiLine, vertex);
281
                            if(fork!=null){
282
                                previousPoint = fork;
283
                                // OJO, aqu? previousPoint pasa a ser 2DM
284
                            }
285
                        } else {
286
                            // En caso de salto, calculamos el previousPoint
287
                            // buscando el v?rtice m?s cercano
288
                            previousPoint = getClosestVertex(auxMultiLine, vertex);
289
                            // OJO, aqu? previousPoint pasa a ser 2DM
290
                            gap = true;
291
                        }
292
                        previousM = previousPoint.getCoordinateAt(previousPoint.getDimension() - 1);
293
                        if (i == 0) {
294
                            firstM = previousM;
295
                        }
296
                        if (gap && !ignoreSpatialGaps) {
297
                            Point previousVertex = getPreviousVertexToPoint(auxMultiLine, previousPoint);
298
                            if(areInSame2DLocation(previousPoint,previousVertex)){
299
                                Point nextVertex = getNextVertexToPoint(auxMultiLine, previousPoint);
300
                                double distanceToNextPoint = nextVertex.distance(previousPoint);
301
                                previousM = LrsAlgorithmUtils.straightLineThroughTwoPointsEquation(0, distanceToNextPoint,
302
                                    previousM, nextVertex.getCoordinateAt(previousVertex.getDimension() - 1),
303
                                        previousPoint.distance(point));
304
                            } else {
305
                                double distanceToPreviousPoint = previousVertex.distance(previousPoint);
306
                                previousM = LrsAlgorithmUtils.straightLineThroughTwoPointsEquation(0, distanceToPreviousPoint,
307
                                        previousVertex.getCoordinateAt(previousVertex.getDimension() - 1), previousM,
308
                                        distanceToPreviousPoint + previousPoint.distance(point));
309
                            }
310
                            firstM = previousM;
311
                        }
312
                    }
313
                    if (i != 0) {
314
                        distance += previousPoint.distance(vertex);
315
                    }
316
                    double m =
317
                        LrsAlgorithmUtils.straightLineThroughTwoPointsEquation(0, geometryLength, firstM, firstM + mSegment.fromValue,
318
                            distance);
319
                    point.setCoordinateAt(point.getDimension() - 1, m);
320
                    auxLine.addVertex(point);
321
                    previousM = m;
322
                    previousPoint = vertex;
323
                }
324
                auxMultiLine.addPrimitive(auxLine);
325
            } else if (geom instanceof MultiLine) {
326
                MultiLine multiline = (MultiLine) geom;
327
                for (int i = 0; i < multiline.getPrimitivesNumber(); i++) {
328
                    Line line = (Line) multiline.getPrimitiveAt(i);
329
                    Line auxLine = (Line) gmanager.create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM);
330
                    double distance = 0.0;
331
                    double firstM = previousM;
332
                    for (int j = 0; j < line.getNumVertices(); j++) {
333
                        Point vertex = line.getVertex(j);
334
                        Point point = (Point) gmanager.create(Geometry.TYPES.POINT, Geometry.SUBTYPES.GEOM2DM);
335
                        point.setX(vertex.getX());
336
                        point.setY(vertex.getY());
337
                        if (j == 0 && previousPoint != null) {
338
                            boolean gap = false;
339
                            if (areInSame2DLocation(previousPoint, vertex)) {
340
                                // Buscamos si ha sido una bifurcaci?n
341
                                previousPoint = getPossibleFork(auxMultiLine, vertex);
342
                                // OJO, aqu? previousPoint pasa a ser 2DM
343
                            } else {
344
                                // En caso de salto, calculamos el previousPoint
345
                                // buscando el v?rtice m?s cercano
346
                                previousPoint = getClosestVertex(auxMultiLine, vertex);
347
                                // OJO, aqu? previousPoint pasa a ser 2DM
348
                                gap = true;
349
                            }
350
                            previousM = previousPoint.getCoordinateAt(previousPoint.getDimension() - 1);
351
                            if (j == 0) {
352
                                firstM = previousM;
353
                            }
354
                            if (gap && !ignoreSpatialGaps) {
355
                                Point previousVertex = getPreviousVertexToPoint(auxMultiLine, previousPoint);
356
                                previousVertex.getCoordinateAt(previousVertex.getDimension() - 1);
357
                                previousM =
358
                                    LrsAlgorithmUtils.straightLineThroughTwoPointsEquation(0, previousVertex.distance(previousPoint),
359
                                        previousVertex.getCoordinateAt(previousVertex.getDimension() - 1), previousM,
360
                                        previousVertex.distance(previousPoint) + previousPoint.distance(point));
361
                                firstM = previousM;
362
                            }
363
                        }
364
                        if (j != 0) {
365
                            distance += previousPoint.distance(vertex);
366
                        }
367
                        double m =
368
                            LrsAlgorithmUtils.straightLineThroughTwoPointsEquation(0, geometryLength, firstM, firstM + mSegment.fromValue,
369
                                distance);
370
                        point.setCoordinateAt(point.getDimension() - 1, m);
371
                        auxLine.addVertex(point);
372
                        previousM = m;
373
                        previousPoint = vertex;
374
                    }
375
                    multiline.addPrimitive(auxLine);
376
                }
377
            } else {
378
                // NO deber?a entrar por aqu?
379
                logger.warn("A not LINE nor MULTILINE geometry found in CreateRoute process");
380
            }
381
        }
382

  
383
        return compactMultiLine(auxMultiLine);
384
    }
385

  
386
    /**
387
     * Joins consecutive adjacent lines into the multiLine that are not involved in a fork
388
     *
389
     * @param auxMultiLine
390
     * @return
391
     * @throws CreateGeometryException
392
     * @throws GeometryOperationException
393
     * @throws GeometryOperationNotSupportedException
394
     */
395
    private MultiLine compactMultiLine(MultiLine multiLine) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
396
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
397
        MultiLine result =  (MultiLine) geomManager.create(multiLine.getGeometryType());
398

  
399
        int primitivesNumber = multiLine.getPrimitivesNumber();
400
        List<Line> lines = new ArrayList<Line>(primitivesNumber);
401
        for(int i = 0; i < primitivesNumber; i++){
402
            lines.add((Line)multiLine.getPrimitiveAt(i).cloneGeometry());
403
        }
404
        if (lines.size() > 0) {
405
            Line line = lines.get(0);
406
            while (lines.size() > 1) {
407
                Point lastVertex = line.getVertex(line.getNumVertices() - 1);
408
                lines.remove(0);
409
                // Borramos la primera linea de la lista ==> lines.get(0) es la siguiente
410
                Line line2 = lines.get(0);
411
                // Si el ultimo punto de la primera
412
                if (lastVertex.equals(line2.getVertex(0)) && !bifurcation(lastVertex, lines)) {
413
                    for(int i = 1; i<line2.getNumVertices(); i++){
414
                        line.addVertex(line2.getVertex(i));
415
                    }
416
                } else {
417
                    result.addPrimitive(line);
418
                    line = line2;
419
                }
420
            }
421
            result.addPrimitive(line);
422
        }
423
        return result;
424
    }
425

  
426
    /**
427
     * Checks if a bifurcation occurs at one point.
428
     *
429
     * @param point
430
     * @param lines
431
     * @return
432
     */
433
    private boolean bifurcation(Point point, List<org.gvsig.fmap.geom.primitive.Line> lines) {
434
        // Saltamos la primera linea
435
        for(int i = 1; i<lines.size(); i++){
436
            if(point.equals(lines.get(i).getVertex(0))){
437
                return true;
438
            }
439
        }
440
        return false;
441
    }
442

  
443
    /**
444
     * Returns the previous vertex to a point.
445
     *
446
     * @param auxMultiLine
447
     * @param previousPoint
448
     * @return
449
     * @throws GeometryOperationException
450
     * @throws GeometryOperationNotSupportedException
451
     * @throws CreateGeometryException
452
     */
453
    private Point getPreviousVertexToPoint(MultiLine multiLine, Point point) throws CreateGeometryException,
454
        GeometryOperationNotSupportedException, GeometryOperationException {
455
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
456
        for (int i = 0; i < multiLine.getPrimitivesNumber(); i++) {
457
            Line line = (Line) multiLine.getPrimitiveAt(i);
458
            if (line.intersects(point)) {
459
                for (int j = 0; j < line.getNumVertices() - 1; j++) {
460
                    if (point.equals(line.getVertex(j + 1))) {
461
                        return line.getVertex(j);
462
                    }
463
                    Line auxLine = (Line) geomManager.create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM);
464
                    auxLine.addVertex(line.getVertex(j));
465
                    auxLine.addVertex(line.getVertex(j + 1));
466
                    if (auxLine.intersects(point)) {
467
                        return line.getVertex(j);
468
                    }
469
                }
470
            }
471
        }
472
        return null;
473
    }
474

  
475
    /**
476
     * Returns the next vertex to a point.
477
     *
478
     * @param auxMultiLine
479
     * @param previousPoint
480
     * @return
481
     * @throws GeometryOperationException
482
     * @throws GeometryOperationNotSupportedException
483
     * @throws CreateGeometryException
484
     */
485
    private Point getNextVertexToPoint(MultiLine multiLine, Point point) throws CreateGeometryException,
486
        GeometryOperationNotSupportedException, GeometryOperationException {
487
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
488
        for (int i = 0; i < multiLine.getPrimitivesNumber(); i++) {
489
            Line line = (Line) multiLine.getPrimitiveAt(i);
490
            if (line.intersects(point)) {
491
                for (int j = 0; j < line.getNumVertices() - 1; j++) {
492
                    if (point.equals(line.getVertex(j))) {
493
                        return line.getVertex(j+1);
494
                    }
495
                    Line auxLine = (Line) geomManager.create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM);
496
                    auxLine.addVertex(line.getVertex(j));
497
                    auxLine.addVertex(line.getVertex(j + 1));
498
                    if (auxLine.intersects(point)) {
499
                        return line.getVertex(j+1);
500
                    }
501
                }
502
            }
503
        }
504
        return null;
505
    }
506

  
507
    /**
508
     * Checks if a bifurcation occurs at one point and return the vertex with maximum M
509
     *
510
     * @param multiLine
511
     * @param vertex
512
     * @return
513
     */
514
    private Point getPossibleFork(MultiLine multiLine, Point point) {
515

  
516
        List<Point> vertices = new ArrayList<Point>();
517
        for (int i = 0; i < multiLine.getPrimitivesNumber(); i++) {
518
            Line line = (Line) multiLine.getPrimitiveAt(i);
519
            for (int j = 0; j < line.getNumVertices(); j++) {
520
                Point vertex = line.getVertex(j);
521
                if (areInSame2DLocation(vertex, point)) {
522
                    vertices.add(vertex);
523
                }
524
            }
525
        }
526
        if (vertices.size() > 0) {
527
            Double maxM = Double.NEGATIVE_INFINITY;
528
            Point forked = null;
529
            for (Iterator<Point> iterator = vertices.iterator(); iterator.hasNext();) {
530
                Point vertex = (Point) iterator.next();
531
                double m = vertex.getCoordinateAt(vertex.getDimension() - 1);
532
                if (m > maxM) {
533
                    maxM = m;
534
                    forked = vertex;
535
                }
536
            }
537
            return forked;
538
        }
539
        return null;
540
    }
541

  
542
    /**
543
     * Compares x & y coordinates of a point.
544
     *
545
     * @param p1
546
     * @param p2
547
     * @return
548
     */
549
    private boolean areInSame2DLocation(Point p1, Point p2) {
550
        return ((p1.getX() == p2.getX()) && (p1.getY() == p2.getY()));
551
    }
552

  
553
    /**
554
     * Returns the vertex of the multiline closest to a point
555
     *
556
     * @param mGeometry
557
     * @param vertex
558
     * @return
559
     * @throws GeometryOperationException
560
     * @throws GeometryOperationNotSupportedException
561
     * @throws CreateEnvelopeException
562
     */
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff