Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.lib / org.gvsig.vectorediting.lib.prov / org.gvsig.vectorediting.lib.prov.extendline / src / main / java / org / gvsig / vectorediting / lib / prov / extendline / operation / ExtendLineOperationUtils.java @ 2786

History | View | Annotate | Download (28.4 KB)

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

    
26
import java.util.HashMap;
27
import java.util.Map;
28
import java.util.function.Predicate;
29
import org.gvsig.fmap.dal.exception.DataException;
30
import org.gvsig.fmap.dal.feature.Feature;
31
import org.gvsig.fmap.dal.feature.FeatureSelection;
32
import org.gvsig.fmap.geom.Geometry;
33
import org.gvsig.fmap.geom.Geometry.TYPES;
34
import org.gvsig.fmap.geom.GeometryException;
35
import org.gvsig.fmap.geom.GeometryLocator;
36
import org.gvsig.fmap.geom.GeometryManager;
37
import org.gvsig.fmap.geom.GeometryUtils;
38
import org.gvsig.fmap.geom.aggregate.Aggregate;
39
import org.gvsig.fmap.geom.aggregate.MultiLine;
40
import org.gvsig.fmap.geom.aggregate.MultiPoint;
41
import org.gvsig.fmap.geom.complex.Complex;
42
import org.gvsig.fmap.geom.exception.CreateGeometryException;
43
import org.gvsig.fmap.geom.operation.GeometryOperationException;
44
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
45
import org.gvsig.fmap.geom.primitive.Arc;
46
import org.gvsig.fmap.geom.primitive.Curve;
47
import org.gvsig.fmap.geom.primitive.Point;
48
import org.gvsig.fmap.geom.primitive.Primitive;
49
import org.gvsig.tools.dispose.DisposableIterator;
50

    
51
/**
52
 * @author llmarques
53
 *
54
 */
55
public class ExtendLineOperationUtils {
56

    
57
    /**
58
     * Use it to indicate start side should be extended
59
     */
60
    public static final String START_SIDE = "start";
61

    
62
    /**
63
     * Use it to indicate end side should be extended
64
     */
65
    public static final String END_SIDE = "end";
66

    
67
    /**
68
     * Number of projections computed to know intersection points.
69
     */
70
    private final static int PROJECTION_LIMIT = 100;
71

    
72
    /**
73
     * Number of steps to compute to know intersection points.
74
     */
75
    private final static int PROJECTION_STEPS = 10;
76

    
77
    private static final Map<Integer, ExtendLineOperation> operations
78
            = new HashMap<Integer, ExtendLineOperation>();
79

    
80
    public ExtendLineOperationUtils() {
81
    }
82

    
83
    public static void register(ExtendLineOperation operation, int geometryType) {
84
        operations.put(geometryType, operation);
85
    }
86

    
87
    public static ExtendLineOperation getOperation(Primitive geom) {
88
        Integer type = geom.getGeometryType().getType();
89

    
90
        ExtendLineOperation operation = operations.get(type);
91

    
92
        return operation;
93
    }
94

    
95
    /**
96
     * Calculates the nearest intersection among curve and boundary objects
97
     * depending on side received as parameter.
98
     *
99
     * @param line to be extended
100
     * @param sideToExtend What side will be extend. Use
101
     * {@link ExtendLineOperationUtils#START_SIDE} and
102
     * {@link ExtendLineOperationUtils#END_SIDE}
103
     * @param boundaryObjects to calculate intersection points.
104
     * @return the nearest intersection point. Return Null if arc does not
105
     * intersect with any boundary object
106
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
107
     * @throws org.gvsig.fmap.dal.exception.DataException
108
     * @throws
109
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
110
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
111
     */
112
    public static Point curveIntersection(Curve line, String sideToExtend,
113
            FeatureSelection boundaryObjects) throws CreateGeometryException,
114
            DataException, GeometryOperationNotSupportedException,
115
            GeometryOperationException {
116

    
117
        Point initPoint = getExtremeSegmentInitPoint(line, sideToExtend);
118
        Point endPoint = getExtremeSegmentEndPoint(line, sideToExtend);
119

    
120
        return getIntersectionOfProjectedLine(initPoint, endPoint,
121
                boundaryObjects);
122
    }
123

    
124
    /**
125
     * Calculates the nearest intersection among curve and boundary objects
126
     * depending on side received as parameter.
127
     *
128
     * @param line to be extended
129
     * @param sideToExtend What side will be extend. Use
130
     * {@link ExtendLineOperationUtils#START_SIDE} and
131
     * {@link ExtendLineOperationUtils#END_SIDE}
132
     * @param boundaryObject to calculate intersection points.
133
     * @return the nearest intersection point. Return Null if arc does not
134
     * intersect with any boundary object
135
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
136
     * @throws org.gvsig.fmap.dal.exception.DataException
137
     * @throws
138
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
139
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
140
     */
141
    public static Point curveIntersection(Curve line, String sideToExtend,
142
            Geometry boundaryObject) throws GeometryException,
143
            DataException, GeometryOperationNotSupportedException,
144
            GeometryOperationException {
145

    
146
        Point initPoint = getExtremeSegmentInitPoint(line, sideToExtend);
147
        Point endPoint = getExtremeSegmentEndPoint(line, sideToExtend);
148

    
149
        return getIntersectionOfProjectedLine(initPoint, endPoint,
150
                boundaryObject);
151
    }
152

    
153
    private static Point getExtremeSegmentEndPoint(Curve line, String sideToExtend) {
154
        // Start side line is formed by second point and first point
155
        if (sideToExtend.equalsIgnoreCase(START_SIDE)) {
156
            return line.getVertex(0);
157
            // End side line is formed by penultimate point and last point
158
        } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
159
            return line.getVertex(line.getNumVertices() - 1);
160
        }
161
        return null;
162
    }
163

    
164
    private static Point getExtremeSegmentInitPoint(Curve line, String sideToExtend) {
165
        // Start side line is formed by second point and first point
166
        if (sideToExtend.equalsIgnoreCase(START_SIDE)) {
167
            return line.getVertex(1);
168
            // End side line is formed by penultimate point and last point
169
        } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
170
            return line.getVertex(line.getNumVertices() - 2);
171
        }
172
        return null;
173
    }
174

    
175
    /**
176
     * Calculates the nearest intersection point among arc and boundary objects
177
     * depending on side received as parameter.Strategy:
178
     *
179
     * 1- Create a full arc with the same center and radius of arc received by
180
     * parameter.2- Iterate over boundary objects.3- If some boundary object
181
     * intersects with full arc, calculates the distance to start point or end
182
     * point depending on side to be extend.4- Return the nearest intersection
183
     * point.
184
     *
185
     *
186
     * @param arcToBeExtended Arc to be extended
187
     * @param sideToExtend What side will be extend. Use
188
     * {@link ExtendLineOperationUtils#START_SIDE} and
189
     * {@link ExtendLineOperationUtils#END_SIDE}
190
     * @param boundaryObjects to calculate intersection points.
191
     * @return the nearest intersection point. Return Null if arc does not
192
     * intersect with any boundary object
193
     * @throws
194
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
195
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
196
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
197
     * @throws org.gvsig.fmap.dal.exception.DataException
198
     */
199
    public static Point arcIntersection(Arc arcToBeExtended,
200
            String sideToExtend, FeatureSelection boundaryObjects)
201
            throws GeometryOperationNotSupportedException,
202
            GeometryOperationException, CreateGeometryException, DataException {
203

    
204
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
205
        int subtype = arcToBeExtended.getGeometryType().getSubType();
206

    
207
        Point center = arcToBeExtended.getCenterPoint();
208
        double radius = center.distance(arcToBeExtended.getInitPoint());
209

    
210
        Point intersection = null;
211

    
212
        double minDistance = Double.POSITIVE_INFINITY;
213

    
214
        Arc tmpArc = (Arc) geoManager.create(TYPES.ARC, subtype);
215
        tmpArc.setPoints(center, radius, 0, Math.PI * 2);
216

    
217
        DisposableIterator it = boundaryObjects.fastIterator();
218
        while (it.hasNext()) {
219
            Feature feature = (Feature) it.next();
220
            Geometry geometry = feature.getDefaultGeometry();
221
            if (tmpArc.intersects(geometry)) {
222
                Geometry intersectionGeometry = tmpArc.intersection(geometry);
223
                
224
                if(intersectionGeometry instanceof Complex){
225
                    intersectionGeometry = ((Complex)intersectionGeometry).createAggregate(
226
                            Geometry.TYPES.MULTIPOINT, 
227
                            (Geometry t) -> t.getGeometryType().getType() == Geometry.TYPES.MULTIPOINT || t.getGeometryType().getType() == Geometry.TYPES.POINT
228
                    );
229
                }
230

    
231
                if (intersectionGeometry instanceof MultiPoint) {
232
                    MultiPoint intersectionMultiPoint
233
                            = (MultiPoint) intersectionGeometry;
234

    
235
                    for (int i = 0; i < intersectionMultiPoint
236
                            .getPrimitivesNumber(); i++) {
237
                        Point point = intersectionMultiPoint.getPointAt(i);
238
                        double distance = Double.POSITIVE_INFINITY;
239

    
240
                        if (sideToExtend.equalsIgnoreCase(START_SIDE)) {
241
                            distance
242
                                    = point.distance(arcToBeExtended.getInitPoint());
243
                        } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
244
                            distance
245
                                    = point.distance(arcToBeExtended.getEndPoint());
246
                        }
247

    
248
                        if (distance < minDistance) {
249
                            intersection = point;
250
                            minDistance = distance;
251
                        }
252
                    }
253
                } else if (intersectionGeometry instanceof Point) {
254
                    Point intersectionPoint = (Point) intersectionGeometry;
255
                    double distance = Double.POSITIVE_INFINITY;
256

    
257
                    if (sideToExtend.equalsIgnoreCase("start")) {
258
                        distance
259
                                = intersectionPoint.distance(arcToBeExtended
260
                                        .getInitPoint());
261
                    } else if (sideToExtend.equalsIgnoreCase("end")) {
262
                        distance
263
                                = intersectionPoint.distance(arcToBeExtended
264
                                        .getEndPoint());
265
                    }
266

    
267
                    if (distance < minDistance) {
268
                        intersection = intersectionPoint;
269
                        minDistance = distance;
270
                    }
271
                }
272
            }
273
        }
274
        it.dispose();
275
        return intersection;
276
    }
277

    
278
    /**
279
     * Calculates the nearest intersection point among arc and boundary objects
280
     * depending on side received as parameter.Strategy:
281
     *
282
     * 1- Create a full arc with the same center and radius of arc received by
283
     * parameter.2- Iterate over boundary objects.3- If some boundary object
284
     * intersects with full arc, calculates the distance to start point or end
285
     * point depending on side to be extend.4- Return the nearest intersection
286
     * point.
287
     *
288
     *
289
     * @param arcToBeExtended Arc to be extended
290
     * @param sideToExtend What side will be extend. Use
291
     * {@link ExtendLineOperationUtils#START_SIDE} and
292
     * {@link ExtendLineOperationUtils#END_SIDE}
293
     * @param boundaryObject to calculate intersection points.
294
     * @return the nearest intersection point. Return Null if arc does not
295
     * intersect with any boundary object
296
     * @throws
297
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
298
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
299
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
300
     * @throws org.gvsig.fmap.dal.exception.DataException
301
     */
302
    public static Point arcIntersection(Arc arcToBeExtended,
303
            String sideToExtend, Geometry boundaryObject)
304
            throws GeometryOperationNotSupportedException,
305
            GeometryOperationException, CreateGeometryException, DataException {
306

    
307
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
308
        int subtype = arcToBeExtended.getGeometryType().getSubType();
309

    
310
        Point center = arcToBeExtended.getCenterPoint();
311
        double radius = center.distance(arcToBeExtended.getInitPoint());
312

    
313
        Point intersection = null;
314

    
315
//        double minDistance = Double.POSITIVE_INFINITY;
316

    
317
        Arc tmpArc = (Arc) geoManager.create(TYPES.ARC, subtype);
318
        tmpArc.setPoints(center, radius, 0, Math.PI * 2);
319

    
320
        double distance = Double.POSITIVE_INFINITY;
321
        double minDistance = Double.POSITIVE_INFINITY;
322
        if (tmpArc.intersects(boundaryObject)) {
323
            Geometry intersectionGeometry = tmpArc.intersection(boundaryObject);
324
            if (intersectionGeometry instanceof Complex) {
325
                intersectionGeometry = ((Complex) intersectionGeometry).createAggregate(
326
                        Geometry.TYPES.MULTIPOINT,
327
                        (Geometry t) -> t.getGeometryType().getType() == Geometry.TYPES.MULTIPOINT || t.getGeometryType().getType() == Geometry.TYPES.POINT
328
                );
329
            }
330

    
331
            if (intersectionGeometry instanceof MultiPoint) {
332
                MultiPoint intersectionMultiPoint
333
                        = (MultiPoint) intersectionGeometry;
334

    
335
                for (int i = 0; i < intersectionMultiPoint
336
                        .getPrimitivesNumber(); i++) {
337
                    Point point = intersectionMultiPoint.getPointAt(i);
338

    
339
                    if (sideToExtend.equalsIgnoreCase(START_SIDE)) {
340
                        distance
341
                                = point.distance(arcToBeExtended.getInitPoint());
342
                    } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
343
                        distance
344
                                = point.distance(arcToBeExtended.getEndPoint());
345
                    }
346

    
347
                    if (distance < minDistance) {
348
                        intersection = point;
349
                        minDistance = distance;
350
                    }
351
                }
352
            } else if (intersectionGeometry instanceof Point) {
353
                Point intersectionPoint = (Point) intersectionGeometry;
354

    
355
                intersection = intersectionPoint;
356
            }
357
        }
358
        return intersection;
359
    }
360

    
361
    // FIXME: remove this method when geometry library has this utility method
362
    public static double getAngle(Point start, Point end)
363
            throws GeometryOperationNotSupportedException,
364
            GeometryOperationException {
365
        double angle
366
                = Math.acos((end.getX() - start.getX()) / start.distance(end));
367

    
368
        if (start.getY() > end.getY()) {
369
            angle = -angle;
370
        }
371

    
372
        if (angle < 0) {
373
            angle += (2 * Math.PI);
374
        }
375

    
376
        return angle;
377
    }
378

    
379
    /**
380
     * Gets intersection among the line formed by initPoint and endPoint and
381
     * boundary objects.If line or its projection does not intersect with any
382
     * boundary object return null.Strategy:
383
     *
384
     * 1- Get module of line to determine if an intersection point already be
385
     * vertex of line.If the distance between intersection point and start point
386
     * of line is less than module indicates that intersection point already be
387
     * curve point.2- Project line with the line parametric equation. 3- Iterate
388
     * over boundary objects. 4- Check if boundary object does not contains end
389
     * point of projected line. 5- If projected line intersects with any
390
     * boundary object, get the nearest intersection point 6- Return it.
391
     *
392
     *
393
     * @param initPoint of curve to extend
394
     * @param endPoint end point of curve to extend
395
     * @param boundaryObjects to calculate intersection points.
396
     * @return the nearest intersection point. Return Null if arc does not
397
     * intersect with any boundary object
398
     * @throws
399
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
400
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
401
     * @throws org.gvsig.fmap.dal.exception.DataException
402
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
403
     */
404
    public static Point getIntersectionOfProjectedLine(Point initPoint,
405
            Point endPoint, FeatureSelection boundaryObjects)
406
            throws GeometryOperationNotSupportedException,
407
            GeometryOperationException, DataException, CreateGeometryException {
408

    
409
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
410
        int subtype = initPoint.getGeometryType().getSubType();
411

    
412
        double module = initPoint.distance(endPoint);
413

    
414
        double minDistance = Double.POSITIVE_INFINITY;
415
        Point intersectionPoint = null;
416

    
417
        double x, y;
418
        double x1 = initPoint.getX();
419
        double y1 = initPoint.getY();
420
        double x2 = endPoint.getX();
421
        double y2 = endPoint.getY();
422

    
423
        for (int t = 1; t < PROJECTION_LIMIT; t += 10) {
424
            x = (x2 - x1) * t + x1;
425
            y = (y2 - y1) * t + y1;
426

    
427
            DisposableIterator it = boundaryObjects.fastIterator();
428
            while (it.hasNext()) {
429
                Feature feature = (Feature) it.next();
430
                Geometry geometry = feature.getDefaultGeometry();
431
                Point projectedPoint = geoManager.createPoint(x, y, subtype);
432

    
433
                if (!geometry.contains(projectedPoint)) {
434
                    Curve tmpLine = geoManager.createLine(subtype);
435
                    tmpLine.setPoints(initPoint, projectedPoint);
436

    
437
                    if (tmpLine.intersects(geometry)) {
438

    
439
                        Geometry intersectionGeometry
440
                                = geometry.intersection(tmpLine);
441

    
442
                        if (intersectionGeometry instanceof Complex) {
443
                            Aggregate intersection = ((Complex) intersectionGeometry).createAggregate(
444
                                    Geometry.TYPES.MULTIPOINT,
445
                                    (Geometry g) -> g.getGeometryType().getType() == Geometry.TYPES.MULTIPOINT || g.getGeometryType().getType() == Geometry.TYPES.POINT
446
                            );
447
                            if(intersection.getPrimitivesNumber() > 0) {
448
                               intersectionGeometry = intersection; 
449
                            } else {
450
                                intersection = ((Complex) intersectionGeometry).createAggregate(
451
                                    Geometry.TYPES.MULTILINE,
452
                                    (Geometry g) -> GeometryUtils.isSubtype(Geometry.TYPES.MULTICURVE, g.getGeometryType().getType()) || GeometryUtils.isSubtype(Geometry.TYPES.CURVE, g.getGeometryType().getType())
453
                                );
454
                                if(intersection.getPrimitivesNumber() > 0){
455
                                    intersectionGeometry = intersection.getPrimitiveAt(0);
456
                                }
457
                            }
458
                        }
459

    
460
                        if (intersectionGeometry instanceof Point) {
461

    
462
                            double distance
463
                                    = ((Point) intersectionGeometry)
464
                                            .distance(initPoint);
465

    
466
                            if (distance < minDistance && distance > (module + 0.01)) {
467
                                intersectionPoint = (Point) intersectionGeometry;
468
                                minDistance = distance;
469
                            }
470

    
471
                        } else if (intersectionGeometry instanceof MultiPoint) {
472

    
473
                            MultiPoint intersectionMultiPoint
474
                                    = (MultiPoint) intersectionGeometry;
475

    
476
                            for (int i = 0; i < intersectionMultiPoint
477
                                    .getPrimitivesNumber(); i++) {
478

    
479
                                double distance
480
                                        = intersectionMultiPoint.getPointAt(i)
481
                                                .distance(initPoint);
482

    
483
                                if (distance < minDistance && distance > (module + 0.01)) {
484
                                    intersectionPoint
485
                                            = intersectionMultiPoint.getPointAt(i);
486
                                    minDistance = distance;
487
                                }
488
                            }
489
                        } else if (intersectionGeometry instanceof Curve) {
490

    
491
                            Curve intersectionCurve
492
                                    = (Curve) intersectionGeometry;
493

    
494
                            for (int i = 0; i < intersectionCurve
495
                                    .getNumVertices(); i++) {
496

    
497
                                double distance
498
                                        = intersectionCurve.getVertex(i).distance(
499
                                                endPoint);
500

    
501
                                if (distance < minDistance && distance > (module + 0.01)) {
502
                                    intersectionPoint
503
                                            = intersectionCurve.getVertex(i);
504
                                    minDistance = distance;
505
                                }
506
                            }
507
                        }
508
                    }
509
                }
510
            }
511
            it.dispose();
512
            if (intersectionPoint != null) {
513
                break;
514
            }
515
        }
516
        return intersectionPoint;
517
    }
518

    
519
    /**
520
     * Gets intersection among the line formed by initPoint and endPoint and
521
     * boundary object.If line or its projection does not intersect with
522
     * boundary object return null.Strategy:
523
     *
524
     * 1- Get module of line to determine if an intersection point already be
525
     * vertex of line.If the distance between intersection point and start point
526
     * of line is less than module indicates that intersection point already be
527
     * curve point.2- Project line with the line parametric equation. 3- Check
528
     * if boundary object does not contains end point of projected line. 5- If
529
     * projected line intersects with boundary object, get the nearest
530
     * intersection point 6- Return it.
531
     *
532
     *
533
     * @param initPoint of curve to extend
534
     * @param endPoint end point of curve to extend
535
     * @param boundaryObject to calculate intersection points.
536
     * @return the nearest intersection point. Return Null if arc does not
537
     * intersect with any boundary object
538
     * @throws
539
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
540
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
541
     * @throws org.gvsig.fmap.dal.exception.DataException
542
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
543
     */
544
    public static Point getIntersectionOfProjectedLine(Point initPoint,
545
            Point endPoint, Geometry boundaryObject)
546
            throws GeometryOperationNotSupportedException,
547
            GeometryOperationException, DataException, GeometryException {
548

    
549
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
550
        int subtype = initPoint.getGeometryType().getSubType();
551

    
552
        double module = initPoint.distance(endPoint);
553

    
554
        double minDistance = Double.POSITIVE_INFINITY;
555
        Point intersectionPoint = null;
556

    
557
        double x, y;
558
        double x1 = initPoint.getX();
559
        double y1 = initPoint.getY();
560
        double x2 = endPoint.getX();
561
        double y2 = endPoint.getY();
562

    
563
        double projectionLimit = 2 * endPoint.distance(boundaryObject);
564
        double step = projectionLimit/PROJECTION_STEPS;
565

    
566
        for (double t = 1; t < projectionLimit; t += step) {
567
            x = (x2 - x1) * t + x1;
568
            y = (y2 - y1) * t + y1;
569

    
570
            Point projectedPoint = geoManager.createPoint(x, y, subtype);
571
            MultiLine boundaryObjectLines=  boundaryObject.toLines();
572
            if (!boundaryObjectLines.contains(projectedPoint)) {
573
                Curve tmpLine = geoManager.createLine(subtype);
574
                tmpLine.setPoints(initPoint, projectedPoint);
575

    
576
                if (tmpLine.intersects(boundaryObject)) {
577

    
578
                    Geometry intersectionGeometry
579
                            = boundaryObjectLines.intersection(tmpLine);
580

    
581
                        if (intersectionGeometry instanceof Complex) {
582
                            Aggregate intersection = ((Complex) intersectionGeometry).createAggregate(
583
                                    Geometry.TYPES.MULTIPOINT,
584
                                    (Geometry g) -> g.getGeometryType().getType() == Geometry.TYPES.MULTIPOINT || g.getGeometryType().getType() == Geometry.TYPES.POINT
585
                            );
586
                            if(intersection.getPrimitivesNumber() > 0) {
587
                               intersectionGeometry = intersection; 
588
                            } else {
589
                                intersection = ((Complex) intersectionGeometry).createAggregate(
590
                                    Geometry.TYPES.MULTILINE,
591
                                    (Geometry g) -> GeometryUtils.isSubtype(Geometry.TYPES.MULTICURVE, g.getGeometryType().getType()) || GeometryUtils.isSubtype(Geometry.TYPES.CURVE, g.getGeometryType().getType())
592
                                );
593
                                if(intersection.getPrimitivesNumber() > 0){
594
                                    intersectionGeometry = intersection.getPrimitiveAt(0);
595
                                }
596
                            }
597
                        }
598
                    
599
                    if (intersectionGeometry instanceof Point) {
600

    
601
                        double distance
602
                                = ((Point) intersectionGeometry)
603
                                        .distance(initPoint);
604

    
605
                        if (distance < minDistance && distance > (module + 0.01)) {
606
                            intersectionPoint = (Point) intersectionGeometry;
607
                            minDistance = distance;
608
                        }
609

    
610
                    } else if (intersectionGeometry instanceof MultiPoint) {
611

    
612
                        MultiPoint intersectionMultiPoint
613
                                = (MultiPoint) intersectionGeometry;
614

    
615
                        for (int i = 0; i < intersectionMultiPoint
616
                                .getPrimitivesNumber(); i++) {
617

    
618
                            double distance
619
                                    = intersectionMultiPoint.getPointAt(i)
620
                                            .distance(initPoint);
621

    
622
                            if (distance < minDistance && distance > (module + 0.01)) {
623
                                intersectionPoint
624
                                        = intersectionMultiPoint.getPointAt(i);
625
                                minDistance = distance;
626
                            }
627
                        }
628
                    } else if (intersectionGeometry instanceof Curve) {
629

    
630
                        Curve intersectionCurve
631
                                = (Curve) intersectionGeometry;
632

    
633
                        for (int i = 0; i < intersectionCurve
634
                                .getNumVertices(); i++) {
635

    
636
                            double distance
637
                                    = intersectionCurve.getVertex(i).distance(
638
                                            endPoint);
639

    
640
                            if (distance < minDistance && distance > (module + 0.01)) {
641
                                intersectionPoint
642
                                        = intersectionCurve.getVertex(i);
643
                                minDistance = distance;
644
                            }
645
                        }
646
                    }
647
                }
648
            } else {
649
                intersectionPoint = projectedPoint;
650
            }
651
            if (intersectionPoint != null) {
652
                break;
653
            }
654
        }
655
        return intersectionPoint;
656
    }
657

    
658
}