Revision 960

View differences:

org.gvsig.lrs/tags/org.gvsig.lrs-1.0.175/org.gvsig.lrs.lib/org.gvsig.lrs.lib.impl/src/test/java/org/gvsig/lrs/lib/impl/TestLineInterpolatePoint.java
1
package org.gvsig.lrs.lib.impl;
2

  
3
import junit.framework.TestCase;
4
import org.gvsig.fmap.geom.Geometry;
5
import org.gvsig.fmap.geom.GeometryLocator;
6
import org.gvsig.fmap.geom.GeometryManager;
7
import org.gvsig.fmap.geom.primitive.Point;
8
import org.gvsig.lrs.lib.impl.expressionevaluator.function.lrs.STLineInterpolatePointFunction;
9
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
10

  
11
public class TestLineInterpolatePoint extends TestCase {
12
    
13
    public TestLineInterpolatePoint(String testName) {
14
        super(testName);
15
    }
16
    
17
    @Override
18
    protected void setUp() throws Exception {
19
        super.setUp();
20
        new DefaultLibrariesInitializer().fullInitialize();
21
    }
22
    
23
    @Override
24
    protected void tearDown() throws Exception {
25
        super.tearDown();
26
    }
27

  
28
    // TODO add test methods here. The name must begin with 'test'. For example:
29
    // public void testHello() {}
30
    
31
    public void testLine1() throws Exception{
32
        
33
        GeometryManager manager = GeometryLocator.getGeometryManager();
34
        Geometry line = manager.createFrom("LINESTRING (100 400, 400 400, 605 464, 800 460)");
35
        
36
        double fraction = 150/line.perimeter();
37
        
38
        Point point = STLineInterpolatePointFunction.lineInterpolatePoint(line, fraction);
39
        
40
        assertEquals("POINT (250 400)", point.convertToWKT());
41
    }
42

  
43
    public void testMultiLine1() throws Exception{
44
        
45
        GeometryManager manager = GeometryLocator.getGeometryManager();
46
        Geometry line = manager.createFrom("MULTILINESTRING ((100 400, 400 400),  (400 500, 600 500),  (600 500, 800 460))");
47

  
48
        double fraction = 400/line.perimeter();
49
        
50
        Point point = STLineInterpolatePointFunction.lineInterpolatePoint(line, fraction);
51
        
52
        assertEquals("POINT (500 500)", point.convertToWKT());
53
    }
54
    
55
    public void testLineM1() throws Exception{
56
        
57
        GeometryManager manager = GeometryLocator.getGeometryManager();
58
        Geometry line = manager.createFrom("LINESTRING M(100 400 0, 400 400 300, 605 464 505, 800 460 700)");
59
        
60
        double fraction = 150/line.perimeter();
61
        
62
        Point point = STLineInterpolatePointFunction.lineInterpolatePoint(line, fraction);
63
        
64
        assertEquals("POINT M (250 400 150)", point.convertToWKT());
65
    }
66

  
67
    public void testMultiLineM1() throws Exception{
68
        
69
        GeometryManager manager = GeometryLocator.getGeometryManager();
70
        Geometry line = manager.createFrom("MULTILINESTRING M((100 400 0, 400 400 300),  (400 500 300, 600 500 500),  (600 500 500, 800 460 700))");
71

  
72
        double fraction = 400/line.perimeter();
73
        
74
        Point point = STLineInterpolatePointFunction.lineInterpolatePoint(line, fraction);
75
        
76
        assertEquals("POINT M (500 500 400)", point.convertToWKT());
77
    }
78
    
79
}
org.gvsig.lrs/tags/org.gvsig.lrs-1.0.175/org.gvsig.lrs.lib/org.gvsig.lrs.lib.impl/src/test/java/org/gvsig/lrs/lib/impl/TestLineLocatePoint.java
1
package org.gvsig.lrs.lib.impl;
2

  
3
import junit.framework.TestCase;
4
import org.gvsig.fmap.geom.Geometry;
5
import org.gvsig.fmap.geom.GeometryLocator;
6
import org.gvsig.fmap.geom.GeometryManager;
7
import org.gvsig.fmap.geom.aggregate.MultiLine;
8
import org.gvsig.fmap.geom.primitive.Line;
9
import org.gvsig.fmap.geom.primitive.Point;
10
import org.gvsig.lrs.lib.impl.expressionevaluator.function.lrs.STLineLocatePointFunction;
11
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
12

  
13
public class TestLineLocatePoint extends TestCase {
14
    
15
    public TestLineLocatePoint(String testName) {
16
        super(testName);
17
    }
18
    
19
    @Override
20
    protected void setUp() throws Exception {
21
        super.setUp();
22
        new DefaultLibrariesInitializer().fullInitialize();
23
    }
24
    
25
    @Override
26
    protected void tearDown() throws Exception {
27
        super.tearDown();
28
    }
29

  
30
    // TODO add test methods here. The name must begin with 'test'. For example:
31
    // public void testHello() {}
32
    
33
    public void testLine1() throws Exception{
34
        
35
        GeometryManager manager = GeometryLocator.getGeometryManager();
36
        Geometry line = manager.createFrom("LINESTRING (100 400, 400 400, 605 464, 800 460)");
37
        
38
        Geometry point = manager.createFrom("POINT (250 350)");
39
        
40
        double location = STLineLocatePointFunction.lineLocatePoint((Line)line, (Point)point);
41
        assertEquals(150/line.perimeter(), location);
42
    }
43

  
44
    public void testMultiLine1() throws Exception{
45
        
46
        GeometryManager manager = GeometryLocator.getGeometryManager();
47
        Geometry line = manager.createFrom("MULTILINESTRING ((100 400, 400 400),  (400 500, 600 500),  (600 500, 800 460))");
48
        
49
        Geometry point = manager.createFrom("POINT (500 450)");
50
        
51
        double location = STLineLocatePointFunction.lineLocatePoint((MultiLine)line, (Point)point);
52
        assertEquals(400/line.perimeter(), location);
53
    }
54
    
55
}
0 56

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

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

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

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

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

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

  
69
            featureType.setDefaultGeometryAttributeName("Geometry");
70

  
71
            newFeatureStoreParameters.setDefaultFeatureType(featureType);
72
            serverExplorer.add("Shape", newFeatureStoreParameters, true);
73

  
74
            DataStore store = dataManager.createStore(newFeatureStoreParameters);
75

  
76
            return (FeatureStore) store;
77

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

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

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

  
98
        List<Point> points = new ArrayList<Point>();
99

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

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

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

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

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

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

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

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

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

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

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

  
312

  
313

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

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

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

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

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

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

  
427

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

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

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

  
459
            }
460
        }
461
        return geometry;
462
    }
463

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

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

  
494
}
org.gvsig.lrs/tags/org.gvsig.lrs-1.0.175/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.175/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.175/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
            }
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff