1 package org.djunits.quantity;
2
3 import org.djunits.quantity.def.AbstractReference;
4 import org.djunits.quantity.def.ComparableAbsQuantity;
5 import org.djunits.quantity.def.Quantity;
6
7 /**
8 * Position is the absolute equivalent of Length, and can, e.g., represent an absolute offset relative to a defined origin.
9 * <p>
10 * Copyright (c) 2025-2026 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
11 * for project information <a href="https://djunits.org" target="_blank">https://djunits.org</a>. The DJUNITS project is
12 * distributed under a <a href="https://djunits.org/docs/license.html" target="_blank">three-clause BSD-style license</a>.
13 * @author Alexander Verbraeck
14 */
15 public class Position extends ComparableAbsQuantity<Position, Length, Position.Reference>
16 {
17 /** */
18 private static final long serialVersionUID = 600L;
19
20 /**
21 * Instantiate a Position quantity with an SI or base value, or a value expressed in a unit, and a reference point.
22 * @param value the length value, either expressed in the SI unit, or in the provided unit, relative to the reference point
23 * @param unit the length display unit or unit
24 * @param reference the reference point of this position
25 * @param useSi when true, value is taken as the SI value; when false, value is expressed in the unit
26 */
27 public Position(final double value, final Length.Unit unit, final Reference reference, final boolean useSi)
28 {
29 super(new Length(value, unit, useSi), reference);
30 }
31
32 /**
33 * Instantiate a Position instance based on an length and a reference point.
34 * @param length the length, relative to the reference point
35 * @param reference the reference point of this position
36 */
37 public Position(final Length length, final Reference reference)
38 {
39 super(length, reference);
40 }
41
42 /**
43 * Return a Position instance based on an SI value and a reference point.
44 * @param si the length si value, relative to the reference point
45 * @param reference the reference point of this position
46 * @return the Position instance based on an SI value
47 */
48 public static Position ofSi(final double si, final Reference reference)
49 {
50 return new Position(si, Length.Unit.SI, reference, true);
51 }
52
53 @Override
54 public Position instantiate(final Length length, final Reference reference)
55 {
56 return new Position(length, reference);
57 }
58
59 /**
60 * Returns a Position representation of a textual representation of a value with a unit. The String representation that can
61 * be parsed is the double value in the unit, followed by a localized or English abbreviation of the unit. Spaces are
62 * allowed, but not required, between the value and the unit.
63 * @param text the textual representation to parse into a Position
64 * @param reference the reference point of this position
65 * @return the Scalar representation of the value in its unit
66 * @throws IllegalArgumentException when the text cannot be parsed
67 * @throws NullPointerException when the text argument is null
68 */
69 public static Position valueOf(final String text, final Reference reference)
70 {
71 return new Position(Quantity.valueOf(text, Length.ZERO), reference);
72 }
73
74 /**
75 * Returns a Position based on a value and the textual representation of the unit, which can be localized.
76 * @param valueInUnit the value, expressed in the unit as given by unitString
77 * @param unitString the textual representation of the unit
78 * @param reference the reference point of this position
79 * @return the Scalar representation of the value in its unit
80 * @throws IllegalArgumentException when the unit cannot be parsed or is incorrect
81 * @throws NullPointerException when the unitString argument is null
82 */
83 public static Position of(final double valueInUnit, final String unitString, final Reference reference)
84 {
85 return new Position(Quantity.of(valueInUnit, unitString, Length.ZERO), reference);
86 }
87
88 @Override
89 public Length subtract(final Position other)
90 {
91 var otherRef = other.relativeTo(getReference());
92 return Length.ofSi(si() - otherRef.si(), getQuantity().getDisplayUnit());
93 }
94
95 @Override
96 public Position add(final Length other)
97 {
98 return new Position(Length.ofSi(si() + other.si(), getQuantity().getDisplayUnit()), getReference());
99 }
100
101 @Override
102 public Position subtract(final Length other)
103 {
104 return new Position(Length.ofSi(si() - other.si(), getQuantity().getDisplayUnit()), getReference());
105 }
106
107 /**
108 * The reference class to define a reference point for the position. No references have been defined yet, since there is no
109 * "natural" origin for a position that we can include here. User-defined origins van be easily added and used.
110 */
111 public static final class Reference extends AbstractReference<Reference, Position, Length>
112 {
113 /**
114 * Define a new reference point for the position.
115 * @param id the id
116 * @param name the name or explanation
117 * @param offset the offset w.r.t. the offsetReference
118 * @param offsetReference the reference to which the offset is relative
119 */
120 public Reference(final String id, final String name, final Length offset, final Reference offsetReference)
121 {
122 super(id, name, offset, offsetReference);
123 }
124
125 /**
126 * Define a new reference point for the position.
127 * @param id the id
128 * @param name the name or explanation
129 */
130 public Reference(final String id, final String name)
131 {
132 this(id, name, Length.ZERO, null);
133 }
134
135 /**
136 * Define a new reference point for the position.
137 * @param id the id
138 * @param name the name or explanation
139 * @param offset the offset w.r.t. the offsetReference
140 * @param offsetReference the reference to which the offset is relative
141 */
142 public static void add(final String id, final String name, final Length offset, final Reference offsetReference)
143 {
144 new Reference(id, name, offset, offsetReference);
145 }
146
147 /**
148 * Define a new reference point for the position.
149 * @param id the id
150 * @param name the name or explanation
151 */
152 public static void add(final String id, final String name)
153 {
154 new Reference(id, name);
155 }
156
157 /**
158 * Get a reference point for the position, based on its id. Return null when the id could not be found.
159 * @param id the id
160 * @return the PositionReference object
161 */
162 public static Reference get(final String id)
163 {
164 return AbstractReference.get(Position.Reference.class, id);
165 }
166
167 @Override
168 public Position instantiate(final Length length)
169 {
170 return new Position(length, this);
171 }
172 }
173 }