1 /*
  2  * LengthUnit.js - Unit conversions for length measurements
  3  *
  4  * Copyright © 2014-2015, 2018 JEDLSoft
  5  *
  6  * Licensed under the Apache License, Version 2.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at
  9  *
 10  *     http://www.apache.org/licenses/LICENSE-2.0
 11  *
 12  * Unless required by applicable law or agreed to in writing, software
 13  * distributed under the License is distributed on an "AS IS" BASIS,
 14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  *
 16  * See the License for the specific language governing permissions and
 17  * limitations under the License.
 18  */
 19 
 20 /*
 21 !depends
 22 Measurement.js
 23 */
 24 
 25 var Measurement = require("./Measurement.js");
 26 
 27 /**
 28  * @class
 29  * Create a new length measurement instance.
 30  *
 31  * @constructor
 32  * @extends Measurement
 33  * @param options {{unit:string,amount:number|string|undefined}} Options controlling
 34  * the construction of this instance
 35  */
 36 var LengthUnit = function (options) {
 37     this.unit = "meter";
 38     this.amount = 0;
 39 
 40     this.ratios = LengthUnit.ratios;
 41     this.aliases = LengthUnit.aliases;
 42     this.aliasesLower = LengthUnit.aliasesLower;
 43     this.systems = LengthUnit.systems;
 44 
 45     this.parent.call(this, options);
 46 };
 47 
 48 LengthUnit.prototype = new Measurement();
 49 LengthUnit.prototype.parent = Measurement;
 50 LengthUnit.prototype.constructor = LengthUnit;
 51 
 52 LengthUnit.ratios = {
 53     /*               index, µm           mm           cm           inch         dm           foot          yard          m             dam            hm              km              mile            nm            Mm             Gm             */
 54     "micrometer":    [ 1,   1,           1e-3,        1e-4,        3.93701e-5,  1e-5,        3.28084e-6,   1.09361e-6,   1e-6,         1e-7,          1e-8,           1e-9,           6.21373e-10,  5.39957e-10,  1e-12,          1e-15           ],
 55     "millimeter":    [ 2,   1000,        1,           0.1,         0.0393701,   0.01,        0.00328084,   1.09361e-3,   0.001,        1e-4,          1e-5,           1e-6,           6.21373e-7,   5.39957e-7,   1e-9,           1e-12           ],
 56     "centimeter":    [ 3,   1e4,         10,          1,           0.393701,    0.1,         0.0328084,    0.0109361,    0.01,         0.001,         1e-4,           1e-5,           6.21373e-6,   5.39957e-6,   1e-8,           1e-9            ],
 57     "inch":          [ 4,   25399.986,   25.399986,   2.5399986,   1,           0.25399986,  0.083333333,  0.027777778,  0.025399986,  2.5399986e-3,  2.5399986e-4,   2.5399986e-5,   1.5783e-5,    1.3715e-5,    2.5399986e-8,   2.5399986e-11   ],
 58     "decimeter":     [ 5,   1e5,         100,         10,          3.93701,     1,           0.328084,     0.109361,     0.1,          0.01,          0.001,          1e-4,           6.21373e-5,   5.39957e-5,   1e-7,           1e-8            ],
 59     "foot":          [ 6,   304799.99,   304.79999,   30.479999,   12,          3.0479999,   1,            0.33333333,   0.30479999,   0.030479999,   3.0479999e-3,   3.0479999e-4,   1.89394e-4,   1.64579e-4,   3.0479999e-7,   3.0479999e-10   ],
 60     "yard":          [ 7,   914402.758,  914.402758,  91.4402758,  36,          9.14402758,  3,            1,            0.914402758,  0.0914402758,  9.14402758e-3,  9.14402758e-4,  5.68182e-4,   4.93737e-4,   9.14402758e-7,  9.14402758e-10  ],
 61     "meter":         [ 8,   1e6,         1000,        100,         39.3701,     10,          3.28084,      1.09361,      1,            0.1,           0.01,           0.001,          6.213712e-4,  5.39957e-4,   1e-6,           1e-7            ],
 62     "decameter":     [ 9,   1e7,         1e4,         1000,        393.701,     100,         32.8084,      10.9361,      10,           1,             0.1,            0.01,           6.21373e-3,   5.39957e-3,   1e-5,           1e-6            ],
 63     "hectometer":    [ 10,  1e8,         1e5,         1e4,         3937.01,     1000,        328.084,      109.361,      100,          10,            1,              0.1,            0.0621373,    0.0539957,    1e-4,           1e-5            ],
 64     "kilometer":     [ 11,  1e9,         1e6,         1e5,         39370.1,     1e4,         3280.84,      1093.61,      1000,         100,           10,             1,              0.621373,     0.539957,     0.001,          1e-4            ],
 65     "mile":          [ 12,  1.60934e9,   1.60934e6,   1.60934e5,   63360,       1.60934e4,   5280,         1760,         1609.34,      160.934,       16.0934,        1.60934,        1,            0.868976,     1.60934e-3,     1.60934e-6      ],
 66     "nautical-mile": [ 13,  1.852e9,     1.852e6,     1.852e5,     72913.4,     1.852e4,     6076.12,      2025.37,      1852,         185.2,         18.52,          1.852,          1.15078,      1,            1.852e-3,       1.852e-6        ],
 67     "megameter":     [ 14,  1e12,        1e9,         1e6,         3.93701e7,   1e5,         3.28084e6,    1.09361e6,    1e4,          1000,          100,            10,             621.373,      539.957,      1,              0.001           ],
 68     "gigameter":     [ 15,  1e15,        1e12,        1e9,         3.93701e10,  1e8,         3.28084e9,    1.09361e9,    1e7,          1e6,           1e5,            1e4,            621373.0,     539957.0,     1000,           1               ]
 69 };
 70 
 71 /**
 72  * Return a new instance of this type of measurement.
 73  *
 74  * @param {Object} params parameters to the constructor
 75  * @return {Measurement} a measurement subclass instance
 76  */
 77 LengthUnit.prototype.newUnit = function(params) {
 78     return new LengthUnit(params);
 79 };
 80 
 81 LengthUnit.systems = {
 82     "metric": [
 83         "micrometer",
 84         "millimeter",
 85         "centimeter",
 86         "decimeter",
 87         "meter",
 88         "decameter",
 89         "hectometer",
 90         "kilometer",
 91         "megameter",
 92         "gigameter"
 93     ],
 94     "imperial": [
 95         "inch",
 96         "foot",
 97         "yard",
 98         "mile",
 99         "nautical-mile"
100     ],
101     "uscustomary": [
102         "inch",
103         "foot",
104         "yard",
105         "mile",
106         "nautical-mile"
107     ],
108     "conversions": {
109         "metric": {
110             "uscustomary": {
111                 "micrometer": "inch",
112                 "millimeter": "inch",
113                 "centimeter": "inch",
114                 "decimeter": "inch",
115                 "meter": "yard",
116                 "decameter": "yard",
117                 "hectometer": "mile",
118                 "kilometer": "mile",
119                 "megameter": "mile",
120                 "gigameter": "mile"
121             },
122             "imperial": {
123                 "micrometer": "inch",
124                 "millimeter": "inch",
125                 "centimeter": "inch",
126                 "decimeter": "inch",
127                 "meter": "yard",
128                 "decameter": "yard",
129                 "hectometer": "mile",
130                 "kilometer": "mile",
131                 "megameter": "mile",
132                 "gigameter": "mile"
133             }
134         },
135         "uscustomary": {
136             "metric": {
137                 "inch": "centimeter",
138                 "foot": "centimeter",
139                 "yard": "meter",
140                 "mile": "kilometer",
141                 "nautical-mile": "kilometer"
142             }
143         },
144         "imperial": {
145             "metric": {
146                 "inch": "centimeter",
147                 "foot": "centimeter",
148                 "yard": "meter",
149                 "mile": "kilometer",
150                 "nautical-mile": "kilometer"
151             }
152         }
153     }
154 };
155 
156 /**
157  * Return the type of this measurement. Examples are "mass",
158  * "length", "speed", etc. Measurements can only be converted
159  * to measurements of the same type.<p>
160  *
161  * The type of the units is determined automatically from the
162  * units. For example, the unit "grams" is type "mass". Use the
163  * static call {@link Measurement.getAvailableUnits}
164  * to find out what units this version of ilib supports.
165  *
166  * @returns {string} the name of the type of this measurement
167  */
168 LengthUnit.prototype.getMeasure = function() {
169     return "length";
170 };
171 
172 LengthUnit.aliases = {
173     "miles": "mile",
174     "mile":"mile",
175     "nauticalmiles": "nautical-mile",
176     "nautical mile": "nautical-mile",
177     "nautical miles": "nautical-mile",
178     "nauticalmile":"nautical-mile",
179     "yards": "yard",
180     "yard": "yard",
181     "feet": "foot",
182     "foot": "foot",
183     "inches": "inch",
184     "inch": "inch",
185     "in": "inch",
186     "meters": "meter",
187     "metre": "meter",
188     "metres": "meter",
189     "m": "meter",
190     "meter": "meter",
191     "micrometers": "micrometer",
192     "micrometres": "micrometer",
193     "micrometre": "micrometer",
194     "µm": "micrometer",
195     "micrometer": "micrometer",
196     "millimeters": "millimeter",
197     "millimetres": "millimeter",
198     "millimetre": "millimeter",
199     "mm": "millimeter",
200     "millimeter": "millimeter",
201     "centimeters": "centimeter",
202     "centimetres": "centimeter",
203     "centimetre": "centimeter",
204     "cm": "centimeter",
205     "centimeter": "centimeter",
206     "decimeters": "decimeter",
207     "decimetres": "decimeter",
208     "decimetre": "decimeter",
209     "dm": "decimeter",
210     "decimeter": "decimeter",
211     "decameters": "decameter",
212     "decametres": "decameter",
213     "decametre": "decameter",
214     "dam": "decameter",
215     "decameter": "decameter",
216     "hectometers": "hectometer",
217     "hectometres": "hectometer",
218     "hectometre": "hectometer",
219     "hm": "hectometer",
220     "hectometer": "hectometer",
221     "kilometers": "kilometer",
222     "kilometres": "kilometer",
223     "kilometre": "kilometer",
224     "km": "kilometer",
225     "kilometer": "kilometer",
226     "megameters": "megameter",
227     "megametres": "megameter",
228     "megametre": "megameter",
229     "Mm": "megameter",
230     "megameter": "megameter",
231     "gigameters": "gigameter",
232     "gigametres": "gigameter",
233     "gigametre": "gigameter",
234     "Gm": "gigameter",
235     "gigameter": "gigameter"
236 };
237 
238 (function() {
239     LengthUnit.aliasesLower = {};
240     for (var a in LengthUnit.aliases) {
241         LengthUnit.aliasesLower[a.toLowerCase()] = LengthUnit.aliases[a];
242     }
243 })();
244 
245 /**
246  * Convert a length to another measure.
247  * @static
248  * @param to {string} unit to convert to
249  * @param from {string} unit to convert from
250  * @param length {number} amount to be convert
251  * @returns {number|undefined} the converted amount
252  */
253 LengthUnit.convert = function(to, from, length) {
254     from = Measurement.getUnitIdCaseInsensitive(LengthUnit, from) || from;
255     to = Measurement.getUnitIdCaseInsensitive(LengthUnit, to) || to;
256     var fromRow = LengthUnit.ratios[from];
257     var toRow = LengthUnit.ratios[to];
258     if (typeof(from) === 'undefined' || typeof(to) === 'undefined') {
259         return undefined;
260     }
261     return length * fromRow[toRow[0]];
262 };
263 
264 /**
265  * @private
266  * @static
267  */
268 LengthUnit.getMeasures = function () {
269     return Object.keys(LengthUnit.ratios);
270 };
271 
272 //register with the factory method
273 Measurement._constructors["length"] = LengthUnit;
274 
275 module.exports = LengthUnit;
276