您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Find segments that don't match lock levels
当前为
// ==UserScript== // @name WME Wide-Angle Lens Locks // @namespace https://greasyfork.org/en/users/19861-vtpearce // @description Find segments that don't match lock levels // @author vtpearce and crazycaveman // @include https://www.waze.com/editor // @include /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor.*$/ // @version 1.2.3 // @grant none // @copyright 2017 vtpearce // @license CC BY-SA 4.0 // ==/UserScript== /*global W, OL, $, WazeWrap, WMEWAL*/ var WMEWAL_Locks; (function (WMEWAL_Locks) { var IncludeInOutput; (function (IncludeInOutput) { IncludeInOutput[IncludeInOutput["Low"] = 1] = "Low"; IncludeInOutput[IncludeInOutput["High"] = 2] = "High"; })(IncludeInOutput || (IncludeInOutput = {})); var Operation; (function (Operation) { Operation[Operation["Equal"] = 1] = "Equal"; Operation[Operation["NotEqual"] = 2] = "NotEqual"; })(Operation || (Operation = {})); var pluginName = "WMEWAL-Locks"; WMEWAL_Locks.Title = "Locks"; WMEWAL_Locks.MinimumZoomLevel = 2; WMEWAL_Locks.SupportsSegments = true; WMEWAL_Locks.SupportsVenues = false; var settingsKey = "WMEWALLocksSettings"; var savedSettingsKey = "WMEWALLocksSavedSettings"; var settings = null; var savedSettings = ""; var streets = null; var state; var stateName; var nameRegex = null; var cityRegex = null; var initCount = 0; function GetTab() { var html = "<table style='border-collapse: separate; border-spacing:0px 1px;'>"; html += "<tbody>"; html += "<tr><td style='font-size:1.2em'><b>Output To:</b></td></tr>"; html += "<tr><td style='padding-left:20px'>" + "<select id='_wmewalLocksOutputTo'>" + "<option value='csv'>CSV File</option>" + "<option value='tab'>Browser Tab</option>" + "<option value='both'>Both CSV File and Browser Tab</option></select></td></tr>"; html += "<tr><td style='border-top: 1px solid; font-size: 1.2em'><b>Saved Settings</b></td></tr>"; html += "<tr><td style='padding-left: 20px; padding-bottom: 8px'>" + "<select id='_wmewalLocksSavedSettings'/><br/>" + "<button class='btn btn-primary' id='_wmewalLocksLoadSetting' title='Load'>Load</button>" + "<button class='btn btn-primary' style='margin-left: 4px;' id='_wmewalLocksSaveSetting' title='Save'>Save</button>" + "<button class='btn btn-primary' style='margin-left: 4px;' id='_wmewalLocksDeleteSetting' title='Delete'>Delete</button></td></tr>"; html += "<tr><td style='border-top: 1px solid; padding-top: 4px;font-size:1.2em'><b>Lock Levels</b></td></tr>"; html += "<tr><td><table style='border-collapse: separate; border-spacing: 0px'>"; html += "<tr><td><b>Include in output</b></td>" + "<td><select id='_wmewalLocksIncludeInOutput'>" + "<option value='" + IncludeInOutput.Low.toString() + "'>Locked too low</option>" + "<option value='" + IncludeInOutput.High.toString() + "'>Locked too high</option>" + "<option value='" + (IncludeInOutput.Low | IncludeInOutput.High).toString() + "'>Locked incorrectly</option></select></td></tr>"; html += "<tr><td>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.Street)) + "</td><td><select id='_wmewalLocksStreet'>" + "<option value='1' selected='selected'>1</option>" + "<option value='2'>2</option>" + "<option value='3'>3</option>" + "<option value='4'>4</option>" + "<option value='5'>5</option>" + "<option value='6'>6</option></select>" + "<br/><input id='_wmewalLocksPlusOneWayStreet' type='checkbox'/><label for='_wmewalLocksPlusOneWayStreet' style='margin-left: 8px'>+1 for One-Way</label>" + "</td></tr>"; html += "<tr><td>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.PrimaryStreet)) + "</td><td><select id='_wmewalLocksPrimaryStreet'>" + "<option value='1'>1</option>" + "<option value='2' selected='selected'>2</option>" + "<option value='3'>3</option>" + "<option value='4'>4</option>" + "<option value='5'>5</option>" + "<option value='6'>6</option></select>" + "<br/><input id='_wmewalLocksPlusOneWayPS' type='checkbox'/><label for='_wmewalLocksPlusOneWayPS' style='margin-left: 8px'>+1 for One-Way</label></td></tr>"; html += "<tr><td>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.MinorHighway)) + "</td><td><select id='_wmewalLocksMinorHighway'>" + "<option value='1'>1</option>" + "<option value='2'>2</option>" + "<option value='3' selected='selected'>3</option>" + "<option value='4'>4</option>" + "<option value='5'>5</option>" + "<option value='6'>6</option></select>" + "<br/><input id='_wmewalLocksPlusOneWayMinorH' type='checkbox'/><label for='_wmewalLocksPlusOneWayMinorH' style='margin-left: 8px'>+1 for One-Way</label></td></tr>"; html += "<tr><td>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.MajorHighway)) + "</td><td><select id='_wmewalLocksMajorHighway'>" + "<option value='1'>1</option>" + "<option value='2'>2</option>" + "<option value='3'>3</option>" + "<option value='4' selected='selected'>4</option>" + "<option value='5'>5</option>" + "<option value='6'>6</option></select>" + "<br/><input id='_wmewalLocksPlusOneWayMajorH' type='checkbox'/><label for='_wmewalLocksPlusOneWayMajorH' style='margin-left: 8px'>+1 for One-Way</label></td></tr>"; html += "<tr><td>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.Freeway)) + "</td><td><select id='_wmewalLocksFreeway'>" + "<option value='1'>1</option>" + "<option value='2'>2</option>" + "<option value='3'>3</option>" + "<option value='4'>4</option>" + "<option value='5' selected='selected'>5</option>" + "<option value='6'>6</option></select>" + "<br/><input id='_wmewalLocksPlusOneWayFW' type='checkbox'/><label for='_wmewalLocksPlusOneWayFW' style='margin-left: 8px'>+1 for One-Way</label></td></tr>"; html += "<tr><td>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.Ramp)) + "</td><td><select id='_wmewalLocksRamp'>" + "<option value='7' selected='selected'>Highest connection</option>" + "<option value='1'>1</option>" + "<option value='2'>2</option>" + "<option value='3'>3</option>" + "<option value='4'>4</option>" + "<option value='5'>5</option>" + "<option value='6'>6</option></select>" + "<br/><input id='_wmewalLocksPlusOneWayRamp' type='checkbox'/><label for='_wmewalLocksPlusOneWayRamp' style='margin-left: 8px'>+1 for One-Way</label></td></tr>"; html += "<tr><td>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.Railroad)) + "</td><td><select id='_wmewalLocksRailroad'>" + "<option value='1'>1</option>" + "<option value='2' selected='selected'>2</option>" + "<option value='3'>3</option>" + "<option value='4'>4</option>" + "<option value='5'>5</option>" + "<option value='6'>6</option></select>" + "</td></tr>"; html += "</table></td></tr>"; html += "<tr><td style='border-top: 1px solid; padding-top: 4px;font-size:1.2em'><b>Filters</b></td></tr>"; html += "<tr><td><b>Name RegEx:</b></td></tr>"; html += "<tr><td style='padding-left: 20px'><input type='text' id='_wmewalLocksName' class='wal-textbox'/><br/>" + "<input id='_wmewalLocksIgnoreCase' type='checkbox'/>" + "<label for='_wmewalLocksIgnoreCase' style='margin-left: 8px'>Ignore case</label></td></tr>"; html += "<tr><td><b>City RegEx:</b></td></tr>"; html += "<tr><td style='padding-left: 20px'><input type='text' id='_wmewalLocksCity' class='wal-textbox'/><br/>" + "<input id='_wmewalLocksCityIgnoreCase' type='checkbox'/>" + "<label for='_wmewalLocksCityIgnoreCase' style='margin-left: 8px'>Ignore case</label></td></tr>"; html += "<tr><td><b>State:</b></td></tr>"; html += "<tr><td style='padding-left: 20px'>" + "<select id='_wmewalLocksStateOp'>" + "<option value='" + Operation.Equal.toString() + "' selected='selected'>=</option>" + "<option value='" + Operation.NotEqual.toString() + "'><></option></select>" + "<select id='_wmewalLocksState'/></td></tr>"; html += "<tr><td><b>Road Type:</b></td></tr>"; html += "<tr><td style='padding-left: 20px'>" + "<button id='_wmewalLocksRoadTypeAny' class='btn btn-primary' style='margin-right: 8px' title='Any'>Any</button>" + "<button id='_wmewalLocksRoadTypeClear' class='btn btn-primary' title='Clear'>Clear</button><br/>" + "<input type='checkbox' id='_wmewalLocksRoadTypeStreet' name='_wmewalLocksRoadType' value='" + WMEWAL.RoadType.Street.toString() + "'/>" + "<label for='_wmewalLocksRoadTypeStreet' style='margin-left: 8px'>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.Street)) + "</label><br/>" + "<input type='checkbox' id='_wmewalLocksRoadTypePrimary' name='_wmewalLocksRoadType' value='" + WMEWAL.RoadType.PrimaryStreet.toString() + "'/>" + "<label for='_wmewalLocksRoadTypePrimary' style='margin-left: 8px'>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.PrimaryStreet)) + "</label><br/>" + "<input type='checkbox' id='_wmewalLocksRoadTypeMinorHighway' name='_wmewalLocksRoadType' value='" + WMEWAL.RoadType.MinorHighway.toString() + "'/>" + "<label for='_wmewalLocksRoadTypeMinorHighway' style='margin-left: 8px'>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.MinorHighway)) + "</label><br/>" + "<input type='checkbox' id='_wmewalLocksRoadTypeMajorHighway' name='_wmewalLocksRoadType' value='" + WMEWAL.RoadType.MajorHighway.toString() + "'/>" + "<label for='_wmewalLocksRoadTypeMajorHighway' style='margin-left: 8px'>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.MajorHighway)) + "</label><br/>" + "<input type='checkbox' id='_wmewalLocksRoadTypeRamp' name='_wmewalLocksRoadType' value='" + WMEWAL.RoadType.Ramp.toString() + "'/>" + "<label for='_wmewalLocksRoadTypeRamp' style='margin-left: 8px'>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.Ramp)) + "</label><br/>" + "<input type='checkbox' checked='checked' id='_wmewalLocksRoadTypeFreeway' name='_wmewalLocksRoadType' value='" + WMEWAL.RoadType.Freeway.toString() + "'/>" + "<label for='_wmewalLocksRoadTypeFreeway' style='margin-left: 8px'>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.Freeway)) + "</label><br/>" + "<input type='checkbox' checked='checked' id='_wmewalLocksRoadTypeRailroad' name='_wmewalLocksRoadType' value='" + WMEWAL.RoadType.Railroad.toString() + "'/>" + "<label for='_wmewalLocksRoadTypeRailroad' style='margin-left: 8px'>" + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(WMEWAL.RoadType.Railroad)) + "</label>" + "</td></tr>"; html += "<tr><td><input id='_wmewalLocksEditable' type='checkbox'/>" + "<label for='_wmewalLocksEditable' style='margin-left: 8px'>Editable by me</label></td></tr>"; html += "<tr><td><input id='_wmewalLocksExcludeRoundabouts' type='checkbox'/>" + "<label for='_wmewalLocksExcludeRoundabouts' style='margin-left: 8px'>Exclude Roundabouts</label></td></tr>"; html += "<tr><td><input id='_wmewalLocksExcludeJunctionBoxes' type='checkbox' checked='checked'/>" + "<label for='_wmewalLocksExcludeJunctionBoxes' style='margin-left: 8px'>Exclude Junction Boxes</label></td></tr>"; html += "</tbody></table>"; return html; } WMEWAL_Locks.GetTab = GetTab; function TabLoaded() { updateStates(); updateUI(); updateSavedSettingsList(); $("#_wmewalLocksState").on("focus", updateStates); $("#_wmewalLocksRoadTypeAny").on("click", function () { $("input[name=_wmewalLocksRoadType]").prop("checked", true); }); $("#_wmewalLocksRoadTypeClear").on("click", function () { $("input[name=_wmewalLocksRoadType]").prop("checked", false); }); $("#_wmewalLocksLoadSetting").on("click", loadSetting); $("#_wmewalLocksSaveSetting").on("click", saveSetting); $("#_wmewalLocksDeleteSetting").on("click", deleteSetting); } WMEWAL_Locks.TabLoaded = TabLoaded; function updateStates() { var selectState = $("#_wmewalLocksState"); // Preserve current selection var currentId = parseInt(selectState.val()); selectState.empty(); var stateObjs = []; stateObjs.push({ id: null, name: "" }); for (var s in W.model.states.objects) { if (W.model.states.objects.hasOwnProperty(s)) { var st = W.model.states.get(parseInt(s)); if (st.id !== 1 && st.name.length > 0) { stateObjs.push({ id: st.id, name: st.name }); } } } stateObjs.sort(function (a, b) { if (a.id == null) { return -1; } else { return a.name.localeCompare(b.name); } }); for (var ix = 0; ix < stateObjs.length; ix++) { var so = stateObjs[ix]; var stateOption = $("<option/>").text(so.name).attr("value", so.id); if (currentId != null && so.id === currentId) { stateOption.attr("selected", "selected"); } selectState.append(stateOption); } } function updateSavedSettingsList() { var s = $("#_wmewalLocksSavedSettings"); s.empty(); for (var ixSaved = 0; ixSaved < savedSettings.length; ixSaved++) { var opt = $("<option/>").attr("value", ixSaved).text(savedSettings[ixSaved].Name); s.append(opt); } } function updateUI() { $("#_wmewalLocksOutputTo").val(settings.OutputTo); $("#_wmewalLocksIncludeInOutput").val(settings.IncludeInOutput); $("#_wmewalLocksStreet").val(settings.StreetLockLevel); $("#_wmewalLocksPrimaryStreet").val(settings.PrimaryStreetLockLevel); $("#_wmewalLocksMinorHighway").val(settings.MinorHighwayLockLevel); $("#_wmewalLocksMajorHighway").val(settings.MajorHighwayLockLevel); $("#_wmewalLocksFreeway").val(settings.FreewayLockLevel); $("#_wmewalLocksRamp").val(settings.RampLockLevel); $("#_wmewalLocksRailroad").val(settings.RailroadLockLevel); $("#_wmewalLocksName").val(settings.Regex || ""); $("#_wmewalLocksIgnoreCase").prop("checked", settings.RegexIgnoreCase); $("#_wmewalLocksCity").val(settings.CityRegex || ""); $("#_wmewalLocksCityIgnoreCase").prop("checked", settings.CityRegexIgnoreCase); $("#_wmewalLocksState").val(settings.State); $("#_wmewalLocksRoadTypeStreet").prop("checked", settings.RoadTypeMask & WMEWAL.RoadType.Street); $("#_wmewalLocksRoadTypePrimary").prop("checked", settings.RoadTypeMask & WMEWAL.RoadType.PrimaryStreet); $("#_wmewalLocksRoadTypeMinorHighway").prop("checked", settings.RoadTypeMask & WMEWAL.RoadType.MinorHighway); $("#_wmewalLocksRoadTypeMajorHighway").prop("checked", settings.RoadTypeMask & WMEWAL.RoadType.MajorHighway); $("#_wmewalLocksRoadTypeRamp").prop("checked", settings.RoadTypeMask & WMEWAL.RoadType.Ramp); $("#_wmewalLocksRoadTypeFreeway").prop("checked", settings.RoadTypeMask & WMEWAL.RoadType.Freeway); $("#_wmewalLocksRoadTypeRailroad").prop("checked", settings.RoadTypeMask & WMEWAL.RoadType.Railroad); $("#_wmewalLocksEditable").prop("checked", settings.EditableByMe); $("#_wmewalLocksExcludeRoundabouts").prop("checked", settings.ExcludeRoundabouts); $("#_wmewalLocksExcludeJunctionBoxes").prop("checked", settings.ExcludeJunctionBoxes); $("#_wmewalLocksPlusOneWayStreet").prop("checked", settings.PlusOneWayMask & WMEWAL.RoadType.Street); $("#_wmewalLocksPlusOneWayPS").prop("checked", settings.PlusOneWayMask & WMEWAL.RoadType.PrimaryStreet); $("#_wmewalLocksPlusOneWayMinorH").prop("checked", settings.PlusOneWayMask & WMEWAL.RoadType.MinorHighway); $("#_wmewalLocksPlusOneWayMajorH").prop("checked", settings.PlusOneWayMask & WMEWAL.RoadType.MajorHighway); $("#_wmewalLocksPlusOneWayFW").prop("checked", settings.PlusOneWayMask & WMEWAL.RoadType.Freeway); $("#_wmewalLocksPlusOneWayRamp").prop("checked", settings.PlusOneWayMask & WMEWAL.RoadType.Ramp); $("#_wmewalLocksStateOp").val(settings.StateOperation || Operation.Equal.toString()); } function loadSetting() { var selectedSetting = parseInt($("#_wmewalLocksSavedSettings").val()); if (selectedSetting == null || isNaN(selectedSetting) || selectedSetting < 0 || selectedSetting > savedSettings.length) { return; } var savedSetting = savedSettings[selectedSetting].Setting; settings.OutputTo = $("#_wmewalLocksOutputTo").val(); for (var name_1 in savedSetting) { if (settings.hasOwnProperty(name_1)) { settings[name_1] = savedSetting[name_1]; } } updateUI(); } function validateSettings() { var allOk = true; var message = ""; var mask = 0; $("input[name=_wmewalLocksRoadType]:checked").each(function (ix, e) { mask = mask | parseInt(e.value); }); if (mask === 0) { message = "Please select at least one road type."; allOk = false; } var selectedState = $("#_wmewalLocksState").val(); if (selectedState != null && selectedState.length > 0) { if (W.model.states.get(selectedState) == null) { message += ((message.length > 0 ? "\n" : "") + "Invalid state selection"); allOk = false; } } var ignoreCase = $("#_wmewalLocksIgnoreCase").prop("checked"); var pattern = $("#_wmewalLocksName").val(); var r; if (pattern.length > 0) { try { r = (ignoreCase ? new RegExp(pattern, "i") : new RegExp(pattern)); } catch (error) { message += ((message.length > 0 ? "\n" : "") + "Name RegEx is invalid"); allOk = false; } } ignoreCase = $("#_wmewalLocksCityIgnoreCase").prop("checked"); pattern = $("#_wmewalLocksCity").val(); if (pattern.length > 0) { try { r = (ignoreCase ? new RegExp(pattern, "i") : new RegExp(pattern)); } catch (error) { message += ((message.length > 0 ? "\n" : "") + "City RegEx is invalid"); allOk = false; } } if (!allOk) { alert(pluginName + ": " + message); } return allOk; } function saveSetting() { if (validateSettings()) { var plusOneWayMask = 0; var s_1 = { RoadTypeMask: null, State: null, Regex: null, RegexIgnoreCase: $("#_wmewalLocksIgnoreCase").prop("checked"), ExcludeJunctionBoxes: $("#_wmewalLocksExcludeJunctionBoxes").prop("checked"), ExcludeRoundabouts: $("#_wmewalLocksExcludeRoundabouts").prop("checked"), EditableByMe: $("#_wmewalLocksEditable").prop("checked"), StreetLockLevel: parseInt($("#_wmewalLocksStreet").val()), PrimaryStreetLockLevel: parseInt($("#_wmewalLocksPrimaryStreet").val()), MinorHighwayLockLevel: parseInt($("#_wmewalLocksMinorHighway").val()), MajorHighwayLockLevel: parseInt($("#_wmewalLocksMajorHighway").val()), FreewayLockLevel: parseInt($("#_wmewalLocksFreeway").val()), RampLockLevel: parseInt($("#_wmewalLocksRamp").val()), IncludeInOutput: parseInt($("#_wmewalLocksIncludeInOutput").val()), PlusOneWayMask: plusOneWayMask, CityRegex: null, CityRegexIgnoreCase: $("#_wmewalLocksCityIgnoreCase").prop("checked"), StateOperation: parseInt($("#_wmewalLocksStateOp").val()), RailroadLockLevel: parseInt($("#_wmewalLocksRailroad").val()) }; s_1.RoadTypeMask = 0; $("input[name=_wmewalLocksRoadType]:checked").each(function (ix, e) { s_1.RoadTypeMask = s_1.RoadTypeMask | parseInt(e.value); }); if ($("#_wmewalLocksPlusOneWayStreet").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.Street; } if ($("#_wmewalLocksPlusOneWayPS").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.PrimaryStreet; } if ($("#_wmewalLocksPlusOneWayMinorH").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.MinorHighway; } if ($("#_wmewalLocksPlusOneWayMajorH").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.MajorHighway; } if ($("#_wmewalLocksPlusOneWayFW").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.Freeway; } if ($("#_wmewalLocksPlusOneWayRamp").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.Ramp; } var selectedState = $("#_wmewalLocksState").val(); if (selectedState != null && selectedState.length > 0) { s_1.State = W.model.states.get(parseInt(selectedState)).id; } var pattern = $("#_wmewalLocksName").val(); if (pattern.length > 0) { s_1.Regex = pattern; } pattern = $("#_wmewalLocksCity").val(); if (pattern.length > 0) { s_1.CityRegex = pattern; } var sName = prompt("Enter a name for this setting"); if (sName == null) { return; } // Check to see if there is already a name that matches this for (var ixSetting = 0; ixSetting < savedSettings.length; ixSetting++) { if (savedSettings[ixSetting].Name === sName) { if (confirm("A setting with this name already exists. Overwrite?")) { savedSettings[ixSetting].Setting = s_1; updateSavedSettings(); } else { alert("Please pick a new name."); } return; } } var savedSetting = { Name: sName, Setting: s_1 }; savedSettings.push(savedSetting); updateSavedSettings(); } } function deleteSetting() { var selectedSetting = parseInt($("#_wmewalLocksSavedSettings").val()); if (selectedSetting == null || isNaN(selectedSetting) || selectedSetting < 0 || selectedSetting > savedSettings.length) { return; } if (confirm("Are you sure you want to delete this saved setting?")) { savedSettings.splice(selectedSetting, 1); updateSavedSettings(); } } function ScanStarted() { var allOk = validateSettings(); streets = []; if (allOk) { settings.OutputTo = $("#_wmewalLocksOutputTo").val(); settings.RoadTypeMask = 0; $("input[name=_wmewalLocksRoadType]:checked").each(function (ix, e) { settings.RoadTypeMask = settings.RoadTypeMask | parseInt(e.value); }); var selectedState = $("#_wmewalLocksState").val(); state = null; settings.State = null; stateName = null; if (selectedState != null && selectedState.length > 0) { state = W.model.states.get(selectedState); settings.State = state.id; stateName = state.name; } settings.StateOperation = parseInt($("#_wmewalLocksStateOp").val()); settings.RegexIgnoreCase = $("#_wmewalLocksIgnoreCase").prop("checked"); var pattern = $("#_wmewalLocksName").val(); settings.Regex = null; nameRegex = null; if (pattern.length > 0) { settings.Regex = pattern; nameRegex = (settings.RegexIgnoreCase ? new RegExp(pattern, "i") : new RegExp(pattern)); } settings.CityRegexIgnoreCase = $("#_wmewalLocksCityIgnoreCase").prop("checked"); pattern = $("#_wmewalLocksCity").val(); settings.CityRegex = null; cityRegex = null; if (pattern.length > 0) { settings.CityRegex = pattern; cityRegex = (settings.CityRegexIgnoreCase ? new RegExp(pattern, "i") : new RegExp(pattern)); } settings.ExcludeRoundabouts = $("#_wmewalLocksExcludeRoundabouts").prop("checked"); settings.ExcludeJunctionBoxes = $("#_wmewalLocksExcludeJunctionBoxes").prop("checked"); settings.EditableByMe = $("#_wmewalLocksEditable").prop("checked"); settings.StreetLockLevel = parseInt($("#_wmewalLocksStreet").val()); settings.PrimaryStreetLockLevel = parseInt($("#_wmewalLocksPrimaryStreet").val()); settings.MinorHighwayLockLevel = parseInt($("#_wmewalLocksMinorHighway").val()); settings.MajorHighwayLockLevel = parseInt($("#_wmewalLocksMajorHighway").val()); settings.FreewayLockLevel = parseInt($("#_wmewalLocksFreeway").val()); settings.RampLockLevel = parseInt($("#_wmewalLocksRamp").val()); settings.RailroadLockLevel = parseInt($("#_wmewalLocksRailroad").val()); settings.IncludeInOutput = parseInt($("#_wmewalLocksIncludeInOutput").val()); var plusOneWayMask = 0; if ($("#_wmewalLocksPlusOneWayStreet").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.Street; } if ($("#_wmewalLocksPlusOneWayPS").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.PrimaryStreet; } if ($("#_wmewalLocksPlusOneWayMinorH").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.MinorHighway; } if ($("#_wmewalLocksPlusOneWayMajorH").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.MajorHighway; } if ($("#_wmewalLocksPlusOneWayFW").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.Freeway; } if ($("#_wmewalLocksPlusOneWayRamp").prop("checked")) { plusOneWayMask = plusOneWayMask | WMEWAL.RoadType.Ramp; } settings.PlusOneWayMask = plusOneWayMask; if (settings.RoadTypeMask & 1 || settings.RoadTypeMask & 4096) { WMEWAL_Locks.MinimumZoomLevel = 4; } else { WMEWAL_Locks.MinimumZoomLevel = 2; } updateSettings(); } return allOk; } WMEWAL_Locks.ScanStarted = ScanStarted; function isOneWay(segment) { return segment.attributes.fwdDirection !== segment.attributes.revDirection && (segment.attributes.fwdDirection || segment.attributes.revDirection); } function ScanExtent(segments, venues) { var def = $.Deferred(); var extentStreets = []; function addSegment(s, rId) { var sid = s.attributes.primaryStreetID; var address = s.getAddress(); var thisStreet = null; if (sid != null) { // let street = W.model.streets.get(sid); thisStreet = extentStreets.find(function (e) { var matches = (e.id === sid && (e.lockLevel === (s.attributes.lockRank || 0) + 1) && e.roundaboutId === rId && e.roadType === s.attributes.roadType); if (matches && (nameRegex != null || cityRegex != null)) { // Test for alt names for (var ixAlt = 0; ixAlt < e.altStreets.length && matches; ixAlt++) { matches = false; for (var ixSegAlt = 0; ixSegAlt < address.attributes.altStreets.length && !matches; ixSegAlt++) { if (e.altStreets[ixAlt].id === address.attributes.altStreets[ixSegAlt].id) { matches = true; } } } } return matches; }); } if (thisStreet == null) { thisStreet = { id: sid, city: ((address && !address.attributes.isEmpty && address.attributes.city.hasName()) ? address.attributes.city.attributes.name : "No City"), state: ((address && !address.attributes.isEmpty) ? address.attributes.state.name : "No State"), name: ((address && !address.attributes.isEmpty && !address.attributes.street.isEmpty) ? address.attributes.street.name : "No street"), geometries: new OL.Geometry.Collection(), lockLevel: (s.attributes.lockRank || 0) + 1, segments: [], roundaboutId: rId, altStreets: [], roadType: s.attributes.roadType }; if (nameRegex != null) { for (var ixAlt = 0; ixAlt < s.attributes.streetIDs.length; ixAlt++) { var altStreet = W.model.streets.get(s.attributes.streetIDs[ixAlt]); if (altStreet != null) { thisStreet.altStreets.push({ id: s.attributes.streetIDs[ixAlt], name: altStreet.name }); } } } extentStreets.push(thisStreet); } thisStreet.segments.push({ id: s.attributes.id, center: s.attributes.geometry.getCentroid() }); thisStreet.geometries.addComponents([s.attributes.geometry.clone()]); } for (var ix = 0; ix < segments.length; ix++) { var segment = segments[ix]; if (segment != null) { if ((WMEWAL.WazeRoadTypeToRoadTypeBitmask(segment.attributes.roadType) & settings.RoadTypeMask) && (!settings.EditableByMe || segment.arePropertiesEditable()) && (!settings.ExcludeJunctionBoxes || !segment.isInBigJunction())) { var address = segment.getAddress(); if (state != null) { if (address != null && address.attributes != null && !address.attributes.isEmpty && address.attributes.state != null) { if (settings.StateOperation === Operation.Equal && address.attributes.state.id !== state.id || settings.StateOperation === Operation.NotEqual && address.attributes.state.id === state.id) { continue; } } else if (settings.StateOperation === Operation.Equal) { continue; } } var plusOne = (isOneWay(segment) && (WMEWAL.WazeRoadTypeToRoadTypeBitmask(segment.attributes.roadType) & settings.PlusOneWayMask)) ? 1 : 0; var incorrectLock = false; switch (segment.attributes.roadType) { case 1: if ((settings.IncludeInOutput & IncludeInOutput.Low && (segment.attributes.lockRank || 0) + 1 < settings.StreetLockLevel + plusOne) || (settings.IncludeInOutput & IncludeInOutput.High && (segment.attributes.lockRank || 0) + 1 > settings.StreetLockLevel + plusOne)) { incorrectLock = true; } break; case 2: if ((settings.IncludeInOutput & IncludeInOutput.Low && (segment.attributes.lockRank || 0) + 1 < settings.PrimaryStreetLockLevel + plusOne) || (settings.IncludeInOutput & IncludeInOutput.High && (segment.attributes.lockRank || 0) + 1 > settings.PrimaryStreetLockLevel + plusOne)) { incorrectLock = true; } break; case 3: if ((settings.IncludeInOutput & IncludeInOutput.Low && (segment.attributes.lockRank || 0) + 1 < settings.FreewayLockLevel + plusOne) || (settings.IncludeInOutput & IncludeInOutput.High && (segment.attributes.lockRank || 0) + 1 > settings.FreewayLockLevel + plusOne)) { incorrectLock = true; } break; case 4: var expectedLockRank = 0; if (settings.RampLockLevel === 7) { // Find lock rank of every connected segment var fromSegments = segment.getConnectedSegments("from"); for (var ix_1 = 0; ix_1 < fromSegments.length; ix_1++) { if (fromSegments[ix_1].attributes.id !== segment.attributes.id && (fromSegments[ix_1].attributes.lockRank || 0) + 1 > expectedLockRank) { expectedLockRank = (fromSegments[ix_1].attributes.lockRank || 0) + 1; } } var toSegments = segment.getConnectedSegments("to"); for (var ix_2 = 0; ix_2 < toSegments.length; ix_2++) { if (toSegments[ix_2].attributes.id !== segment.attributes.id && (toSegments[ix_2].attributes.lockRank || 0) + 1 > expectedLockRank) { expectedLockRank = (toSegments[ix_2].attributes.lockRank || 0) + 1; } } } else { expectedLockRank = settings.RampLockLevel; } expectedLockRank += plusOne; if ((settings.IncludeInOutput & IncludeInOutput.Low && (segment.attributes.lockRank || 0) + 1 < expectedLockRank) || (settings.IncludeInOutput & IncludeInOutput.High && (segment.attributes.lockRank || 0) + 1 > expectedLockRank)) { incorrectLock = true; } break; case 6: if ((settings.IncludeInOutput & IncludeInOutput.Low && (segment.attributes.lockRank || 0) + 1 < settings.MajorHighwayLockLevel + plusOne) || (settings.IncludeInOutput & IncludeInOutput.High && (segment.attributes.lockRank || 0) + 1 > settings.MajorHighwayLockLevel + plusOne)) { incorrectLock = true; } break; case 7: if ((settings.IncludeInOutput & IncludeInOutput.Low && (segment.attributes.lockRank || 0) + 1 < settings.MinorHighwayLockLevel + plusOne) || (settings.IncludeInOutput & IncludeInOutput.High && (segment.attributes.lockRank || 0) + 1 > settings.MinorHighwayLockLevel + plusOne)) { incorrectLock = true; } break; case 18: if ((settings.IncludeInOutput & IncludeInOutput.Low && (segment.attributes.lockRank || 0) + 1 < settings.RailroadLockLevel + plusOne) || (settings.IncludeInOutput & IncludeInOutput.High && (segment.attributes.lockRank || 0) + 1 > settings.RailroadLockLevel + plusOne)) { incorrectLock = true; } break; default: break; } if (!incorrectLock) { continue; } if (nameRegex != null || cityRegex != null) { var nameMatched = false; if (address != null && address.attributes != null && !address.attributes.isEmpty) { if (nameRegex != null && address.attributes.street != null) { nameMatched = nameRegex.test(address.attributes.street.name); } if (!nameMatched && cityRegex != null && address.attributes.city != null && address.attributes.city.hasName()) { nameMatched = cityRegex.test(address.attributes.city.attributes.name); } if (!nameMatched && segment.attributes.streetIDs != null) { for (var streetIx = 0; streetIx < segment.attributes.streetIDs.length && !nameMatched; streetIx++) { if (segment.attributes.streetIDs[streetIx] != null) { var street = W.model.streets.get(segment.attributes.streetIDs[streetIx]); if (street != null) { if (nameRegex != null) { nameMatched = nameRegex.test(street.name); } if (!nameMatched && cityRegex != null && street.cityID != null) { var city = W.model.cities.get(street.cityID); if (city != null && city.hasName()) { nameMatched = cityRegex.test(city.attributes.name); } } } } } } } if (!nameMatched) { continue; } } if (!WMEWAL.IsSegmentInArea(segment)) { continue; } if (!segment.isInRoundabout()) { addSegment(segment, null); } else if (!settings.ExcludeRoundabouts) { var r = segment.getRoundabout(); for (var rIx = 0; rIx < r.segIDs.length; rIx++) { addSegment(W.model.segments.get(r.segIDs[rIx]), r.id); } } } } } for (var ix = 0; ix < extentStreets.length; ix++) { extentStreets[ix].center = extentStreets[ix].geometries.getCentroid(true); delete extentStreets[ix].geometries; streets.push(extentStreets[ix]); } def.resolve(); return def.promise(); } WMEWAL_Locks.ScanExtent = ScanExtent; function ScanComplete() { if (streets.length === 0) { alert(pluginName + ": No streets found."); } else { streets.sort(function (a, b) { var cmp = getStreetName(a).localeCompare(getStreetName(b)); if (cmp !== 0) { return cmp; } cmp = a.state.localeCompare(b.state); if (cmp !== 0) { return cmp; } cmp = a.city.localeCompare(b.city); if (cmp !== 0) { return cmp; } if (a.lockLevel < b.lockLevel) { return -1; } else if (a.lockLevel > b.lockLevel) { return 1; } return 0; }); var outputTo = $("#_wmewalLocksOutputTo").val(); var isCSV = (outputTo === "csv" || outputTo === "both"); var isTab = (outputTo === "tab" || outputTo === "both"); var includeAltNames = (nameRegex != null || cityRegex != null); var lineArray = void 0; var columnArray = void 0; var w = void 0; var fileName = void 0; if (isCSV) { lineArray = []; columnArray = ["Name"]; if (includeAltNames) { columnArray.push("Alt Names"); } columnArray.push("City"); columnArray.push("State"); columnArray.push("Road Type"); columnArray.push("Lock Level"); columnArray.push("Latitude"); columnArray.push("Longitude"); columnArray.push("Permalink"); lineArray.push(columnArray); fileName = "Locks_" + WMEWAL.areaName; for (var rt in WMEWAL.RoadType) { if (WMEWAL.RoadType.hasOwnProperty(rt)) { var mask = parseInt(rt); if (!isNaN(mask) && settings.RoadTypeMask & mask) { fileName += "_" + WMEWAL.RoadType[mask.toString()]; } } } fileName += ".csv"; } if (isTab) { w = window.open(); w.document.write("<html><head><title>Locks</title></head><body>"); w.document.write("<h3>Area: " + WMEWAL.areaName + "</h3>"); w.document.write("<b>Filters</b>"); w.document.write("<br/>Road Type(s): "); var comma = ""; for (var rt in WMEWAL.RoadType) { if (WMEWAL.RoadType.hasOwnProperty(rt)) { var mask = parseInt(rt); if (!isNaN(mask) && settings.RoadTypeMask & mask) { w.document.write(comma + WMEWAL.TranslateRoadType(WMEWAL.RoadTypeBitmaskToWazeRoadType(mask))); if (settings.PlusOneWayMask & mask) { w.document.write(" (+1 for one-way)"); } comma = ", "; } } } if (stateName != null) { w.document.write("<br/>State " + (settings.StateOperation === Operation.NotEqual ? "does not equal " : "equals ") + stateName); } if (nameRegex != null) { w.document.write("<br/>Name matches " + nameRegex.source); if (settings.RegexIgnoreCase) { w.document.write(" (ignoring case)"); } } if (cityRegex != null) { w.document.write("</br/>City name matches " + cityRegex.source); if (settings.CityRegexIgnoreCase) { w.document.write(" (ignoring case)"); } } if (settings.ExcludeRoundabouts) { w.document.write("<br/>Roundabouts excluded"); } if (settings.ExcludeJunctionBoxes) { w.document.write("<br/>Junction boxes excluded"); } if (settings.EditableByMe) { w.document.write("<br/>Editable by me"); } w.document.write("</p><table style='border-collapse: separate; border-spacing: 8px 0px'><tr><th>Name</th>"); if (includeAltNames) { w.document.write("<th>Alt Names</th>"); } w.document.write("<th>City</th><th>State</th>"); w.document.write("<th>Road Type</th><th>Lock Level</th><th>Latitude</th><th>Longitude</th><th>Permalink</th></tr>"); } for (var ixStreet = 0; ixStreet < streets.length; ixStreet++) { var street = streets[ixStreet]; var roadTypeText = WMEWAL.TranslateRoadType(street.roadType); if (street.name == null && street.roundaboutId == null) { for (var ixSeg = 0; ixSeg < street.segments.length; ixSeg++) { var segment = street.segments[ixSeg]; var latlon = OL.Layer.SphericalMercator.inverseMercator(segment.center.x, segment.center.y); var plSeg = getSegmentPL(segment); if (isCSV) { columnArray = [getStreetName(street)]; if (includeAltNames) { columnArray.push(""); } columnArray.push("\"" + street.city + "\""); columnArray.push("\"" + street.state + "\""); columnArray.push("\"" + roadTypeText + "\""); columnArray.push(street.lockLevel.toString()); columnArray.push(latlon.lat.toString()); columnArray.push(latlon.lon.toString()); columnArray.push("\"" + plSeg + "\""); lineArray.push(columnArray); } if (isTab) { w.document.write("<tr><td>" + getStreetName(street) + "</td>"); if (includeAltNames) { w.document.write("<td> </td>"); } w.document.write("<td>" + street.city + "</td>"); w.document.write("<td>" + street.state + "</td>"); w.document.write("<td>" + roadTypeText + "</td><td>" + street.lockLevel + "</td>" + "<td>" + latlon.lat.toString() + "</td><td>" + latlon.lon.toString() + "</td>" + "<td><a href=\'" + plSeg + "\' target=\'_blank\'>Permalink</a></td></tr>"); } } } else { var latlon = OL.Layer.SphericalMercator.inverseMercator(street.center.x, street.center.y); var plStreet = getStreetPL(street); var altNames = ""; for (var ixAlt = 0; ixAlt < street.altStreets.length; ixAlt++) { if (ixAlt > 0) { altNames += ", "; } altNames += street.altStreets[ixAlt].name; } if (isCSV) { columnArray = ["\"" + getStreetName(street) + "\""]; if (includeAltNames) { columnArray.push("\"" + altNames + "\""); } columnArray.push("\"" + street.city + "\""); columnArray.push("\"" + street.state + "\""); columnArray.push("\"" + roadTypeText + "\""); columnArray.push(street.lockLevel.toString()); columnArray.push(latlon.lat.toString()); columnArray.push(latlon.lon.toString()); columnArray.push("\"" + plStreet + "\""); lineArray.push(columnArray); } if (isTab) { w.document.write("<tr><td>" + getStreetName(street) + "</td>"); if (includeAltNames) { w.document.write("<td>" + altNames + "</td>"); } w.document.write("<td>" + street.city + "</td>"); w.document.write("<td>" + street.state + "</td>"); w.document.write("<td>" + roadTypeText + "</td><td>" + street.lockLevel + "</td>" + "<td>" + latlon.lat.toString() + "</td><td>" + latlon.lon.toString() + "</td>" + "<td><a href=\'" + plStreet + "\' target=\'_blank\'>Permalink</a></td></tr>"); } } } if (isCSV) { var csvContent = encodeURIComponent(lineArray.join("\n")); //var encodedUri = "data:text/csv;charset=utf-8," + encodeURIComponent(csvContent); var blob = new Blob([csvContent], {type: "data:text/csv;charset=utf-8;"}); var link = document.createElement("a"); var url = URL.createObjectURL(blob); link.setAttribute("href", url); link.setAttribute("download", fileName); var node = document.body.appendChild(link); link.click(); document.body.removeChild(node); } if (isTab) { w.document.write("</table></body></html>"); w.document.close(); w = null; } } } WMEWAL_Locks.ScanComplete = ScanComplete; function ScanCancelled() { ScanComplete(); } WMEWAL_Locks.ScanCancelled = ScanCancelled; function getStreetPL(street) { var latlon = OL.Layer.SphericalMercator.inverseMercator(street.center.x, street.center.y); var url = "https://www.waze.com/editor/?env=" + W.location.code + "&lon=" + latlon.lon + "&lat=" + latlon.lat + "&zoom=" + WMEWAL.zoomLevel + "&segments="; for (var ix = 0; ix < street.segments.length; ix++) { if (ix > 0) { url += ","; } url += street.segments[ix].id; } return url; } function getSegmentPL(segment) { var latlon = OL.Layer.SphericalMercator.inverseMercator(segment.center.x, segment.center.y); return "https://www.waze.com/editor/?env=" + W.location.code + "&lon=" + latlon.lon + "&lat=" + latlon.lat + "&zoom=5&segments=" + segment.id; } function getStreetName(street) { return street.name || "No street"; } function Init() { console.group(pluginName + ": Initializing"); initCount++; var objectToCheck = [ "W.location", "W.model.states", "OL", "WMEWAL.RegisterPlugIn"]; for (var i = 0; i < objectToCheck.length; i++) { var path = objectToCheck[i].split("."); var object = window; for (var j = 0; j < path.length; j++) { object = object[path[j]]; if (typeof object === "undefined" || object == null) { console.warn(path[j] + " NOT OK"); if (initCount < 60) { console.groupEnd(); window.setTimeout(Init, 1000); } else { console.error("Giving up on initialization"); console.groupEnd(); } return; } } console.log(objectToCheck[i] + " OK"); } if (typeof Storage !== "undefined") { if (localStorage[settingsKey]) { settings = JSON.parse(localStorage[settingsKey]); } if (localStorage[savedSettingsKey]) { try { savedSettings = JSON.parse(WMEWAL.LZString.decompressFromUTF16(localStorage[savedSettingsKey])); } catch (e) {} if (typeof savedSettings === "undefined" || savedSettings === null || savedSettings === "") { console.debug(pluginName + ": decompressFromUTF16 failed, attempting decompress"); localStorage[savedSettingsKey +"Backup"] = localStorage[savedSettingsKey]; try { savedSettings = JSON.parse(WMEWAL.LZString.decompress(localStorage[savedSettingsKey])); } catch (e) {} if (typeof savedSettings === "undefined" || savedSettings === null || savedSettings === "") { console.debug(pluginName + ": decompress failed, savedSettings unrecoverable. Using blank"); savedSettings = []; } updateSavedSettings(); } } } if (settings == null) { settings = { OutputTo: "csv", RoadTypeMask: WMEWAL.RoadType.Freeway, State: null, Regex: null, RegexIgnoreCase: true, ExcludeRoundabouts: false, ExcludeJunctionBoxes: true, EditableByMe: true, StreetLockLevel: 1, PrimaryStreetLockLevel: 2, MinorHighwayLockLevel: 3, MajorHighwayLockLevel: 4, FreewayLockLevel: 5, RampLockLevel: 7, IncludeInOutput: IncludeInOutput.Low | IncludeInOutput.High, PlusOneWayMask: 0, CityRegex: null, CityRegexIgnoreCase: true, StateOperation: Operation.Equal, RailroadLockLevel: 2 }; } else { if (!settings.hasOwnProperty("RailroadLockLevel")) { settings.RailroadLockLevel = 2; } } console.log("Initialized"); console.groupEnd(); WMEWAL.RegisterPlugIn(WMEWAL_Locks); } function updateSavedSettings() { if (typeof Storage !== "undefined") { localStorage[savedSettingsKey] = WMEWAL.LZString.compressToUTF16(JSON.stringify(savedSettings)); } updateSavedSettingsList(); } function updateSettings() { if (typeof Storage !== "undefined") { localStorage[settingsKey] = JSON.stringify(settings); } } Init(); })(WMEWAL_Locks || (WMEWAL_Locks = {}));