WME E87 Inconsistent direction

Solves the inconsistent direction problem

当前为 2023-01-06 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name WME E87 Inconsistent direction
  3. // @version 0.0.4
  4. // @description Solves the inconsistent direction problem
  5. // @license MIT License
  6. // @author Anton Shevchuk
  7. // @namespace https://greasyfork.org/users/227648-anton-shevchuk
  8. // @supportURL https://github.com/AntonShevchuk/wme-template/issues
  9. // @match https://*.waze.com/editor*
  10. // @match https://*.waze.com/*/editor*
  11. // @exclude https://*.waze.com/user/editor*
  12. // @icon data:image/png;base64,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Z2ltcC5vcmcveG1wLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICB4bXBNTTpEb2N1bWVudElEPSJnaW1wOmRvY2lkOmdpbXA6ZDRiNjNhYzgtYmMyOC00ODg2LThlNDgtYTNkM2YxNzJmNmU2IgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjVlOTUyNDgwLWRmMTAtNDVhMS1iYWY3LTEzMTUzNTJjNWQ0ZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOmIyOWI4Y2FmLTc3OTctNDZhZi1hMjljLTdhMzQ1ZDJmZGNlOSIKICAgZGM6Rm9ybWF0PSJpbWFnZS9wbmciCiAgIEdJTVA6QVBJPSIyLjAiCiAgIEdJTVA6UGxhdGZvcm09Ik1hYyBPUyIKICAgR0lNUDpUaW1lU3RhbXA9IjE2NzE1NDk5MDM4MTk2NDkiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zMiIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjI6MTI6MjBUMTY6MjU6MDMrMDE6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIyOjEyOjIwVDE2OjI1OjAzKzAxOjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MDU0ZmRjNDgtNjg1MC00OTg0LTkxMzItY2M2YjdmNDg1MjkxIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKE1hYyBPUykiCiAgICAgIHN0RXZ0OndoZW49IjIwMjItMTItMjBUMTY6MjU6MDMrMDE6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+lrIRmQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB+YMFA8ZAx8XwGkAAAZ4SURBVHja7ZpvTFRXFsB/w/8/CypSmFGmWpRotKASMRSkgVrTZrsplrVqa7XY1IC0UdovtjTrELdpv7QftJuGaiO4RohDGkY2Jl34QGlnCKm1Eyi2TWUkVWAe/4cpdHVxeP1AeXA74AAqOzu8XzLJO/edd+89Z94959ybByoqKioqKioqKioqCxGNcnUMPzQUALuArciT7vmGpTJgBoxo+JhiRiduGtBhwFJWUybb++yyr2Lvs8tlNWUyBiwY0E12gPnyj5flhcLlHy/LGDCPvRgG8krTS0tyt+cC0NDSwLnGc5R0lPjUCshfns++1H2kPZoGQFltGQcsB/I0GKi3H7Y/ro3SYvnOwtbPtvp00DP/1Ux6YjpSv4TupO5LP3/8M7RRWgA+NX/q81F/3EZtlBZ//DP8dP46JdqXdZX5vAMm26jz12n8FnodEDATpZwlOayLXjenAZy3nZy8cXLKe4eWH+LJtU+yImYFMjKDw4PYJBulzaU03mp00z/y8BEigiNmNX5zTzPVjup7c8De5L3kZOTMyQGdvZ2c/IfogD3Rezi+4zgJcQlu+tvYxr5t+6j8spKXLS8L997KfgvtUu2sxq+oq6C6/h4dcD9JDUmlJLeERX9aNK1OaHAo+7fvJzAgkBfrX3yg85n3GPDhXz50M753sBd7n51b/70ltO/M2MmOxTv+9zHgj/QN9tEmtc1It2ewR5A3JWwSZGO9kd11uwHIXpzNmVfOEBUZBUBgQCC7N+7G9IUJgKbrTbT3tt91vOhF0azUrlTkbmf3/XdAm9RGSkXKrJ87/PBhQoNDJwLksFMxHuCi4yLmFjPPpj2rtK3WrVaun770tMcxbhy6oVx39HZQaC30niUQGRwpyMO3ht10vu/8XpzgLDL1R5s/Qh+rV+Tz9ee9KwaMyqOeJ/QHg2VZnnH/L2S8oFy3d7dz9Luj3uWA91vfZ+TOiCKHh4S76azVrRXT6EDnjPo+l3GOpYuWKnK5udz7soCMzJWfrkwsifBIKrdVCikybX2aIo/cGeFM4xmP/W4J2UL2Y9mKbO+zc7T56IzmNKcgGLs4lgtZFzzqOYYd5H2dJ7S9++93KV9RTmR4pJLqbKtsOH91ska/RgiSJosJk8PkcZyijCIiwiYqxJpvax5sGtTH6oVgMx1Sn+TmgEuDlzjyzyO8+dSbJMYnAhC/LF5Ms84+qhqqONh40OMYQZogntj0hJBZci253lsIASyLWEZ4cPj0lWBQKKu1q0kNSfXY1+n008K/b7lq8e5K8L3171G8p5j45fFKZmjtaMXaasU57AQgLCSMzI2ZGF8xsiVky137y0rKEuRTDacefCV4s/smjT80etQbGB4Q5OTgZF575jUCAwKVIPdB1QcUXS0CIMYvhtq9tSStShpbajF63nn8HbJrsqfs/3X96+hjJpaircM2o5hxzw7oGuhiV92uWT+XtyGPyLCJYsh6zaoYD9A92s2xfx3DVDhhROaGTJgmpuUkizvUb659492boaSVSYJsk2xuOhcdF+lx9Aip8rklz03Z34ZVGwT5QtMF73ZAgL/4wtl6bVPquVwuQV4fvd5NJzc2V9k0jW/QqgaqvH87PJmEhxKmbB+PEXcrh7MSxODXZm+b0xzm1QFD/xkSZO0S99Od7RHbhZIW4ITthHvJvFwsma93XZ+/84DYJbEYs4wz1i+3lmNymGj6uYnMjZkTpe+6VA40HKC0q1RpMzxlEJ5t72lnSB5yryWilwlyS0fL/DlAH6MX0o8nmtubMTlMFFoLeSnzJeUfDg4M5pODn/DGjTe4PXIbbZSWuIfihGfrmuqm3lqHiVtraUj6/zgSO1VzijuuO8J6T4xPZPOazW7Gt9nb2G/eP7UDwkUHnO48PX9vwL1QdLUIDRoK/lzgZsRkrNesFHxW8OAz00yUzK1mXKOuOQ/S0iOuz7evvo2x1Uj+xnySH0kmJiqGIP8g+n/pR+qXqG6q5sTPJ+7aZ2V95X1xgCbueJx88283x4Ri3/omYtpzieKxtKr/ux4/u8suTy4ufJ3JNtpddtnPhesrqX8sgr669VWfd8C4jVK/hAvXV37A+c+vfA5AemI6lp0W8uPyx74e8qFfflw+lp0W0hPTAfjd5t+PjRfwJzLjdcDzKRUpDWdrzzK+HHwRqV/ibO1ZUipSGoDnYaF+JifzMccZRUVFRUVFRUVFRUVlwfIbL4zT3SPCFmYAAAAASUVORK5CYII=
  13. // @grant none
  14. // @require https://greasyfork.org/scripts/389765-common-utils/code/CommonUtils.js?version=1090053
  15. // @require https://greasyfork.org/scripts/450160-wme-bootstrap/code/WME-Bootstrap.js?version=1135567
  16. // @require https://greasyfork.org/scripts/452563-wme/code/WME.js?version=1101598
  17. // @require https://greasyfork.org/scripts/450221-wme-base/code/WME-Base.js?version=1129908
  18. // @require https://greasyfork.org/scripts/450320-wme-ui/code/WME-UI.js?version=1134661
  19. // ==/UserScript==
  20.  
  21. /* jshint esversion: 8 */
  22.  
  23. /* global require */
  24. /* global $, jQuery */
  25. /* global W */
  26. /* global I18n */
  27. /* global OpenLayers */
  28. /* global WME, WMEBase */
  29. /* global WMEUI, WMEUIHelper, WMEUIHelperPanel, WMEUIHelperModal, WMEUIHelperTab, WMEUIShortcut, WMEUIHelperFieldset */
  30. /* global Container, Settings, SimpleCache, Tools */
  31.  
  32. (function () {
  33. 'use strict'
  34.  
  35. // Script name, uses as unique index
  36. const NAME = 'E87'
  37.  
  38. // Translations
  39. const TRANSLATION = {
  40. 'en': {
  41. title: 'Direction →',
  42. description: 'Plugin WME E87 solves the inconsistent direction problem',
  43. buttons: {
  44. toggle: 'Change direction',
  45. forward: 'A → B',
  46. reverse: 'B → A',
  47. },
  48. },
  49. 'uk': {
  50. title: 'Напрямки →',
  51. description: 'Плагін WME E87 для вирішиння проблеми різно направленних вулиць',
  52. buttons: {
  53. toggle: 'Змінити напрямок',
  54. forward: 'A → B',
  55. reverse: 'B → A',
  56. },
  57. },
  58. 'ru': {
  59. title: 'Направления →',
  60. description: 'Плагин WME E87 для решения проблемы разнонаправленных улиц',
  61. buttons: {
  62. toggle: 'Изменить направление',
  63. forward: 'A → B',
  64. reverse: 'B → A',
  65. },
  66. }
  67. }
  68.  
  69. const STYLE =
  70. 'button.waze-btn.e87 { background: #f2f4f7; border: 1px solid #ccc; margin: 2px; } ' +
  71. 'button.waze-btn.e87:hover { background: #ffffff; transition: background-color 100ms linear; box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1), inset 0 0 100px 100px rgba(255, 255, 255, 0.3); } ' +
  72. 'button.waze-btn.e87:focus { background: #f2f4f7; } ' +
  73. 'button.e87-forward, button.e87-reverse { margin: 2px 8px; }' +
  74. 'div.e87-container { display: flex; flex: auto; justify-content: space-evenly; } ' +
  75. 'p.e87-info { border-top: 1px solid #ccc; color: #777; font-size: x-small; margin-top: 15px; padding-top: 10px; text-align: center; }'
  76.  
  77. WMEUI.addTranslation(NAME, TRANSLATION)
  78. WMEUI.addStyle(STYLE)
  79.  
  80. const BUTTONS = {
  81. toggle: {
  82. title: I18n.t(NAME).buttons.toggle,
  83. description: I18n.t(NAME).buttons.toggle,
  84. shortcut: '',
  85. },
  86. }
  87.  
  88. // Default settings
  89. const SETTINGS = {}
  90.  
  91. class E87 extends WMEBase {
  92. constructor (name, settings = null) {
  93. super(name, settings)
  94.  
  95. /** @type {WMEUIHelper} */
  96. this.helper = new WMEUIHelper(this.name)
  97.  
  98. this.panel = this.helper.createPanel(I18n.t(name).title)
  99.  
  100. /** @type {WMEUIHelperTab} */
  101. this.tab = this.helper.createTab(
  102. I18n.t(this.name).title,
  103. {
  104. 'icon': 'switch'
  105. }
  106. )
  107. this.tab.addText(
  108. 'description',
  109. I18n.t(this.name).description,
  110. )
  111. this.tab.addText(
  112. 'info',
  113. '<a href="' + GM_info.scriptUpdateURL + '">' + GM_info.script.name + '</a> ' + GM_info.script.version
  114. )
  115.  
  116. // Inject custom HTML to container in the WME interface
  117. this.tab.inject()
  118. }
  119.  
  120. /**
  121. * Init button for selection of the segment
  122. * @param buttons
  123. */
  124. init (buttons) {
  125. buttons.toggle.callback = (e) => {
  126. e.preventDefault()
  127. this.invert(WME.getSelectedSegment().getID())
  128. }
  129. this.panel.addButtons(buttons)
  130. }
  131.  
  132. /**
  133. * Handler for `segment.wme` event
  134. * @param {jQuery.Event} event
  135. * @param {HTMLElement} element
  136. * @param {W.model} model
  137. * @return {void}
  138. */
  139. onSegment (event, element, model) {
  140. this.log('Selected one segment')
  141. element.prepend(this.panel.html())
  142. }
  143.  
  144. /**
  145. * Handler for `segments.wme` event
  146. * @param {jQuery.Event} event
  147. * @param {HTMLElement} element
  148. * @param {Array} models
  149. * @return {void}
  150. */
  151. onSegments (event, element, models) {
  152. this.log('Check selected segments')
  153.  
  154. let reversed = W.selectionManager.getReversedSegments()
  155.  
  156. if (reversed.numReversed === 0) {
  157. return
  158. }
  159.  
  160. let result = this.detect(reversed)
  161.  
  162. if (result.forward.length && result.reverse.length) {
  163. this.log('Inconsistent direction detected: forward = ' + result.forward.length + ' backward = ' + result.reverse.length)
  164.  
  165. let buttonToForward = document.createElement('button')
  166. buttonToForward.type = 'button'
  167. buttonToForward.title = I18n.t(NAME).buttons.toggle
  168. buttonToForward.className = 'waze-btn waze-btn-small waze-btn-white e87 e87-forward'
  169. buttonToForward.innerHTML = I18n.t(NAME).buttons.forward + ' (' + result.reverse.length + ')'
  170. buttonToForward.onclick = (e) => {
  171. e.preventDefault()
  172. result.reverse.forEach(el => this.invert(el))
  173. }
  174. let buttonToReverse = document.createElement('button')
  175. buttonToReverse.type = 'button'
  176. buttonToReverse.title = I18n.t(NAME).buttons.toggle
  177. buttonToReverse.className = 'waze-btn waze-btn-small waze-btn-white e87 e87-reverse'
  178. buttonToReverse.innerHTML = I18n.t(NAME).buttons.reverse + ' (' + result.forward.length + ')'
  179. buttonToReverse.onclick = (e) => {
  180. e.preventDefault()
  181. result.forward.forEach(el => this.invert(el))
  182. }
  183.  
  184. let container = document.createElement('div')
  185. container.className = 'e87-container'
  186. container.append(buttonToForward)
  187. container.append(buttonToReverse)
  188.  
  189. $('wz-alert.sidebar-alert.inconsistent-direction-alert .sidebar-alert-content')
  190. .after(container)
  191. }
  192. }
  193.  
  194. /**
  195. * Detect directions
  196. * @param {Object} segments information
  197. * @return {Object}
  198. */
  199. detect (segments) {
  200. let forward = [], reverse = []
  201.  
  202. for (let el in segments) {
  203. el = Number.parseInt(el)
  204. if (Number.isNaN(el)) {
  205. continue
  206. }
  207. if (segments[el]) {
  208. reverse.push(el)
  209. } else {
  210. forward.push(el)
  211. }
  212. }
  213.  
  214. return {
  215. forward: forward,
  216. reverse: reverse
  217. }
  218. }
  219.  
  220. /**
  221. * Invert direction of the segment
  222. * @param {Number} id of the segment
  223. */
  224. invert (id) {
  225. let segment = W.model.segments.getObjectById(id)
  226. if (segment.isLockedByHigherRank()) {
  227. this.log('Locked by higher rank')
  228. return
  229. }
  230. console.groupCollapsed(
  231. '%c' + this.name + ':%c invert segment',
  232. 'color: #0DAD8D; font-weight: bold',
  233. 'color: dimgray; font-weight: normal'
  234. )
  235. console.log('segment', segment)
  236.  
  237. // setup and reverse attributes
  238. let attributes = {}
  239. attributes.fwdDirection = segment.attributes.revDirection
  240. attributes.revDirection = segment.attributes.fwdDirection
  241. let fwdTurnsLocked = segment.attributes.fwdTurnsLocked
  242. let revTurnsLocked = segment.attributes.revTurnsLocked
  243. // attributes.fwdTurnsLocked = segment.attributes.revTurnsLocked // ???
  244. // attributes.revTurnsLocked = segment.attributes.fwdTurnsLocked // ???
  245. // segment.setAttribute("revTurnsLocked", segment.attributes.fwdTurnsLocked)}
  246. // segment.setAttribute("fwdTurnsLocked", segment.attributes.revTurnsLocked)}
  247. attributes.fwdMaxSpeed = segment.attributes.revMaxSpeed
  248. attributes.revMaxSpeed = segment.attributes.fwdMaxSpeed
  249. attributes.fwdMaxSpeedUnverified = segment.attributes.revMaxSpeedUnverified
  250. attributes.revMaxSpeedUnverified = segment.attributes.fwdMaxSpeedUnverified
  251. attributes.fwdLaneCount = segment.attributes.revLaneCount
  252. attributes.revLaneCount = segment.attributes.fwdLaneCount
  253.  
  254. attributes.restrictions = []
  255. for (let i = 0; i < segment.attributes.restrictions.length; i++) {
  256. attributes.restrictions[i] = segment.attributes.restrictions[i].withReverseDirection()
  257. }
  258.  
  259. console.log('attributes', attributes)
  260.  
  261. let fromNode = segment.getFromNode()
  262. let toNode = segment.getToNode()
  263.  
  264. let onA = {}
  265. let toConnections = {}
  266. fromNode.getSegmentIds().forEach(segId => {
  267. // incoming directions
  268. if (segId !== id) {
  269. onA[segId] = W.model.getTurnGraph().getTurnThroughNode(fromNode, W.model.segments.getObjectById(segId), segment)
  270. onA[segId].toVertex.direction = onA[segId].toVertex.direction === 'fwd' ? 'rev' : 'fwd'
  271. }
  272. // outgoing directions
  273. toConnections[segId] = W.model.getTurnGraph().getTurnThroughNode(fromNode, segment, W.model.segments.getObjectById(segId))
  274. toConnections[segId].fromVertex.direction = toConnections[segId].fromVertex.direction === 'fwd' ? 'rev' : 'fwd'
  275. // u-turn
  276. if (segId === id) {
  277. toConnections[segId].toVertex.direction = toConnections[segId].toVertex.direction === 'fwd' ? 'rev' : 'fwd'
  278. }
  279. })
  280.  
  281. let onB = {}
  282. let fromConnections = {}
  283. toNode.getSegmentIds().forEach(segId => {
  284. if (segId !== id) {
  285. onB[segId] = W.model.getTurnGraph().getTurnThroughNode(toNode, W.model.segments.getObjectById(segId), segment)
  286. onB[segId].toVertex.direction = onB[segId].toVertex.direction === 'fwd' ? 'rev' : 'fwd'
  287. }
  288.  
  289. fromConnections[segId] = W.model.getTurnGraph().getTurnThroughNode(toNode, segment, W.model.segments.getObjectById(segId))
  290. fromConnections[segId].fromVertex.direction = fromConnections[segId].fromVertex.direction === 'fwd' ? 'rev' : 'fwd'
  291.  
  292. // u-turn
  293. if (segId === id) {
  294. fromConnections[segId].toVertex.direction = fromConnections[segId].toVertex.direction === 'fwd' ? 'rev' : 'fwd'
  295. }
  296. })
  297.  
  298. // invert the geometry of the segment
  299. let geometry = segment.geometry.clone()
  300. geometry.components.reverse()
  301.  
  302. if (!geometry.components[0].equals(toNode.attributes.geometry)) {
  303. let delta = { x: 0, y: 0 }
  304. delta.x = toNode.attributes.geometry.x - geometry.components[0].x
  305. delta.y = toNode.attributes.geometry.y - geometry.components[0].y
  306. geometry.components[0].move(delta.x, delta.y)
  307. }
  308. let points = geometry.components.length - 1
  309. if (!geometry.components[points].equals(fromNode.attributes.geometry)) {
  310. let delta = { x: 0, y: 0 }
  311. delta.x = fromNode.attributes.geometry.x - geometry.components[points].x
  312. delta.y = fromNode.attributes.geometry.y - geometry.components[points].y
  313. geometry.components[points].move(delta.x, delta.y)
  314. }
  315.  
  316. // disconnect the segment
  317. let disconnect = new WazeActionMultiAction([new WazeActionDisconnectSegment(segment, fromNode), new WazeActionDisconnectSegment(segment, toNode)])
  318. disconnect._description = I18n.t('save.changes_log.actions.DisconnectSegment.default')
  319. W.model.actionManager.add(disconnect)
  320.  
  321. // update geometry of the segment
  322. W.model.actionManager.add(new WazeActionUpdateSegmentGeometry(segment, segment.geometry, geometry))
  323.  
  324. // update attributes
  325. W.model.actionManager.add(new WazeActionUpdateObject(segment, attributes))
  326.  
  327. // connect the segment
  328. let connect = new WazeActionMultiAction([new WazeActionConnectSegment(toNode, segment), new WazeActionConnectSegment(fromNode, segment)])
  329. connect._description = I18n.t('save.changes_log.actions.ConnectSegment.default')
  330. W.model.actionManager.add(connect)
  331.  
  332. // update Turn's attributes
  333. segment.setAttribute('fwdTurnsLocked', revTurnsLocked)
  334. segment.setAttribute('revTurnsLocked', fwdTurnsLocked)
  335. // W.model.actionManager.add(new WazeActionUpdateObject(segment, segment.getAttributes()))
  336.  
  337. // allow all connections
  338. // W.model.actionManager.add(new WazeActionModifyAllConnections(segment.getToNode(), true));
  339. // W.model.actionManager.add(new WazeActionModifyAllConnections(segment.getFromNode(), true));
  340.  
  341. this.applyTurns(fromConnections)
  342. this.applyTurns(toConnections)
  343. this.applyTurns(onA)
  344. this.applyTurns(onB)
  345.  
  346. console.groupEnd()
  347. }
  348.  
  349. /**
  350. * Apply turns for segments
  351. * @param segments
  352. */
  353. applyTurns (segments) {
  354. let actions = []
  355. for (let sid in segments) {
  356. let segment = segments[sid]
  357. let turn
  358. switch (segment.turnData.state) {
  359. case 0 :
  360. case 1 :
  361. turn = WazeModelGraphTurnData.create()
  362. turn = turn.withState(segment.turnData.state)
  363. .withRestrictions(segment.turnData.restrictions)
  364. .withInstructionOpcode(segment.turnData.instructionOpcode)
  365. .withLanes(segment.turnData.lanes)
  366.  
  367. actions.push(new WazeModelGraphActionsSetTurn(W.model.getTurnGraph(), segment.withTurnData(turn)))
  368. break
  369. }
  370. }
  371. let multiAction = new WazeActionMultiAction(actions)
  372. multiAction._description = I18n.t('save.changes_log.actions.SetTurn.update')
  373. W.model.actionManager.add(multiAction)
  374. }
  375. }
  376.  
  377. let WazeActionConnectSegment
  378. let WazeActionDisconnectSegment
  379. let WazeActionModifyAllConnections
  380. let WazeActionMultiAction
  381. let WazeActionUpdateObject
  382. let WazeActionUpdateSegmentGeometry
  383. let WazeModelGraphTurnData
  384. let WazeModelGraphActionsSetTurn
  385.  
  386. $(document).on('bootstrap.wme', () => {
  387. let Instance = new E87(NAME, SETTINGS)
  388. Instance.init(BUTTONS)
  389.  
  390. WazeActionConnectSegment = require('Waze/Action/ConnectSegment')
  391. WazeActionDisconnectSegment = require('Waze/Action/DisconnectSegment')
  392. WazeActionModifyAllConnections = require('Waze/Action/ModifyAllConnections')
  393. WazeActionMultiAction = require('Waze/Action/MultiAction')
  394. WazeActionUpdateObject = require('Waze/Action/UpdateObject')
  395. WazeActionUpdateSegmentGeometry = require('Waze/Action/UpdateSegmentGeometry')
  396. WazeModelGraphTurnData = require('Waze/Model/Graph/TurnData')
  397. WazeModelGraphActionsSetTurn = require('Waze/Model/Graph/Actions/SetTurn')
  398. })
  399. })()