View Javadoc
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 }