Revision 2204 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

View differences:

ExtendLineOperationUtils.java
21 21
 * For any additional information, do not hesitate to contact us
22 22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 23
 */
24

  
25 24
package org.gvsig.vectorediting.lib.prov.extendline.operation;
26 25

  
27 26
import java.util.HashMap;
28 27
import java.util.Map;
29

  
30 28
import org.gvsig.fmap.dal.exception.DataException;
31 29
import org.gvsig.fmap.dal.feature.Feature;
32 30
import org.gvsig.fmap.dal.feature.FeatureSelection;
......
65 63
     */
66 64
    private final static int PROJECTION_LIMIT = 100;
67 65

  
68
    private static Map<Integer, ExtendLineOperation> operations =
69
        new HashMap<Integer, ExtendLineOperation>();
66
    private static Map<Integer, ExtendLineOperation> operations
67
            = new HashMap<Integer, ExtendLineOperation>();
70 68

  
71 69
    public ExtendLineOperationUtils() {
72 70
    }
......
86 84
    /**
87 85
     * Calculates the nearest intersection among curve and boundary objects
88 86
     * depending on side received as parameter.
89
     * 
90
     * @param line
91
     *            to be extended
92
     * @param sideToExtend
93
     *            What side will be extend. Use
94
     *            {@link ExtendLineOperationUtils#START_SIDE} and
95
     *            {@link ExtendLineOperationUtils#END_SIDE}
96
     * @param boundaryObjects
97
     *            to calculate intersection points.
87
     *
88
     * @param line to be extended
89
     * @param sideToExtend What side will be extend. Use
90
     * {@link ExtendLineOperationUtils#START_SIDE} and
91
     * {@link ExtendLineOperationUtils#END_SIDE}
92
     * @param boundaryObjects to calculate intersection points.
98 93
     * @return the nearest intersection point. Return Null if arc does not
99
     *         intersect
100
     *         with any boundary object
94
     * intersect with any boundary object
95
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
96
     * @throws org.gvsig.fmap.dal.exception.DataException
97
     * @throws
98
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
99
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
101 100
     */
102 101
    public static Point curveIntersection(Curve line, String sideToExtend,
103
        FeatureSelection boundaryObjects) throws CreateGeometryException,
104
        DataException, GeometryOperationNotSupportedException,
105
        GeometryOperationException {
102
            FeatureSelection boundaryObjects) throws CreateGeometryException,
103
            DataException, GeometryOperationNotSupportedException,
104
            GeometryOperationException {
106 105

  
107
        Point initPoint = null;
108
        Point endPoint = null;
106
        Point initPoint = getExtremeSegmentInitPoint(line, sideToExtend);
107
        Point endPoint = getExtremeSegmentEndPoint(line, sideToExtend);
109 108

  
109
        return getIntersectionOfProjectedLine(initPoint, endPoint,
110
                boundaryObjects);
111
    }
112

  
113
    /**
114
     * Calculates the nearest intersection among curve and boundary objects
115
     * depending on side received as parameter.
116
     *
117
     * @param line to be extended
118
     * @param sideToExtend What side will be extend. Use
119
     * {@link ExtendLineOperationUtils#START_SIDE} and
120
     * {@link ExtendLineOperationUtils#END_SIDE}
121
     * @param boundaryObject to calculate intersection points.
122
     * @return the nearest intersection point. Return Null if arc does not
123
     * intersect with any boundary object
124
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
125
     * @throws org.gvsig.fmap.dal.exception.DataException
126
     * @throws
127
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
128
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
129
     */
130
    public static Point curveIntersection(Curve line, String sideToExtend,
131
            Geometry boundaryObject) throws CreateGeometryException,
132
            DataException, GeometryOperationNotSupportedException,
133
            GeometryOperationException {
134

  
135
        Point initPoint = getExtremeSegmentInitPoint(line, sideToExtend);
136
        Point endPoint = getExtremeSegmentEndPoint(line, sideToExtend);
137

  
138
        return getIntersectionOfProjectedLine(initPoint, endPoint,
139
                boundaryObject);
140
    }
141

  
142
    private static Point getExtremeSegmentEndPoint(Curve line, String sideToExtend) {
110 143
        // Start side line is formed by second point and first point
111 144
        if (sideToExtend.equalsIgnoreCase(START_SIDE)) {
145
            return line.getVertex(0);
146
            // End side line is formed by penultimate point and last point
147
        } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
148
            return line.getVertex(line.getNumVertices() - 1);
149
        }
150
        return null;
151
    }
112 152

  
113
            initPoint = line.getVertex(1);
114
            endPoint = line.getVertex(0);
115

  
153
    private static Point getExtremeSegmentInitPoint(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(1);
116 157
            // End side line is formed by penultimate point and last point
117 158
        } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
118

  
119
            initPoint = line.getVertex(line.getNumVertices() - 2);
120
            endPoint = line.getVertex(line.getNumVertices() - 1);
121

  
159
            return line.getVertex(line.getNumVertices() - 2);
122 160
        }
123

  
124
        return getIntersectionOfProjectedLine(initPoint, endPoint,
125
            boundaryObjects);
161
        return null;
126 162
    }
127 163

  
128 164
    /**
129 165
     * Calculates the nearest intersection point among arc and boundary objects
130
     * depending on side received as parameter.
131
     * 
132
     * Strategy:
133
     * 
166
     * depending on side received as parameter.Strategy:
167
     *
134 168
     * 1- Create a full arc with the same center and radius of arc received by
135
     * parameter.
136
     * 2- Iterate over boundary objects.
137
     * 3- If some boundary object intersects with full arc, calculates the
138
     * distance to start point or end point depending on side to be extend.
139
     * 4- Return the nearest intersection point.
140
     * 
141
     * @param arcToBeExtended
142
     *            Arc to be extended
143
     * @param sideToExtend
144
     *            What side will be extend. Use
145
     *            {@link ExtendLineOperationUtils#START_SIDE} and
146
     *            {@link ExtendLineOperationUtils#END_SIDE}
147
     * @param boundaryObjects
148
     *            to calculate intersection points.
169
     * parameter.2- Iterate over boundary objects.3- If some boundary object
170
     * intersects with full arc, calculates the distance to start point or end
171
     * point depending on side to be extend.4- Return the nearest intersection
172
     * point.
173
     *
174
     *
175
     * @param arcToBeExtended Arc to be extended
176
     * @param sideToExtend What side will be extend. Use
177
     * {@link ExtendLineOperationUtils#START_SIDE} and
178
     * {@link ExtendLineOperationUtils#END_SIDE}
179
     * @param boundaryObjects to calculate intersection points.
149 180
     * @return the nearest intersection point. Return Null if arc does not
150
     *         intersect with any boundary object
181
     * intersect with any boundary object
182
     * @throws
183
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
184
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
185
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
186
     * @throws org.gvsig.fmap.dal.exception.DataException
151 187
     */
152 188
    public static Point arcIntersection(Arc arcToBeExtended,
153
        String sideToExtend, FeatureSelection boundaryObjects)
154
        throws GeometryOperationNotSupportedException,
155
        GeometryOperationException, CreateGeometryException, DataException {
189
            String sideToExtend, FeatureSelection boundaryObjects)
190
            throws GeometryOperationNotSupportedException,
191
            GeometryOperationException, CreateGeometryException, DataException {
156 192

  
157 193
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
158 194
        int subtype = arcToBeExtended.getGeometryType().getSubType();
......
175 211
                Geometry intersectionGeometry = tmpArc.intersection(geometry);
176 212

  
177 213
                if (intersectionGeometry instanceof MultiPoint) {
178
                    MultiPoint intersectionMultiPoint =
179
                        (MultiPoint) intersectionGeometry;
214
                    MultiPoint intersectionMultiPoint
215
                            = (MultiPoint) intersectionGeometry;
180 216

  
181 217
                    for (int i = 0; i < intersectionMultiPoint
182
                        .getPrimitivesNumber(); i++) {
218
                            .getPrimitivesNumber(); i++) {
183 219
                        Point point = intersectionMultiPoint.getPointAt(i);
184 220
                        double distance = Double.POSITIVE_INFINITY;
185 221

  
186 222
                        if (sideToExtend.equalsIgnoreCase(START_SIDE)) {
187
                            distance =
188
                                point.distance(arcToBeExtended.getInitPoint());
223
                            distance
224
                                    = point.distance(arcToBeExtended.getInitPoint());
189 225
                        } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
190
                            distance =
191
                                point.distance(arcToBeExtended.getEndPoint());
226
                            distance
227
                                    = point.distance(arcToBeExtended.getEndPoint());
192 228
                        }
193 229

  
194 230
                        if (distance < minDistance) {
......
201 237
                    double distance = Double.POSITIVE_INFINITY;
202 238

  
203 239
                    if (sideToExtend.equalsIgnoreCase("start")) {
204
                        distance =
205
                            intersectionPoint.distance(arcToBeExtended
206
                                .getInitPoint());
240
                        distance
241
                                = intersectionPoint.distance(arcToBeExtended
242
                                        .getInitPoint());
207 243
                    } else if (sideToExtend.equalsIgnoreCase("end")) {
208
                        distance =
209
                            intersectionPoint.distance(arcToBeExtended
210
                                .getEndPoint());
244
                        distance
245
                                = intersectionPoint.distance(arcToBeExtended
246
                                        .getEndPoint());
211 247
                    }
212 248

  
213 249
                    if (distance < minDistance) {
......
221 257
        return intersection;
222 258
    }
223 259

  
260
    /**
261
     * Calculates the nearest intersection point among arc and boundary objects
262
     * depending on side received as parameter.Strategy:
263
     *
264
     * 1- Create a full arc with the same center and radius of arc received by
265
     * parameter.2- Iterate over boundary objects.3- If some boundary object
266
     * intersects with full arc, calculates the distance to start point or end
267
     * point depending on side to be extend.4- Return the nearest intersection
268
     * point.
269
     *
270
     *
271
     * @param arcToBeExtended Arc to be extended
272
     * @param sideToExtend What side will be extend. Use
273
     * {@link ExtendLineOperationUtils#START_SIDE} and
274
     * {@link ExtendLineOperationUtils#END_SIDE}
275
     * @param boundaryObject to calculate intersection points.
276
     * @return the nearest intersection point. Return Null if arc does not
277
     * intersect with any boundary object
278
     * @throws
279
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
280
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
281
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
282
     * @throws org.gvsig.fmap.dal.exception.DataException
283
     */
284
    public static Point arcIntersection(Arc arcToBeExtended,
285
            String sideToExtend, Geometry boundaryObject)
286
            throws GeometryOperationNotSupportedException,
287
            GeometryOperationException, CreateGeometryException, DataException {
288

  
289
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
290
        int subtype = arcToBeExtended.getGeometryType().getSubType();
291

  
292
        Point center = arcToBeExtended.getCenterPoint();
293
        double radius = center.distance(arcToBeExtended.getInitPoint());
294

  
295
        Point intersection = null;
296

  
297
//        double minDistance = Double.POSITIVE_INFINITY;
298

  
299
        Arc tmpArc = (Arc) geoManager.create(TYPES.ARC, subtype);
300
        tmpArc.setPoints(center, radius, 0, Math.PI * 2);
301

  
302
        double distance = Double.POSITIVE_INFINITY;
303
        double minDistance = Double.POSITIVE_INFINITY;
304
        if (tmpArc.intersects(boundaryObject)) {
305
            Geometry intersectionGeometry = tmpArc.intersection(boundaryObject);
306

  
307
            if (intersectionGeometry instanceof MultiPoint) {
308
                MultiPoint intersectionMultiPoint
309
                        = (MultiPoint) intersectionGeometry;
310

  
311
                for (int i = 0; i < intersectionMultiPoint
312
                        .getPrimitivesNumber(); i++) {
313
                    Point point = intersectionMultiPoint.getPointAt(i);
314

  
315
                    if (sideToExtend.equalsIgnoreCase(START_SIDE)) {
316
                        distance
317
                                = point.distance(arcToBeExtended.getInitPoint());
318
                    } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
319
                        distance
320
                                = point.distance(arcToBeExtended.getEndPoint());
321
                    }
322

  
323
                    if (distance < minDistance) {
324
                        intersection = point;
325
                        minDistance = distance;
326
                    }
327
                }
328
            } else if (intersectionGeometry instanceof Point) {
329
                Point intersectionPoint = (Point) intersectionGeometry;
330

  
331
                intersection = intersectionPoint;
332
            }
333
        }
334
        return intersection;
335
    }
336

  
224 337
    // FIXME: remove this method when geometry library has this utility method
225 338
    public static double getAngle(Point start, Point end)
226
        throws GeometryOperationNotSupportedException,
227
        GeometryOperationException {
228
        double angle =
229
            Math.acos((end.getX() - start.getX()) / start.distance(end));
339
            throws GeometryOperationNotSupportedException,
340
            GeometryOperationException {
341
        double angle
342
                = Math.acos((end.getX() - start.getX()) / start.distance(end));
230 343

  
231 344
        if (start.getY() > end.getY()) {
232 345
            angle = -angle;
......
241 354

  
242 355
    /**
243 356
     * Gets intersection among the line formed by initPoint and endPoint and
244
     * boundary objects. If line or its projection does not intersect with any
245
     * boundary object return null.
246
     * 
247
     * Strategy:
248
     * 
357
     * boundary objects.If line or its projection does not intersect with any
358
     * boundary object return null.Strategy:
359
     *
249 360
     * 1- Get module of line to determine if an intersection point already be
250
     * vertex of line. If the distance between intersection point and start
251
     * point of line is less than module indicates that intersection point
252
     * already be curve point.
253
     * 2- Project line with the line parametric equation.
254
     * 3- Iterate over boundary objects.
255
     * 4- Check if boundary object does not contains end point of projected
256
     * line.
257
     * 5- If projected line intersects with any boundary object, get the nearest
258
     * intersection point
259
     * 6- Return it.
260
     * 
261
     * 
262
     * @param initPoint
263
     *            of curve to extend
264
     * @param endPoint
265
     *            end point of curve to extend
266
     * @param boundaryObjects
267
     *            to calculate intersection points.
361
     * vertex of line.If the distance between intersection point and start point
362
     * of line is less than module indicates that intersection point already be
363
     * curve point.2- Project line with the line parametric equation. 3- Iterate
364
     * over boundary objects. 4- Check if boundary object does not contains end
365
     * point of projected line. 5- If projected line intersects with any
366
     * boundary object, get the nearest intersection point 6- Return it.
367
     *
368
     *
369
     * @param initPoint of curve to extend
370
     * @param endPoint end point of curve to extend
371
     * @param boundaryObjects to calculate intersection points.
268 372
     * @return the nearest intersection point. Return Null if arc does not
269
     *         intersect with any boundary object
373
     * intersect with any boundary object
374
     * @throws
375
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
376
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
377
     * @throws org.gvsig.fmap.dal.exception.DataException
378
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
270 379
     */
271 380
    public static Point getIntersectionOfProjectedLine(Point initPoint,
272
        Point endPoint, FeatureSelection boundaryObjects)
273
        throws GeometryOperationNotSupportedException,
274
        GeometryOperationException, DataException, CreateGeometryException {
381
            Point endPoint, FeatureSelection boundaryObjects)
382
            throws GeometryOperationNotSupportedException,
383
            GeometryOperationException, DataException, CreateGeometryException {
275 384

  
276 385
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
277 386
        int subtype = initPoint.getGeometryType().getSubType();
......
303 412

  
304 413
                    if (tmpLine.intersects(geometry)) {
305 414

  
306
                        Geometry intersecionGeometry =
307
                            geometry.intersection(tmpLine);
415
                        Geometry intersecionGeometry
416
                                = geometry.intersection(tmpLine);
308 417

  
309 418
                        if (intersecionGeometry instanceof Point) {
310 419

  
311
                            double distance =
312
                                ((Point) intersecionGeometry)
313
                                    .distance(initPoint);
420
                            double distance
421
                                    = ((Point) intersecionGeometry)
422
                                            .distance(initPoint);
314 423

  
315 424
                            if (distance < minDistance && distance > (module + 0.01)) {
316 425
                                intersectionPoint = (Point) intersecionGeometry;
......
319 428

  
320 429
                        } else if (intersecionGeometry instanceof MultiPoint) {
321 430

  
322
                            MultiPoint intersectionMultiPoint =
323
                                (MultiPoint) intersecionGeometry;
431
                            MultiPoint intersectionMultiPoint
432
                                    = (MultiPoint) intersecionGeometry;
324 433

  
325 434
                            for (int i = 0; i < intersectionMultiPoint
326
                                .getPrimitivesNumber(); i++) {
435
                                    .getPrimitivesNumber(); i++) {
327 436

  
328
                                double distance =
329
                                    intersectionMultiPoint.getPointAt(i)
330
                                        .distance(initPoint);
437
                                double distance
438
                                        = intersectionMultiPoint.getPointAt(i)
439
                                                .distance(initPoint);
331 440

  
332 441
                                if (distance < minDistance && distance > (module + 0.01)) {
333
                                    intersectionPoint =
334
                                        intersectionMultiPoint.getPointAt(i);
442
                                    intersectionPoint
443
                                            = intersectionMultiPoint.getPointAt(i);
335 444
                                    minDistance = distance;
336 445
                                }
337 446
                            }
338 447
                        } else if (intersecionGeometry instanceof Curve) {
339 448

  
340
                            Curve intersectionCurve =
341
                                (Curve) intersecionGeometry;
449
                            Curve intersectionCurve
450
                                    = (Curve) intersecionGeometry;
342 451

  
343 452
                            for (int i = 0; i < intersectionCurve
344
                                .getNumVertices(); i++) {
453
                                    .getNumVertices(); i++) {
345 454

  
346
                                double distance =
347
                                    intersectionCurve.getVertex(i).distance(
348
                                        endPoint);
455
                                double distance
456
                                        = intersectionCurve.getVertex(i).distance(
457
                                                endPoint);
349 458

  
350 459
                                if (distance < minDistance && distance > (module + 0.01)) {
351
                                    intersectionPoint =
352
                                        intersectionCurve.getVertex(i);
460
                                    intersectionPoint
461
                                            = intersectionCurve.getVertex(i);
353 462
                                    minDistance = distance;
354 463
                                }
355 464
                            }
......
364 473
        }
365 474
        return intersectionPoint;
366 475
    }
476

  
477
    /**
478
     * Gets intersection among the line formed by initPoint and endPoint and
479
     * boundary object.If line or its projection does not intersect with
480
     * boundary object return null.Strategy:
481
     *
482
     * 1- Get module of line to determine if an intersection point already be
483
     * vertex of line.If the distance between intersection point and start point
484
     * of line is less than module indicates that intersection point already be
485
     * curve point.2- Project line with the line parametric equation. 3- Check
486
     * if boundary object does not contains end point of projected line. 5- If
487
     * projected line intersects with boundary object, get the nearest
488
     * intersection point 6- Return it.
489
     *
490
     *
491
     * @param initPoint of curve to extend
492
     * @param endPoint end point of curve to extend
493
     * @param boundaryObject to calculate intersection points.
494
     * @return the nearest intersection point. Return Null if arc does not
495
     * intersect with any boundary object
496
     * @throws
497
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
498
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
499
     * @throws org.gvsig.fmap.dal.exception.DataException
500
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
501
     */
502
    public static Point getIntersectionOfProjectedLine(Point initPoint,
503
            Point endPoint, Geometry boundaryObject)
504
            throws GeometryOperationNotSupportedException,
505
            GeometryOperationException, DataException, CreateGeometryException {
506

  
507
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
508
        int subtype = initPoint.getGeometryType().getSubType();
509

  
510
        double module = initPoint.distance(endPoint);
511

  
512
        double minDistance = Double.POSITIVE_INFINITY;
513
        Point intersectionPoint = null;
514

  
515
        double x, y;
516
        double x1 = initPoint.getX();
517
        double y1 = initPoint.getY();
518
        double x2 = endPoint.getX();
519
        double y2 = endPoint.getY();
520

  
521
        for (int t = 1; t < PROJECTION_LIMIT; t += 10) {
522
            x = (x2 - x1) * t + x1;
523
            y = (y2 - y1) * t + y1;
524

  
525
            Point projectedPoint = geoManager.createPoint(x, y, subtype);
526

  
527
            if (!boundaryObject.contains(projectedPoint)) {
528
                Curve tmpLine = geoManager.createLine(subtype);
529
                tmpLine.setPoints(initPoint, projectedPoint);
530

  
531
                if (tmpLine.intersects(boundaryObject)) {
532

  
533
                    Geometry intersecionGeometry
534
                            = boundaryObject.intersection(tmpLine);
535

  
536
                    if (intersecionGeometry instanceof Point) {
537

  
538
                        double distance
539
                                = ((Point) intersecionGeometry)
540
                                        .distance(initPoint);
541

  
542
                        if (distance < minDistance && distance > (module + 0.01)) {
543
                            intersectionPoint = (Point) intersecionGeometry;
544
                            minDistance = distance;
545
                        }
546

  
547
                    } else if (intersecionGeometry instanceof MultiPoint) {
548

  
549
                        MultiPoint intersectionMultiPoint
550
                                = (MultiPoint) intersecionGeometry;
551

  
552
                        for (int i = 0; i < intersectionMultiPoint
553
                                .getPrimitivesNumber(); i++) {
554

  
555
                            double distance
556
                                    = intersectionMultiPoint.getPointAt(i)
557
                                            .distance(initPoint);
558

  
559
                            if (distance < minDistance && distance > (module + 0.01)) {
560
                                intersectionPoint
561
                                        = intersectionMultiPoint.getPointAt(i);
562
                                minDistance = distance;
563
                            }
564
                        }
565
                    } else if (intersecionGeometry instanceof Curve) {
566

  
567
                        Curve intersectionCurve
568
                                = (Curve) intersecionGeometry;
569

  
570
                        for (int i = 0; i < intersectionCurve
571
                                .getNumVertices(); i++) {
572

  
573
                            double distance
574
                                    = intersectionCurve.getVertex(i).distance(
575
                                            endPoint);
576

  
577
                            if (distance < minDistance && distance > (module + 0.01)) {
578
                                intersectionPoint
579
                                        = intersectionCurve.getVertex(i);
580
                                minDistance = distance;
581
                            }
582
                        }
583
                    }
584
                }
585
            }
586
            if (intersectionPoint != null) {
587
                break;
588
            }
589
        }
590
        return intersectionPoint;
591
    }
592

  
367 593
}

Also available in: Unified diff