// ==UserScript==
// @name WME Road Selector Highlights
// @namespace https://greasyfork.org/users/11629-TheLastTaterTot
// @description Adds highlighting ability to WME Road Selector. Requires WME Road Selector to function.
// @include https://editor-beta.waze.com/*editor/*
// @include https://www.waze.com/*editor/*
// @exclude https://www.waze.com/user/*editor/*
// @version 0.5.1.1
// @grant none
// ==/UserScript==
(function() {
function RSH() {
this.USR_EXPR = [{}];
this.PREFS = {
strokeColor: ["#FFFF00"],
strokeOpacity: [0.5],
strokeDashstyle: [0],
strokeLinecap: [0],
strokeWidthScale: [1],
strokeDashSizeScale: [1],
strokeSpacingScale: [1]
};
this.lastIdx = 0;
this.idx = 0;
this.zLoadOrder = [0];
this.eraseOnScreen_idx = false;
this.triggerUpdate = true;
this.showSessionHighlights = false;
this.loadedSavedSession = false;
this.presets = {
linePropObjKeys: [
'strokeColor',
'strokeOpacity',
'strokeDashstyle',
'strokeLinecap',
'strokeWidthScale',
'strokeDashSizeScale',
'strokeSpacingScale'
],
linePropIds: ['selRSHColors', 'numRSHOpacity', 'selRSHDash',
'selRSHCap', 'numRSHScaleWidth', 'numRSHDashSizeScale',
'numRSHSpacingScale'
],
linePropAttrType: ['value', 'valueAsNumber', 'selectedIndex',
'selectedIndex', 'valueAsNumber', 'valueAsNumber', 'valueAsNumber'
],
defaultLineAttributes: {
strokeColor: "#FFFF00",
strokeOpacity: 0.5,
strokeDashstyle: 0,
strokeLinecap: 0,
strokeWidthScale: 1,
strokeDashSizeScale: 1,
strokeSpacingScale: 1
},
lineAttributes: {
strokeWidth: [4, 5, 7, 8, 9, 11, 13, 14, 14, 15, 15],
strokeDashstyle: ["solid", "- - - - -", "– ‧ – ‧"],
strokeDasharray: [
["solid"],
[1, 1],
[2, 1, 1, 1]
],
strokeLinecap: ["butt", "round", "square"]
}
};
this.addLayer = function() {
this.idx = this.USR_EXPR.length; //next index
this.USR_EXPR[this.idx] = {};
this.PREFS.strokeColor[this.idx] = "#FFFF00";
this.PREFS.strokeOpacity[this.idx] = 0.5;
this.PREFS.strokeDashstyle[this.idx] = 0;
this.PREFS.strokeLinecap[this.idx] = 0;
this.PREFS.strokeWidthScale[this.idx] = 1;
this.PREFS.strokeDashSizeScale[this.idx] = 1;
this.PREFS.strokeSpacingScale[this.idx] = 1;
this.lastIdx = this.idx;
this.zLoadOrder[this.idx] = this.idx;
this.triggerUpdate = true;
};
this.removeLayer = function() {
var seq = function(b) {
return Array.apply(null, Array(b)).map(function(_, c) {
return c;
});
}
this.USR_EXPR.splice(this.idx, 1);
this.PREFS.strokeColor.splice(this.idx, 1);
this.PREFS.strokeOpacity.splice(this.idx, 1);
this.PREFS.strokeDashstyle.splice(this.idx, 1);
this.PREFS.strokeLinecap.splice(this.idx, 1);
this.PREFS.strokeWidthScale.splice(this.idx, 1);
this.PREFS.strokeDashSizeScale.splice(this.idx, 1);
this.PREFS.strokeSpacingScale.splice(this.idx, 1);
((this.idx - 1) > 0) ? this.idx--: this.idx = 0;
this.lastIdx = this.USR_EXPR.length - 1;
this.zLoadOrder = seq(this.USR_EXPR.length);
this.triggerUpdate = true;
};
this.housekeep = function() {
numLayers = this.USR_EXPR.length;
notEmptyIndexes = elementsWithValues(this.USR_EXPR);
numNewLayers = notEmptyIndexes.length;
this.USR_EXPR = removeEmpty(this.USR_EXPR, notEmptyIndexes)
var p = this.presets.linePropObjKeys.length;
while (p--) {
lineProp = this.presets.linePropObjKeys[p];
//console.log(lineProp)
this.PREFS[lineProp] = removeEmpty(this.PREFS[lineProp],
notEmptyIndexes);
}
this.zLoadOrder = removeEmpty(this.zLoadOrder, notEmptyIndexes);
if (numLayers !== numNewLayers) {
this.lastIdx = numNewLayers - 1;
this.idx = this.zLoadOrder.indexOf(this.idx);
if (this.idx === -1) this.idx = this.lastIdx;
return true;
} else {
return false;
}
};
this.importLayers = function(addThis) {
this.USR_EXPR = addThis.USR_EXPR;
this.PREFS.strokeColor = addThis.PREFS.strokeColor;
this.PREFS.strokeOpacity = addThis.PREFS.strokeOpacity;
this.PREFS.strokeDashstyle = addThis.PREFS.strokeDashstyle;
this.PREFS.strokeLinecap = addThis.PREFS.strokeLinecap;
this.PREFS.strokeWidthScale = addThis.PREFS.strokeWidthScale;
this.PREFS.strokeDashSizeScale = addThis.PREFS.strokeDashSizeScale;
this.PREFS.strokeSpacingScale = addThis.PREFS.strokeSpacingScale;
this.zLoadOrder = addThis.zLoadOrder;
this.housekeep();
this.lastIdx = this.USR_EXPR.length - 1;
this.idx = this.lastIdx;
this.triggerUpdate = true;
this.loadedSavedSession = true;
this.showSessionHighlights = addThis.
showSessionHighlights;
};
}
//------------------------------------------------------------------------------
var jClone = function(obj) {
return JSON.parse(JSON.stringify(obj));
}
var sum = function(arr) {
return arr.reduce(function(a, b) {
return a + b
});
}
var seq = function(b) {
return Array.apply(null, Array(b)).map(function(_, c) {
return c;
});
}
var elementsWithValues = function(arr) {
try {
var reverseIndices = [],
e = arr.length,
r = 0;
while (e--) {
if (arr[e] !== null && arr[e] != undefined &&
Object.keys(arr[e]).length !== 0)
reverseIndices[r++] = e;
}
return reverseIndices;
} catch (err) {
console.error(err);
}
}
// removeEmpty(arr,{ii}) - ii is an optional array of indices of arr to keep
var removeEmpty = function(arr, ii) { //***Note: the expected indices should be reverse order (last->first)
//bc of the optimized negative while loop
try {
var reverseIndices = [],
arrnew = [],
e = arr.length,
r = 0;
if (typeof ii === 'undefined') {
while (e--) {
if (arr[e] !== null && arr[e] != undefined &&
arr[e].length !== undefined && Object.keys(arr[e])
.length !== 0)
reverseIndices[r++] = e;
}
} else {
reverseIndices = ii;
r = ii.length;
}
while (r--) {
arrnew[r] = arr[reverseIndices[r]];
}
return arrnew;
} catch (err) {
console.error(err);
}
}
/*////////////////////////////////////////////////////////////////////////////*/
//
// TODO: Organize code...convert some functions to methods and prototypes
//
function RSelHighlights(RSel) {
function updatePrefsFromPanel() {
rsh.PREFS.strokeColor[rsh.idx] = document.getElementById("selRSHColors").value
rsh.PREFS.strokeOpacity[rsh.idx] = document.getElementById("numRSHOpacity")
.valueAsNumber
rsh.PREFS.strokeDashstyle[rsh.idx] = document.getElementById("selRSHDash").selectedIndex;
rsh.PREFS.strokeLinecap[rsh.idx] = document.getElementById("selRSHCap").selectedIndex;
rsh.PREFS.strokeWidthScale[rsh.idx] = document.getElementById(
"numRSHScaleWidth").valueAsNumber
rsh.PREFS.strokeDashSizeScale[rsh.idx] = document.getElementById(
"numRSHDashSizeScale").valueAsNumber
rsh.PREFS.strokeSpacingScale[rsh.idx] = document.getElementById(
"numRSHSpacingScale").valueAsNumber
//Update variable with settings from the UI
/*var jj = rsh.presets.linePropObjKeys.length;
while (jj--) {
lineProp = rsh.presets.linePropObjKeys[jj];
eval(
'rsh.PREFS[lineProp][rsh.idx] = document.getElementById(rsh.presets.linePropIds[jj]).' +
rsh.presets.linePropAttrType[jj]);
}*/
}
var updateHighlightButton = function() {
// -----------------------------------------------------------------
var hexToRgb = function(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
};
var rgbToHex = function(rgb) {
rgb = rgb.match(
/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i
);
return (rgb && rgb.length === 4) ? "#" +
("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) +
("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) +
("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : '';
};
// -----------------------------------------------------------------
// Recolor background of Highlight button
var hex = rsh.PREFS.strokeColor[rsh.idx],
rgb;
//$("#selRSHColors").val(hex).change();
$("#selRSHColors").css('background-color', hex);
rgb = hexToRgb(hex);
$("#selRSHColors").css('border-bottom', 'solid 2px rgb(' +
parseInt(rgb.r * 0.7) + ',' + parseInt(rgb.g * 0.7) + ',' + parseInt(
rgb.b *
0.7) + ')');
if (!$("#selRSHColors").hasClass('rsh-btn-color')) $("#selRSHColors").addClass(
'rsh-btn-color');
//-----
document.getElementById("selRSHColors").onclick = function() {
document.getElementById("selRSHColors").onchange = function() {
rsh.triggerUpdate = true;
updatePrefsFromPanel();
updateHighlightButton();
updateExprMenu();
};
};
}
var updateDashButtons = function() {
// Check to enable or disable line option input boxes
var dashSizeScaleObj = document.getElementById("numRSHDashSizeScale"),
strokeSpacingScaleObj = document.getElementById("numRSHSpacingScale");
if (rsh.PREFS.strokeDashstyle[rsh.idx] !== 0) {
dashSizeScaleObj.disabled = false;
strokeSpacingScaleObj.disabled = false;
dashSizeScaleObj.style.backgroundColor = "#FFFFFF";
strokeSpacingScaleObj.style.backgroundColor = "#FFFFFF";
} else {
dashSizeScaleObj.disabled = true;
strokeSpacingScaleObj.disabled = true;
dashSizeScaleObj.style.backgroundColor = "#E0E0E0";
strokeSpacingScaleObj.style.backgroundColor = "#E0E0E0";
}
}
function updateEraseButton(disableBtn) {
if (disableBtn === undefined) {
(rsh.lastIdx === 0) ? disableBtn = true: disableBtn = !rsh.showSessionHighlights;
}
if (disableBtn) {
rsh.eraseOnScreen_idx = true;
$("a#btnRSHClearTop").addClass('disabled');
} else {
rsh.eraseOnScreen_idx = false; // reset
$("a#btnRSHClearTop").removeClass('disabled');
}
}
function updateLayerCountButtons() {
if (rsh.lastIdx !== 0) {
$("a#btnRSHSubtract").removeClass('disabled');
$("a#btnRSHClearAll").removeClass('disabled')
updateEraseButton(false);
} else {
$("a#btnRSHSubtract").addClass('disabled');
$("a#btnRSHClearAll").addClass('disabled');
updateEraseButton(true);
}
$("#txtRSHCount").html(rsh.idx + 1);
}
function updatePanelFromPrefs() {
//console.log('updatePanelFromPrefs()')
// Apply panel settings from saved preferences
//$("#selRSHColors").val(rsh.PREFS.strokeColor[rsh.idx]).change();
$("#numRSHOpacity").val(rsh.PREFS.strokeOpacity[rsh.idx]).change();
$("#selRSHDash").val(rsh.presets.lineAttributes.strokeDashstyle[
rsh.PREFS.strokeDashstyle[rsh.idx]]).change();
$("#selRSHCap").val(rsh.presets.lineAttributes.strokeLinecap[
rsh.PREFS.strokeLinecap[rsh.idx]]).change();
$("#numRSHScaleWidth").val(rsh.PREFS.strokeWidthScale[rsh.idx]).change();
$("#numRSHDashSizeScale").val(rsh.PREFS.strokeDashSizeScale[rsh.idx]).change();
$("#numRSHSpacingScale").val(rsh.PREFS.strokeSpacingScale[rsh.idx]).change();
updateHighlightButton();
updateDashButtons();
updateLayerCountButtons();
}
function updateExprMenu() {
//console.log('updateExprMenu()')
// Dropup menu for selecting layers
var e = rsh.USR_EXPR.length,
htmlText = '',
selStatus;
while (e--) {
(e === rsh.idx) ? selStatus = 'active ': selStatus = '';
if (rsh.USR_EXPR[e] === undefined) {
exprText = '';
} else {
exprText = RSel.getExpressionText(rsh.USR_EXPR[e]);
}
/* '<table class="rsh-expr-menu"><tr><td style="width: 27px">' +
'<div class="icon-sign-blank fa fa-sign-blank rsh-expr-color" style="color:' +
rsh.PREFS.strokeColor[e] + '"></div></td>' +
'<td><a id="liRSHexpr" name="' + e + '" ' +
'class = "rsh-expr-menu ' + selStatus +
'" ' +
'href="javascript:void(0)">' +
exprText + '</a></td></tr></table></li>'*/
htmlText += '<li>' +
'<a id="liRSHexpr" name="' + e + '" ' +
'class = "rsh-expr-menu ' + selStatus +
'" ' + 'href="javascript:void(0)">' +
'<div class="rsh-btn-row">' +
'<div class="icon-sign-blank fa fa-sign-blank rsh-expr-color" style="color:' +
rsh.PREFS.strokeColor[e] + '"></div>' +
exprText + ' </div> ' +
'</a></li>'
if (e !== 0) htmlText +=
'<li role="separator" class="divider rsh-expr-menu" style="background-color: #CBE1E8; color: #CBE1E8; margin: 0; padding: 0; height: 2px;"></li>';
}
updatePanelFromPrefs();
$(".rsh-expr-menu").html(htmlText);
$("a.rsh-expr-menu").click(function() {
rsh.idx = parseInt(this.name);
//console.log('click')
//updatePanelFromPrefs();
updateExprMenu();
updateHighlightButton();
});
}
// ---------------------------------------------------------------------
var setupLineAttributes = function() {
var bgRoadColor = document.getElementById("selRSHBgRoadColor").value,
numHighlights = rsh.lastIdx + 1;
updatePrefsFromPanel();
// preset line attributes for each zoom level
var z = 11;
while (z--) { // for each zoom level
rsh_seg[z] = {
hlLineStyle: [],
hlLineStyleOvrlp: [],
bgLineStyle: {}
};
var strokeWidthAtZoom = rsh.presets.lineAttributes.strokeWidth[z],
bgStrokeWidthAtZoom = strokeWidthAtZoom - parseInt(strokeWidthAtZoom *
0.5),
mm = numHighlights;
while (mm--) {
// Stroke width (line thickness)
var separationAmt = parseInt((strokeWidthAtZoom) / numHighlights),
strokeWidthScale = rsh.PREFS.strokeWidthScale[mm],
strokeWidthAtZoomScaledOvrlp = Math.round(((strokeWidthAtZoom + 2) - mm *
separationAmt) * strokeWidthScale),
strokeWidthAtZoomScaled = Math.round(strokeWidthAtZoom *
strokeWidthScale),
strokeOpacity = rsh.PREFS.strokeOpacity[mm],
strokeOpacityOvrlp = strokeOpacity;
// Dash style and customized spacing
var dashSpecs = rsh.presets.lineAttributes.strokeDasharray[
rsh.PREFS.strokeDashstyle[mm]],
dashSizeScale = rsh.PREFS.strokeDashSizeScale[mm],
spacingScale = rsh.PREFS.strokeSpacingScale[mm],
dashSize = dashSizeScale * strokeWidthAtZoomScaled,
spacing = spacingScale * strokeWidthAtZoomScaled,
dashSizeOvrlp = dashSizeScale * strokeWidthAtZoomScaledOvrlp,
spacingOvrlp = spacingScale * strokeWidthAtZoomScaledOvrlp,
strokeDashstyle, strokeDashstyleOvrlp;
// Make width 1 if the strokeWidth is less than 1 at this zoom
// Also increase opacity to compensate for the small strokeWidth
if (strokeWidthAtZoomScaled <= 1) {
strokeWidthAtZoomScaled = 1;
if (strokeOpacity < 0.9) strokeOpacity = 0.9;
}
// adjust strokeWidth for multiple highlights
strokeOpacityOvrlp = rsh.PREFS.strokeOpacity[mm];
if (strokeWidthAtZoomScaledOvrlp <= 1) {
strokeWidthAtZoomScaledOvrlp = 1;
if (strokeOpacityOvrlp < 0.9) strokeOpacityOvrlp = 0.9;
}
switch (rsh.PREFS.strokeDashstyle[mm]) {
case 0:
strokeDashstyle = dashSpecs[0];
strokeDashstyleOvrlp = dashSpecs[0];
break;
case 1:
strokeDashstyle = dashSpecs[0] * dashSize + ' ' + dashSpecs[1] *
spacing;
strokeDashstyleOvrlp = dashSpecs[0] * dashSizeOvrlp + ' ' + dashSpecs[
1] *
spacingOvrlp;
break;
case 2:
strokeDashstyle = dashSpecs[0] * dashSize + ' ' + dashSpecs[1] *
spacing +
' ' + dashSpecs[2] * strokeWidthAtZoomScaled + ' ' + dashSpecs[3] *
spacing;
strokeDashstyleOvrlp = dashSpecs[0] * dashSizeOvrlp + ' ' + dashSpecs[
1] *
spacingOvrlp + ' ' + dashSpecs[2] * strokeWidthAtZoomScaledOvrlp +
' ' +
dashSpecs[3] * spacingOvrlp;
break;
}
rsh_seg[z].hlLineStyle[mm] = {
strokeColor: rsh.PREFS.strokeColor[mm],
strokeOpacity: strokeOpacity,
strokeDashstyle: strokeDashstyle,
strokeLinecap: rsh.presets.lineAttributes.strokeLinecap[rsh.PREFS.strokeLinecap[
mm]],
strokeWidth: strokeWidthAtZoomScaled,
graphicZIndex: mm + 1
};
rsh_seg[z].hlLineStyleOvrlp[mm] = {
strokeColor: rsh_seg[z].hlLineStyle[mm].strokeColor,
strokeOpacity: strokeOpacityOvrlp,
strokeDashstyle: strokeDashstyleOvrlp,
strokeLinecap: rsh_seg[z].hlLineStyle[mm].strokeLinecap,
strokeWidth: strokeWidthAtZoomScaledOvrlp,
graphicZIndex: mm + 1
};
}
// lineStyle for background (Bg) highlighting
if (bgStrokeWidthAtZoom < 1) bgStrokeWidthAtZoom = 1;
rsh_seg[z].bgLineStyle = {
strokeColor: bgRoadColor,
strokeOpacity: 0.9,
strokeWidth: bgStrokeWidthAtZoom,
strokeLinecap: "butt",
strokeDashstyle: "solid",
graphicZIndex: 0
};
}
rsh.triggerUpdate = false;
}
// ---------------------------------------------------------------------
function drawHighlightsLayer() {
currExpr = RSel.getCurrentExpression();
if (currExpr !== null) {
rsh.USR_EXPR[rsh.idx] = currExpr;
}
setTimeout(updateExprMenu, 0);
setTimeout(Highlight, 0);
rsh.showSessionHighlights = true;
rsh_oLayer.setVisibility(true);
updateEraseButton(false);
if (sessionStorage) sessionStorage.WME_RSHighlights = JSON.stringify(rsh);
}
function eraseHighlight() {
rsh.USR_EXPR[rsh.idx] = {};
updateEraseButton(true);
setTimeout(updateExprMenu, 0);
setTimeout(Highlight, 0);
}
function clearAllHighlights() {
rsh_oLayer.destroyFeatures();
rsh = new RSH();
updatePanelFromPrefs(); //reset panel settings with defaults from rsh.PREFS
updateExprMenu(); //reset expressions menu
setupLineAttributes(); //reset line attributes in rsh.PREFS
/*
// quick fix for resetting RSel's select button due to bug
document.getElementById("btnRSSelect").disabled = false;
document.getElementById("btnRSSelect").style.background = '#E9E9E9';
*/
if (sessionStorage) sessionStorage.WME_RSHighlights = false;
}
// ---------------------------------------------------------------------
function addHighlightLayer() {
drawHighlightsLayer();
currExpr = RSel.getCurrentExpression();
if (Object.keys(rsh.USR_EXPR[rsh.idx]).length === 0 && currExpr === null) {
return false;
} else {
rsh.addLayer();
updatePanelFromPrefs();
updateExprMenu();
if (sessionStorage) sessionStorage.WME_RSHighlights = JSON.stringify(rsh);
return true;
}
}
function subtractHighlightLayer() {
if (rsh.lastIdx > 0) {
rsh.removeLayer();
updatePanelFromPrefs();
updateExprMenu();
if (sessionStorage) sessionStorage.WME_RSHighlights = JSON.stringify(rsh);
return true;
} else {
return false;
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
function Highlight() {
var doBgHighlighting = function(nodes, backgroundLine) {
var lineFeature = new OL.Feature.Vector(new OL.Geometry.LineString(
nodes),
null, backgroundLine);
rsh_oLayer.addFeatures([lineFeature]);
};
var doHighlighting = function(nodes, highlightLine, n) {
if (n === 1) highlightLine.strokeOpacity = 0.9;
var lineFeature = new OL.Feature.Vector(new OL.Geometry.LineString(
nodes),
null, highlightLine);
rsh_oLayer.addFeatures([lineFeature]);
};
if (rsh.triggerUpdate) setupLineAttributes();
if (rsh_oLayer.visibility) {
var usrBgHighlight = document.getElementById("cbRSHBgHighlight").checked,
usrEditable = document.getElementById("cbRSEditable").checked,
usrSuppressRoad = document.getElementById("cbRSHSuppRoad").checked,
currentZoom = Waze.map.zoom,
numHighlights = rsh.lastIdx + 1,
exprArrays = rsh.USR_EXPR,
hlLineStyle = jClone(rsh_seg[currentZoom].hlLineStyle),
hlLineStyleOvrlp = rsh_seg[currentZoom].hlLineStyleOvrlp,
bgLineStyle = rsh_seg[currentZoom].bgLineStyle,
wazeSegObjs = Waze.model.segments.objects,
segIds = Object.keys(wazeSegObjs),
numSegments = segIds.length;
//subsegIds;
// Redraw the highlights each time... there's got to be a better way to do this.
rsh_oLayer.destroyFeatures();
//var drawSegments = function(segIds) {
var s = segIds.length,
seg, segNodes, countHighlighted, h;
while (s--) {
//seg = wazeSegObjs.get(segIds[s]),
seg = wazeSegObjs[segIds[s]];
segNodes = seg.geometry.components;
countHighlighted = 0;
//setTimeout(, 0);
for (h = 0; h < numHighlights; h++) {
if (seg.arePropertiesEditable() || !usrEditable) {
if (RSel.checkSegment(exprArrays[h], seg)) {
countHighlighted++;
if (countHighlighted == 1) {
doHighlighting(segNodes, hlLineStyle[h],
countHighlighted * usrSuppressRoad);
} else {
doHighlighting(segNodes, hlLineStyleOvrlp[h]);
}
}
}
}
if (usrBgHighlight && countHighlighted === 0) {
doBgHighlighting(segNodes, bgLineStyle);
}
}
//};
/*if (numSegments > 500) {
var segStart = 0,
segEnd = 300;
while (segStart < numSegments) {
if (segEnd < numSegments) {
subsegIds = segmentIds.slice(segStart, segEnd);
} else {
subsegIds = segmentIds.slice(segStart);
}
setTimeout(function() {
drawSegments(subsegIds)
}, 0);
segStart = segStart + segEnd;
segEnd = segEnd * 2;
}
} else {
setTimeout(function() {
drawSegments(segmentIds)
}, 0);
}
*/
} else {
rsh.showSessionHighlights = false;
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
var InitRSelHighlights = function() { // return rsh
var checkForAutosave = function() { // return rsh
rsh = new RSH();
// Load autosaved parameters from sessionStorage
if (sessionStorage.WME_RSHighlights !== undefined) {
rsh.importLayers(JSON.parse(sessionStorage.WME_RSHighlights));
console.log("WMERSH: Imported data from previous session.")
//var rsh = JSON.parse(sessionStorage.WME_RSHighlights);
}
if (rsh.USR_EXPR === undefined) {
rsh = new RSH();
currExpr = RSel.getCurrentExpression();
if (currExpr === null) currExpr = {};
rsh.USR_EXPR = [currExpr];
}
if (rsh.loadedSavedSession) {
if (rsh.USR_EXPR[rsh.lastIdx] !== null) {
rsh.addLayer();
}
}
if (rsh.showSessionHighlights === undefined) {
rsh.showSessionHighlights = false;
}
return rsh;
};
var ToggleDropBarMenu = function() {
var dropBarPanel = document.getElementById("divRSHdropBarPanel"),
dropBarHeader = document.getElementById("spanRSHdropBarHeader"),
dropBarContents = document.getElementById("spanRSHdropBarContents"),
mainPanel = document.getElementById("divRSHmainPanel");
if (document.getElementById("aRSHdropBarLink").name == "Hide") {
mainPanel.style.borderBottomLeftRadius = "5px";
mainPanel.style.borderBottomRightRadius = "5px";
dropBarPanel.style.borderWidth = 0;
dropBarPanel.style.backgroundColor = "transparent";
dropBarHeader.style.backgroundColor = "transparent";
dropBarHeader.style.bottomBorderWidth = 0;
dropBarHeader.innerHTML =
'<a id="aRSHdropBarLink" name="Show" class="rsh-link" href="javascript:void(0);"><div class="rsh-arrow-up rsh-vcentered"></div> Show additional line options</a>';
dropBarContents.style.display = "none";
} else {
mainPanel.style.borderBottomLeftRadius = 0;
mainPanel.style.borderBottomRightRadius = 0;
dropBarPanel.style.borderWidth = "2px";
dropBarPanel.style.backgroundColor = "#F9F9F9";
dropBarHeader.style.backgroundColor = "#D1D3D4";
dropBarHeader.style.bottomBorderWidth = "1px";
dropBarHeader.innerHTML =
'<a id="aRSHdropBarLink" name="Hide" class="rsh-link" href="javascript:void(0);"><div class="rsh-arrow-down rsh-vcentered"></div> Hide additional line options</a>';
dropBarContents.style.display = "block";
}
$("a#aRSHdropBarLink").click(ToggleDropBarMenu); //
};
var SetupRSHInterface = function() {
// CSS for RSel Highlights
var rshCSS = document.createElement("style");
rshCSS.type = "text/css";
// UI panel
rshCSS.innerHTML =
'.rsh-main-panel { width: 100%; background-color: #B1D4DF; ' +
' border-style: solid; border-width: 2px; border-collapse: collapse; ' +
' padding: 5px; border-color: #82B8C9; margin-top: 25px; ' +
' border-top-left-radius: 5px; border-top-right-radius: 5px; ' +
' border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; ' +
' vertical-align: middle}' +
'.rsh-dropbar-panel { color: #444444; width: 100%; border-style: inset; margin-top: 0; ' +
' border-width: 2px; border-color: #D5D5D5; background-color: #f9f9f9; ' +
' border-bottom-left-radius: 5px; border-bottom-right-radius: 5px} ' + // border-bottom-left-radius: 5px; border-bottom-right-radius: 5px0
'.rsh-dropbar-panel table { border: 0; width: 100%; display: inline-table;} ' +
'.rsh-dropbar-panel td { font-size: 7pt; font-weight: 600; line-height: 6px; ' +
' padding: 0px 4px 4px 4px; margin: 0; vertical-align: middle; }' +
'.rsh-arrow-up { width: 0; height: 0; border-left: 6px solid transparent; ' +
' border-right: 6px solid transparent; border-bottom: 6px solid black; }' +
'.rsh-arrow-down { width: 0; height: 0; border-left: 6px solid transparent; ' +
' border-right: 6px solid transparent; border-top: 6px solid black; }' +
'span.rsh-vcentered { position: relative; padding: 3px 5px 2px; width: 100%; display: inline-block; align: left; vertical-align: middle; text-align: left; }' +
'div.rsh-vcentered { position: relative; top: 50%; left: 8px; transform: translate(-50%, -50%); display: inline-block; }' +
'span.rsh-dropbar-contents {display: block; margin: 8px 0px 0px; padding: 0; border: 0 }' +
'select.rsh-dropbar-panel { height:20px; width: 100px; background-color: #FFFFFF; border: 1px solid #959595; margin: 0px 0px 2px 2px; padding: 0; }' +
'input.rsh-dropbar-panel { height:20px; width: 36px; background-color: #FFFFFF; border: 1px solid #C1C1C1; border-radius: 0; margin: 0px 0px 2px 2px; padding: 0; }' +
'.rsh-dropbar-header { color: #000000; border-bottom: 1px solid #c0c0c0 }' +
'a.rsh-link { text-decoration: none; }';
//'input.rsh-dropdown-menu { width:45px; height:25px; margin:0px 5px; border: 1px solid #B4B4B4 }' +
// Buttons
rshCSS.innerHTML +=
'.rsh-btn-row { position: relative; display: block; vertical-align: middle; ' +
' margin-top: 2px; margin-bottom: 2px; padding: 0}' +
'.rsh-btn-container { height: 25px; position: relative; display: inline-table; ' +
' vertical-align: middle; padding: 0}' +
'.rsh-btn-drop { height: 22px; background-color: #FEFEFE; border: 1px solid #CBE1E8; ' +
' margin-top: 0px; margin-bottom: 0px !important}' +
'.rsh-btn-color { -moz-border-top-right-radius: 0px; -webkit-border-top-right-radius: 0px; ' +
' -moz-border-bottom-right-radius: 0px; -webkit-border-bottom-right-radius: 0px; ' +
' -webkit-appearance: none; -moz-appearance: none; background-color: yellow; ' +
' width: 25px; height: 25px; padding: 7px 7px 7px 3px; ' +
' background-position: 50% 55%; background-repeat: no-repeat; ' +
' background-image:url(data:image/png;base64,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);' +
' !important }' +
'.rsh-btn-highlight { -moz-border-top-left-radius: 0px; -webkit-border-top-left-radius: 0px; ' +
' -moz-border-bottom-left-radius: 0px; -webkit-border-bottom-left-radius: 0px; padding-right: 6px;}' + //border-bottom: solid 2px #E4E4E4; border-top: 0; border-right: 0; border-left: 0; }' +
'.rsh-btn-counter, a.rsh-btn-counter:hover, a.rsh-btn-counter:active, a.rsh-btn-counter.active, a.rsh-btn-counter:focus { ' +
' height: 25px; width: 25px; padding: 4px; cursor: default; ' +
' background-color: #CFE0E6; border-left: solid 1px #7AB0BE; border-bottom: 0; ' +
' -moz-box-shadow: inset 0 4px 8px -3px #88888E, inset 0 -3px 8px -4px #88888E; ' +
' -webkit-box-shadow: inset 0 4px 8px -3px #88888E, inset 0 -3px 8px -4px #88888E; ' +
' box-shadow: inset 0 4px 8px -3px #88888E, inset 0 -3px 8px -4px #88888E; } ' +
'.rsh-btn { font-size: 10 pt; font-weight: bold; color: #396179 }' +
'.rsh-btn:hover { background-color: #B1DCE9; color: #48758C }' +
'.rsh-btn:disabled { color: #8FB5C5 }' +
'.rsh-btn:active, .rsh-btn:focus, .rsh-btn.active { background-image: none; outline: 0; -webkit-box-shadow: none; box-shadow: none; } ' +
'.rsh-btn-fa { color: #48758C; padding: 3px; height: 25px; !important}' +
'.rsh-btn > .tooltip-inner { font-weight: bold }';
rshCSS.innerHTML += // Dropup expressions menu
'.rsh-expr-menu { font-size: 10px; max-height: 400px; width: 310px; overflow-x: hidden; overflow-y: auto;} ' +
'li.rsh-expr-menu { background-color: #CBE1E8; color: #CBE1E8; margin: 0; padding: 0; height: 2px; !important } ' +
'.rsh-expr-menu>li>a:active, .rsh-expr-menu>li>a.active { background-color: #D8E7EC } ' +
'.rsh-expr-menu>li>a { word-wrap: break-word; white-space: normal; ' +
' padding-top: 8px; padding-bottom: 8px; padding-left:10px; padding-right:10px;} ' +
'.rsh-expr-color { display: inline-block; margin-left: 0px; margin-right: 8px; padding: 0;}' +
'';
// '.rsh-expr-menu>td>a:active, .rsh-expr-menu>li>a.active { background-color: #D8E7EC } ' +
// '.rsh-expr-menu>td>a { text-decoration: none; word-wrap: break-word; white-space: normal; ' +
// ' padding-top: 8px; padding-bottom: 8px; padding-left:10px; padding-right:10px;} ' +
// '.rsh-expr-menu table {border: 0; padding:0; margin:0; vertical-align: middle; display: inline-block; text-align: left;}' +
// CSS-generated icons
rshCSS.innerHTML +=
'.rsh-icn-outerbox { display: inline-block; width: 13px; height: 11px; ' +
' margin: 5px 3px 6px 3px; padding: 0; font-size: 0; border: 0; ' +
' vertical-align: middle; line-height: 0px}' +
'.rsh-icn-indark { display: inline-block; margin: 0; padding: 0; background-color: #555555 }' +
'.rsh-icn-inwhite { display: inline-block; margin: 0; padding: 0; background-color: #FFFFFF }' +
'.rsh-icn-inclear { display: inline-block; margin: 0; padding: 0; background-color: transparent }' +
'.rsh-icn-brdark { display: block; margin: 0; padding: 0; background-color: #555555 }' +
'.rsh-icn-brclear { display: block; margin: 0; padding: 0; background-color: transparent }' +
'.rsh-icn-ingray { display: inline-block; margin: 0; padding: 0; background-color: #bbbbbb }' +
'.rsh-icn-2x2 { width: 2px; height: 2px }' +
'.rsh-icn-3x2 { width: 3px; height: 2px }' +
'.rsh-icn-2x1 { width: 2px; height: 1px }' +
'.rsh-icn-1x2 { width: 1px; height: 2px }' +
'.rsh-icn-1x1 { width: 1px; height: 1px }' +
'.rsh-icn-3x3 { width: 3px; height: 3px }' +
'.rsh-icn-4x3 { width: 4px; height: 3px }' +
'.rsh-icn-13x1 { width: 13px; height: 1px }';
document.body.appendChild(rshCSS);
//------------------------------------------------------------------
// CSS-HTML Icons
// [weight, opacity, stroke type, end cap, dash size, dash spacing]
var rshIcons = [
'<div class="rsh-icn-outerbox"><div class="rsh-icn-brdark" style="width: 13px; height: 3px"></div><div class="rsh-icn-brclear" style="width: 13px; height: 2px"></div><div class="rsh-icn-brdark" style="width: 13px; height: 2px"></div><div class="rsh-icn-brclear" style="width: 13px; height: 3px"></div><div class="rsh-icn-brdark" style="width: 13px; height: 1px"></div></div>',
'<div class="rsh-icn-outerbox"><div class="rsh-icn-indark rsh-icn-3x3"></div><div class="rsh-icn-inwhite rsh-icn-3x3"></div><div class="rsh-icn-indark rsh-icn-3x3" style="background-color: #ababab !important"></div><div class="rsh-icn-inwhite rsh-icn-3x3" style="background-color: #f1f1f1 !important"></div><div class="rsh-icn-inwhite rsh-icn-3x3"></div><div class="rsh-icn-indark rsh-icn-3x3" style="background-color: #999999 !important"></div><div class="rsh-icn-inwhite rsh-icn-3x3" style="background-color: #f1f1f1 !important"></div><div class="rsh-icn-indark rsh-icn-3x3" style="background-color: #CCCCCC !important"></div><div class="rsh-icn-indark rsh-icn-3x3" style="background-color: #888888 !important"></div><div class="rsh-icn-inwhite rsh-icn-3x3" style="background-color: #fafafa !important"></div><div class="rsh-icn-indark rsh-icn-3x3" style="background-color: #bbbbbb !important"></div><div class="rsh-icn-inclear rsh-icn-3x3"></div><div class="rsh-icn-inwhite rsh-icn-3x3" style="background-color: #fbfbfB !important"></div><div class="rsh-icn-indark rsh-icn-3x3" style="background-color: #bbbbbb !important"></div><div class="rsh-icn-inclear rsh-icn-3x3"></div><div class="rsh-icn-indark rsh-icn-3x3" style="background-color: #dddddd !important"></div></div>',
'<div class="rsh-icn-outerbox"><div class="rsh-icn-brdark" style="width: 13px; height: 2px"></div><div class="rsh-icn-brclear" style="width: 13px; height: 2px"></div><div class="rsh-icn-indark" style="width: 6px; height: 2px"></div><div class="rsh-icn-inclear" style="width: 1px; height: 2px"></div><div class="rsh-icn-indark" style="width: 6px; height: 2px"></div><div class="rsh-icn-brclear" style="width: 13px; height: 2px"></div><div class="rsh-icn-indark" style="width: 3px; height: 3px"></div><div class="rsh-icn-inclear" style="width: 2px; height: 3px"></div><div class="rsh-icn-indark" style="width: 3px; height: 3px"></div><div class="rsh-icn-inclear" style="width: 2px; height: 3px"></div><div class="rsh-icn-indark" style="width: 3px; height: 3px"></div></div>',
'',
'<div class="rsh-icn-outerbox" style="width: 13px !important"><div class="rsh-icn-indark rsh-icn-1x2"></div><div class="rsh-icn-inclear rsh-icn-2x2"></div><div class="rsh-icn-indark rsh-icn-1x2"></div><div class="rsh-icn-inclear rsh-icn-2x2"></div><div class="rsh-icn-indark rsh-icn-1x2"></div><div class="rsh-icn-inclear rsh-icn-2x2"></div><div class="rsh-icn-indark rsh-icn-1x2"></div><div class="rsh-icn-inclear rsh-icn-2x2"></div><div class="rsh-icn-indark rsh-icn-1x2"></div><!-->>--><div class="rsh-icn-brclear" style="width: 13px; height: 3px"></div><!--<<--><div class="rsh-icn-indark rsh-icn-3x2"></div><div class="rsh-icn-inclear rsh-icn-2x2"></div><div class="rsh-icn-indark rsh-icn-3x2"></div><div class="rsh-icn-inclear rsh-icn-2x2"></div><div class="rsh-icn-indark rsh-icn-3x2"></div><!-->>--><div class="rsh-icn-brclear" style="width: 13px; height: 2px"></div><!--<<--><div class="rsh-icn-indark" style="width: 6px; height: 2px"></div><div class="rsh-icn-inclear" style="width: 2px; height: 2px"></div><div class="rsh-icn-indark" style="width: 5px; height: 2px"></div></div>',
'<div class="rsh-icn-outerbox"><div class="rsh-icn-brclear" style="width: 13px; height: 1px"></div><div class="rsh-icn-indark rsh-icn-4x3"></div><div class="rsh-icn-inclear" style="width: 5px; height: 3px"></div><div class="rsh-icn-indark rsh-icn-4x3"></div><div class="rsh-icn-brclear" style="width: 13px; height: 3px"></div><div class="rsh-icn-inclear rsh-icn-2x1"></div><div class="rsh-icn-ingray rsh-icn-1x1"></div><div class="rsh-icn-inclear" style="width: 7px; height: 1px"></div><div class="rsh-icn-ingray rsh-icn-1x1"></div><div class="rsh-icn-inclear rsh-icn-2x1"></div><div class="rsh-icn-inclear rsh-icn-2x1"></div><div class="rsh-icn-ingray" style="width: 9px; height: 1px"></div><div class="rsh-icn-inclear rsh-icn-2x1"></div><div class="rsh-icn-inclear rsh-icn-2x1"></div><div class="rsh-icn-ingray rsh-icn-1x1"></div><div class="rsh-icn-inclear" style="width: 7px; height: 1px"></div><div class="rsh-icn-ingray rsh-icn-1x1"></div><div class="rsh-icn-inclear rsh-icn-2x1"></div><div class="rsh-icn-brclear" style="width: 13px; height: 2px"></div></div>'
];
//------------------------------------------------------------------
// Main RSel Highlights panel
$("#RSselection").append(
'<div class="rsh-main-panel" id="divRSHmainPanel" style="padding-bottom: 5px;">' +
'<div class="rsh-btn-row">' +
' <div class="rsh-btn-container">' +
' <input type="checkbox" id="cbRSHSuppRoad" class="btn btn-default" ' +
' style="margin-bottom: 4px; margin-right: 0px; margin-left: 2px;" ' + // Suppress roads
' data-toggle="tooltip" title="Suppress appearance of roads underneath highlights">' +
' </div>' +
' <div class="rsh-btn-container" style="margin-left: 2px;">' +
' <input type="color" id="selRSHColors" value="#FFFF00" class="btn rsh-btn-color" ' + // highlight color
' list="colors" style="" ' +
' data-toggle="tooltip" title="Highlight color">' +
' <datalist id="colors">' +
' <option>#CCFF66</option><option>#28F311</option><option>#66FFCC</option><option>#00F2F2</option><option>#0037D1</option>' +
' <option>#FFFF00</option><option>#F5950E</option><option>#E1201B</option><option>#FF00FF</option><option>#8000FF</option>' +
' </datalist>' +
' <button id="btnRSHighlight" class="btn btn-primary rsh-btn-fa rsh-btn rsh-btn-highlight active" ' + // HIGHLIGHT
' style="height:25px; width: 75px; margin-right: 3px; padding-right: 5px;" ' +
' data-toggle="tooltip" title="Update highlights">' +
' Highlight</button>' +
' <a id="btnRSHClearTop" class="btn btn-primary rsh-btn-fa rsh-btn disabled" href="javascript:void(0)">' + // undo eraser
' <div style="padding-left: 5px; padding-right: 5px" class="icon-eraser fa fa-eraser"' +
' data-toggle="tooltip" title="Erase active highlights"></div></a>' +
' </div>' +
' <div class="rsh-btn-container" style="margin-left: 5px">' +
' <div class="btn-group" role="group">' +
' <a id="btnRSHAdd" style="border-right: solid 1px #7AB0BE;" ' + // Add layer
' class="btn btn-primary rsh-btn-fa rsh-btn" href="javascript:void(0)">' +
' <div style="padding-left: 6px; padding-right: 5px" class="icon-plus fa fa-plus" ' +
' data-toggle="tooltip" title="Add new highlight layer"></div></a>' +
' <div class="btn-group dropup" role="group">' +
' <a id="btnRSHCount" class="btn btn-primary rsh-btn-counter" ' + // layer counter
' href="javascript:void(0)" data-toggle="dropdown">' +
' <span id="txtRSHCount" style="width: 25px; color: #88888E; !important">0</span></a>' + // [#]
' <ul class="dropdown-menu pull-right dropdown-menu-right list-group rsh-expr-menu" ' +
' style="right: -75px; padding: 1px; border-radius: 2px; ">' +
' <li></li>' +
' </ul>' +
' </div>' +
' <a id="btnRSHSubtract" style="border-left: solid 1px #7AB0BE; border-right: solid 1px #7AB0BE;" ' + // Subtract layer
' class="btn btn-primary rsh-btn-fa rsh-btn disabled" href="javascript:void(0)">' +
' <div style="padding-left: 5px; padding-right: 5px" class="icon-minus fa fa-minus" ' +
' data-toggle="tooltip" title="Remove highlight layer"></div></a>' +
' <a id="btnRSHClearAll" style="border-left: solid 1px #B099B1;" ' + // Clear all
' class="btn btn-danger rsh-btn-fa disabled" href="javascript:void(0)">' +
' <div style="color: white; padding-left: 6px; padding-right: 7px !important" class="icon-trash fa fa-trash" ' +
' data-toggle="tooltip" title="Delete all"></div></a>' +
' </div></div>' +
'</div>' +
'<div class="rsh-btn-row" style="margin-top: 6px; margin-bottom: 0px;">' +
' <div class="rsh-btn-container" style="">' +
' <select class="btn rsh-btn-drop disabled" style="width: 166px; margin-left: 4px; margin-right: 2px">' +
' <option><i>(coming soon)</i></option>' +
' </select>' +
' <a id="btnRSHsave" class="btn rsh-btn-fa rsh-btn disabled" style="margin-bottom: 1px" href="javascript:void(0)">' + // Save
' <div style="font-size: 20px; padding:0; margin-right: 6px;" class="icon-save fa fa-save"' +
' data-toggle="tooltip" title="Save highlights"></div></a>' +
' </div>' +
' <div class="rsh-btn-container">' +
' <div class="rsh-btn-container">' +
' <input type="color" id="selRSHBgRoadColor" value="#c0c0c0" class="btn rsh-btn-drop" ' + // trace color
' list="bgRdcolors" style="width: 40px; height: 20px; margin-top:2px; margin-right: 4px; padding: 4px 8px 4px 8px; background-color: #CBE1E8;" ' +
' data-toggle="tooltip" title="Tracing color for non-highlighted roads">' +
' <datalist id="bgRdcolors">' +
' <option>#FFFFFF</option><option>#c0c0c0</option><option>#000000</option><option>#264B01</option><option>#634D41</option>' +
' </datalist>' +
' <input type="checkbox" id="cbRSHBgHighlight" class="btn btn-default" style="margin-bottom: 5px" ' + // Trace background roads checkbox
' data-toggle="tooltip" title="Trace over non-highlighted roads with a single color">' +
' </div>' +
' </div>' +
'</div>');
$("[data-toggle=tooltip]").tooltip({
placement: 'auto top',
delay: {
show: 1100,
hide: 100
},
html: true,
template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="my-tooltip-header"><b></b></div><div class="my-tooltip-body tooltip-inner" style="font-weight: bold; !important"></div></div>'
});
// Additional line options drop menu
$("#RSselection").append(
'<div id="divRSHdropBarPanel" class="rsh-dropbar-panel">' +
'<span id="spanRSHdropBarHeader" class="rsh-vcentered">' +
'<a id="aRSHdropBarLink" name="Hide" class="rsh-link" href="javascript:void(0);"><div class="rsh-arrow-up rsh-vcentered"></div> Hide additional line options</a></span>' +
'<span id="spanRSHdropBarContents" class="rsh-dropbar-contents">' +
// table for additional line options within dropBar panel
'<table class="rsh-dropbar-panel">' +
'<tr><td style="vertical-align: bottom">Weight</td><td style="vertical-align: bottom">Opacity</td>' +
'<td rowspan=4>' +
// inner table for dash style options
'<table class="rsh-dropbar-panel" style="padding-left: 3px; padding-right: 3px; border-left: 1px solid #DFDFDF !important">' +
'<tr><td colspan=2 style="vertical-align: bottom">Dash style</td>' +
'</tr><tr><td colspan=2>' + rshIcons[2] +
'<select id="selRSHDash" class="rsh-dropbar-panel" style="border-color: #B4B4B4"></select></td>' +
'</tr><tr>' +
'<td style="vertical-align: bottom">Dash width</td><td style="vertical-align: bottom">Spacing</td>' +
'</tr><tr>' +
'<td>' + rshIcons[4] +
'<input type="number" id="numRSHDashSizeScale" style="border-radius: 3px; background-color: #EFEFEF;" class="rsh-dropbar-panel" min="0.1" max="10" value="1" step="0.1" title="Dash size (relative)" disabled \></td>' +
'<td>' + rshIcons[5] +
'<input type="number" id="numRSHSpacingScale" style="border-radius: 3px; background-color: #EFEFEF;" class="rsh-dropbar-panel" min="0.1" max="10" value="1" step="0.1" title="Dash spacing (relative)" disabled \></td>' +
'</tr></table></td>' +
'</tr><tr>' +
'<td>' + rshIcons[0] +
'<input type="number" id="numRSHScaleWidth" style="border-radius: 3px" class="rsh-dropbar-panel" min="0.1" max="10" value="1" step="0.1" title="Line weight (relative)"></td>' +
'<td>' + rshIcons[1] +
'<input type="number" id="numRSHOpacity" style="border-radius: 3px" class="rsh-dropbar-panel" min="0" max="1" value="0.5" step="0.1" title="Color opacity (0–1)"></td>' +
'</tr><tr>' +
'<td colspan=2 style="vertical-align: bottom">End cap</td>' +
'<tr><td colspan=2>' + '' +
'<select id="selRSHCap" class="rsh-dropbar-panel" style="border-color: #B4B4B4"></select></td>' +
'</tr></table>' +
'</span></div>');
};
// Insert UI into side-panel of WME under RSel tab
SetupRSHInterface();
setTimeout(ToggleDropBarMenu, 0);
// Retrieve any data from saved sessionStorage
var rsh = checkForAutosave();
// Setup event listeners/triggers
$("#btnRSHighlight").click(drawHighlightsLayer);
$("#btnRSHAdd").click(addHighlightLayer);
$("#btnRSHSubtract").click(subtractHighlightLayer);
$("#btnRSHClearTop").click(eraseHighlight);
$("#btnRSHClearAll").click(clearAllHighlights);
var d, c, dashSelection = document.getElementById("selRSHDash"),
capSelection = document.getElementById("selRSHCap");
for (d = 0; d < rsh.presets.lineAttributes.strokeDashstyle.length; d++) {
dashSelection.add(new Option(rsh.presets.lineAttributes.strokeDashstyle[
d]));
};
for (c = 0; c < rsh.presets.lineAttributes.strokeLinecap.length; c++) {
capSelection.add(new Option(rsh.presets.lineAttributes.strokeLinecap[c]));
};
//$("#selRSHColors").click(
document.getElementById("selRSHColors").onclick = function() {
rsh.triggerUpdate = true;
updatePrefsFromPanel();
updateHighlightButton();
};
document.getElementById("cbRSHBgHighlight").onclick = function() {
document.getElementById("numRSHSpacingScale").onchange = function() {
rsh.triggerUpdate = true;
updatePrefsFromPanel();
};
};
dashSelection.onclick = function() {
rsh.triggerUpdate = true;
updatePrefsFromPanel();
updateDashButtons();
};
capSelection.onclick = function() {
rsh.triggerUpdate = true;
updatePrefsFromPanel();
};
document.getElementById("numRSHOpacity").onclick = function() {
document.getElementById("numRSHOpacity").onchange = function() {
rsh.triggerUpdate = true;
updatePrefsFromPanel();
};
};
document.getElementById("numRSHScaleWidth").onclick = function() {
document.getElementById("numRSHScaleWidth").onchange = function() {
rsh.triggerUpdate = true;
updatePrefsFromPanel();
};
};
document.getElementById("numRSHDashSizeScale").onclick = function() {
document.getElementById("numRSHDashSizeScale").onchange = function() {
rsh.triggerUpdate = true;
updatePrefsFromPanel();
};
};
document.getElementById("numRSHSpacingScale").onclick = function() {
document.getElementById("numRSHSpacingScale").onchange = function() {
rsh.triggerUpdate = true;
updatePrefsFromPanel();
};
};
window.addEventListener("beforeunload", function() {
//rsh.USR_EXPR[rsh.lastIdx] = {};
rsh.housekeep();
rsh.idx = rsh.lastIdx;
if (sessionStorage) sessionStorage.WME_RSHighlights = JSON.stringify(
rsh);
}, false);
// Event listeners to redraw highlights
Waze.map.events.register("zoomend", Waze.map, function() {
Highlight();
setTimeout(Highlight, 1500)
});
Waze.map.events.register("moveend", Waze.map, function() {
Highlight();
setTimeout(Highlight, 1500)
});
Waze.map.events.register("mergeend", Waze.map, function() {
Highlight();
setTimeout(Highlight, 1500)
});
//Waze.map.events.register("move", Waze.map, Highlight);
//Waze.map.events.register("changelayer", Waze.map, Highlight);
//Waze.map.events.register("visibilitychanged", Waze.map, Highlight);
return rsh
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var createHighlightLayer = function() {
var rsh_oLayer = new OL.Layer.Vector("Road Selector Highlights", {
rendererOptions: {
zIndexing: true
},
uniqueName: '__RSel_Highlights'
});
I18n.translations.en.layers.name["__RSel_Highlights"] =
"Road Selector Highlights";
rsh_oLayer.setZIndex(52);
Waze.map.addLayer(rsh_oLayer);
Waze.map.addControl(new OL.Control.DrawFeature(rsh_oLayer, OL.Handler
.Path));
rsh_oLayer.displayOutsideMapExtent = true;
rsh_oLayer.setVisibility(rsh.showSessionHighlights);
return rsh_oLayer;
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var rsh = InitRSelHighlights();
// Update panel
if (rsh.loadedSavedSession) {
updatePanelFromPrefs(rsh);
updateExprMenu(rsh);
} else {
updatePanelFromPrefs(rsh);
}
var rsh_seg = [];
// Add Road Selector Highlights layer to map
var rsh_oLayer = createHighlightLayer();
RSH_TEST = rsh;
Highlight();
}
/*//////////////////////////////////////////////////////////////////////////*/
function waitForWMERSel() {
var waitCount = 0,
tryInit = function() {
try {
if (typeof unsafeWindow.RoadSelector === 'undefined') {
if (waitCount++ < 20) {
setTimeout(tryInit, 600);
} else {
console.error(
'WME RSel Highlights: Could not link up with WME Road Selector.');
}
} else {
/* unsafeWindow.RoadSelector:
checkSegment(expression, segment)
getCurrentExpression()
getExpressionText(expression)
getSavedNames()
getSavedExpression(name)
*/
var RSel = unsafeWindow.RoadSelector;
RSelHighlights(RSel);
}
} catch (err) {
console.error(err)
}
};
tryInit();
}
setTimeout(waitForWMERSel, 500);
})();