Greasy Fork is available in English.

WME Brooklyn UR Project Overlay

Adds a group area overlay for the Brooklyn UR Project (2018).

  1. // ==UserScript==
  2. // @name WME Brooklyn UR Project Overlay
  3. // @namespace WazeDev
  4. // @version 2019.02.26.01
  5. // @description Adds a group area overlay for the Brooklyn UR Project (2018).
  6. // @author MapOMatic, Dude495
  7. // @include /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor\/?.*$/
  8. // @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
  9. // @license GNU GPLv3
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. const PROJECT_NAME = 'NY UR Project';
  17. const STATE_ABBR = 'Brooklyn';
  18. const VERSION = GM_info.script.version;
  19. var SCRIPT_NAME = GM_info.script.name;
  20. const UPDATE_NOTES = 'Fixed code that Waze broke to jump between areas in the drop down.';
  21.  
  22. // Enter the MapRaid area names and the desired fill colors, in order they appear in the original map legend:
  23. const GROUPS = [
  24. {name: '1', fillColor:'#ff99e6', zoomTo: 3},
  25. {name: '2', fillColor:'#FF0000', zoomTo: 3},
  26. {name: '3', fillColor:'#01579b', zoomTo: 3},
  27. {name: '4', fillColor:'#7cb342', zoomTo: 2},
  28. {name: '5', fillColor:'#f57c00', zoomTo: 2},
  29. {name: '6', fillColor:'#ffcc33', zoomTo: 3},
  30. {name: '7', fillColor:'#b84dff', zoomTo: 3},
  31. {name: '8', fillColor:'#80d4ff', zoomTo: 2},
  32. ];
  33.  
  34. // There must be a GROUP above for each WKT_STRING below
  35. const WKT_STRINGS = [
  36. 'POLYGON((-73.9904330486728 40.70549262317117,-73.982364963956 40.69264088276152,-73.90621168560517 40.70023835045976,-73.92108185238368 40.72351341822026,-73.94811851925385 40.737887521686716,-73.96262390560639 40.74191951783877,-73.96502716488374 40.72279788398495,-73.97712929195893 40.71043744237824,-73.9904330486728 40.70549262317117))',
  37. 'POLYGON((-73.96871788448823 40.672951764600896,-73.982364963956 40.69264088276152,-73.90253169483674 40.70057183829086,-73.89399154133326 40.679575117124344,-73.9228413814975 40.6682320210483,-73.95565016216767 40.670331534429955,-73.96871788448823 40.672951764600896))',
  38. 'POLYGON((-73.84889824337495 40.64391191093184,-73.85461810922197 40.66140089151345,-73.8740708852252 40.69437533937751,-73.89564936699549 40.68364455309436,-73.89399126307762 40.67957692098405,-73.9228413814975 40.6682320210483,-73.88698561138642 40.62305206652372,-73.84889824337495 40.64391191093184))',
  39. 'POLYGON((-73.92391426510346 40.633751489330514,-73.95687604193296 40.62959257536632,-73.96873243172479 40.67293649646323,-73.9556379897706 40.670330176220006,-73.9228413814975 40.6682320210483,-73.88698561138642 40.62305206652372,-73.89618022388947 40.62175727124528,-73.92391426510346 40.633751489330514))',
  40. 'POLYGON((-73.92391426510346 40.633751489330514,-73.95687604193296 40.62959257536632,-73.94675977547479 40.57464813420046,-73.88104183620942 40.57376700856745,-73.86775953716767 40.592686991724484,-73.89618022388947 40.62175727124528,-73.92391426510346 40.633751489330514))',
  41. 'POLYGON((-73.99042231983674 40.70548403890334,-73.9822975053138 40.6925472355467,-73.96871659850649 40.672941881184975,-73.95687604193296 40.62959257536632,-73.97946126778436 40.63694407719938,-74.03330547756684 40.6686877349959,-74.01216967052949 40.68732051277307,-73.99748189396394 40.70452476197392,-73.99042231983674 40.70548403890334))',
  42. 'POLYGON((-74.04810054249299 40.632309891249044,-74.0375724686927 40.602939093514834,-74.01781175231508 40.59738589064224,-73.95687604193296 40.62959257536632,-73.97946126778436 40.63694407719938,-74.02457220501435 40.66352822013939,-74.04810054249299 40.632309891249044))',
  43. 'POLYGON((-73.94678596378611 40.574754788886835,-74.01353987591926 40.56434974042763,-74.01781175231508 40.59738589064224,-73.95687604193296 40.62959257536632,-73.94678596378611 40.574754788886835))',
  44. ];
  45. const SETTINGS_STORE_NAME = '_wme_' + STATE_ABBR + '_mapraid';
  46. const DEFAULT_FILL_OPACITY = 0.3;
  47.  
  48. var _settings;
  49. var _layer;
  50.  
  51. function loadSettingsFromStorage() {
  52. _settings = $.parseJSON(localStorage.getItem(SETTINGS_STORE_NAME));
  53. if(!_settings) {
  54. _settings = {
  55. layerVisible: true,
  56. hiddenAreas: []
  57. };
  58. } else {
  59. _settings.layerVisible = (_settings.layerVisible === true);
  60. _settings.hiddenAreas = _settings.hiddenAreas || [];
  61. }
  62. }
  63.  
  64. function saveSettingsToStorage() {
  65. if (localStorage) {
  66. var settings = {
  67. layerVisible: _layer.visibility,
  68. hiddenAreas: _settings.hiddenAreas
  69. };
  70. localStorage.setItem(SETTINGS_STORE_NAME, JSON.stringify(settings));
  71. }
  72. }
  73.  
  74. function updateDistrictNameDisplay(){
  75. $('.mapraid-region').remove();
  76. if (_layer !== null) {
  77. var mapCenter = new OpenLayers.Geometry.Point(W.map.center.lon,W.map.center.lat);
  78. for (var i=0;i<_layer.features.length;i++){
  79. var feature = _layer.features[i];
  80. var color;
  81. var text = '';
  82. if(feature.geometry.containsPoint(mapCenter)) {
  83. text = feature.attributes.name;
  84. color = '#ff0';
  85. var $div = $('<div>', {id:'mapraid', class:'mapraid-region', style:'display:inline-block;margin-left:10px;', title:'Click to toggle color on/off for this group'})
  86. .css({color:color, cursor:'pointer', fontWeight:'bold', fontSize:'14px'})
  87. .click(toggleAreaFill);
  88. var $span = $('<span>').css({display:'inline-block'});
  89. $span.text('Group: ' + text).appendTo($div);
  90. $('.location-info-region').parent().append($div);
  91. if (color) {
  92. break;
  93. }
  94. }
  95. }
  96. }
  97. }
  98.  
  99. function toggleAreaFill() {
  100. var text = $('#mapraid span').text();
  101. if (text) {
  102. var match = text.match(/^Group: (.*)/);
  103. if (match.length > 1) {
  104. var areaName = match[1];
  105. var f = _layer.getFeaturesByAttribute('name', areaName)[0];
  106. var hide = f.attributes.fillOpacity !== 0;
  107. f.attributes.fillOpacity = hide ? 0 : DEFAULT_FILL_OPACITY;
  108. var idx = _settings.hiddenAreas.indexOf(areaName);
  109. if (hide) {
  110. if (idx === -1) _settings.hiddenAreas.push(areaName);
  111. } else {
  112. if (idx > -1) {
  113. _settings.hiddenAreas.splice(idx,1);
  114. }
  115. }
  116. saveSettingsToStorage();
  117. _layer.redraw();
  118. }
  119. }
  120. }
  121.  
  122. function layerToggled(visible) {
  123. _layer.setVisibility(visible);
  124. saveSettingsToStorage();
  125. }
  126.  
  127. function init() {
  128. loadSettingsFromStorage();
  129. let layerid = 'wme_' + STATE_ABBR + '_mapraid';
  130. let wkt = new OL.Format.WKT();
  131. let features = WKT_STRINGS.map(polyString => {
  132. var f = wkt.read(polyString);
  133. f.geometry.transform(W.map.displayProjection, W.map.projection);
  134. return f;
  135. });
  136. GROUPS.forEach((group, i) => {
  137. let f = features[i];
  138. f.attributes.name = group.name;
  139. f.attributes.fillColor = group.fillColor;
  140. f.attributes.fillOpacity = _settings.hiddenAreas.indexOf(group.name) > -1 ? 0 : DEFAULT_FILL_OPACITY;
  141. group.feature = f;
  142. });
  143.  
  144. let layerStyle = new OpenLayers.StyleMap({
  145. strokeDashstyle: 'solid',
  146. strokeColor: '#000000',
  147. strokeOpacity: 1,
  148. strokeWidth: 3,
  149. fillOpacity: '${fillOpacity}',
  150. fillColor: '${fillColor}',
  151. label: 'Group ${name}',
  152. fontOpacity: 0.9,
  153. fontSize: '20px',
  154. fontFamily: 'Arial',
  155. fontWeight: 'bold',
  156. fontColor: '#fff',
  157. labelOutlineColor: '#000',
  158. labelOutlineWidth: 2
  159. });
  160. _layer = new OL.Layer.Vector(STATE_ABBR + ' UR Project', {
  161. rendererOptions: { zIndexing: true },
  162. uniqueName: layerid,
  163. shortcutKey: 'S+' + 0,
  164. layerGroup: STATE_ABBR + '_mapraid',
  165. zIndex: -9999,
  166. displayInLayerSwitcher: true,
  167. visibility: _settings.layerVisible,
  168. styleMap: layerStyle
  169. });
  170. I18n.translations[I18n.locale].layers.name[layerid] = STATE_ABBR + ' MapRaid';
  171. _layer.addFeatures(features);
  172. W.map.addLayer(_layer);
  173. W.map.events.register('moveend', null, updateDistrictNameDisplay);
  174. window.addEventListener('beforeunload', function saveOnClose() { saveSettingsToStorage(); }, false);
  175. updateDistrictNameDisplay();
  176.  
  177. // Add the layer checkbox to the Layers menu.
  178. WazeWrap.Interface.AddLayerCheckbox('display', STATE_ABBR + ' UR Project', _settings.layerVisible, layerToggled);
  179.  
  180. initAreaJumper();
  181. }
  182.  
  183. function initAreaJumper() {
  184. let $areaJumper = $('#mapraidDropdown');
  185.  
  186. // If another script hasn't already created the dropdown, create it now.
  187. if (!$areaJumper.length) {
  188. let $areaJumperContainer = $('<div style="flex-grow: 1;padding-top: 6px;">').insertBefore('#edit-buttons');
  189. $areaJumper = $('<select id=mapraidDropdown style="margin-top: 4px;display: block;width: 80%;margin: 0 auto;">')
  190. .appendTo($areaJumperContainer)
  191. .append($('<option>', {value: 0}).text(PROJECT_NAME));
  192. }
  193.  
  194. // Append the groups to the dropdown.
  195. $areaJumper.append(
  196. $('<optgroup>', {label: STATE_ABBR}).append(GROUPS.map(group => {
  197. return $('<option>', {value: STATE_ABBR + group.name}).text('Group ' + group.name);
  198. }))
  199. );
  200.  
  201. // Handle a group selection.
  202. $areaJumper.change(function() {
  203. let value = $(this).val();
  204. let group = GROUPS.find(group => STATE_ABBR + group.name === value);
  205. if (group) {
  206. var pt = group.feature.geometry.getCentroid();
  207. W.map.moveTo(new OL.LonLat(pt.x, pt.y), group.zoomTo);
  208. $areaJumper.val('0');
  209. }
  210. });
  211. }
  212.  
  213. function bootstrap() {
  214. if (W && W.loginManager && W.loginManager.user && $('#topbar-container > div > div > div.location-info-region > div').length && $('#layer-switcher-group_display').length && WazeWrap.Interface) {
  215. init();
  216. console.log(STATE_ABBR + ' Area Overlay:', 'Initialized');
  217. WazeWrap.Interface.ShowScriptUpdate(SCRIPT_NAME, VERSION, UPDATE_NOTES, "https://greasyfork.org/en/scripts/370857-wme-brooklyn-ur-project-overlay", "");
  218. } else {
  219. console.log(STATE_ABBR + ' MR Overlay: ', 'Bootstrap failed. Trying again...');
  220. window.setTimeout(() => bootstrap(), 500);
  221. }
  222. }
  223.  
  224. bootstrap();
  225. })();