// ==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 += '';
//Single Shift Buttons
alertsHTML += '';//margin-left:23px;">';
alertsHTML += ' ';
alertsHTML += ' ';
alertsHTML += ' ';
//alertsHTML += '';
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 += '';
//alertsHTML += ' ';
alertsHTML += '';//position:relative;padding:2px;padding-left:3px;padding-right:3px;top:10px;margin-left:15px;">';
alertsHTML += ' ';
alertsHTML += ' ';
alertsHTML += ' ';
alertsHTML += ' ';
alertsHTML += ' ';
//alertsHTML += '';
alertsHTML += '';
alertsHTML += ' ';
alertsHTML += '';
//alertsHTML += ' ';
alertsHTML += '';//;position:relative;top:20px;margin-left:17px;">';
alertsHTML += ' ';
alertsHTML += ' ';
alertsHTML += ' ';
alertsHTML += ' ';
alertsHTML += ' ';
alertsHTML += ' ';
//alertsHTML += '';
alertsHTML += '
';
alertsHTML += '
';
//***************** Rotation **************************
alertsHTML += '';
alertsHTML += '';
alertsHTML += 'Rotation amount
degrees(s) ';
alertsHTML += '
';
alertsHTML += '
';
alertsHTML += '';
alertsHTML += '';
alertsHTML += '';//margin-left:23px;">';
alertsHTML += ' ';
alertsHTML += ' ';
alertsHTML += ' ';
alertsHTML += ' ';
alertsHTML += '';
alertsHTML += '';//margin-left:23px;">';
alertsHTML += ' ';
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