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