UnitConvert.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. const FEET_TO_INCHES_FACTOR = 12
  2. const EIGHTHS_SYMBOLS = ["", "⅛", "¼", "⅜", "½", "⅝", "¾", "⅞"]//eighths 八分之……
  3. class UnitOfMeasurement{//转化单位工具
  4. constructor(t, e, n, i){
  5. this.name = t,
  6. this.symbol = e,
  7. this.base = n,
  8. this.factor = i
  9. }
  10. toBase(t) {//换算到base
  11. return t * this.factor
  12. }
  13. fromBase(t) {//换算到当前
  14. return t / this.factor
  15. }
  16. }
  17. /* var o = function t(e) {
  18. this.gettext = e,
  19. t.METRIC = this.gettext("metric", void 0, "measurement system"),
  20. t.IMPERIAL = this.gettext("imperial", void 0, "measurement system")
  21. };
  22. e.UoMSystem = o;
  23. let UoMSystem = {
  24. } */
  25. /* var MeasurementDomain = {
  26. DISTANCE : "DISTANCE",
  27. t.AREA = "AREA",
  28. t.VOLUME = "VOLUME",
  29. t.DATA = "DATA",
  30. t
  31. }
  32. */
  33. var UnitsOfMeasurement = {
  34. MILLIMETER : ["Millimeter", "mm"],
  35. CENTIMETER : ["Centimeter", "cm"],
  36. METER : ["Meter", "m"],
  37. KILOMETER : ["Kilometer", "km"],
  38. INCH : ["Inch", "in"],
  39. FOOT : ["Foot", "ft"],
  40. MILE : ["Mile", "mi"],
  41. SQUAREMETER : ["SquareMeter", "m²"],
  42. SQUAREFOOT : ["SquareFoot", "ft²"],
  43. CUBICMETER : ["CubicMeter", "m³"],
  44. CUBICFOOT : ["CubicFoot", "ft³"],
  45. BYTE : ["Byte", "B"],
  46. KILOBYTE : ["Kilobyte", "kB"],
  47. MEGABYTE : ["Megabyte", "MB"],
  48. GIGABYTE : ["Gigabyte", "GB"],
  49. TERABYTE : ["Terabyte", "TB"],
  50. PETABYTE : ["Petabyte", "PB"],
  51. init : function() {
  52. var e, n, i, a, s, c, l, u, d, p, h,
  53. f = new UnitOfMeasurement(UnitsOfMeasurement.METER[0],UnitsOfMeasurement.METER[1],void 0,1),
  54. g = new UnitOfMeasurement(UnitsOfMeasurement.SQUAREMETER[0],UnitsOfMeasurement.SQUAREMETER[1],void 0,1),
  55. m = new UnitOfMeasurement(UnitsOfMeasurement.CUBICMETER[0],UnitsOfMeasurement.CUBICMETER[1],void 0,1),
  56. v = new UnitOfMeasurement(UnitsOfMeasurement.BYTE[0],UnitsOfMeasurement.BYTE[1],void 0,1);
  57. UnitsOfMeasurement.DISTANCE = (
  58. (e = {})['metric'] = ((n = {})[UnitsOfMeasurement.MILLIMETER[0]] = new UnitOfMeasurement(UnitsOfMeasurement.MILLIMETER[0],UnitsOfMeasurement.MILLIMETER[1],f,.001),
  59. n[UnitsOfMeasurement.CENTIMETER[0]] = new UnitOfMeasurement(UnitsOfMeasurement.CENTIMETER[0],UnitsOfMeasurement.CENTIMETER[1],f,.01),
  60. n[UnitsOfMeasurement.METER[0]] = f,
  61. n[UnitsOfMeasurement.KILOMETER[0]] = new UnitOfMeasurement(UnitsOfMeasurement.KILOMETER[0],UnitsOfMeasurement.KILOMETER[1],f,1e3),
  62. n),
  63. e['imperial'] = ((i = {})[UnitsOfMeasurement.INCH[0]] = new UnitOfMeasurement(UnitsOfMeasurement.INCH[0],UnitsOfMeasurement.INCH[1],f,.0254),
  64. i[UnitsOfMeasurement.FOOT[0]] = new UnitOfMeasurement(UnitsOfMeasurement.FOOT[0],UnitsOfMeasurement.FOOT[1],f,.3048),
  65. i[UnitsOfMeasurement.MILE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.MILE[0],UnitsOfMeasurement.MILE[1],f,1609.344),
  66. i),
  67. e);
  68. UnitsOfMeasurement.AREA = ((a = {})['metric'] = ((s = {})[UnitsOfMeasurement.SQUAREMETER[0]] = g,
  69. s),
  70. a['imperial'] = ((c = {})[UnitsOfMeasurement.SQUAREFOOT[0]] = new UnitOfMeasurement(UnitsOfMeasurement.SQUAREFOOT[0],UnitsOfMeasurement.SQUAREFOOT[1],g,.092903),
  71. c),
  72. a);
  73. UnitsOfMeasurement.VOLUME = ((l = {})['metric'] = ((u = {})[UnitsOfMeasurement.CUBICMETER[0]] = m,
  74. u),
  75. l['imperial'] = ((d = {})[UnitsOfMeasurement.CUBICFOOT[0]] = new UnitOfMeasurement(UnitsOfMeasurement.CUBICFOOT[0],UnitsOfMeasurement.CUBICFOOT[1],m,.0283168),
  76. d),
  77. l);
  78. //数据大小
  79. var y = ((p = {})[UnitsOfMeasurement.BYTE[0]] = v,
  80. p[UnitsOfMeasurement.KILOBYTE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.KILOBYTE[0],UnitsOfMeasurement.KILOBYTE[1],v,1e3),
  81. p[UnitsOfMeasurement.MEGABYTE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.MEGABYTE[0],UnitsOfMeasurement.MEGABYTE[1],v,1e6),
  82. p[UnitsOfMeasurement.GIGABYTE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.GIGABYTE[0],UnitsOfMeasurement.GIGABYTE[1],v,1e9),
  83. p[UnitsOfMeasurement.TERABYTE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.TERABYTE[0],UnitsOfMeasurement.TERABYTE[1],v,1e12),
  84. p[UnitsOfMeasurement.PETABYTE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.PETABYTE[0],UnitsOfMeasurement.PETABYTE[1],v,1e15),
  85. p);
  86. UnitsOfMeasurement.DATA = ((h = {})['metric'] = y,
  87. h['imperial'] = y,
  88. h)
  89. }
  90. ,
  91. getUnitsOfMeasurementByDomain : function(e) {
  92. return this[e.toUpperCase()]
  93. /* switch (e.toUpperCase()) {
  94. case a.DISTANCE:
  95. return t.DISTANCE;
  96. case a.AREA:
  97. return t.AREA;
  98. case a.VOLUME:
  99. return t.VOLUME;
  100. case a.DATA:
  101. return t.DATA;
  102. default:
  103. console.error(e + " measurement domain is not supported.")
  104. } */
  105. }
  106. ,
  107. getUnitsOfMeasurementByDomainAndSystem : function(domain, system) {
  108. var r = this.getUnitsOfMeasurementByDomain(domain);
  109. if (r.hasOwnProperty(system.toLowerCase()))
  110. return r[system.toLowerCase()];
  111. console.error(n + " measurement system is not supported.")
  112. }
  113. ,
  114. getDefaultUnitByDomainAndSystem : function(e, n) {
  115. switch (e.toUpperCase()) {
  116. case 'DISTANCE':
  117. switch (n.toLowerCase()) {
  118. case 'metric':
  119. return this.DISTANCE['metric'][this.METER[0]];
  120. case 'imperial':
  121. return this.DISTANCE['imperial'][this.FOOT[0]];
  122. default:
  123. console.error(n + " measurement system is not supported.")
  124. }
  125. case 'AREA':
  126. switch (n.toLowerCase()) {
  127. case 'metric':
  128. return this.AREA['metric'][this.SQUAREMETER[0]];
  129. case 'imperial':
  130. return this.AREA['imperial'][this.SQUAREFOOT[0]];
  131. default:
  132. console.error(n + " measurement system is not supported.")
  133. }
  134. case 'VOLUME':
  135. switch (n.toLowerCase()) {
  136. case 'metric':
  137. return this.VOLUME['metric'][this.CUBICMETER[0]];
  138. case 'imperial':
  139. return this.VOLUME['imperial'][this.CUBICFOOT[0]];
  140. default:
  141. console.error(n + " measurement system is not supported.")
  142. }
  143. case 'DATA':
  144. switch (n.toLowerCase()) {
  145. case 'metric':
  146. return this.DATA['metric'][this.BYTE[0]];
  147. case 'imperial':
  148. return this.DATA['imperial'][this.BYTE[0]];
  149. default:
  150. console.error(n + " measurement system is not supported.")
  151. }
  152. default:
  153. console.error(e + " measurement domain is not supported.")
  154. }
  155. }
  156. }
  157. class UnitService{
  158. constructor(/* e, n, i */){
  159. //this.LanguageService = e,
  160. //this.localStorageService = n,
  161. //this.gettext = i,
  162. //this.unitChanged = new r.Signal,
  163. this.LOCAL_STORAGE_KEY = "iv_unit_key"//?
  164. UnitsOfMeasurement.init()
  165. this.unitSystems = ['metric', 'imperial']//[o.UoMSystem.METRIC, o.UoMSystem.IMPERIAL],
  166. this.defaultSystem = 'metric'//'imperial'
  167. //var a = this.LanguageService.getBrowserLocaleString().toLowerCase();
  168. //this.defaultSystem = t.isLocaleImperial(a) ? o.UoMSystem.IMPERIAL : o.UoMSystem.METRIC,
  169. //this.initUnit()
  170. }
  171. /* initUnit() {
  172. var t = this.localStorageService.get(this.LOCAL_STORAGE_KEY);
  173. if (t)
  174. for (var e = 0, n = this.unitSystems; e < n.length; e++) {
  175. var i = n[e];
  176. if (i === t)
  177. return void this.setUnit(i, !0)
  178. }
  179. this.setUnit(this.defaultSystem, !1)
  180. }
  181. setUnit(t, e) {
  182. this.currentSystem !== t && (this.currentSystem = t,
  183. this.unitChanged.emit()),
  184. e && this.localStorageService.set(this.LOCAL_STORAGE_KEY, t)
  185. } */
  186. /*isLocaleImperial(e) {
  187. return t.IMPERIAL_LOCALES.indexOf(e.toLowerCase()) >= 0
  188. }
  189. ,
  190. t.IMPERIAL_LOCALES = ["en_us"],
  191. t.ɵfac(e) {
  192. return new (e || t)(c.ɵɵinject(l.LanguageService),
  193. c.ɵɵinject("localStorageService"),c.ɵɵinject("gettext"))
  194. }
  195. ,
  196. t.ɵprov = c.ɵɵdefineInjectable({
  197. token: t,
  198. factory: t.ɵfac,
  199. providedIn: "root"
  200. }), */
  201. }
  202. class UoMService{
  203. constructor(/* UnitService */){
  204. this.UnitService = new UnitService()/* UnitService */
  205. }
  206. scopedConvert (t, n, precision = 2, r, minFactor) {
  207. return this.convert(t, n, precision, r, minFactor)
  208. }
  209. convert(number, domain, precision = 2, system, minFactor, ifEighths = !1, ifRestrictFactor) {
  210. if (!number) return "";
  211. var s = this.getMostRelevantMeasurement(domain, system || this.UnitService.currentSystem, number, minFactor, ifRestrictFactor);
  212. return this.getFormattedMeasurementString(s[0], s[1], precision, ifEighths)
  213. }
  214. convertBack(number, domain, precision = 2, fromSystem, minFactor ) { //从英制转到'metric'
  215. if (!number) return "";
  216. var d = UnitsOfMeasurement.getDefaultUnitByDomainAndSystem(domain,'metric')
  217. var s = this.getMostRelevantMeasurement2(domain, fromSystem, number, minFactor);
  218. return this.getFormattedMeasurementString(s[0], d, precision )
  219. /* 栗子:
  220. viewer.unitConvert.convertBack(1, 'area', 5, 'imperial')
  221. '0.09290 m²'
  222. viewer.unitConvert.convertBack(1, 'Distance', 2, 'imperial')
  223. '0.03 m'
  224. */
  225. }
  226. getFormattedMeasurementString(number, unit, precision, ifEighths) {
  227. var result
  228. if(ifEighths && unit.name === UnitsOfMeasurement.FOOT[0]){
  229. result = this.formatImperialDistance(number * FEET_TO_INCHES_FACTOR)
  230. }else if(ifEighths && unit.name === UnitsOfMeasurement.INCH[0]){
  231. result = this.formatImperialDistance(number)
  232. }else{
  233. result = number.toLocaleString(void 0, {
  234. minimumFractionDigits: precision,
  235. maximumFractionDigits: precision
  236. }) + " " + unit.symbol
  237. }
  238. return result
  239. }
  240. formatImperialDistance(e) {
  241. var n = Math.round(8 * e)
  242. , i = Math.floor(n / 8)
  243. , r = Math.floor(i / FEET_TO_INCHES_FACTOR)
  244. , o = i - r * FEET_TO_INCHES_FACTOR
  245. , a = EIGHTHS_SYMBOLS[n % 8]
  246. , s = 0 === o && "" !== a ? "" : o;
  247. "" !== s && "" !== a && (a = " " + a)
  248. return 0 !== r ? r + "' " + s + a + '"' : "" + s + a + '"'
  249. }
  250. getMostRelevantMeasurement(domain, system, number, minFactor=0, ifRestrictFactor) {
  251. /* var a = r.values(UnitsOfMeasurement.getUnitsOfMeasurementByDomainAndSystem(domain, system))
  252. , s = r.filter(a, function(t) {
  253. return t.factor >= i
  254. })
  255. , c = r.reduce(s, function(t, e) {
  256. return e.fromBase(number) < t.fromBase(number) && e.fromBase(number) >= 1 ? e : t
  257. }); */
  258. let a = []
  259. let u = UnitsOfMeasurement.getUnitsOfMeasurementByDomainAndSystem(domain, system)
  260. for(let i in u){a.push(u[i])}
  261. let s
  262. if(ifRestrictFactor){//是否只用这一单位,如只用mm。如果不是,就会寻找最大的接近的单位,如设置最小为mmminFactor=0.001),则1.2米时是'1.2m'、0.2米时是'20cm'、0.002米时是'2mm'
  263. s = a.filter(m=>m.factor == minFactor)
  264. }else{
  265. s = a.filter(m=>m.factor >= minFactor)
  266. }
  267. let c = s.reduce(function(prev, currentValue) {//reduce最终值是最后一次return的值 ( 没看懂这句话作用)
  268. return currentValue.fromBase(number) < prev.fromBase(number) && currentValue.fromBase(number) >= 1 ? currentValue : prev
  269. })
  270. return c ? [c.fromBase(number), c] : void 0
  271. }
  272. getMostRelevantMeasurement2(domain, system, number, minFactor=0) {//add
  273. let a = []
  274. let u = UnitsOfMeasurement.getUnitsOfMeasurementByDomainAndSystem(domain, system)
  275. for(let i in u){a.push(u[i])}
  276. let s = a.filter(m=>m.factor >= minFactor)
  277. let c = s.reduce(function(prev, currentValue) {//reduce最终值是最后一次return的值 ( 没看懂这句话作用)
  278. return currentValue.toBase(number) < prev.toBase(number) && currentValue.toBase(number) >= 1 ? currentValue : prev
  279. })
  280. return c ? [c.toBase(number), c] : void 0
  281. }
  282. /* ɵfac(e){
  283. return new (e || t)(c.ɵɵinject(l.UnitService))
  284. }
  285. ɵprov = c.ɵɵdefineInjectable({
  286. token: t,
  287. factory: t.ɵfac,
  288. providedIn: "root"
  289. }) */
  290. }
  291. /*
  292. 使用方法:
  293. 初始化:
  294. var unitConvert = new UoMService();
  295. 要设置的类型,两种:var unitSystem = 'metric' || 'imperial'
  296. 使用:
  297. 面积:
  298. let text = viewer.unitConvert.convert(area, 'area', void 0, unitSystem, )
  299. 长度:
  300. var text = viewer.unitConvert.convert(distance, 'distance', void 0, unitSystem, 0.1 , true)//distance要传0.1这个factor。 最后一个参数传true代表使用八分之一表示。
  301. */
  302. export {UoMService}