Statistics
| Revision:

gvsig-lrs / org.gvsig.lrs / trunk / org.gvsig.lrs / org.gvsig.lrs.lib / org.gvsig.lrs.lib.impl / src / main / java / org / gvsig / lrs / lib / impl / LrsAlgorithmUtils.java @ 28

History | View | Annotate | Download (18.8 KB)

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.Iterator;
12
import java.util.List;
13

    
14
import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;
15

    
16
import org.gvsig.fmap.dal.DALLocator;
17
import org.gvsig.fmap.dal.DataManager;
18
import org.gvsig.fmap.dal.DataServerExplorer;
19
import org.gvsig.fmap.dal.DataServerExplorerParameters;
20
import org.gvsig.fmap.dal.DataStore;
21
import org.gvsig.fmap.dal.DataTypes;
22
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
23
import org.gvsig.fmap.dal.feature.EditableFeatureType;
24
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
25
import org.gvsig.fmap.dal.feature.FeatureStore;
26
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
27
import org.gvsig.fmap.dal.store.shp.SHPNewStoreParameters;
28
import org.gvsig.fmap.geom.Geometry;
29
import org.gvsig.fmap.geom.GeometryLocator;
30
import org.gvsig.fmap.geom.GeometryManager;
31
import org.gvsig.fmap.geom.aggregate.MultiLine;
32
import org.gvsig.fmap.geom.exception.CreateGeometryException;
33
import org.gvsig.fmap.geom.operation.GeometryOperationException;
34
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
35
import org.gvsig.fmap.geom.primitive.Line;
36
import org.gvsig.fmap.geom.primitive.Point;
37
import org.gvsig.fmap.geom.type.GeometryType;
38
import org.gvsig.lrs.lib.api.exceptions.LrsCreateRouteException;
39
import org.gvsig.tools.dataTypes.DataType;
40
import org.gvsig.tools.locator.LocatorException;
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
            SHPNewStoreParameters shapeStoreParams = (SHPNewStoreParameters) newFeatureStoreParameters;
53
            File file = shapeStoreParams.getFile();
54
            String filePath = file.getPath().substring(0, file.getPath().lastIndexOf(File.separator));
55

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

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

    
70
            featureType.setDefaultGeometryAttributeName("Geometry");
71

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

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

    
77
            return (FeatureStore) store;
78

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

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

    
97
    static List<Point> getPointsWithM(Geometry geom, double m) throws CreateGeometryException, LocatorException {
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 point = getPointWithMBetweenTwoMPoints(m, line.getVertex(i), line.getVertex(i + 1));
104
                if (point != null) {
105
                    points.add(point);
106
                }
107
            }
108
        } else if (geom instanceof MultiLine) {
109
            MultiLine multiLine = (MultiLine) geom;
110
            for (int p = 0; p < multiLine.getPrimitivesNumber(); p++) {
111
                Line line = (Line) multiLine.getPrimitiveAt(p);
112
                for (int i = 0; i < line.getNumVertices() - 1; i++) {
113
                    Point point = getPointWithMBetweenTwoMPoints(m, line.getVertex(i), line.getVertex(i + 1));
114
                    if (point != null) {
115
                        points.add(point);
116
                    }
117
                }
118
            }
119
        }
120
        return points;
121
    }
122

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

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

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

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

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

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

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

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

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

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

    
310

    
311

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

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

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

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

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

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

    
425

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

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

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

    
456
            }
457
        }
458
    }
459

    
460

    
461
}