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