1 package org.opentrafficsim.core.network;
2
3 import org.opentrafficsim.core.unit.LengthUnit;
4 import org.opentrafficsim.core.value.vdouble.scalar.DoubleScalar;
5
6 /**
7 * "1D" implementation. Mapping on the design line (often the center line) of a road.
8 * <p>
9 * Copyright (c) 2013-2014 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
10 * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
11 * <p>
12 * @version Oct 22, 2014 <br>
13 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
14 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
15 */
16 public class LinkLocation
17 {
18 /** The link of the location of a point relative to the GTU. */
19 private final Link<?, ?> link;
20
21 /** The fractional position (between 0.0 and 1.0) of the reference point on the lane. */
22 private final double fractionalLongitudinalPosition;
23
24 /**
25 * @param link The link of the location of a point relative to the GTU.
26 * @param fractionalLongitudinalPosition The fractional position (between 0.0 and 1.0) of the reference point on the link.
27 */
28 public LinkLocation(final Link<?, ?> link, final double fractionalLongitudinalPosition)
29 {
30 super();
31 this.link = link;
32 this.fractionalLongitudinalPosition = fractionalLongitudinalPosition;
33 }
34
35 /**
36 * @param link The link of the location of a point relative to the GTU.
37 * @param position The position as a length of the reference point on the link.
38 */
39 public LinkLocation(final Link<?, ?> link, final DoubleScalar.Rel<LengthUnit> position)
40 {
41 super();
42 this.link = link;
43 this.fractionalLongitudinalPosition = DoubleScalar.divide(position, this.link.getLength()).doubleValue();
44 }
45
46 /**
47 * @return lane.
48 */
49 public final Link<?, ?> getLink()
50 {
51 return this.link;
52 }
53
54 /**
55 * @return fractionalLongitudinalPosition.
56 */
57 public final double getFractionalLongitudinalPosition()
58 {
59 return this.fractionalLongitudinalPosition;
60 }
61
62 /**
63 * @return position as a length as a traveled length on this link.
64 */
65 public final DoubleScalar.Rel<LengthUnit> getLongitudinalPosition()
66 {
67 return new DoubleScalar.Rel<LengthUnit>(this.link.getLength().getSI() * getFractionalLongitudinalPosition(),
68 LengthUnit.METER);
69 }
70
71 /**
72 * Returns the distance to another LinkLocation. If the other location is in front of us, the distance is positive. If it is
73 * behind us, it is negative.
74 * @param loc the link location to find the distance to.
75 * @return the distance to another LinkLocation.
76 */
77 public final DoubleScalar.Rel<LengthUnit> distance(final LinkLocation loc)
78 {
79 if (this.link.equals(loc.getLink()))
80 {
81 return DoubleScalar.minus(loc.getLongitudinalPosition(), this.getLongitudinalPosition()).immutable();
82 }
83
84 // TODO not on the same link. Find shortest path...
85 return null;
86 }
87
88 /** {@inheritDoc} */
89 public final String toString()
90 {
91 return String.format("%s %.3f%s", getLink(), getLongitudinalPosition().getInUnit(), getLongitudinalPosition()
92 .getUnit());
93 }
94 }