qwc2 2025.10.9 → 2025.10.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/actions/display.js +30 -1
  2. package/actions/editing.js +22 -1
  3. package/actions/layerinfo.js +13 -1
  4. package/actions/layers.js +213 -3
  5. package/actions/localConfig.js +58 -1
  6. package/actions/locale.js +21 -1
  7. package/actions/locate.js +26 -1
  8. package/actions/logging.js +10 -1
  9. package/actions/map.js +105 -2
  10. package/actions/measurement.js +12 -1
  11. package/actions/processNotifications.js +37 -1
  12. package/actions/redlining.js +18 -1
  13. package/actions/redliningPick.js +12 -1
  14. package/actions/search.js +12 -1
  15. package/actions/serviceinfo.js +12 -1
  16. package/actions/task.js +55 -3
  17. package/actions/theme.js +339 -19
  18. package/actions/windows.js +164 -5
  19. package/components/AppMenu.js +435 -3
  20. package/components/AttributeForm.js +928 -32
  21. package/components/AttributeTableWidget.js +1105 -13
  22. package/components/AutoEditForm.js +189 -3
  23. package/components/CoordinateDisplayer.js +78 -2
  24. package/components/EditComboField.js +190 -6
  25. package/components/EditUploadField.js +315 -3
  26. package/components/ExportSelection.js +203 -2
  27. package/components/FullscreenSwitcher.js +90 -3
  28. package/components/Icon.js +81 -2
  29. package/components/IdentifyViewer.js +1161 -6
  30. package/components/ImportLayer.js +718 -20
  31. package/components/LayerInfoWindow.js +145 -2
  32. package/components/LinkFeatureForm.js +246 -5
  33. package/components/MapButton.js +88 -2
  34. package/components/MapSelection.js +287 -8
  35. package/components/MessageBar.js +68 -2
  36. package/components/NumericInputWindow.js +359 -2
  37. package/components/PickFeature.js +266 -2
  38. package/components/PluginsContainer.js +227 -8
  39. package/components/PrintSelection.js +620 -49
  40. package/components/ProcessNotifications.js +104 -2
  41. package/components/QtDesignerForm.js +1137 -18
  42. package/components/ResizeableWindow.js +591 -8
  43. package/components/SearchBox.js +1307 -20
  44. package/components/ServiceInfoWindow.js +107 -2
  45. package/components/SideBar.js +204 -4
  46. package/components/StandardApp.js +381 -20
  47. package/components/Swipeable.js +15 -1
  48. package/components/TaskBar.js +85 -2
  49. package/components/ThemeLayersListWindow.js +216 -4
  50. package/components/ThemeList.js +381 -7
  51. package/components/Toolbar.js +106 -2
  52. package/components/WindowManager.js +178 -2
  53. package/components/map/OlLayer.js +257 -6
  54. package/components/map/OlMap.js +405 -5
  55. package/components/map/layers/BingLayer.js +31 -2
  56. package/components/map/layers/GoogleLayer.js +222 -19
  57. package/components/map/layers/GraticuleLayer.js +21 -1
  58. package/components/map/layers/ImageLayer.js +15 -1
  59. package/components/map/layers/MVTLayer.js +52 -2
  60. package/components/map/layers/OSMLayer.js +24 -2
  61. package/components/map/layers/OverlayLayer.js +55 -3
  62. package/components/map/layers/VectorLayer.js +173 -8
  63. package/components/map/layers/WFSLayer.js +220 -6
  64. package/components/map/layers/WMSLayer.js +180 -6
  65. package/components/map/layers/WMTSLayer.js +67 -3
  66. package/components/map/layers/XYZLayer.js +24 -2
  67. package/components/map/layers/index.js +28 -1
  68. package/components/map3d/EditDataset3D.js +190 -3
  69. package/components/map3d/HeightProfile3D.js +402 -3
  70. package/components/map3d/ImportObjects3D.js +162 -2
  71. package/components/map3d/Map3D.js +1304 -38
  72. package/components/map3d/MapControls3D.js +392 -7
  73. package/components/map3d/SearchField3D.js +183 -11
  74. package/components/map3d/View3DSwitcher.js +98 -2
  75. package/components/map3d/drawtool/CreateTool3D.js +174 -4
  76. package/components/map3d/drawtool/EditTool3D.js +590 -6
  77. package/components/map3d/drawtool/NumericInput3D.js +336 -4
  78. package/components/map3d/layers/GeoTIFFLayer3D.js +15 -1
  79. package/components/map3d/layers/VectorLayer3D.js +53 -2
  80. package/components/map3d/layers/WFSLayer3D.js +109 -3
  81. package/components/map3d/layers/WMSLayer3D.js +70 -2
  82. package/components/map3d/layers/WMTSLayer3D.js +27 -3
  83. package/components/map3d/layers/index.js +14 -1
  84. package/components/map3d/utils/FirstPersonControls3D.js +423 -16
  85. package/components/map3d/utils/MiscUtils3D.js +221 -13
  86. package/components/map3d/utils/OrbitControls3D.js +176 -5
  87. package/components/map3d/utils/Tiles3DStyle.js +238 -9
  88. package/components/share/ShareLink.js +54 -2
  89. package/components/share/ShareQRCode.js +62 -2
  90. package/components/share/ShareSocials.js +125 -3
  91. package/components/timeline/FixedTimeline.js +236 -5
  92. package/components/timeline/InfiniteTimeline.js +347 -8
  93. package/components/timeline/TimelineFeaturesSlider.js +439 -5
  94. package/components/widgets/AccordeonWidget.js +96 -2
  95. package/components/widgets/ButtonBar.js +124 -2
  96. package/components/widgets/ColorButton.js +201 -3
  97. package/components/widgets/ComboBox.js +166 -2
  98. package/components/widgets/CopyButton.js +110 -2
  99. package/components/widgets/DateTimeInput.js +100 -3
  100. package/components/widgets/EditableSelect.js +230 -3
  101. package/components/widgets/FileSelector.js +128 -4
  102. package/components/widgets/Input.js +124 -2
  103. package/components/widgets/InputContainer.js +96 -2
  104. package/components/widgets/LayerCatalogWidget.js +219 -3
  105. package/components/widgets/MenuButton.js +157 -1
  106. package/components/widgets/ModalDialog.js +64 -2
  107. package/components/widgets/NavBar.js +119 -2
  108. package/components/widgets/NumberInput.js +226 -4
  109. package/components/widgets/PopupMenu.js +72 -1
  110. package/components/widgets/Primitives.js +6 -1
  111. package/components/widgets/ReCaptchaWidget.js +55 -1
  112. package/components/widgets/SearchWidget.js +255 -2
  113. package/components/widgets/Spinner.js +44 -2
  114. package/components/widgets/SuggestionInput.js +77 -2
  115. package/components/widgets/TextInput.js +308 -2
  116. package/components/widgets/ToggleSwitch.js +85 -2
  117. package/components/widgets/VectorLayerPicker.js +85 -3
  118. package/libs/openlayers.js +225 -5
  119. package/package.json +1 -1
  120. package/plugins/API.js +358 -15
  121. package/plugins/AttributeTable.js +109 -3
  122. package/plugins/Authentication.js +130 -5
  123. package/plugins/BackgroundSwitcher.js +218 -4
  124. package/plugins/Bookmark.js +289 -3
  125. package/plugins/BottomBar.js +298 -4
  126. package/plugins/CookiePopup.js +67 -3
  127. package/plugins/Cyclomedia.js +442 -5
  128. package/plugins/Editing.js +497 -9
  129. package/plugins/FeatureForm.js +366 -4
  130. package/plugins/FeatureSearch.js +458 -3
  131. package/plugins/GeometryDigitizer.js +664 -7
  132. package/plugins/HeightProfile.js +763 -15
  133. package/plugins/Help.js +102 -3
  134. package/plugins/HomeButton.js +80 -3
  135. package/plugins/Identify.js +543 -5
  136. package/plugins/LayerCatalog.js +215 -4
  137. package/plugins/LayerTree.js +1194 -6
  138. package/plugins/LocateButton.js +94 -3
  139. package/plugins/Map.js +320 -16
  140. package/plugins/MapCompare.js +94 -3
  141. package/plugins/MapCopyright.js +127 -5
  142. package/plugins/MapExport.js +613 -20
  143. package/plugins/MapFilter.js +868 -12
  144. package/plugins/MapInfoTooltip.js +277 -3
  145. package/plugins/MapLegend.js +253 -4
  146. package/plugins/MapTip.js +290 -4
  147. package/plugins/Measure.js +220 -4
  148. package/plugins/NewsPopup.js +137 -3
  149. package/plugins/OverviewMap.js +167 -7
  150. package/plugins/Panoramax.js +340 -2
  151. package/plugins/Portal.js +199 -4
  152. package/plugins/Print.js +1231 -15
  153. package/plugins/Redlining.js +750 -6
  154. package/plugins/Reports.js +332 -3
  155. package/plugins/Routing.js +1278 -15
  156. package/plugins/ScratchDrawing.js +173 -5
  157. package/plugins/Settings.js +241 -4
  158. package/plugins/Share.js +198 -3
  159. package/plugins/StartupMarker.js +84 -4
  160. package/plugins/TaskButton.js +88 -3
  161. package/plugins/ThemeSwitcher.js +164 -4
  162. package/plugins/TimeManager.js +971 -10
  163. package/plugins/TopBar.js +300 -7
  164. package/plugins/TourGuide.js +213 -2
  165. package/plugins/ValueTool.js +419 -4
  166. package/plugins/View3D.js +519 -14
  167. package/plugins/ZoomButtons.js +165 -3
  168. package/plugins/map/EditingSupport.js +199 -7
  169. package/plugins/map/LocateSupport.js +260 -4
  170. package/plugins/map/MeasurementSupport.js +216 -8
  171. package/plugins/map/RedliningPickSupport.js +201 -7
  172. package/plugins/map/RedliningSupport.js +726 -17
  173. package/plugins/map/SnapInteraction.js +101 -1
  174. package/plugins/map/SnapSupport.js +210 -2
  175. package/plugins/map/SnappingSupport.js +356 -17
  176. package/plugins/map3d/BackgroundSwitcher3D.js +44 -3
  177. package/plugins/map3d/BottomBar3D.js +118 -3
  178. package/plugins/map3d/Compare3D.js +422 -8
  179. package/plugins/map3d/Draw3D.js +353 -6
  180. package/plugins/map3d/ExportObjects3D.js +393 -18
  181. package/plugins/map3d/HideObjects3D.js +313 -12
  182. package/plugins/map3d/Identify3D.js +283 -12
  183. package/plugins/map3d/LayerTree3D.js +323 -3
  184. package/plugins/map3d/MapCopyright3D.js +128 -5
  185. package/plugins/map3d/MapExport3D.js +590 -10
  186. package/plugins/map3d/MapLight3D.js +553 -6
  187. package/plugins/map3d/Measure3D.js +571 -20
  188. package/plugins/map3d/OverviewMap3D.js +169 -3
  189. package/plugins/map3d/Settings3D.js +73 -3
  190. package/plugins/map3d/TopBar3D.js +207 -9
  191. package/plugins/redlining/RedliningBufferSupport.js +206 -3
  192. package/reducers/display.js +34 -2
  193. package/reducers/editing.js +68 -3
  194. package/reducers/index.js +9 -1
  195. package/reducers/layerinfo.js +26 -2
  196. package/reducers/layers.js +456 -9
  197. package/reducers/localConfig.js +122 -2
  198. package/reducers/locale.js +38 -2
  199. package/reducers/locate.js +40 -2
  200. package/reducers/map.js +176 -5
  201. package/reducers/measurement.js +42 -2
  202. package/reducers/processNotifications.js +49 -2
  203. package/reducers/redlining.js +50 -2
  204. package/reducers/redliningPick.js +27 -2
  205. package/reducers/search.js +20 -1
  206. package/reducers/serviceinfo.js +25 -2
  207. package/reducers/task.js +45 -2
  208. package/reducers/theme.js +51 -2
  209. package/reducers/windows.js +203 -2
  210. package/scripts/dist.sh +1 -1
  211. package/scripts/gen-plugin-docs.js +152 -2
  212. package/scripts/makeIconkit.js +85 -6
  213. package/scripts/themesConfig.js +742 -40
  214. package/scripts/updateTranslations.js +251 -10
  215. package/selectors/searchproviders.js +44 -2
  216. package/stores/StandardStore.js +42 -2
  217. package/utils/ConfigUtils.js +84 -3
  218. package/utils/CoordinatesUtils.js +234 -23
  219. package/utils/DxfUtils.js +237 -11
  220. package/utils/EditingInterface.js +421 -87
  221. package/utils/EditingUtils.js +357 -13
  222. package/utils/ElevationInterface.js +83 -22
  223. package/utils/FeatureStyles.js +429 -5
  224. package/utils/IdentifyUtils.js +443 -7
  225. package/utils/ImageEditor.js +79 -9
  226. package/utils/LayerUtils.js +1516 -50
  227. package/utils/LocaleUtils.js +117 -7
  228. package/utils/MapUtils.js +241 -59
  229. package/utils/MeasureUtils.js +323 -2
  230. package/utils/MiscUtils.js +189 -11
  231. package/utils/PermaLinkUtils.js +429 -6
  232. package/utils/PluginStore.js +27 -1
  233. package/utils/ResourceRegistry.js +15 -1
  234. package/utils/RoutingInterface.js +307 -7
  235. package/utils/SearchProviders.js +722 -19
  236. package/utils/ServiceLayerUtils.js +669 -14
  237. package/utils/Signal.js +32 -2
  238. package/utils/ThemeUtils.js +341 -7
  239. package/utils/VectorLayerUtils.js +589 -15
  240. package/utils/expr_grammar/grammar.js +2239 -2
  241. package/utils/expr_grammar/test.js +65 -3
@@ -1,23 +1,1286 @@
1
- function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},_typeof(o)}function _toConsumableArray(r){return _arrayWithoutHoles(r)||_iterableToArray(r)||_unsupportedIterableToArray(r)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0}}function _iterableToArray(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}function _arrayWithoutHoles(r){if(Array.isArray(r))return _arrayLikeToArray(r)}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n}function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable})),t.push.apply(t,o)}return t}function _objectSpread(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?ownKeys(Object(t),!0).forEach(function(r){_defineProperty(e,r,t[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ownKeys(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})}return e}function _classCallCheck(a,n){if(!(a instanceof n))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var o=r[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,_toPropertyKey(o.key),o)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _callSuper(t,o,e){return o=_getPrototypeOf(o),_possibleConstructorReturn(t,_isNativeReflectConstruct()?Reflect.construct(o,e||[],_getPrototypeOf(t).constructor):o.apply(t,e))}function _possibleConstructorReturn(t,e){if(e&&("object"==_typeof(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return _assertThisInitialized(t)}function _assertThisInitialized(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _isNativeReflectConstruct(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(_isNativeReflectConstruct=function _isNativeReflectConstruct(){return!!t})()}function _getPrototypeOf(t){return _getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},_getPrototypeOf(t)}function _inherits(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&_setPrototypeOf(t,e)}function _setPrototypeOf(t,e){return _setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},_setPrototypeOf(t,e)}function _defineProperty(e,r,t){return(r=_toPropertyKey(r))in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:i+""}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===r?String:Number)(t)}/**
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
3
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
5
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
6
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
7
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
8
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
10
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
11
+ function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
12
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
13
+ function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
14
+ function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
15
+ function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
16
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
17
+ function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
18
+ function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
19
+ function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
20
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
21
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
22
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
23
+ /**
2
24
  * Copyright 2024 Sourcepole AG
3
25
  * All rights reserved.
4
26
  *
5
27
  * This source code is licensed under the BSD-style license found in the
6
28
  * LICENSE file in the root directory of this source tree.
7
- */import React from"react";import{connect}from"react-redux";import Sortable from"react-sortablejs";import FileSaver from"file-saver";import PropTypes from"prop-types";import{createSelector}from"reselect";import{v4 as uuidv4}from"uuid";import{LayerRole,addLayerFeatures,removeLayer}from"../actions/layers";import{zoomToExtent}from"../actions/map";import{setCurrentTask}from"../actions/task";import Icon from"../components/Icon";import ResizeableWindow from"../components/ResizeableWindow";import ButtonBar from"../components/widgets/ButtonBar";import DateTimeInput from"../components/widgets/DateTimeInput";import NumberInput from"../components/widgets/NumberInput";import SearchWidget from"../components/widgets/SearchWidget";import Spinner from"../components/widgets/Spinner";import ToggleSwitch from"../components/widgets/ToggleSwitch";import VectorLayerPicker from"../components/widgets/VectorLayerPicker";import searchProvidersSelector from"../selectors/searchproviders";import ConfigUtils from"../utils/ConfigUtils";import CoordinatesUtils from"../utils/CoordinatesUtils";import LocaleUtils from"../utils/LocaleUtils";import MeasureUtils from"../utils/MeasureUtils";import RoutingInterface from"../utils/RoutingInterface";import VectorLayerUtils from"../utils/VectorLayerUtils";import"./style/Routing.css";/**
29
+ */
30
+
31
+ import React from 'react';
32
+ import { connect } from 'react-redux';
33
+ import Sortable from 'react-sortablejs';
34
+ import FileSaver from 'file-saver';
35
+ import PropTypes from 'prop-types';
36
+ import { createSelector } from 'reselect';
37
+ import { v4 as uuidv4 } from 'uuid';
38
+ import { LayerRole, addLayerFeatures, removeLayer } from '../actions/layers';
39
+ import { zoomToExtent } from '../actions/map';
40
+ import { setCurrentTask } from '../actions/task';
41
+ import Icon from '../components/Icon';
42
+ import ResizeableWindow from '../components/ResizeableWindow';
43
+ import ButtonBar from '../components/widgets/ButtonBar';
44
+ import DateTimeInput from '../components/widgets/DateTimeInput';
45
+ import NumberInput from '../components/widgets/NumberInput';
46
+ import SearchWidget from '../components/widgets/SearchWidget';
47
+ import Spinner from '../components/widgets/Spinner';
48
+ import ToggleSwitch from '../components/widgets/ToggleSwitch';
49
+ import VectorLayerPicker from '../components/widgets/VectorLayerPicker';
50
+ import searchProvidersSelector from '../selectors/searchproviders';
51
+ import ConfigUtils from '../utils/ConfigUtils';
52
+ import CoordinatesUtils from '../utils/CoordinatesUtils';
53
+ import LocaleUtils from '../utils/LocaleUtils';
54
+ import MeasureUtils from '../utils/MeasureUtils';
55
+ import RoutingInterface from '../utils/RoutingInterface';
56
+ import VectorLayerUtils from '../utils/VectorLayerUtils';
57
+ import './style/Routing.css';
58
+
59
+ /**
8
60
  * Compute routes and isochrones.
9
61
  *
10
62
  * Requires `routingServiceUrl` in `config.json` pointing to a Valhalla routing service.
11
- */var Routing=/*#__PURE__*/function(_React$Component){function Routing(props){var _this;_classCallCheck(this,Routing);_this=_callSuper(this,Routing,[props]);_defineProperty(_this,"state",{visible:false,currentTab:"Route",mode:"auto",settings:{auto:{method:"fastest",maxSpeed:130,useFerries:true,useHighways:true,useTollways:true},heavyvehicle:{method:"fastest",maxSpeed:100,useFerries:true,useHighways:true,useTollways:true},transit:{timepoint:"now",time:""},bicycle:{method:"fastest",maxSpeed:25,useFerries:true},pedestrian:{method:"fastest",maxSpeed:4,useFerries:true}},settingsPopup:false,routeConfig:{points:[{text:"",pos:null,crs:null},{text:"",pos:null,crs:null}],result:null,roundtrip:false,optimized_route:false,excludeLayer:null},isoConfig:{points:[{text:"",pos:null,crs:null}],mode:"time",units:{time:"min",distance:"km"},intervals:"5, 10",result:null},searchProviders:[],searchParams:{},highlightId:null});_defineProperty(_this,"renderSettings",function(){var settings=_this.state.settings[_this.state.mode];return/*#__PURE__*/React.createElement("div",{className:"routing-settings-menu"},/*#__PURE__*/React.createElement("table",{className:"routing-settings-menu-entries"},/*#__PURE__*/React.createElement("tbody",null,settings.method!==undefined?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("routing.method"),":"),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.updateSetting(_this.state.mode,{method:ev.target.value})},value:settings.method},/*#__PURE__*/React.createElement("option",{value:"fastest"},LocaleUtils.tr("routing.fastest")),/*#__PURE__*/React.createElement("option",{value:"shortest"},LocaleUtils.tr("routing.shortest"))))):null,settings.maxSpeed!==undefined?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("routing.maxspeed"),":"),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement(NumberInput,{max:350,min:1,mobile:true,onChange:function onChange(value){return _this.updateSetting(_this.state.mode,{maxSpeed:value})},suffix:" km/h",value:settings.maxSpeed}))):null,settings.useFerries!==undefined?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("routing.useferries"),":"),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement(ToggleSwitch,{active:settings.useFerries,onChange:function onChange(value){return _this.updateSetting(_this.state.mode,{useFerries:value})}}))):null,settings.useHighways!==undefined?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("routing.usehighways"),":"),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement(ToggleSwitch,{active:settings.useHighways,onChange:function onChange(value){return _this.updateSetting(_this.state.mode,{useHighways:value})}}))):null,settings.useTollways!==undefined?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("routing.usetollways"),":"),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement(ToggleSwitch,{active:settings.useTollways,onChange:function onChange(value){return _this.updateSetting(_this.state.mode,{useTollways:value})}}))):null)))});_defineProperty(_this,"renderRouteWidget",function(){var routeConfig=_this.state.routeConfig;var vectorLayers=_this.props.layers.filter(function(layer){return layer.type==="vector"&&layer.role===LayerRole.USERLAYER&&!layer.readonly});var numpoints=routeConfig.points.length;return/*#__PURE__*/React.createElement("div",{className:"routing-tab-widget"},/*#__PURE__*/React.createElement("div",{className:"routing-input"},/*#__PURE__*/React.createElement("div",{className:"routing-points"},/*#__PURE__*/React.createElement(Sortable,{onChange:_this.onSortChange,options:{ghostClass:"drop-ghost",delay:200}},routeConfig.points.map(function(entry,idx){var placeholder=LocaleUtils.tr("routing.addviapoint");if(idx===0){placeholder=LocaleUtils.tr("routing.fromhere")}else if(idx===routeConfig.points.length-1){placeholder=LocaleUtils.tr("routing.tohere")}return _this.renderSearchField(entry,idx,"routeConfig",idx>0&&idx<numpoints-1,placeholder)})),/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(Icon,{icon:"up-down-arrow",onClick:_this.reverseRoutePts}))),/*#__PURE__*/React.createElement("div",{className:"routing-points-commands"},/*#__PURE__*/React.createElement("a",{href:"#",onClick:function onClick(){return _this.addPoint("routeConfig",-1)}},/*#__PURE__*/React.createElement(Icon,{icon:"plus"})," ",LocaleUtils.tr("routing.add")),/*#__PURE__*/React.createElement("span",{className:"routing-points-commands-spacer"}),_this.renderImportButton("routeConfig"),/*#__PURE__*/React.createElement("span",{className:"routing-points-commands-spacer"}),/*#__PURE__*/React.createElement("a",{href:"#",onClick:function onClick(){return _this.clearConfig("routeConfig")}},/*#__PURE__*/React.createElement(Icon,{icon:"clear"})," ",LocaleUtils.tr("routing.clear"))),_this.state.mode==="transit"?/*#__PURE__*/React.createElement("div",{className:"routing-time-settings"},/*#__PURE__*/React.createElement("select",{onChange:_this.updateTransitTimepoint,value:_this.state.settings.transit.timepoint},/*#__PURE__*/React.createElement("option",{value:"now"},LocaleUtils.tr("routing.leavenow")),/*#__PURE__*/React.createElement("option",{value:"leaveat"},LocaleUtils.tr("routing.leaveat")),/*#__PURE__*/React.createElement("option",{value:"arriveat"},LocaleUtils.tr("routing.arriveat"))),_this.state.settings.transit.timepoint!=="now"?/*#__PURE__*/React.createElement(DateTimeInput,{onChange:function onChange(value){return _this.updateSetting("transit",{time:value})},value:_this.state.settings.transit.time}):null):null,/*#__PURE__*/React.createElement("div",{className:"routing-points-commands"},/*#__PURE__*/React.createElement("label",null,/*#__PURE__*/React.createElement("input",{onChange:function onChange(ev){return _this.updateRouteConfig({roundtrip:ev.target.checked})},type:"checkbox",value:routeConfig.roundtrip})," ",LocaleUtils.tr("routing.roundtrip"))),_this.state.mode!=="transit"?/*#__PURE__*/React.createElement("div",{className:"routing-points-commands"},/*#__PURE__*/React.createElement("label",null,/*#__PURE__*/React.createElement("input",{onChange:function onChange(ev){return _this.updateRouteConfig({optimized_route:ev.target.checked})},type:"checkbox",value:routeConfig.optimized_route})," ",LocaleUtils.tr("routing.optimized_route"))):null,ConfigUtils.havePlugin("Redlining")?/*#__PURE__*/React.createElement("div",{className:"routing-points-commands controlgroup"},/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("routing.excludepolygons"),":\xA0"),/*#__PURE__*/React.createElement(VectorLayerPicker,{layers:vectorLayers,onChange:function onChange(layer){return _this.updateRouteConfig({excludeLayer:(layer||{}).id})},showNone:true,value:routeConfig.excludeLayer||""}),/*#__PURE__*/React.createElement("button",{className:"button",onClick:_this.setRedliningTool},/*#__PURE__*/React.createElement(Icon,{icon:"draw"}))):null),routeConfig.busy?/*#__PURE__*/React.createElement("div",{className:"routing-busy"},/*#__PURE__*/React.createElement(Spinner,null)," ",LocaleUtils.tr("routing.computing")):null,routeConfig.result?_this.renderRouteResult(routeConfig):null)});_defineProperty(_this,"updateTransitTimepoint",function(ev){var diff={timepoint:ev.target.value};if(ev.target.value!=="now"&&_this.state.settings.transit.timepoint==="now"){var tzoffset=new Date().getTimezoneOffset()*60000;diff.time=new Date(Date.now()-tzoffset).toISOString().slice(0,-1)}_this.updateSetting("transit",diff)});_defineProperty(_this,"setRedliningTool",function(){_this.props.setCurrentTask("Redlining",null,null,{layerId:_this.state.routeConfig.excludeLayer})});_defineProperty(_this,"renderRouteResult",function(routeConfig){if(routeConfig.result.success===false){return/*#__PURE__*/React.createElement("div",{className:"routing-status-failure"},routeConfig.result.data.errorMsgId?LocaleUtils.tr(routeConfig.result.data.errorMsgId):routeConfig.result.data.error)}else{return/*#__PURE__*/React.createElement("div",{className:"routing-result"},/*#__PURE__*/React.createElement("div",{className:"routing-result-summary"},/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement(Icon,{icon:"clock"})," ",MeasureUtils.formatDuration(routeConfig.result.data.summary.time)),/*#__PURE__*/React.createElement("span",{className:"routing-result-spacer"}),/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement(Icon,{icon:"measure"})," ",MeasureUtils.formatMeasurement(routeConfig.result.data.summary.length,false)),/*#__PURE__*/React.createElement("span",{className:"routing-result-spacer"}),/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement(Icon,{icon:"export"})," ",/*#__PURE__*/React.createElement("a",{href:"#",onClick:_this.exportRoute},LocaleUtils.tr("routing.export"))),/*#__PURE__*/React.createElement("span",{className:"routing-result-spacer"}),/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement(Icon,{icon:"layers"})," ",/*#__PURE__*/React.createElement("a",{href:"#",onClick:_this.addRouteLayer},LocaleUtils.tr("routing.addlayer")))),/*#__PURE__*/React.createElement("div",{className:"routing-result-instructions"},routeConfig.result.data.legs.map(function(leg,lidx){return leg.maneuvers.map(function(entry,eidx){return/*#__PURE__*/React.createElement("div",{className:"routing-result-instruction",key:"instr"+lidx+":"+eidx,onMouseEnter:function onMouseEnter(){return _this.highlightRouteSection(lidx+":"+eidx,entry,leg)},onMouseLeave:function onMouseLeave(){return _this.clearRouteSectionHighlight(lidx+":"+eidx)}},/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(Icon,{icon:entry.icon}),/*#__PURE__*/React.createElement("b",null,entry.instruction)),/*#__PURE__*/React.createElement("div",{className:"routing-result-instruction-summary"},/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement(Icon,{icon:"clock"})," ",MeasureUtils.formatDuration(entry.time)),/*#__PURE__*/React.createElement("span",{className:"routing-result-spacer"}),/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement(Icon,{icon:"measure"})," ",MeasureUtils.formatMeasurement(entry.length,false))))})})))}});_defineProperty(_this,"highlightRouteSection",function(id,entry,leg){_this.setState({highlightId:id});var feature={type:"Feature",crs:"EPSG:4326",geometry:{type:"LineString",coordinates:leg.coordinates.slice(entry.geom_indices[0],entry.geom_indices[1]+1)}};var sellayer={id:"routingselection",role:LayerRole.SELECTION,styleOptions:{strokeWidth:3,strokeColor:[255,255,0,1],strokeDash:[]}};_this.props.addLayerFeatures(sellayer,[feature],true)});_defineProperty(_this,"clearRouteSectionHighlight",function(id){if(_this.state.highlightId===id){_this.setState({highlightId:null});_this.props.removeLayer("routingselection")}});_defineProperty(_this,"renderIsochroneWidget",function(){var isoConfig=_this.state.isoConfig;var intervalValid=!!isoConfig.intervals.match(/^\d+(,\s*\d+)*$/);return/*#__PURE__*/React.createElement("div",{className:"routing-tab-widget"},/*#__PURE__*/React.createElement("div",{className:"routing-input"},/*#__PURE__*/React.createElement("div",null,isoConfig.points.map(function(entry,idx){return _this.renderSearchField(entry,idx,"isoConfig",idx>0)})),/*#__PURE__*/React.createElement("table",{className:"routing-iso-settings"},/*#__PURE__*/React.createElement("tbody",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("routing.iso_mode"),": "),/*#__PURE__*/React.createElement("td",{colSpan:"2"},/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.updateIsoConfig({mode:ev.target.value})},value:isoConfig.mode},/*#__PURE__*/React.createElement("option",{value:"time"},LocaleUtils.tr("routing.iso_mode_time")),/*#__PURE__*/React.createElement("option",{value:"distance"},LocaleUtils.tr("routing.iso_mode_distance"))))),/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("routing.iso_intervals"),": "),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("input",{className:isoConfig.intervals&&!intervalValid?"routing-input-invalid":"",onChange:function onChange(ev){return _this.updateIsoConfig({intervals:ev.target.value})},placeholder:"5, 10, 15",type:"text",value:isoConfig.intervals})),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){_this.setState(function(state){return{isoConfig:_objectSpread(_objectSpread({},state.isoConfig),{},{units:_objectSpread(_objectSpread({},state.isoConfig.units),{},_defineProperty({},state.isoConfig.mode,ev.target.value))})}});_this.recomputeIfNeeded()},value:isoConfig.units[isoConfig.mode]},Object.keys(_this.props.units[isoConfig.mode]).map(function(unit){return/*#__PURE__*/React.createElement("option",{key:unit,value:unit},unit)})))))),/*#__PURE__*/React.createElement("div",{className:"routing-points-commands"},/*#__PURE__*/React.createElement("a",{href:"#",onClick:function onClick(){return _this.addPoint("isoConfig",isoConfig.points.length)}},/*#__PURE__*/React.createElement(Icon,{icon:"plus"})," ",LocaleUtils.tr("routing.add")),/*#__PURE__*/React.createElement("span",{className:"routing-points-commands-spacer"}),_this.renderImportButton("isoConfig"),/*#__PURE__*/React.createElement("span",{className:"routing-points-commands-spacer"}),/*#__PURE__*/React.createElement("a",{href:"#",onClick:function onClick(){return _this.clearConfig("isoConfig")}},/*#__PURE__*/React.createElement(Icon,{icon:"clear"})," ",LocaleUtils.tr("routing.clear")))),isoConfig.busy?/*#__PURE__*/React.createElement("div",{className:"routing-busy"},/*#__PURE__*/React.createElement(Spinner,null)," ",LocaleUtils.tr("routing.computing")):null,isoConfig.result?_this.renderIsochroneResult(isoConfig):null)});_defineProperty(_this,"renderIsochroneResult",function(isoConfig){if(isoConfig.result.success===false){return/*#__PURE__*/React.createElement("div",{className:"routing-status-failure"},isoConfig.result.data.errorMsgId?LocaleUtils.tr(isoConfig.result.data.errorMsgId):isoConfig.result.data.error)}else{return/*#__PURE__*/React.createElement("div",{className:"routing-result"},/*#__PURE__*/React.createElement("div",{className:"routing-result-summary"},/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement(Icon,{icon:"export"})," ",/*#__PURE__*/React.createElement("a",{href:"#",onClick:_this.exportIsochrone},LocaleUtils.tr("routing.export"))),/*#__PURE__*/React.createElement("span",{className:"routing-result-spacer"}),/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement(Icon,{icon:"layers"})," ",/*#__PURE__*/React.createElement("a",{href:"#",onClick:_this.addIsochroneLayer},LocaleUtils.tr("routing.addlayer")))))}});_defineProperty(_this,"renderSearchField",function(entry,idx,config,removeable){var placeholder=arguments.length>4&&arguments[4]!==undefined?arguments[4]:null;return/*#__PURE__*/React.createElement("div",{className:"routing-search-field controlgroup",key:"field"+idx},/*#__PURE__*/React.createElement(SearchWidget,{placeholder:placeholder,resultSelected:function resultSelected(result){return _this.searchResultSelected(config,idx,result)},role:"input",searchParams:_this.state.searchParams,searchProviders:_this.state.searchProviders,value:entry.text}),idx===0?/*#__PURE__*/React.createElement("button",{className:"button",disabled:!_this.props.locatePos,onClick:function onClick(){return _this.updatePoint(config,0,_this.locatePos())},role:"suffix"},/*#__PURE__*/React.createElement(Icon,{icon:"screenshot"})):null,removeable?/*#__PURE__*/React.createElement("button",{className:"button",onClick:function onClick(){return _this.removePoint(config,idx)},role:"suffix"},/*#__PURE__*/React.createElement(Icon,{icon:"remove"})):null)});_defineProperty(_this,"renderImportButton",function(config){return/*#__PURE__*/React.createElement("label",{className:"routing-import-button",title:LocaleUtils.tr("routing.importhint")},/*#__PURE__*/React.createElement(Icon,{icon:"import"})," ",LocaleUtils.tr("routing.importpoints"),/*#__PURE__*/React.createElement("input",{onChange:function onChange(ev){return _this.importPoints(ev,config)},type:"file"}))});_defineProperty(_this,"locatePos",function(){return{pos:_toConsumableArray(_this.props.locatePos),text:_this.props.locatePos.map(function(x){return x.toFixed(4)}).join(", "),crs:"EPSG:4326"}});_defineProperty(_this,"updateSetting",function(mode,diff){_this.setState(function(state){return{settings:_objectSpread(_objectSpread({},state.settings),{},_defineProperty({},mode,_objectSpread(_objectSpread({},state.settings[mode]),diff)))}});_this.recomputeIfNeeded()});_defineProperty(_this,"addPoint",function(config){var index=arguments.length>1&&arguments[1]!==undefined?arguments[1]:-1;var entry=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{text:"",pos:null};_this.setState(function(state){return _defineProperty({},config,_objectSpread(_objectSpread({},state[config]),{},{points:[].concat(_toConsumableArray(state[config].points.slice(0,index)),[entry],_toConsumableArray(state[config].points.slice(index)))}))});if(entry.pos){_this.recomputeIfNeeded()}});_defineProperty(_this,"updatePoint",function(config,idx,diff){_this.setState(function(state){return _defineProperty({},config,_objectSpread(_objectSpread({},state[config]),{},{points:[].concat(_toConsumableArray(state[config].points.slice(0,idx)),[_objectSpread(_objectSpread({},state[config].points[idx]),diff)],_toConsumableArray(state[config].points.slice(idx+1)))}))});_this.recomputeIfNeeded()});_defineProperty(_this,"importPoints",function(ev,config){var reader=new FileReader;reader.onload=function(loadev){try{var obj=JSON.parse(loadev.target.result);var crs="EPSG:4326";if(obj.crs&&obj.crs.properties){crs=CoordinatesUtils.fromOgcUrnCrs(obj.crs.properties.name)}var prec=CoordinatesUtils.getPrecision(crs);_this.setState(function(state){return _defineProperty({},config,_objectSpread(_objectSpread({},state[config]),{},{points:obj.features.map(function(feature){var coordinates=feature.geometry.coordinates;return{text:coordinates.map(function(x){return x.toFixed(prec)}).join(", ")+" ("+crs+")",pos:coordinates,crs:crs}})}))});_this.recomputeIfNeeded()}catch(e){// eslint-disable-next-line
12
- alert(LocaleUtils.tr("routing.importerror"))}};reader.readAsText(ev.target.files[0])});_defineProperty(_this,"removePoint",function(config,idx){_this.setState(function(state){return _defineProperty({},config,_objectSpread(_objectSpread({},state[config]),{},{points:[].concat(_toConsumableArray(state[config].points.slice(0,idx)),_toConsumableArray(state[config].points.slice(idx+1)))}))});_this.recomputeIfNeeded()});_defineProperty(_this,"clearConfig",function(config){var newPoints=config==="routeConfig"?[{text:"",pos:null,crs:null},{text:"",pos:null,crs:null}]:[{text:"",pos:null,crs:null}];_this.setState(function(state){return _defineProperty({},config,_objectSpread(_objectSpread({},state[config]),{},{points:newPoints,result:null}))});_this.props.removeLayer("routinggeometries");_this.props.removeLayer("routingmarkers");_this.recomputeIfNeeded()});_defineProperty(_this,"reverseRoutePts",function(){_this.setState(function(state){return{routeConfig:_objectSpread(_objectSpread({},state.routeConfig),{},{points:state.routeConfig.points.reverse()})}});_this.recomputeIfNeeded()});_defineProperty(_this,"updateRouteConfig",function(diff){var recompute=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;_this.setState(function(state){return{routeConfig:_objectSpread(_objectSpread({},state.routeConfig),diff)}});if(recompute){_this.recomputeIfNeeded()}});_defineProperty(_this,"updateIsoConfig",function(diff){var recompute=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;_this.setState(function(state){return{isoConfig:_objectSpread(_objectSpread({},state.isoConfig),diff)}});if(recompute){_this.recomputeIfNeeded()}});_defineProperty(_this,"searchResultSelected",function(config,idx,result){if(result){_this.updatePoint(config,idx,{text:result.text,pos:[result.x,result.y],crs:result.crs})}else{_this.updatePoint(config,idx,{text:"",pos:null,crs:null})}});_defineProperty(_this,"updateRoutingMarkers",function(){var points=[];if(_this.state.currentTab==="Route"){points=_this.state.routeConfig.points}else{points=_this.state.isoConfig.points}var layer={id:"routingmarkers",role:LayerRole.MARKER,styleName:"marker"};var features=points.filter(function(point){return point.pos}).map(function(point,idx){return{type:"Feature",crs:point.crs,geometry:{type:"Point",coordinates:point.pos},properties:{label:_this.props.showPinLabels&&_this.state.routeConfig.result?String(idx+1):null}}});_this.props.addLayerFeatures(layer,features,true)});_defineProperty(_this,"computeRoute",function(){var locations=_this.state.routeConfig.points.filter(function(entry){return entry.pos}).map(function(entry){return CoordinatesUtils.reproject(entry.pos,entry.crs,"EPSG:4326")});_this.props.removeLayer("routinggeometries");_this.updateRouteConfig({busy:locations.length>=2,result:null},false);if(locations.length<2){return}if(_this.state.routeConfig.roundtrip){locations.push(locations[0])}var settings=_objectSpread({},_this.state.settings[_this.state.mode]);if(_this.state.routeConfig.excludeLayer){var layer=_this.props.layers.find(function(l){return l.id===_this.state.routeConfig.excludeLayer});if(layer){settings.exclude_polygons=layer.features.filter(function(feature){return feature.geometry.type==="Polygon"}).map(function(feature){return VectorLayerUtils.reprojectGeometry(feature.geometry,_this.props.mapCrs,"EPSG:4326").coordinates[0]})}}settings.optimized_route=_this.state.routeConfig.optimized_route;RoutingInterface.computeRoute(_this.state.mode,locations,settings,function(success,result){if(success){// Add routing leg geometries
13
- var _layer={id:"routinggeometries",role:LayerRole.SELECTION,styleName:"default",styleOptions:{strokeColor:[10,10,255,1],strokeWidth:4,strokeDash:[]}};var features=[];result.legs.forEach(function(leg){leg.maneuvers.forEach(function(man){features.push({type:"Feature",crs:"EPSG:4326",styleOptions:{strokeColor:man.color},geometry:{type:"LineString",coordinates:leg.coordinates.slice(man.geom_indices[0],man.geom_indices[1]+1)}})})});_this.props.addLayerFeatures(_layer,features,true);// Reorder locations based on routing result, keeping null entries
14
- var _this$state$routeConf=_this.state.routeConfig.points.reduce(function(res,point,idx){return point.pos?_objectSpread(_objectSpread({},res),{},{points:[].concat(_toConsumableArray(res.points),[point])}):_objectSpread(_objectSpread({},res),{},{nullPoints:[].concat(_toConsumableArray(res.nullPoints),[{point:point,idx:idx}])})},{points:[],nullPoints:[]}),points=_this$state$routeConf.points,nullPoints=_this$state$routeConf.nullPoints;var reorderedPoints=result.locations.map(function(location){return points[location.orig_idx]}).filter(Boolean);nullPoints.forEach(function(entry){reorderedPoints.splice(entry.idx,0,entry.point)});_this.updateRouteConfig({points:reorderedPoints,result:{success:success,data:result},busy:false},false);if(_this.props.zoomAuto){_this.props.zoomToExtent(result.summary.bounds,"EPSG:4326",-1)}}else{_this.updateRouteConfig({result:{success:success,data:result},busy:false},false)}})});_defineProperty(_this,"computeIsochrone",function(){var intervalValid=!!_this.state.isoConfig.intervals.match(/^\d+(,\s*\d+)*$/);if(!intervalValid){return}var locations=_this.state.isoConfig.points.filter(function(entry){return entry.pos}).map(function(entry){return CoordinatesUtils.reproject(entry.pos,entry.crs,"EPSG:4326")});_this.props.removeLayer("routinggeometries");_this.updateIsoConfig({busy:true,result:null},false);var unitsFactor=_this.props.units[_this.state.isoConfig.mode][_this.state.isoConfig.units[_this.state.isoConfig.mode]];var contourOptions={mode:_this.state.isoConfig.mode,intervals:_this.state.isoConfig.intervals.split(",").map(function(entry){return parseInt(entry.trim(),10)/unitsFactor}).sort()};RoutingInterface.computeIsochrone(_this.state.mode,locations,contourOptions,_this.state.settings[_this.state.mode],function(success,result){if(success){var layer={id:"routinggeometries",role:LayerRole.SELECTION,styleOptions:{strokeColor:[10,10,255,1],fillColor:[10,10,255,0.5],strokeWidth:4,strokeDash:[]}};var features=result.areas.map(function(area){return{type:"Feature",crs:"EPSG:4326",geometry:{type:"Polygon",coordinates:[area]}}});_this.props.addLayerFeatures(layer,features,true);if(_this.props.zoomAuto){_this.props.zoomToExtent(result.bounds,"EPSG:4326",-0.5)}}_this.updateIsoConfig({result:{success:success,data:result},busy:false},false)})});_defineProperty(_this,"recomputeIfNeeded",function(){clearTimeout(_this.recomputeTimeout);_this.recomputeTimeout=setTimeout(function(){if(_this.state.currentTab==="Route"&&_this.state.routeConfig.points.filter(function(entry){return entry.pos}).length>=2){_this.computeRoute()}else if(_this.state.currentTab==="Reachability"&&_this.state.isoConfig.points.filter(function(entry){return entry.pos}).length>0){_this.computeIsochrone()}_this.recomputeTimeout=null},750)});_defineProperty(_this,"collectRoutingFeatures",function(){return _this.state.routeConfig.result.data.legs.map(function(leg){return{type:"Feature",properties:{time:leg.time,length:leg.length},geometry:{type:"LineString",coordinates:leg.coordinates},styleName:"default",styleOptions:{strokeColor:[10,10,255,1],strokeWidth:4,strokeDash:[]}}})});_defineProperty(_this,"exportRoute",function(){var data=JSON.stringify({type:"FeatureCollection",features:_this.collectRoutingFeatures()});FileSaver.saveAs(new Blob([data],{type:"text/plain;charset=utf-8"}),"route.json")});_defineProperty(_this,"addRouteLayer",function(){var layer={id:uuidv4(),crs:"EPSG:4326",title:LocaleUtils.tr("routing.route"),type:"vector"};_this.props.addLayerFeatures(layer,_this.collectRoutingFeatures());_this.props.setCurrentTask("LayerTree")});_defineProperty(_this,"collectIsochroneFeatures",function(){return _this.state.isoConfig.result.data.areas.map(function(area){return{type:"Feature",geometry:{type:"Polygon",coordinates:[area]},styleName:"default",styleOptions:{strokeColor:[10,10,255,1],fillColor:[10,10,255,0.5],strokeWidth:4,strokeDash:[]}}})});_defineProperty(_this,"exportIsochrone",function(){var data=JSON.stringify({type:"FeatureCollection",features:_this.collectIsochroneFeatures()});FileSaver.saveAs(new Blob([data],{type:"text/plain;charset=utf-8"}),"isochrone.json")});_defineProperty(_this,"addIsochroneLayer",function(){var layer={id:uuidv4(),crs:"EPSG:4326",title:LocaleUtils.tr("routing.reachability"),type:"vector"};_this.props.addLayerFeatures(layer,[_this.collectIsochroneFeatures()]);_this.props.setCurrentTask("LayerTree")});_defineProperty(_this,"onSortChange",function(order,sortable,ev){var newpoints=_this.state.routeConfig.points.slice(0);var moved=newpoints.splice(ev.oldIndex,1)[0];newpoints.splice(ev.newIndex,0,moved);_this.updateRouteConfig({points:newpoints})});_this.recomputeTimeout=null;_this.state.mode=_this.props.enabledModes[0];return _this}_inherits(Routing,_React$Component);return _createClass(Routing,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){var _this2=this;// Recollect search providers
15
- if(this.props.searchProviders!==prevProps.searchProviders){this.setState({searchProviders:this.props.enabledProviders.map(function(key){return _this2.props.searchProviders[key]}).filter(Boolean),searchParams:{mapcrs:this.props.mapCrs,displaycrs:this.props.displayCrs}})}// Activated / message
16
- if(this.props.task.id==="Routing"){this.props.setCurrentTask(null);if(!this.state.visible){this.setState({visible:true})}var taskData=this.props.task.data||{};if(taskData.from){this.setState({currentTab:"Route"});this.updatePoint("routeConfig",0,taskData.from)}if(taskData.to){this.setState({currentTab:"Route"});this.updatePoint("routeConfig",this.state.routeConfig.points.length-1,taskData.to)}if(taskData.via){this.setState({currentTab:"Route"});this.addPoint("routeConfig",-1,taskData.via)}if(taskData.isocenter){this.setState({currentTab:"Reachability"});this.updateIsoConfig({points:[taskData.isocenter]})}if(taskData.isoextracenter){this.setState({currentTab:"Reachability"});this.updateIsoConfig({points:[].concat(_toConsumableArray(this.state.isoConfig.points),[taskData.isoextracenter])})}}// Window closed
17
- if(!this.state.visible&&prevState.visible){this.props.removeLayer("routinggeometries");this.props.removeLayer("routingmarkers");this.updateRouteConfig({points:[{text:"",pos:null,crs:null},{text:"",pos:null,crs:null}],result:null},false);this.updateIsoConfig({point:{text:"",pos:null,crs:null},result:null},false)}// No further processing beyond here if not visible
18
- if(!this.state.visible){return}// Tab changed
19
- if(this.state.currentTab!==prevState.currentTab){this.props.removeLayer("routinggeometries");this.props.removeLayer("routingmarkers");this.recomputeIfNeeded()}// Mode changed
20
- if(this.state.mode!==prevState.mode){this.recomputeIfNeeded()}// Routing markers
21
- if(this.state.currentTab!==prevState.currentTab||this.state.routeConfig.points!==prevState.routeConfig.points||this.state.isoConfig.points!==prevState.isoConfig.points){this.updateRoutingMarkers()}// Theme changed
22
- if(this.props.theme!==prevProps.theme){this.setState({visible:false})}// Recompute when exclude layer changes
23
- if(this.state.currentTab==="Route"&&this.state.routeConfig.excludeLayer&&this.props.layers!==prevProps.layers){var newlayer=this.props.layers.find(function(layer){return layer.id===_this2.state.routeConfig.excludeLayer});var prevLayer=prevProps.layers.find(function(layer){return layer.id===_this2.state.routeConfig.excludeLayer});if(newlayer!==prevLayer){this.recomputeIfNeeded()}}}},{key:"render",value:function render(){var _this3=this;if(!this.state.visible){return null}var tabButtons=[{key:"Route",label:LocaleUtils.tr("routing.route")},{key:"Reachability",label:LocaleUtils.tr("routing.reachability")}];var tabRenderers={Route:this.renderRouteWidget,Reachability:this.renderIsochroneWidget};var buttons=[{key:"auto",icon:"routing-car",tooltip:LocaleUtils.tr("routing.mode_auto")},{key:"heavyvehicle",icon:"routing-truck",tooltip:LocaleUtils.tr("routing.mode_heavyvehicle")},{key:"transit",icon:"routing-train",tooltip:LocaleUtils.tr("routing.mode_transit")},{key:"bicycle",icon:"routing-bicycle",tooltip:LocaleUtils.tr("routing.mode_bicycle")},{key:"pedestrian",icon:"routing-walking",tooltip:LocaleUtils.tr("routing.mode_walking")}];var enabledButtons=this.props.enabledModes.map(function(entry){return buttons.find(function(button){return button.key===entry})});return/*#__PURE__*/React.createElement(ResizeableWindow,{dockable:this.props.geometry.side,icon:"routing",initialHeight:this.props.geometry.initialHeight,initialWidth:this.props.geometry.initialWidth,initialX:this.props.geometry.initialX,initialY:this.props.geometry.initialY,initiallyDocked:this.props.geometry.initiallyDocked,onClose:function onClose(){return _this3.setState({visible:false})},title:LocaleUtils.tr("routing.windowtitle")},/*#__PURE__*/React.createElement("div",{className:"routing-body",role:"body"},/*#__PURE__*/React.createElement(ButtonBar,{active:this.state.currentTab,buttons:tabButtons,className:"routing-buttonbar",onClick:function onClick(key){return _this3.setState({currentTab:key})}}),/*#__PURE__*/React.createElement("div",{className:"routing-frame"},/*#__PURE__*/React.createElement("div",{className:"routing-buttons controlgroup"},/*#__PURE__*/React.createElement(ButtonBar,{active:this.state.mode,buttons:enabledButtons,onClick:function onClick(key){return _this3.setState({mode:key})}}),/*#__PURE__*/React.createElement("button",{className:"button"+(this.state.settingsPopup?" pressed":""),onClick:function onClick(){return _this3.setState(function(state){return{settingsPopup:!state.settingsPopup}})}},/*#__PURE__*/React.createElement(Icon,{icon:"cog"})),this.state.settingsPopup?this.renderSettings():null),tabRenderers[this.state.currentTab]())))}}])}(React.Component);_defineProperty(Routing,"propTypes",{addLayerFeatures:PropTypes.func,displayCrs:PropTypes.string,/** List of enabled routing modes. */enabledModes:PropTypes.arrayOf(PropTypes.string),/** List of search providers to use for routing location search. */enabledProviders:PropTypes.arrayOf(PropTypes.string),/** Default window geometry with size, position and docking status. Positive position values (including '0') are related to top (InitialY) and left (InitialX), negative values (including '-0') to bottom (InitialY) and right (InitialX). */geometry:PropTypes.shape({initialWidth:PropTypes.number,initialHeight:PropTypes.number,initialX:PropTypes.number,initialY:PropTypes.number,initiallyDocked:PropTypes.bool,side:PropTypes.string}),layers:PropTypes.array,locatePos:PropTypes.array,mapCrs:PropTypes.string,removeLayer:PropTypes.func,searchProviders:PropTypes.object,setCurrentTask:PropTypes.func,/** Whether to label the routing waypoint pins with the route point number. */showPinLabels:PropTypes.bool,task:PropTypes.object,theme:PropTypes.object,/** Set of units for isochrone time/distance intervals to use. */units:PropTypes.object,/** Automatically zoom to the extent of the route */zoomAuto:PropTypes.bool,zoomToExtent:PropTypes.func});_defineProperty(Routing,"defaultProps",{enabledModes:["auto","heavyvehicle","transit","bicycle","pedestrian"],enabledProviders:["coordinates","nominatim"],geometry:{initialWidth:480,initialHeight:640,initialX:0,initialY:0,initiallyDocked:true,side:"left"},showPinLabels:true,units:{time:{min:1,s:60},distance:{km:1,m:1000}},zoomAuto:true});export default connect(createSelector([function(state){return state},searchProvidersSelector],function(state,searchProviders){return{displayCrs:state.map.displayCrs,layers:state.layers.flat,locatePos:state.locate.position,mapCrs:state.map.projection,searchProviders:searchProviders,task:state.task,theme:state.theme.current}}),{addLayerFeatures:addLayerFeatures,removeLayer:removeLayer,setCurrentTask:setCurrentTask,zoomToExtent:zoomToExtent})(Routing);
63
+ */
64
+ var Routing = /*#__PURE__*/function (_React$Component) {
65
+ function Routing(props) {
66
+ var _this;
67
+ _classCallCheck(this, Routing);
68
+ _this = _callSuper(this, Routing, [props]);
69
+ _defineProperty(_this, "state", {
70
+ visible: false,
71
+ currentTab: 'Route',
72
+ mode: 'auto',
73
+ settings: {
74
+ auto: {
75
+ method: 'fastest',
76
+ maxSpeed: 130,
77
+ useFerries: true,
78
+ useHighways: true,
79
+ useTollways: true
80
+ },
81
+ heavyvehicle: {
82
+ method: 'fastest',
83
+ maxSpeed: 100,
84
+ useFerries: true,
85
+ useHighways: true,
86
+ useTollways: true
87
+ },
88
+ transit: {
89
+ timepoint: 'now',
90
+ time: ''
91
+ },
92
+ bicycle: {
93
+ method: 'fastest',
94
+ maxSpeed: 25,
95
+ useFerries: true
96
+ },
97
+ pedestrian: {
98
+ method: 'fastest',
99
+ maxSpeed: 4,
100
+ useFerries: true
101
+ }
102
+ },
103
+ settingsPopup: false,
104
+ routeConfig: {
105
+ points: [{
106
+ text: '',
107
+ pos: null,
108
+ crs: null
109
+ }, {
110
+ text: '',
111
+ pos: null,
112
+ crs: null
113
+ }],
114
+ result: null,
115
+ roundtrip: false,
116
+ optimized_route: false,
117
+ excludeLayer: null
118
+ },
119
+ isoConfig: {
120
+ points: [{
121
+ text: '',
122
+ pos: null,
123
+ crs: null
124
+ }],
125
+ mode: 'time',
126
+ units: {
127
+ time: 'min',
128
+ distance: 'km'
129
+ },
130
+ intervals: '5, 10',
131
+ result: null
132
+ },
133
+ searchProviders: [],
134
+ searchParams: {},
135
+ highlightId: null
136
+ });
137
+ _defineProperty(_this, "renderSettings", function () {
138
+ var settings = _this.state.settings[_this.state.mode];
139
+ return /*#__PURE__*/React.createElement("div", {
140
+ className: "routing-settings-menu"
141
+ }, /*#__PURE__*/React.createElement("table", {
142
+ className: "routing-settings-menu-entries"
143
+ }, /*#__PURE__*/React.createElement("tbody", null, settings.method !== undefined ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("routing.method"), ":"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("select", {
144
+ onChange: function onChange(ev) {
145
+ return _this.updateSetting(_this.state.mode, {
146
+ method: ev.target.value
147
+ });
148
+ },
149
+ value: settings.method
150
+ }, /*#__PURE__*/React.createElement("option", {
151
+ value: "fastest"
152
+ }, LocaleUtils.tr("routing.fastest")), /*#__PURE__*/React.createElement("option", {
153
+ value: "shortest"
154
+ }, LocaleUtils.tr("routing.shortest"))))) : null, settings.maxSpeed !== undefined ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("routing.maxspeed"), ":"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(NumberInput, {
155
+ max: 350,
156
+ min: 1,
157
+ mobile: true,
158
+ onChange: function onChange(value) {
159
+ return _this.updateSetting(_this.state.mode, {
160
+ maxSpeed: value
161
+ });
162
+ },
163
+ suffix: " km/h",
164
+ value: settings.maxSpeed
165
+ }))) : null, settings.useFerries !== undefined ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("routing.useferries"), ":"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(ToggleSwitch, {
166
+ active: settings.useFerries,
167
+ onChange: function onChange(value) {
168
+ return _this.updateSetting(_this.state.mode, {
169
+ useFerries: value
170
+ });
171
+ }
172
+ }))) : null, settings.useHighways !== undefined ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("routing.usehighways"), ":"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(ToggleSwitch, {
173
+ active: settings.useHighways,
174
+ onChange: function onChange(value) {
175
+ return _this.updateSetting(_this.state.mode, {
176
+ useHighways: value
177
+ });
178
+ }
179
+ }))) : null, settings.useTollways !== undefined ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("routing.usetollways"), ":"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(ToggleSwitch, {
180
+ active: settings.useTollways,
181
+ onChange: function onChange(value) {
182
+ return _this.updateSetting(_this.state.mode, {
183
+ useTollways: value
184
+ });
185
+ }
186
+ }))) : null)));
187
+ });
188
+ _defineProperty(_this, "renderRouteWidget", function () {
189
+ var routeConfig = _this.state.routeConfig;
190
+ var vectorLayers = _this.props.layers.filter(function (layer) {
191
+ return layer.type === "vector" && layer.role === LayerRole.USERLAYER && !layer.readonly;
192
+ });
193
+ var numpoints = routeConfig.points.length;
194
+ return /*#__PURE__*/React.createElement("div", {
195
+ className: "routing-tab-widget"
196
+ }, /*#__PURE__*/React.createElement("div", {
197
+ className: "routing-input"
198
+ }, /*#__PURE__*/React.createElement("div", {
199
+ className: "routing-points"
200
+ }, /*#__PURE__*/React.createElement(Sortable, {
201
+ onChange: _this.onSortChange,
202
+ options: {
203
+ ghostClass: 'drop-ghost',
204
+ delay: 200
205
+ }
206
+ }, routeConfig.points.map(function (entry, idx) {
207
+ var placeholder = LocaleUtils.tr("routing.addviapoint");
208
+ if (idx === 0) {
209
+ placeholder = LocaleUtils.tr("routing.fromhere");
210
+ } else if (idx === routeConfig.points.length - 1) {
211
+ placeholder = LocaleUtils.tr("routing.tohere");
212
+ }
213
+ return _this.renderSearchField(entry, idx, 'routeConfig', idx > 0 && idx < numpoints - 1, placeholder);
214
+ })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Icon, {
215
+ icon: "up-down-arrow",
216
+ onClick: _this.reverseRoutePts
217
+ }))), /*#__PURE__*/React.createElement("div", {
218
+ className: "routing-points-commands"
219
+ }, /*#__PURE__*/React.createElement("a", {
220
+ href: "#",
221
+ onClick: function onClick() {
222
+ return _this.addPoint('routeConfig', -1);
223
+ }
224
+ }, /*#__PURE__*/React.createElement(Icon, {
225
+ icon: "plus"
226
+ }), " ", LocaleUtils.tr("routing.add")), /*#__PURE__*/React.createElement("span", {
227
+ className: "routing-points-commands-spacer"
228
+ }), _this.renderImportButton('routeConfig'), /*#__PURE__*/React.createElement("span", {
229
+ className: "routing-points-commands-spacer"
230
+ }), /*#__PURE__*/React.createElement("a", {
231
+ href: "#",
232
+ onClick: function onClick() {
233
+ return _this.clearConfig('routeConfig');
234
+ }
235
+ }, /*#__PURE__*/React.createElement(Icon, {
236
+ icon: "clear"
237
+ }), " ", LocaleUtils.tr("routing.clear"))), _this.state.mode === 'transit' ? /*#__PURE__*/React.createElement("div", {
238
+ className: "routing-time-settings"
239
+ }, /*#__PURE__*/React.createElement("select", {
240
+ onChange: _this.updateTransitTimepoint,
241
+ value: _this.state.settings.transit.timepoint
242
+ }, /*#__PURE__*/React.createElement("option", {
243
+ value: "now"
244
+ }, LocaleUtils.tr("routing.leavenow")), /*#__PURE__*/React.createElement("option", {
245
+ value: "leaveat"
246
+ }, LocaleUtils.tr("routing.leaveat")), /*#__PURE__*/React.createElement("option", {
247
+ value: "arriveat"
248
+ }, LocaleUtils.tr("routing.arriveat"))), _this.state.settings.transit.timepoint !== 'now' ? /*#__PURE__*/React.createElement(DateTimeInput, {
249
+ onChange: function onChange(value) {
250
+ return _this.updateSetting('transit', {
251
+ time: value
252
+ });
253
+ },
254
+ value: _this.state.settings.transit.time
255
+ }) : null) : null, /*#__PURE__*/React.createElement("div", {
256
+ className: "routing-points-commands"
257
+ }, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
258
+ onChange: function onChange(ev) {
259
+ return _this.updateRouteConfig({
260
+ roundtrip: ev.target.checked
261
+ });
262
+ },
263
+ type: "checkbox",
264
+ value: routeConfig.roundtrip
265
+ }), " ", LocaleUtils.tr("routing.roundtrip"))), _this.state.mode !== 'transit' ? /*#__PURE__*/React.createElement("div", {
266
+ className: "routing-points-commands"
267
+ }, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
268
+ onChange: function onChange(ev) {
269
+ return _this.updateRouteConfig({
270
+ optimized_route: ev.target.checked
271
+ });
272
+ },
273
+ type: "checkbox",
274
+ value: routeConfig.optimized_route
275
+ }), " ", LocaleUtils.tr("routing.optimized_route"))) : null, ConfigUtils.havePlugin("Redlining") ? /*#__PURE__*/React.createElement("div", {
276
+ className: "routing-points-commands controlgroup"
277
+ }, /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("routing.excludepolygons"), ":\xA0"), /*#__PURE__*/React.createElement(VectorLayerPicker, {
278
+ layers: vectorLayers,
279
+ onChange: function onChange(layer) {
280
+ return _this.updateRouteConfig({
281
+ excludeLayer: (layer || {}).id
282
+ });
283
+ },
284
+ showNone: true,
285
+ value: routeConfig.excludeLayer || ""
286
+ }), /*#__PURE__*/React.createElement("button", {
287
+ className: "button",
288
+ onClick: _this.setRedliningTool
289
+ }, /*#__PURE__*/React.createElement(Icon, {
290
+ icon: "draw"
291
+ }))) : null), routeConfig.busy ? /*#__PURE__*/React.createElement("div", {
292
+ className: "routing-busy"
293
+ }, /*#__PURE__*/React.createElement(Spinner, null), " ", LocaleUtils.tr("routing.computing")) : null, routeConfig.result ? _this.renderRouteResult(routeConfig) : null);
294
+ });
295
+ _defineProperty(_this, "updateTransitTimepoint", function (ev) {
296
+ var diff = {
297
+ timepoint: ev.target.value
298
+ };
299
+ if (ev.target.value !== 'now' && _this.state.settings.transit.timepoint === 'now') {
300
+ var tzoffset = new Date().getTimezoneOffset() * 60000;
301
+ diff.time = new Date(Date.now() - tzoffset).toISOString().slice(0, -1);
302
+ }
303
+ _this.updateSetting('transit', diff);
304
+ });
305
+ _defineProperty(_this, "setRedliningTool", function () {
306
+ _this.props.setCurrentTask("Redlining", null, null, {
307
+ layerId: _this.state.routeConfig.excludeLayer
308
+ });
309
+ });
310
+ _defineProperty(_this, "renderRouteResult", function (routeConfig) {
311
+ if (routeConfig.result.success === false) {
312
+ return /*#__PURE__*/React.createElement("div", {
313
+ className: "routing-status-failure"
314
+ }, routeConfig.result.data.errorMsgId ? LocaleUtils.tr(routeConfig.result.data.errorMsgId) : routeConfig.result.data.error);
315
+ } else {
316
+ return /*#__PURE__*/React.createElement("div", {
317
+ className: "routing-result"
318
+ }, /*#__PURE__*/React.createElement("div", {
319
+ className: "routing-result-summary"
320
+ }, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Icon, {
321
+ icon: "clock"
322
+ }), " ", MeasureUtils.formatDuration(routeConfig.result.data.summary.time)), /*#__PURE__*/React.createElement("span", {
323
+ className: "routing-result-spacer"
324
+ }), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Icon, {
325
+ icon: "measure"
326
+ }), " ", MeasureUtils.formatMeasurement(routeConfig.result.data.summary.length, false)), /*#__PURE__*/React.createElement("span", {
327
+ className: "routing-result-spacer"
328
+ }), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Icon, {
329
+ icon: "export"
330
+ }), " ", /*#__PURE__*/React.createElement("a", {
331
+ href: "#",
332
+ onClick: _this.exportRoute
333
+ }, LocaleUtils.tr("routing.export"))), /*#__PURE__*/React.createElement("span", {
334
+ className: "routing-result-spacer"
335
+ }), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Icon, {
336
+ icon: "layers"
337
+ }), " ", /*#__PURE__*/React.createElement("a", {
338
+ href: "#",
339
+ onClick: _this.addRouteLayer
340
+ }, LocaleUtils.tr("routing.addlayer")))), /*#__PURE__*/React.createElement("div", {
341
+ className: "routing-result-instructions"
342
+ }, routeConfig.result.data.legs.map(function (leg, lidx) {
343
+ return leg.maneuvers.map(function (entry, eidx) {
344
+ return /*#__PURE__*/React.createElement("div", {
345
+ className: "routing-result-instruction",
346
+ key: "instr" + lidx + ":" + eidx,
347
+ onMouseEnter: function onMouseEnter() {
348
+ return _this.highlightRouteSection(lidx + ":" + eidx, entry, leg);
349
+ },
350
+ onMouseLeave: function onMouseLeave() {
351
+ return _this.clearRouteSectionHighlight(lidx + ":" + eidx);
352
+ }
353
+ }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Icon, {
354
+ icon: entry.icon
355
+ }), /*#__PURE__*/React.createElement("b", null, entry.instruction)), /*#__PURE__*/React.createElement("div", {
356
+ className: "routing-result-instruction-summary"
357
+ }, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Icon, {
358
+ icon: "clock"
359
+ }), " ", MeasureUtils.formatDuration(entry.time)), /*#__PURE__*/React.createElement("span", {
360
+ className: "routing-result-spacer"
361
+ }), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Icon, {
362
+ icon: "measure"
363
+ }), " ", MeasureUtils.formatMeasurement(entry.length, false))));
364
+ });
365
+ })));
366
+ }
367
+ });
368
+ _defineProperty(_this, "highlightRouteSection", function (id, entry, leg) {
369
+ _this.setState({
370
+ highlightId: id
371
+ });
372
+ var feature = {
373
+ type: "Feature",
374
+ crs: "EPSG:4326",
375
+ geometry: {
376
+ type: "LineString",
377
+ coordinates: leg.coordinates.slice(entry.geom_indices[0], entry.geom_indices[1] + 1)
378
+ }
379
+ };
380
+ var sellayer = {
381
+ id: "routingselection",
382
+ role: LayerRole.SELECTION,
383
+ styleOptions: {
384
+ strokeWidth: 3,
385
+ strokeColor: [255, 255, 0, 1],
386
+ strokeDash: []
387
+ }
388
+ };
389
+ _this.props.addLayerFeatures(sellayer, [feature], true);
390
+ });
391
+ _defineProperty(_this, "clearRouteSectionHighlight", function (id) {
392
+ if (_this.state.highlightId === id) {
393
+ _this.setState({
394
+ highlightId: null
395
+ });
396
+ _this.props.removeLayer("routingselection");
397
+ }
398
+ });
399
+ _defineProperty(_this, "renderIsochroneWidget", function () {
400
+ var isoConfig = _this.state.isoConfig;
401
+ var intervalValid = !!isoConfig.intervals.match(/^\d+(,\s*\d+)*$/);
402
+ return /*#__PURE__*/React.createElement("div", {
403
+ className: "routing-tab-widget"
404
+ }, /*#__PURE__*/React.createElement("div", {
405
+ className: "routing-input"
406
+ }, /*#__PURE__*/React.createElement("div", null, isoConfig.points.map(function (entry, idx) {
407
+ return _this.renderSearchField(entry, idx, 'isoConfig', idx > 0);
408
+ })), /*#__PURE__*/React.createElement("table", {
409
+ className: "routing-iso-settings"
410
+ }, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("routing.iso_mode"), ": "), /*#__PURE__*/React.createElement("td", {
411
+ colSpan: "2"
412
+ }, /*#__PURE__*/React.createElement("select", {
413
+ onChange: function onChange(ev) {
414
+ return _this.updateIsoConfig({
415
+ mode: ev.target.value
416
+ });
417
+ },
418
+ value: isoConfig.mode
419
+ }, /*#__PURE__*/React.createElement("option", {
420
+ value: "time"
421
+ }, LocaleUtils.tr("routing.iso_mode_time")), /*#__PURE__*/React.createElement("option", {
422
+ value: "distance"
423
+ }, LocaleUtils.tr("routing.iso_mode_distance"))))), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("routing.iso_intervals"), ": "), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("input", {
424
+ className: isoConfig.intervals && !intervalValid ? "routing-input-invalid" : "",
425
+ onChange: function onChange(ev) {
426
+ return _this.updateIsoConfig({
427
+ intervals: ev.target.value
428
+ });
429
+ },
430
+ placeholder: "5, 10, 15",
431
+ type: "text",
432
+ value: isoConfig.intervals
433
+ })), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("select", {
434
+ onChange: function onChange(ev) {
435
+ _this.setState(function (state) {
436
+ return {
437
+ isoConfig: _objectSpread(_objectSpread({}, state.isoConfig), {}, {
438
+ units: _objectSpread(_objectSpread({}, state.isoConfig.units), {}, _defineProperty({}, state.isoConfig.mode, ev.target.value))
439
+ })
440
+ };
441
+ });
442
+ _this.recomputeIfNeeded();
443
+ },
444
+ value: isoConfig.units[isoConfig.mode]
445
+ }, Object.keys(_this.props.units[isoConfig.mode]).map(function (unit) {
446
+ return /*#__PURE__*/React.createElement("option", {
447
+ key: unit,
448
+ value: unit
449
+ }, unit);
450
+ })))))), /*#__PURE__*/React.createElement("div", {
451
+ className: "routing-points-commands"
452
+ }, /*#__PURE__*/React.createElement("a", {
453
+ href: "#",
454
+ onClick: function onClick() {
455
+ return _this.addPoint('isoConfig', isoConfig.points.length);
456
+ }
457
+ }, /*#__PURE__*/React.createElement(Icon, {
458
+ icon: "plus"
459
+ }), " ", LocaleUtils.tr("routing.add")), /*#__PURE__*/React.createElement("span", {
460
+ className: "routing-points-commands-spacer"
461
+ }), _this.renderImportButton('isoConfig'), /*#__PURE__*/React.createElement("span", {
462
+ className: "routing-points-commands-spacer"
463
+ }), /*#__PURE__*/React.createElement("a", {
464
+ href: "#",
465
+ onClick: function onClick() {
466
+ return _this.clearConfig('isoConfig');
467
+ }
468
+ }, /*#__PURE__*/React.createElement(Icon, {
469
+ icon: "clear"
470
+ }), " ", LocaleUtils.tr("routing.clear")))), isoConfig.busy ? /*#__PURE__*/React.createElement("div", {
471
+ className: "routing-busy"
472
+ }, /*#__PURE__*/React.createElement(Spinner, null), " ", LocaleUtils.tr("routing.computing")) : null, isoConfig.result ? _this.renderIsochroneResult(isoConfig) : null);
473
+ });
474
+ _defineProperty(_this, "renderIsochroneResult", function (isoConfig) {
475
+ if (isoConfig.result.success === false) {
476
+ return /*#__PURE__*/React.createElement("div", {
477
+ className: "routing-status-failure"
478
+ }, isoConfig.result.data.errorMsgId ? LocaleUtils.tr(isoConfig.result.data.errorMsgId) : isoConfig.result.data.error);
479
+ } else {
480
+ return /*#__PURE__*/React.createElement("div", {
481
+ className: "routing-result"
482
+ }, /*#__PURE__*/React.createElement("div", {
483
+ className: "routing-result-summary"
484
+ }, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Icon, {
485
+ icon: "export"
486
+ }), " ", /*#__PURE__*/React.createElement("a", {
487
+ href: "#",
488
+ onClick: _this.exportIsochrone
489
+ }, LocaleUtils.tr("routing.export"))), /*#__PURE__*/React.createElement("span", {
490
+ className: "routing-result-spacer"
491
+ }), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Icon, {
492
+ icon: "layers"
493
+ }), " ", /*#__PURE__*/React.createElement("a", {
494
+ href: "#",
495
+ onClick: _this.addIsochroneLayer
496
+ }, LocaleUtils.tr("routing.addlayer")))));
497
+ }
498
+ });
499
+ _defineProperty(_this, "renderSearchField", function (entry, idx, config, removeable) {
500
+ var placeholder = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
501
+ return /*#__PURE__*/React.createElement("div", {
502
+ className: "routing-search-field controlgroup",
503
+ key: "field" + idx
504
+ }, /*#__PURE__*/React.createElement(SearchWidget, {
505
+ placeholder: placeholder,
506
+ resultSelected: function resultSelected(result) {
507
+ return _this.searchResultSelected(config, idx, result);
508
+ },
509
+ role: "input",
510
+ searchParams: _this.state.searchParams,
511
+ searchProviders: _this.state.searchProviders,
512
+ value: entry.text
513
+ }), idx === 0 ? /*#__PURE__*/React.createElement("button", {
514
+ className: "button",
515
+ disabled: !_this.props.locatePos,
516
+ onClick: function onClick() {
517
+ return _this.updatePoint(config, 0, _this.locatePos());
518
+ },
519
+ role: "suffix"
520
+ }, /*#__PURE__*/React.createElement(Icon, {
521
+ icon: "screenshot"
522
+ })) : null, removeable ? /*#__PURE__*/React.createElement("button", {
523
+ className: "button",
524
+ onClick: function onClick() {
525
+ return _this.removePoint(config, idx);
526
+ },
527
+ role: "suffix"
528
+ }, /*#__PURE__*/React.createElement(Icon, {
529
+ icon: "remove"
530
+ })) : null);
531
+ });
532
+ _defineProperty(_this, "renderImportButton", function (config) {
533
+ return /*#__PURE__*/React.createElement("label", {
534
+ className: "routing-import-button",
535
+ title: LocaleUtils.tr("routing.importhint")
536
+ }, /*#__PURE__*/React.createElement(Icon, {
537
+ icon: "import"
538
+ }), " ", LocaleUtils.tr("routing.importpoints"), /*#__PURE__*/React.createElement("input", {
539
+ onChange: function onChange(ev) {
540
+ return _this.importPoints(ev, config);
541
+ },
542
+ type: "file"
543
+ }));
544
+ });
545
+ _defineProperty(_this, "locatePos", function () {
546
+ return {
547
+ pos: _toConsumableArray(_this.props.locatePos),
548
+ text: _this.props.locatePos.map(function (x) {
549
+ return x.toFixed(4);
550
+ }).join(", "),
551
+ crs: 'EPSG:4326'
552
+ };
553
+ });
554
+ _defineProperty(_this, "updateSetting", function (mode, diff) {
555
+ _this.setState(function (state) {
556
+ return {
557
+ settings: _objectSpread(_objectSpread({}, state.settings), {}, _defineProperty({}, mode, _objectSpread(_objectSpread({}, state.settings[mode]), diff)))
558
+ };
559
+ });
560
+ _this.recomputeIfNeeded();
561
+ });
562
+ _defineProperty(_this, "addPoint", function (config) {
563
+ var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : -1;
564
+ var entry = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
565
+ text: '',
566
+ pos: null
567
+ };
568
+ _this.setState(function (state) {
569
+ return _defineProperty({}, config, _objectSpread(_objectSpread({}, state[config]), {}, {
570
+ points: [].concat(_toConsumableArray(state[config].points.slice(0, index)), [entry], _toConsumableArray(state[config].points.slice(index)))
571
+ }));
572
+ });
573
+ if (entry.pos) {
574
+ _this.recomputeIfNeeded();
575
+ }
576
+ });
577
+ _defineProperty(_this, "updatePoint", function (config, idx, diff) {
578
+ _this.setState(function (state) {
579
+ return _defineProperty({}, config, _objectSpread(_objectSpread({}, state[config]), {}, {
580
+ points: [].concat(_toConsumableArray(state[config].points.slice(0, idx)), [_objectSpread(_objectSpread({}, state[config].points[idx]), diff)], _toConsumableArray(state[config].points.slice(idx + 1)))
581
+ }));
582
+ });
583
+ _this.recomputeIfNeeded();
584
+ });
585
+ _defineProperty(_this, "importPoints", function (ev, config) {
586
+ var reader = new FileReader();
587
+ reader.onload = function (loadev) {
588
+ try {
589
+ var obj = JSON.parse(loadev.target.result);
590
+ var crs = "EPSG:4326";
591
+ if (obj.crs && obj.crs.properties) {
592
+ crs = CoordinatesUtils.fromOgcUrnCrs(obj.crs.properties.name);
593
+ }
594
+ var prec = CoordinatesUtils.getPrecision(crs);
595
+ _this.setState(function (state) {
596
+ return _defineProperty({}, config, _objectSpread(_objectSpread({}, state[config]), {}, {
597
+ points: obj.features.map(function (feature) {
598
+ var coordinates = feature.geometry.coordinates;
599
+ return {
600
+ text: coordinates.map(function (x) {
601
+ return x.toFixed(prec);
602
+ }).join(", ") + " (" + crs + ")",
603
+ pos: coordinates,
604
+ crs: crs
605
+ };
606
+ })
607
+ }));
608
+ });
609
+ _this.recomputeIfNeeded();
610
+ } catch (e) {
611
+ // eslint-disable-next-line
612
+ alert(LocaleUtils.tr("routing.importerror"));
613
+ }
614
+ };
615
+ reader.readAsText(ev.target.files[0]);
616
+ });
617
+ _defineProperty(_this, "removePoint", function (config, idx) {
618
+ _this.setState(function (state) {
619
+ return _defineProperty({}, config, _objectSpread(_objectSpread({}, state[config]), {}, {
620
+ points: [].concat(_toConsumableArray(state[config].points.slice(0, idx)), _toConsumableArray(state[config].points.slice(idx + 1)))
621
+ }));
622
+ });
623
+ _this.recomputeIfNeeded();
624
+ });
625
+ _defineProperty(_this, "clearConfig", function (config) {
626
+ var newPoints = config === 'routeConfig' ? [{
627
+ text: '',
628
+ pos: null,
629
+ crs: null
630
+ }, {
631
+ text: '',
632
+ pos: null,
633
+ crs: null
634
+ }] : [{
635
+ text: '',
636
+ pos: null,
637
+ crs: null
638
+ }];
639
+ _this.setState(function (state) {
640
+ return _defineProperty({}, config, _objectSpread(_objectSpread({}, state[config]), {}, {
641
+ points: newPoints,
642
+ result: null
643
+ }));
644
+ });
645
+ _this.props.removeLayer("routinggeometries");
646
+ _this.props.removeLayer("routingmarkers");
647
+ _this.recomputeIfNeeded();
648
+ });
649
+ _defineProperty(_this, "reverseRoutePts", function () {
650
+ _this.setState(function (state) {
651
+ return {
652
+ routeConfig: _objectSpread(_objectSpread({}, state.routeConfig), {}, {
653
+ points: state.routeConfig.points.reverse()
654
+ })
655
+ };
656
+ });
657
+ _this.recomputeIfNeeded();
658
+ });
659
+ _defineProperty(_this, "updateRouteConfig", function (diff) {
660
+ var recompute = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
661
+ _this.setState(function (state) {
662
+ return {
663
+ routeConfig: _objectSpread(_objectSpread({}, state.routeConfig), diff)
664
+ };
665
+ });
666
+ if (recompute) {
667
+ _this.recomputeIfNeeded();
668
+ }
669
+ });
670
+ _defineProperty(_this, "updateIsoConfig", function (diff) {
671
+ var recompute = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
672
+ _this.setState(function (state) {
673
+ return {
674
+ isoConfig: _objectSpread(_objectSpread({}, state.isoConfig), diff)
675
+ };
676
+ });
677
+ if (recompute) {
678
+ _this.recomputeIfNeeded();
679
+ }
680
+ });
681
+ _defineProperty(_this, "searchResultSelected", function (config, idx, result) {
682
+ if (result) {
683
+ _this.updatePoint(config, idx, {
684
+ text: result.text,
685
+ pos: [result.x, result.y],
686
+ crs: result.crs
687
+ });
688
+ } else {
689
+ _this.updatePoint(config, idx, {
690
+ text: "",
691
+ pos: null,
692
+ crs: null
693
+ });
694
+ }
695
+ });
696
+ _defineProperty(_this, "updateRoutingMarkers", function () {
697
+ var points = [];
698
+ if (_this.state.currentTab === "Route") {
699
+ points = _this.state.routeConfig.points;
700
+ } else {
701
+ points = _this.state.isoConfig.points;
702
+ }
703
+ var layer = {
704
+ id: "routingmarkers",
705
+ role: LayerRole.MARKER,
706
+ styleName: 'marker'
707
+ };
708
+ var features = points.filter(function (point) {
709
+ return point.pos;
710
+ }).map(function (point, idx) {
711
+ return {
712
+ type: "Feature",
713
+ crs: point.crs,
714
+ geometry: {
715
+ type: "Point",
716
+ coordinates: point.pos
717
+ },
718
+ properties: {
719
+ label: _this.props.showPinLabels && _this.state.routeConfig.result ? String(idx + 1) : null
720
+ }
721
+ };
722
+ });
723
+ _this.props.addLayerFeatures(layer, features, true);
724
+ });
725
+ _defineProperty(_this, "computeRoute", function () {
726
+ var locations = _this.state.routeConfig.points.filter(function (entry) {
727
+ return entry.pos;
728
+ }).map(function (entry) {
729
+ return CoordinatesUtils.reproject(entry.pos, entry.crs, "EPSG:4326");
730
+ });
731
+ _this.props.removeLayer("routinggeometries");
732
+ _this.updateRouteConfig({
733
+ busy: locations.length >= 2,
734
+ result: null
735
+ }, false);
736
+ if (locations.length < 2) {
737
+ return;
738
+ }
739
+ if (_this.state.routeConfig.roundtrip) {
740
+ locations.push(locations[0]);
741
+ }
742
+ var settings = _objectSpread({}, _this.state.settings[_this.state.mode]);
743
+ if (_this.state.routeConfig.excludeLayer) {
744
+ var layer = _this.props.layers.find(function (l) {
745
+ return l.id === _this.state.routeConfig.excludeLayer;
746
+ });
747
+ if (layer) {
748
+ settings.exclude_polygons = layer.features.filter(function (feature) {
749
+ return feature.geometry.type === "Polygon";
750
+ }).map(function (feature) {
751
+ return VectorLayerUtils.reprojectGeometry(feature.geometry, _this.props.mapCrs, "EPSG:4326").coordinates[0];
752
+ });
753
+ }
754
+ }
755
+ settings.optimized_route = _this.state.routeConfig.optimized_route;
756
+ RoutingInterface.computeRoute(_this.state.mode, locations, settings, function (success, result) {
757
+ if (success) {
758
+ // Add routing leg geometries
759
+ var _layer = {
760
+ id: "routinggeometries",
761
+ role: LayerRole.SELECTION,
762
+ styleName: "default",
763
+ styleOptions: {
764
+ strokeColor: [10, 10, 255, 1],
765
+ strokeWidth: 4,
766
+ strokeDash: []
767
+ }
768
+ };
769
+ var features = [];
770
+ result.legs.forEach(function (leg) {
771
+ leg.maneuvers.forEach(function (man) {
772
+ features.push({
773
+ type: "Feature",
774
+ crs: "EPSG:4326",
775
+ styleOptions: {
776
+ strokeColor: man.color
777
+ },
778
+ geometry: {
779
+ type: "LineString",
780
+ coordinates: leg.coordinates.slice(man.geom_indices[0], man.geom_indices[1] + 1)
781
+ }
782
+ });
783
+ });
784
+ });
785
+ _this.props.addLayerFeatures(_layer, features, true);
786
+
787
+ // Reorder locations based on routing result, keeping null entries
788
+ var _this$state$routeConf = _this.state.routeConfig.points.reduce(function (res, point, idx) {
789
+ return point.pos ? _objectSpread(_objectSpread({}, res), {}, {
790
+ points: [].concat(_toConsumableArray(res.points), [point])
791
+ }) : _objectSpread(_objectSpread({}, res), {}, {
792
+ nullPoints: [].concat(_toConsumableArray(res.nullPoints), [{
793
+ point: point,
794
+ idx: idx
795
+ }])
796
+ });
797
+ }, {
798
+ points: [],
799
+ nullPoints: []
800
+ }),
801
+ points = _this$state$routeConf.points,
802
+ nullPoints = _this$state$routeConf.nullPoints;
803
+ var reorderedPoints = result.locations.map(function (location) {
804
+ return points[location.orig_idx];
805
+ }).filter(Boolean);
806
+ nullPoints.forEach(function (entry) {
807
+ reorderedPoints.splice(entry.idx, 0, entry.point);
808
+ });
809
+ _this.updateRouteConfig({
810
+ points: reorderedPoints,
811
+ result: {
812
+ success: success,
813
+ data: result
814
+ },
815
+ busy: false
816
+ }, false);
817
+ if (_this.props.zoomAuto) {
818
+ _this.props.zoomToExtent(result.summary.bounds, "EPSG:4326", -1);
819
+ }
820
+ } else {
821
+ _this.updateRouteConfig({
822
+ result: {
823
+ success: success,
824
+ data: result
825
+ },
826
+ busy: false
827
+ }, false);
828
+ }
829
+ });
830
+ });
831
+ _defineProperty(_this, "computeIsochrone", function () {
832
+ var intervalValid = !!_this.state.isoConfig.intervals.match(/^\d+(,\s*\d+)*$/);
833
+ if (!intervalValid) {
834
+ return;
835
+ }
836
+ var locations = _this.state.isoConfig.points.filter(function (entry) {
837
+ return entry.pos;
838
+ }).map(function (entry) {
839
+ return CoordinatesUtils.reproject(entry.pos, entry.crs, "EPSG:4326");
840
+ });
841
+ _this.props.removeLayer("routinggeometries");
842
+ _this.updateIsoConfig({
843
+ busy: true,
844
+ result: null
845
+ }, false);
846
+ var unitsFactor = _this.props.units[_this.state.isoConfig.mode][_this.state.isoConfig.units[_this.state.isoConfig.mode]];
847
+ var contourOptions = {
848
+ mode: _this.state.isoConfig.mode,
849
+ intervals: _this.state.isoConfig.intervals.split(",").map(function (entry) {
850
+ return parseInt(entry.trim(), 10) / unitsFactor;
851
+ }).sort()
852
+ };
853
+ RoutingInterface.computeIsochrone(_this.state.mode, locations, contourOptions, _this.state.settings[_this.state.mode], function (success, result) {
854
+ if (success) {
855
+ var layer = {
856
+ id: "routinggeometries",
857
+ role: LayerRole.SELECTION,
858
+ styleOptions: {
859
+ strokeColor: [10, 10, 255, 1],
860
+ fillColor: [10, 10, 255, 0.5],
861
+ strokeWidth: 4,
862
+ strokeDash: []
863
+ }
864
+ };
865
+ var features = result.areas.map(function (area) {
866
+ return {
867
+ type: "Feature",
868
+ crs: "EPSG:4326",
869
+ geometry: {
870
+ type: "Polygon",
871
+ coordinates: [area]
872
+ }
873
+ };
874
+ });
875
+ _this.props.addLayerFeatures(layer, features, true);
876
+ if (_this.props.zoomAuto) {
877
+ _this.props.zoomToExtent(result.bounds, "EPSG:4326", -0.5);
878
+ }
879
+ }
880
+ _this.updateIsoConfig({
881
+ result: {
882
+ success: success,
883
+ data: result
884
+ },
885
+ busy: false
886
+ }, false);
887
+ });
888
+ });
889
+ _defineProperty(_this, "recomputeIfNeeded", function () {
890
+ clearTimeout(_this.recomputeTimeout);
891
+ _this.recomputeTimeout = setTimeout(function () {
892
+ if (_this.state.currentTab === "Route" && _this.state.routeConfig.points.filter(function (entry) {
893
+ return entry.pos;
894
+ }).length >= 2) {
895
+ _this.computeRoute();
896
+ } else if (_this.state.currentTab === "Reachability" && _this.state.isoConfig.points.filter(function (entry) {
897
+ return entry.pos;
898
+ }).length > 0) {
899
+ _this.computeIsochrone();
900
+ }
901
+ _this.recomputeTimeout = null;
902
+ }, 750);
903
+ });
904
+ _defineProperty(_this, "collectRoutingFeatures", function () {
905
+ return _this.state.routeConfig.result.data.legs.map(function (leg) {
906
+ return {
907
+ type: "Feature",
908
+ properties: {
909
+ time: leg.time,
910
+ length: leg.length
911
+ },
912
+ geometry: {
913
+ type: "LineString",
914
+ coordinates: leg.coordinates
915
+ },
916
+ styleName: "default",
917
+ styleOptions: {
918
+ strokeColor: [10, 10, 255, 1],
919
+ strokeWidth: 4,
920
+ strokeDash: []
921
+ }
922
+ };
923
+ });
924
+ });
925
+ _defineProperty(_this, "exportRoute", function () {
926
+ var data = JSON.stringify({
927
+ type: "FeatureCollection",
928
+ features: _this.collectRoutingFeatures()
929
+ });
930
+ FileSaver.saveAs(new Blob([data], {
931
+ type: "text/plain;charset=utf-8"
932
+ }), "route.json");
933
+ });
934
+ _defineProperty(_this, "addRouteLayer", function () {
935
+ var layer = {
936
+ id: uuidv4(),
937
+ crs: "EPSG:4326",
938
+ title: LocaleUtils.tr("routing.route"),
939
+ type: 'vector'
940
+ };
941
+ _this.props.addLayerFeatures(layer, _this.collectRoutingFeatures());
942
+ _this.props.setCurrentTask("LayerTree");
943
+ });
944
+ _defineProperty(_this, "collectIsochroneFeatures", function () {
945
+ return _this.state.isoConfig.result.data.areas.map(function (area) {
946
+ return {
947
+ type: "Feature",
948
+ geometry: {
949
+ type: "Polygon",
950
+ coordinates: [area]
951
+ },
952
+ styleName: "default",
953
+ styleOptions: {
954
+ strokeColor: [10, 10, 255, 1],
955
+ fillColor: [10, 10, 255, 0.5],
956
+ strokeWidth: 4,
957
+ strokeDash: []
958
+ }
959
+ };
960
+ });
961
+ });
962
+ _defineProperty(_this, "exportIsochrone", function () {
963
+ var data = JSON.stringify({
964
+ type: "FeatureCollection",
965
+ features: _this.collectIsochroneFeatures()
966
+ });
967
+ FileSaver.saveAs(new Blob([data], {
968
+ type: "text/plain;charset=utf-8"
969
+ }), "isochrone.json");
970
+ });
971
+ _defineProperty(_this, "addIsochroneLayer", function () {
972
+ var layer = {
973
+ id: uuidv4(),
974
+ crs: "EPSG:4326",
975
+ title: LocaleUtils.tr("routing.reachability"),
976
+ type: 'vector'
977
+ };
978
+ _this.props.addLayerFeatures(layer, [_this.collectIsochroneFeatures()]);
979
+ _this.props.setCurrentTask("LayerTree");
980
+ });
981
+ _defineProperty(_this, "onSortChange", function (order, sortable, ev) {
982
+ var newpoints = _this.state.routeConfig.points.slice(0);
983
+ var moved = newpoints.splice(ev.oldIndex, 1)[0];
984
+ newpoints.splice(ev.newIndex, 0, moved);
985
+ _this.updateRouteConfig({
986
+ points: newpoints
987
+ });
988
+ });
989
+ _this.recomputeTimeout = null;
990
+ _this.state.mode = _this.props.enabledModes[0];
991
+ return _this;
992
+ }
993
+ _inherits(Routing, _React$Component);
994
+ return _createClass(Routing, [{
995
+ key: "componentDidUpdate",
996
+ value: function componentDidUpdate(prevProps, prevState) {
997
+ var _this2 = this;
998
+ // Recollect search providers
999
+ if (this.props.searchProviders !== prevProps.searchProviders) {
1000
+ this.setState({
1001
+ searchProviders: this.props.enabledProviders.map(function (key) {
1002
+ return _this2.props.searchProviders[key];
1003
+ }).filter(Boolean),
1004
+ searchParams: {
1005
+ mapcrs: this.props.mapCrs,
1006
+ displaycrs: this.props.displayCrs
1007
+ }
1008
+ });
1009
+ }
1010
+ // Activated / message
1011
+ if (this.props.task.id === "Routing") {
1012
+ this.props.setCurrentTask(null);
1013
+ if (!this.state.visible) {
1014
+ this.setState({
1015
+ visible: true
1016
+ });
1017
+ }
1018
+ var taskData = this.props.task.data || {};
1019
+ if (taskData.from) {
1020
+ this.setState({
1021
+ currentTab: 'Route'
1022
+ });
1023
+ this.updatePoint('routeConfig', 0, taskData.from);
1024
+ }
1025
+ if (taskData.to) {
1026
+ this.setState({
1027
+ currentTab: 'Route'
1028
+ });
1029
+ this.updatePoint('routeConfig', this.state.routeConfig.points.length - 1, taskData.to);
1030
+ }
1031
+ if (taskData.via) {
1032
+ this.setState({
1033
+ currentTab: 'Route'
1034
+ });
1035
+ this.addPoint('routeConfig', -1, taskData.via);
1036
+ }
1037
+ if (taskData.isocenter) {
1038
+ this.setState({
1039
+ currentTab: 'Reachability'
1040
+ });
1041
+ this.updateIsoConfig({
1042
+ points: [taskData.isocenter]
1043
+ });
1044
+ }
1045
+ if (taskData.isoextracenter) {
1046
+ this.setState({
1047
+ currentTab: 'Reachability'
1048
+ });
1049
+ this.updateIsoConfig({
1050
+ points: [].concat(_toConsumableArray(this.state.isoConfig.points), [taskData.isoextracenter])
1051
+ });
1052
+ }
1053
+ }
1054
+ // Window closed
1055
+ if (!this.state.visible && prevState.visible) {
1056
+ this.props.removeLayer("routinggeometries");
1057
+ this.props.removeLayer("routingmarkers");
1058
+ this.updateRouteConfig({
1059
+ points: [{
1060
+ text: '',
1061
+ pos: null,
1062
+ crs: null
1063
+ }, {
1064
+ text: '',
1065
+ pos: null,
1066
+ crs: null
1067
+ }],
1068
+ result: null
1069
+ }, false);
1070
+ this.updateIsoConfig({
1071
+ point: {
1072
+ text: '',
1073
+ pos: null,
1074
+ crs: null
1075
+ },
1076
+ result: null
1077
+ }, false);
1078
+ }
1079
+ // No further processing beyond here if not visible
1080
+ if (!this.state.visible) {
1081
+ return;
1082
+ }
1083
+ // Tab changed
1084
+ if (this.state.currentTab !== prevState.currentTab) {
1085
+ this.props.removeLayer("routinggeometries");
1086
+ this.props.removeLayer("routingmarkers");
1087
+ this.recomputeIfNeeded();
1088
+ }
1089
+ // Mode changed
1090
+ if (this.state.mode !== prevState.mode) {
1091
+ this.recomputeIfNeeded();
1092
+ }
1093
+ // Routing markers
1094
+ if (this.state.currentTab !== prevState.currentTab || this.state.routeConfig.points !== prevState.routeConfig.points || this.state.isoConfig.points !== prevState.isoConfig.points) {
1095
+ this.updateRoutingMarkers();
1096
+ }
1097
+ // Theme changed
1098
+ if (this.props.theme !== prevProps.theme) {
1099
+ this.setState({
1100
+ visible: false
1101
+ });
1102
+ }
1103
+ // Recompute when exclude layer changes
1104
+ if (this.state.currentTab === 'Route' && this.state.routeConfig.excludeLayer && this.props.layers !== prevProps.layers) {
1105
+ var newlayer = this.props.layers.find(function (layer) {
1106
+ return layer.id === _this2.state.routeConfig.excludeLayer;
1107
+ });
1108
+ var prevLayer = prevProps.layers.find(function (layer) {
1109
+ return layer.id === _this2.state.routeConfig.excludeLayer;
1110
+ });
1111
+ if (newlayer !== prevLayer) {
1112
+ this.recomputeIfNeeded();
1113
+ }
1114
+ }
1115
+ }
1116
+ }, {
1117
+ key: "render",
1118
+ value: function render() {
1119
+ var _this3 = this;
1120
+ if (!this.state.visible) {
1121
+ return null;
1122
+ }
1123
+ var tabButtons = [{
1124
+ key: "Route",
1125
+ label: LocaleUtils.tr("routing.route")
1126
+ }, {
1127
+ key: "Reachability",
1128
+ label: LocaleUtils.tr("routing.reachability")
1129
+ }];
1130
+ var tabRenderers = {
1131
+ Route: this.renderRouteWidget,
1132
+ Reachability: this.renderIsochroneWidget
1133
+ };
1134
+ var buttons = [{
1135
+ key: "auto",
1136
+ icon: "routing-car",
1137
+ tooltip: LocaleUtils.tr("routing.mode_auto")
1138
+ }, {
1139
+ key: "heavyvehicle",
1140
+ icon: "routing-truck",
1141
+ tooltip: LocaleUtils.tr("routing.mode_heavyvehicle")
1142
+ }, {
1143
+ key: "transit",
1144
+ icon: "routing-train",
1145
+ tooltip: LocaleUtils.tr("routing.mode_transit")
1146
+ }, {
1147
+ key: "bicycle",
1148
+ icon: "routing-bicycle",
1149
+ tooltip: LocaleUtils.tr("routing.mode_bicycle")
1150
+ }, {
1151
+ key: "pedestrian",
1152
+ icon: "routing-walking",
1153
+ tooltip: LocaleUtils.tr("routing.mode_walking")
1154
+ }];
1155
+ var enabledButtons = this.props.enabledModes.map(function (entry) {
1156
+ return buttons.find(function (button) {
1157
+ return button.key === entry;
1158
+ });
1159
+ });
1160
+ return /*#__PURE__*/React.createElement(ResizeableWindow, {
1161
+ dockable: this.props.geometry.side,
1162
+ icon: "routing",
1163
+ initialHeight: this.props.geometry.initialHeight,
1164
+ initialWidth: this.props.geometry.initialWidth,
1165
+ initialX: this.props.geometry.initialX,
1166
+ initialY: this.props.geometry.initialY,
1167
+ initiallyDocked: this.props.geometry.initiallyDocked,
1168
+ onClose: function onClose() {
1169
+ return _this3.setState({
1170
+ visible: false
1171
+ });
1172
+ },
1173
+ title: LocaleUtils.tr("routing.windowtitle")
1174
+ }, /*#__PURE__*/React.createElement("div", {
1175
+ className: "routing-body",
1176
+ role: "body"
1177
+ }, /*#__PURE__*/React.createElement(ButtonBar, {
1178
+ active: this.state.currentTab,
1179
+ buttons: tabButtons,
1180
+ className: "routing-buttonbar",
1181
+ onClick: function onClick(key) {
1182
+ return _this3.setState({
1183
+ currentTab: key
1184
+ });
1185
+ }
1186
+ }), /*#__PURE__*/React.createElement("div", {
1187
+ className: "routing-frame"
1188
+ }, /*#__PURE__*/React.createElement("div", {
1189
+ className: "routing-buttons controlgroup"
1190
+ }, /*#__PURE__*/React.createElement(ButtonBar, {
1191
+ active: this.state.mode,
1192
+ buttons: enabledButtons,
1193
+ onClick: function onClick(key) {
1194
+ return _this3.setState({
1195
+ mode: key
1196
+ });
1197
+ }
1198
+ }), /*#__PURE__*/React.createElement("button", {
1199
+ className: "button" + (this.state.settingsPopup ? " pressed" : ""),
1200
+ onClick: function onClick() {
1201
+ return _this3.setState(function (state) {
1202
+ return {
1203
+ settingsPopup: !state.settingsPopup
1204
+ };
1205
+ });
1206
+ }
1207
+ }, /*#__PURE__*/React.createElement(Icon, {
1208
+ icon: "cog"
1209
+ })), this.state.settingsPopup ? this.renderSettings() : null), tabRenderers[this.state.currentTab]())));
1210
+ }
1211
+ }]);
1212
+ }(React.Component);
1213
+ _defineProperty(Routing, "propTypes", {
1214
+ addLayerFeatures: PropTypes.func,
1215
+ displayCrs: PropTypes.string,
1216
+ /** List of enabled routing modes. */
1217
+ enabledModes: PropTypes.arrayOf(PropTypes.string),
1218
+ /** List of search providers to use for routing location search. */
1219
+ enabledProviders: PropTypes.arrayOf(PropTypes.string),
1220
+ /** Default window geometry with size, position and docking status. Positive position values (including '0') are related to top (InitialY) and left (InitialX), negative values (including '-0') to bottom (InitialY) and right (InitialX). */
1221
+ geometry: PropTypes.shape({
1222
+ initialWidth: PropTypes.number,
1223
+ initialHeight: PropTypes.number,
1224
+ initialX: PropTypes.number,
1225
+ initialY: PropTypes.number,
1226
+ initiallyDocked: PropTypes.bool,
1227
+ side: PropTypes.string
1228
+ }),
1229
+ layers: PropTypes.array,
1230
+ locatePos: PropTypes.array,
1231
+ mapCrs: PropTypes.string,
1232
+ removeLayer: PropTypes.func,
1233
+ searchProviders: PropTypes.object,
1234
+ setCurrentTask: PropTypes.func,
1235
+ /** Whether to label the routing waypoint pins with the route point number. */
1236
+ showPinLabels: PropTypes.bool,
1237
+ task: PropTypes.object,
1238
+ theme: PropTypes.object,
1239
+ /** Set of units for isochrone time/distance intervals to use. */
1240
+ units: PropTypes.object,
1241
+ /** Automatically zoom to the extent of the route */
1242
+ zoomAuto: PropTypes.bool,
1243
+ zoomToExtent: PropTypes.func
1244
+ });
1245
+ _defineProperty(Routing, "defaultProps", {
1246
+ enabledModes: ["auto", "heavyvehicle", "transit", "bicycle", "pedestrian"],
1247
+ enabledProviders: ["coordinates", "nominatim"],
1248
+ geometry: {
1249
+ initialWidth: 480,
1250
+ initialHeight: 640,
1251
+ initialX: 0,
1252
+ initialY: 0,
1253
+ initiallyDocked: true,
1254
+ side: 'left'
1255
+ },
1256
+ showPinLabels: true,
1257
+ units: {
1258
+ time: {
1259
+ min: 1,
1260
+ s: 60
1261
+ },
1262
+ distance: {
1263
+ km: 1,
1264
+ m: 1000
1265
+ }
1266
+ },
1267
+ zoomAuto: true
1268
+ });
1269
+ export default connect(createSelector([function (state) {
1270
+ return state;
1271
+ }, searchProvidersSelector], function (state, searchProviders) {
1272
+ return {
1273
+ displayCrs: state.map.displayCrs,
1274
+ layers: state.layers.flat,
1275
+ locatePos: state.locate.position,
1276
+ mapCrs: state.map.projection,
1277
+ searchProviders: searchProviders,
1278
+ task: state.task,
1279
+ theme: state.theme.current
1280
+ };
1281
+ }), {
1282
+ addLayerFeatures: addLayerFeatures,
1283
+ removeLayer: removeLayer,
1284
+ setCurrentTask: setCurrentTask,
1285
+ zoomToExtent: zoomToExtent
1286
+ })(Routing);