You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
5.6 KiB

  1. var OverpassLayer = require('overpass-layer')
  2. const { measureFrom } = require('measure-ts')
  3. const formatcoords = require('formatcoords')
  4. const settings = {
  5. coordFormat: 'FFf',
  6. coordSpacer: ', ',
  7. system: 'si',
  8. speed: 'km/h'
  9. }
  10. const distanceUnits = {
  11. si: ['cm', 'm', 'km'],
  12. imp: ['in', 'ft', 'yd', 'mi'],
  13. nautical: ['M'],
  14. m: ['m']
  15. }
  16. const areaUnits = {
  17. si: ['cm2', 'm2', 'ha', 'km2'],
  18. imp: ['in2', 'ft2', 'yd2', 'ac', 'mi2'],
  19. nautical: ['M2'],
  20. m: ['m2']
  21. }
  22. const coordsPrecisionFormats = {
  23. 'FFf': [
  24. 'DD X',
  25. 'DD MM X',
  26. 'DD MM X',
  27. 'DD MM ss0 X',
  28. 'DD MM ss1 X',
  29. 'DD MM ss2 X',
  30. 'DD MM ss3 X'
  31. ],
  32. 'Ff': [
  33. 'DD X',
  34. 'DD MM X',
  35. 'DD MM X',
  36. 'DD mm1 X',
  37. 'DD mm2 X',
  38. 'DD mm3 X',
  39. 'DD mm4 X'
  40. ],
  41. 'f': [
  42. 'DD X',
  43. 'dd1 X',
  44. 'dd2 X',
  45. 'dd3 X',
  46. 'dd4 X',
  47. 'dd5 X',
  48. 'dd6 X'
  49. ]
  50. }
  51. module.exports = {
  52. distance: value => {
  53. const measure = measureFrom.apply(this, distanceUnits[settings.system])
  54. return measure(value).toString()
  55. },
  56. height: value => {
  57. switch (settings.system) {
  58. case 'imp':
  59. return (value / 0.3048) .toFixed(0) + ' ft'
  60. case 'nautical':
  61. // not defined for nautical, use 'm' instead
  62. case 'si':
  63. case 'm':
  64. default:
  65. return value.toFixed(0) + ' m'
  66. }
  67. const measure = measureFrom.apply(this, distanceUnits[settings.system])
  68. return measure(value).toString()
  69. },
  70. area: value => {
  71. const measure = measureFrom.apply(this, areaUnits[settings.system])
  72. return measure(value).toString()
  73. },
  74. speed: value => {
  75. switch (settings.speed) {
  76. case 'm/s':
  77. return value.toFixed(0) + ' ' + lang('formatUnits:speed:m/s')
  78. case 'km/h':
  79. return (value * 3.6).toFixed(0) + ' ' + lang('formatUnits:speed:km/h')
  80. case 'mi/h':
  81. return (value * 2.236936).toFixed(0) + ' ' + lang('formatUnits:speed:mi/h')
  82. case 'kn':
  83. return (value * 1.943844).toFixed(0) + ' ' + lang('formatUnits:speed:kn')
  84. case 'ft/s':
  85. return (value * 3.280840).toFixed(0) + ' ' + lang('formatUnits:speed:ft/s')
  86. }
  87. },
  88. coord: (value, options = {}) => {
  89. let format = settings.coordFormat
  90. options.precision = 'precision' in options ? options.precision : 5
  91. let decimalPlaces = 'decimalPlaces' in options ? options.decimalPlaces : options.precision
  92. if ('precision' in options && settings.coordFormat in coordsPrecisionFormats) {
  93. if (options.precision > coordsPrecisionFormats[settings.coordFormat].length) {
  94. format = coordsPrecisionFormats[settings.coordFormat][coordsPrecisionFormats[settings.coordFormat].length - 1]
  95. } else {
  96. format = coordsPrecisionFormats[settings.coordFormat][options.precision]
  97. }
  98. }
  99. let m = format.match(/^(.*)(s|m|d)([0-9]+)(.*)$/)
  100. if (m) {
  101. format = m[1] + m[2] + m[4]
  102. decimalPlaces = parseInt(m[3])
  103. }
  104. let result = formatcoords(value).format(format, {
  105. latLonSeparator: settings.coordSpacer,
  106. decimalPlaces
  107. })
  108. result = '<a href="geo:' + value.lat.toFixed(5) + ',' + value.lng.toFixed(5) + '">' + result + '</a>'
  109. return result
  110. },
  111. settings
  112. }
  113. register_hook('options_form', def => {
  114. def.formatUnitsSystem = {
  115. 'name': lang('formatUnits:system'),
  116. 'type': 'select',
  117. 'values': {
  118. 'si': lang('formatUnits:system:si'),
  119. 'imp': lang('formatUnits:system:imp'),
  120. 'nautical': lang('formatUnits:system:nautical'),
  121. 'm': lang('formatUnits:system:m'),
  122. },
  123. 'default': settings.system
  124. }
  125. def.formatUnitsCoordFormat = {
  126. 'name': lang('formatUnits:coordFormat'),
  127. 'desc': 'A format definition as specified in <a target="_blank" href="https://github.com/nerik/formatcoords">module formatCoords</a>',
  128. 'type': 'select_other',
  129. 'values': {
  130. 'FFf': 'DD° MM′ SS.SSS″ X',
  131. 'Ff': 'DD° MM.MMM′ X',
  132. 'f': 'DD.DDD° X',
  133. '-d': '±DD.DDD'
  134. },
  135. 'default': settings.coordFormat
  136. }
  137. def.formatUnitsCoordSpacer = {
  138. 'name': lang('formatUnits:coordSpacer'),
  139. 'type': 'select_other',
  140. 'values': {
  141. ' ': 'Space',
  142. ', ': 'Colon'
  143. },
  144. 'default': settings.coordSpacer
  145. }
  146. def.formatUnitsSpeed = {
  147. 'name': lang('formatUnits:speed'),
  148. 'type': 'select',
  149. 'values': {
  150. 'km/h': lang('formatUnits:speed:km/h'),
  151. 'mi/h': lang('formatUnits:speed:mi/h'),
  152. 'm/s': lang('formatUnits:speed:m/s'),
  153. 'kn': lang('formatUnits:speed:kn'),
  154. 'ft/s': lang('formatUnits:speed:ft/s')
  155. },
  156. 'default': settings.speed
  157. }
  158. })
  159. register_hook('options_orig_data', data => {
  160. data.formatUnitsSystem = settings.system
  161. data.formatUnitsCoordFormat = settings.coordFormat
  162. data.formatUnitsCoordSpacer = settings.coordSpacer
  163. data.formatUnitsSpeed = settings.speed
  164. })
  165. register_hook('options_save', data => {
  166. let old = JSON.stringify(settings)
  167. settings.coordFormat = data.formatUnitsCoordFormat
  168. settings.coordSpacer = data.formatUnitsCoordSpacer
  169. settings.system = data.formatUnitsSystem
  170. settings.speed = data.formatUnitsSpeed
  171. if (old !== JSON.stringify(settings)) {
  172. call_hooks('format-units-refresh')
  173. }
  174. })
  175. register_hook('init', () => {
  176. let old = JSON.stringify(settings)
  177. settings.coordFormat = global.options.formatUnitsCoordFormat || settings.coordFormat
  178. settings.coordSpacer = global.options.formatUnitsCoordSpacer || settings.coordSpacer
  179. settings.system = global.options.formatUnitsSystem || settings.system
  180. settings.speed = global.options.formatUnitsSpeed || settings.speed
  181. if (old !== JSON.stringify(settings)) {
  182. call_hooks('format-units-refresh')
  183. }
  184. })
  185. OverpassLayer.twig.extendFunction('formatDistance', function () {
  186. return module.exports.distance.call(this, arguments[0])
  187. })