// ==UserScript== // @name WME RA Util // @namespace https://greasyfork.org/users/30701-justins83-waze // @version 0.2.0 // @description Providing basic utility for RA adjustment without the need to delete & recreate // @include https://www.waze.com/editor/* // @include https://www.waze.com/*/editor/* // @include https://beta.waze.com/* // @require https://greasyfork.org/scripts/9794-wlib/code/wLib.js?version=106259 // @require https://greasyfork.org/scripts/23614-wlibext/code/wLibExt.js?version=150020 // @author JustinS83 // @grant none // @license // @downloadURL none // ==/UserScript== /* global W */ /* global wLib */ /* Todo: -diameter change -Determine if it is a circle -If a circle, determine center of circle -shift diagonal? -stretch diagonal? non-normal RA color:#FF8000 normal RA color:#4cc600 */ (function() { 'use strict'; var RAUtilWindow = null; var UpdateSegmentGeometry = require('Waze/Action/UpdateSegmentGeometry'); var MoveNode = require("Waze/Action/MoveNode"); var totalActions = 0; function bootstrap(tries) { tries = tries || 1; if (window.W && window.W.map && window.W.model) { init(); } else if (tries < 1000) { setTimeout(function () {bootstrap(tries++);}, 200); } } bootstrap(); function init(){ RAUtilWindow = document.createElement('div'); RAUtilWindow.id = "RAUtilWindow"; RAUtilWindow.style.position = 'fixed'; RAUtilWindow.style.visibility = 'hidden'; RAUtilWindow.style.top = '15%'; RAUtilWindow.style.left = '25%'; RAUtilWindow.style.zIndex = 100; RAUtilWindow.style.backgroundColor = '#BEDCE5'; RAUtilWindow.style.borderWidth = '3px'; RAUtilWindow.style.borderStyle = 'solid'; RAUtilWindow.style.borderRadius = '10px'; RAUtilWindow.style.boxShadow = '5px 5px 10px Silver'; RAUtilWindow.style.padding = '4px'; var alertsHTML = ''; alertsHTML += '
';//A set of utilities for modifying roundabouts allowing preservation of segment data.';//
Double arrows shift by 2x configured value.'; alertsHTML += '
'; alertsHTML += 'Shift amount
meter(s) '; alertsHTML += '
'; alertsHTML += '
';// style="float:left;">';// padding-bottom:45px;">'; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; //alertsHTML += '
'; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; //alertsHTML += '
'; alertsHTML += '
'; //Single Shift Buttons alertsHTML += '';//margin-left:23px;">'; alertsHTML += ' '; alertsHTML += ''; alertsHTML += ''; //alertsHTML += '
'; alertsHTML += '
'; //alertsHTML += '  '; alertsHTML += '';//position:relative;padding:2px;padding-left:3px;padding-right:3px;margin-left:0px;top:10px;">'; alertsHTML += ' '; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; //alertsHTML += '  '; alertsHTML += '';//position:relative;padding:2px;padding-left:3px;padding-right:3px;top:10px;margin-left:15px;">'; alertsHTML += ' '; alertsHTML += ''; alertsHTML += ''; alertsHTML += '
'; //alertsHTML += '  '; alertsHTML += '';//;position:relative;top:20px;margin-left:17px;">'; alertsHTML += ' '; alertsHTML += ''; alertsHTML += ''; alertsHTML += '
'; alertsHTML += '
'; //***************** Rotation ************************** alertsHTML += '
'; alertsHTML += '
'; alertsHTML += 'Rotation amount
degrees(s) '; alertsHTML += '
'; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += '
'; alertsHTML += '';//margin-left:23px;">'; alertsHTML += ' '; alertsHTML += ''; alertsHTML += ''; alertsHTML += ''; alertsHTML += '';//margin-left:23px;">'; alertsHTML += ' '; alertsHTML += ''; alertsHTML += ''; alertsHTML += '
'; alertsHTML += '
'; alertsHTML += ''; RAUtilWindow.innerHTML = alertsHTML; document.body.appendChild(RAUtilWindow); document.getElementById('RAShiftLeftBtn').addEventListener('click', RAShiftLeftBtnClick, false); document.getElementById('RAShiftRightBtn').addEventListener('click', RAShiftRightBtnClick, false); document.getElementById('RAShiftUpBtn').addEventListener('click', RAShiftUpBtnClick, false); document.getElementById('RAShiftDownBtn').addEventListener('click', RAShiftDownBtnClick, false); document.getElementById('RARotateLeftBtn').addEventListener('click', RARotateLeftBtnClick, false); document.getElementById('RARotateRightBtn').addEventListener('click', RARotateRightBtnClick, false); $('#shiftAmount').keypress(function(event) { if ((event.which != 46 || $(this).val().indexOf('.') != -1) && (event.which < 48 || event.which > 57)) { event.preventDefault(); } }); window.Waze.selectionManager.events.register("selectionchanged", null, checkDisplayTool); W.model.actionManager.events.register("afterundoaction",null, undotriggered); W.model.actionManager.events.register("afterclearactions",null,actionsCleared); } function undotriggered(){ checkSaveChanges(); } function actionsCleared(){ checkSaveChanges(); totalActions = 0; } function checkDisplayTool(){ if(W.selectionManager.hasSelectedItems() && Waze.selectionManager.selectedItems[0].model.type === 'segment'){ if(!AllSelectedSegmentsRA() || W.selectionManager.selectedItems.length === 0) $('#RAUtilWindow').css({'visibility': 'hidden'}); else{ $('#RAUtilWindow').css({'visibility': 'visible'}); if(typeof jQuery.ui !== 'undefined') $('#RAUtilWindow' ).draggable(); checkSaveChanges(); checkAllEditable(wLib.Model.getAllRoundaboutSegmentsFromObj(W.selectionManager.selectedItems[0])); } } else{ $('#RAUtilWindow').css({'visibility': 'hidden'}); if(typeof jQuery.ui !== 'undefined') $('#RAUtilWindow' ).draggable(); } } var pendingChanges = false; /** Returns false if there are pending changes, true if no changes need saved. */ function checkSaveChanges(){ var $RASaveChanges = $('#RAUtilSaveChanges'); if(W.model.actionManager.index >= 0 && (totalActions === 0 && (W.model.actionManager.actions.length > 0))){ if($RASaveChanges.length === 0){ $RASaveChanges = $('
', {id:'RAUtilSaveChanges', style:'color:red'}); $RASaveChanges.text('You must save your changes before using this utility.'); $('#RAUtilWindow').append($RASaveChanges); pendingChanges = true; } } else { $RASaveChanges.remove(); pendingChanges = false; } } function checkAllEditable(RASegs){ var $RAEditable = $('#RAEditable'); var allEditable = true; var segObj, fromNode, toNode; for(i=0; i', {id:'RAEditable', style:'color:red'}); $RAEditable.text('One or more segments are locked above your rank or have a closure.'); $('#RAUtilWindow').append($RAEditable); } } return allEditable; } function AllSelectedSegmentsRA(){ for (i = 0; i < W.selectionManager.selectedItems.length; i++){ if(W.selectionManager.selectedItems[i].model.attributes.id < 0 || !wLib.Model.isRoundaboutSegmentID(W.selectionManager.selectedItems[i].model.attributes.id)) return false; } return true; } function ShiftSegmentNodesLat(segObj, latOffset){ var RASegs = wLib.Model.getAllRoundaboutSegmentsFromObj(segObj); if(checkAllEditable(RASegs)){ var gps; var newGeometry = segObj.geometry.clone(); var originalLength = segObj.geometry.components.length; for(i=0; i