WME PlaceNames

Show area place names in WME, color and highlight places by type and properties

目前为 2014-11-12 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name WME PlaceNames
  3. // @version 0.3
  4. // @description Show area place names in WME, color and highlight places by type and properties
  5. // @include https://www.waze.com/editor/*
  6. // @include https://www.waze.com/*/editor/*
  7. // @include https://editor-beta.waze.com/editor/*
  8. // @include https://editor-beta.waze.com/*/editor/*
  9. // @copyright 2014, ragacs
  10. // @namespace https://gf.qytechs.cn/users/6330
  11. // ==/UserScript==
  12.  
  13. var wmepn_version = "0.3"
  14.  
  15. // Using parts from highlight and route speed scripts by various authors
  16.  
  17. /* bootstrap, will call initialiseLandmarkNames() */
  18. function bootstrapLandmarkNames()
  19. {
  20. var bGreasemonkeyServiceDefined = false;
  21.  
  22. try {
  23. bGreasemonkeyServiceDefined = (typeof Components.interfaces.gmIGreasemonkeyService === "object");
  24. }
  25. catch (err) { /* Ignore */ }
  26.  
  27. if (typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined) {
  28. unsafeWindow = ( function () {
  29. var dummyElem = document.createElement('p');
  30. dummyElem.setAttribute('onclick', 'return window;');
  31. return dummyElem.onclick();
  32. }) ();
  33. }
  34.  
  35. /* begin running the code! */
  36. setTimeout(initialiseLandmarkNames, 999);
  37. }
  38.  
  39. function testWhite(x) {
  40. var white = new RegExp(/^\s$/);
  41. return white.test(x.charAt(0));
  42. };
  43.  
  44. function wordWrap(str, maxWidth) {
  45. var newLineStr = "\n"; done = false; res = '';
  46. do {
  47. found = false;
  48. // Inserts new line at first whitespace of the line
  49. for (i = maxWidth - 1; i >= 0; i--) {
  50. if (testWhite(str.charAt(i))) {
  51. res = res + [str.slice(0, i), newLineStr].join('');
  52. str = str.slice(i + 1);
  53. found = true;
  54. break;
  55. }
  56. }
  57. // Inserts new line at maxWidth position, the word is too long to wrap
  58. if (!found) {
  59. res += [str.slice(0, maxWidth), newLineStr].join('');
  60. str = str.slice(maxWidth);
  61. }
  62.  
  63. if (str.length < maxWidth)
  64. {
  65. res = res + str;
  66. done = true;
  67. }
  68. } while (!done);
  69.  
  70. return res;
  71. }
  72.  
  73. function resetLandmarks()
  74. {
  75. for (var mark in Waze.model.venues.objects) {
  76. var venue = Waze.model.venues.get(mark);
  77. var poly = getId(venue.geometry.id);
  78. if (poly !== null) {
  79. if (poly.getAttribute("stroke-opacity") != 1) {
  80. poly.setAttribute("fill","#d191d6");
  81. poly.setAttribute("stroke","#d191d6");
  82. poly.setAttribute("fill-opacity",0.3);
  83. poly.setAttribute("stroke-opacity",1);
  84. }
  85. }
  86. }
  87. showLandmarkNames();
  88. }
  89.  
  90. function showLandmarkNames() {
  91. var routeLayer = undefined;
  92. var rlayers = unsafeWindow.Waze.map.getLayersBy("uniqueName","__DrawPlaceNames");
  93. if(rlayers.length == 0) {
  94. var lname = "Place Names";
  95. var drc_style1 = new unsafeWindow.OpenLayers.Style({
  96. strokeDashstyle: 'solid',
  97. strokeColor : "${strokeColor}",
  98. strokeOpacity: 1.0,
  99. strokeWidth: "${strokeWidth}",
  100. fillColor: '#0040FF',
  101. fillOpacity: 1.0,
  102. pointRadius: "${pointRadius}",
  103. label : "${labelText}",
  104. fontFamily: "Tahoma, Courier New",
  105. labelOutlineColor: '#FFEEEE',
  106. labelOutlineWidth: 2,
  107. labelAlign: 'cm',
  108. fontColor: "#301130",
  109. fontOpacity: 1.0,
  110. fontSize: "11px",
  111. display: 'block'
  112. });
  113. var drc_mapLayer1 = new unsafeWindow.OpenLayers.Layer.Vector(lname, {
  114. displayInLayerSwitcher: true,
  115. uniqueName: "__DrawPlaceNames",
  116. shortcutKey: "S+n",
  117. accelerator: "toggle" + lname.replace(/\s+/g,''),
  118. styleMap: new unsafeWindow.OpenLayers.StyleMap(drc_style1)
  119. });
  120. drc_mapLayer1.setVisibility(true);
  121. //drc_mapLayer1.moveLayerToTop();
  122. unsafeWindow.Waze.map.addLayer(drc_mapLayer1);
  123. //var zLandmarks = Waze.map.getLayersBy("uniqueName", "landmarks")[0].getZIndex();
  124. //var zPlaceNames = drc_mapLayer1.getZIndex();
  125. //Waze.map.getLayersBy("uniqueName", "landmarks")[0].setZIndex(zPlaceNames);
  126. //drc_mapLayer1.setZIndex(zLandmarks);
  127. routeLayer = drc_mapLayer1;
  128. }
  129. else routeLayer = rlayers[0];
  130. routeLayer.removeAllFeatures();
  131. if (typeof Waze.model.venues == "undefined") {
  132. return;
  133. }
  134.  
  135. var showNames = routeLayer.getVisibility() && Waze.map.getLayersBy("uniqueName", "landmarks")[0].getVisibility();
  136. // if checkbox unticked, reset places to original style
  137. if (!showNames
  138. && !getId('_cbLandmarkColors').checked
  139. && !getId('_cbLandmarkHiliteNoName').checked) {
  140. for (var mark in Waze.model.venues.objects) {
  141. var venue = Waze.model.venues.get(mark);
  142. var poly = getId(venue.geometry.id);
  143. if (poly !== null) {
  144. if (poly.getAttribute("stroke-opacity") != 1) {
  145. poly.setAttribute("fill","#d191d6");
  146. poly.setAttribute("stroke","#d191d6");
  147. poly.setAttribute("fill-opacity",0.3);
  148. poly.setAttribute("stroke-opacity",1);
  149. }
  150. }
  151. }
  152. return;
  153. }
  154.  
  155. var specificCity = getId('_cbLandmarkHiliteNoName').checked;
  156. var colorLandmarks = getId('_cbLandmarkColors').checked;
  157. var showPoints = (getId('_seLandmarkPoints').value == "all" || getId('_seLandmarkPoints').value == "point");
  158. var showAreas = (getId('_seLandmarkPoints').value == "all" || getId('_seLandmarkPoints').value == "area");
  159. //var routeLayer = unsafeWindow.Waze.map.getLayersBy("uniqueName","landmarks")[0];
  160. //routeLayer.styleMap.styles.default = drc_style1;
  161.  
  162. for (var mark in Waze.model.venues.objects) {
  163. var venue = Waze.model.venues.get(mark);
  164. var poly = getId(venue.geometry.id);
  165. if (poly !== null && venue.geometry.toString().match(/^POLYGON/)) {
  166. venueStreet = Waze.model.streets.get(venue.attributes.streetID);
  167. selectedCityMatch = (venue.attributes.name.length == 0);
  168.  
  169. if(showNames && venue.attributes.name.length > 0 && showAreas)
  170. {
  171. // Add label texts
  172. var labelFeatures = [];
  173. var pt = new OpenLayers.Geometry.Point((venue.geometry.bounds.left + venue.geometry.bounds.right)/2, (venue.geometry.bounds.top + venue.geometry.bounds.bottom)/2);
  174. var closest =_.min(routeLayer.features, function(feature) {
  175. return feature.geometry.distanceTo(pt);
  176. });
  177. //console.log(closest);
  178. var wrappedText = wordWrap(venue.attributes.name, 30);
  179. var textFeature = new OpenLayers.Feature.Vector( pt, {labelText: wrappedText, fontColor: '#F0F0F0', pointRadius: 0 } );
  180. labelFeatures.push(textFeature);
  181. routeLayer.addFeatures(labelFeatures);
  182. //if(closest != Infinity && closest.geometry.bounds.intersectsBounds(textFeature.geometry.bounds))
  183. //{
  184. // routeLayer.removeFeatures(labelFeatures);
  185. //}
  186. }
  187. // Production polygons: #d191d6, Beta editor polygons: #c290c6
  188. if ((poly.getAttribute("fill") == "#d191d6" || poly.getAttribute("fill") == "#c290c6") && poly.getAttribute("stroke-opacity") == 1) {
  189. var categories = venue.attributes.categories;
  190.  
  191. if(colorLandmarks)
  192. {
  193. // gas station = orange
  194. if (categories.indexOf("GAS_STATION") > -1) {
  195. poly.setAttribute("fill","#f90");
  196. poly.setAttribute("stroke","#f90");
  197. }
  198. // parking lot = cyan
  199. else if (categories.indexOf("PARKING_LOT") > -1) {
  200. poly.setAttribute("fill","#099");
  201. poly.setAttribute("stroke","#0cc");
  202. }
  203. // water = blue
  204. else if (categories.indexOf("RIVER_STREAM") > -1 ||
  205. categories.indexOf("SEA_LAKE_POOL") > -1) {
  206. poly.setAttribute("fill","#09f");
  207. poly.setAttribute("stroke","#06c");
  208. }
  209. // park/grass/trees = green
  210. else if (categories.indexOf("PARK") > -1 ||
  211. categories.indexOf("FARM") > -1 ||
  212. categories.indexOf("FOREST_GROVE") > -1 ||
  213. categories.indexOf("GOLF_COURSE") > -1) {
  214. poly.setAttribute("fill","#4f4");
  215. poly.setAttribute("stroke","#6a6");
  216. }
  217. }
  218.  
  219. poly.setAttribute("stroke-opacity",0.97);
  220. // highlight places which have no name
  221. if (poly.getAttribute("fill") == "#d191d6" || poly.getAttribute("fill") == "#c290c6") {
  222. if (specificCity && selectedCityMatch) {
  223. poly.setAttribute("fill","#ff8");
  224. poly.setAttribute("stroke","#cc0");
  225. }
  226. }
  227. // if was yellow and now not yellow, reset
  228. else if (poly.getAttribute("fill") == "#ff8" && (!specificCity || !selectedCityMatch)) {
  229. poly.setAttribute("fill","#d191d6");
  230. poly.setAttribute("stroke","#d191d6");
  231. poly.setAttribute("stroke-opacity",1);
  232. }
  233. }
  234. }
  235. if(poly !== null && venue.geometry.toString().match(/^POINT/) && showPoints == true && showNames == true && venue.attributes.name.length > 0)
  236. {
  237. // Add label texts
  238. var labelFeatures = [];
  239. var pt = new OpenLayers.Geometry.Point(venue.geometry.x, venue.geometry.y);
  240. var wrappedText = wordWrap(venue.attributes.name, 30);
  241. var textFeature = new OpenLayers.Feature.Vector( pt, {labelText: wrappedText, fontColor: '#F0F0F0', pointRadius: 0 } );
  242. labelFeatures.push(textFeature);
  243. routeLayer.addFeatures(labelFeatures);
  244. }
  245. }
  246. }
  247.  
  248. function toggleOptions () {
  249. return false;
  250. }
  251.  
  252. /* helper function */
  253. function getElementsByClassName(classname, node) {
  254. if(!node) node = document.getElementsByTagName("body")[0];
  255. var a = [];
  256. var re = new RegExp('\\b' + classname + '\\b');
  257. var els = node.getElementsByTagName("*");
  258. for (var i=0,j=els.length; i<j; i++)
  259. if (re.test(els[i].className)) a.push(els[i]);
  260. return a;
  261. }
  262.  
  263. function getId(node) {
  264. return document.getElementById(node);
  265. }
  266.  
  267. /* =========================================================================== */
  268.  
  269. function initialiseLandmarkNames()
  270. {
  271. // global variables
  272. advancedMode = false;
  273. betaMode = location.hostname.match(/editor-beta.waze.com/);
  274. lastSelected = null;
  275. lastModified = false;
  276. selectedLines = [];
  277.  
  278. // add new box to left of the map
  279. var addon = document.createElement('section');
  280. addon.id = "landmarkname-addon";
  281.  
  282. if (navigator.userAgent.match(/Chrome/)) {
  283. addon.innerHTML = '<b>'
  284. + '<a href="https://www.waze.com/forum/viewtopic.php?f=819&t=116843" target="_blank">WME PlaceNames</a></b> &nbsp; v' + wmepn_version;
  285. } else {
  286. addon.innerHTML = '<b>'
  287. + '<a href="https://www.waze.com/forum/viewtopic.php?f=819&t=116843" target="_blank">WME PlaceNames</a></b> &nbsp; v' + wmepn_version;
  288. }
  289.  
  290. // highlight landmarks
  291. section = document.createElement('p');
  292. section.style.padding = "8px 16px";
  293. //section.style.textIndent = "-16px";
  294. section.id = "nameLandmarks";
  295. section.innerHTML = '<input type="checkbox" id="_cbLandmarkColors" /> <b>Color places</b><br>'
  296. + '<input type="checkbox" id="_cbLandmarkHiliteNoName" /> <b>Highlight places without name</b><br>'
  297. + '<b>Show</b> <select id="_seLandmarkPoints"> <option value="area">Area only</option><option value="all">Area and Point</option><option value="point">Point only</option><br>';
  298. addon.appendChild(section);
  299.  
  300. var userTabs = getId('user-info');
  301. var navTabs = getElementsByClassName('nav-tabs', userTabs)[0];
  302. var tabContent = getElementsByClassName('tab-content', userTabs)[0];
  303.  
  304. newtab = document.createElement('li');
  305. newtab.innerHTML = '<a href="#sidepanel-landmarknames" data-toggle="tab">PlaceNames</a>';
  306. navTabs.appendChild(newtab);
  307.  
  308. addon.id = "sidepanel-landmarknames";
  309. addon.className = "tab-pane";
  310. tabContent.appendChild(addon);
  311.  
  312. // setup onclick handlers for instant update:
  313. getId('_cbLandmarkColors').onclick = resetLandmarks;
  314. getId('_cbLandmarkHiliteNoName').onclick = resetLandmarks;
  315. getId('_seLandmarkPoints').onchange = resetLandmarks;
  316.  
  317. // restore saved settings
  318. if (localStorage.WMELandmarkNamesScript) {
  319. console.log("WME LandmarkNames: loading options");
  320. options = JSON.parse(localStorage.WMELandmarkNamesScript);
  321.  
  322. getId('_cbLandmarkColors').checked = options[1];
  323. getId('_cbLandmarkHiliteNoName').checked = options[2];
  324. getId('_seLandmarkPoints').value = options[3];
  325. } else {
  326. getId('_cbLandmarkColors').checked = true;
  327. getId('_cbLandmarkHiliteNoName').checked = true;
  328. getId('_seLandmarkPoints').value = "area";
  329. }
  330.  
  331. if (typeof Waze.model.venues == "undefined") {
  332. getId('_cbLandmarkColors').checked = false;
  333. getId('_cbLandmarkHiliteNoName').checked = false;
  334. getId('_cbLandmarkColors').disabled = true;
  335. getId('_cbLandmarkHiliteNoName').disabled = true;
  336. getId('_seLandmarkPoints').disabled = true;
  337. }
  338.  
  339. // overload the WME exit function
  340. saveLandmarkNamesOptions = function() {
  341. if (localStorage) {
  342. console.log("WME LandmarkNames: saving options");
  343. var options = [];
  344.  
  345. // preserve previous options which may get lost after logout
  346. if (localStorage.WMELandmarkNamesScript)
  347. options = JSON.parse(localStorage.WMELandmarkNamesScript);
  348. options[1] = getId('_cbLandmarkColors').checked;
  349. options[2] = getId('_cbLandmarkHiliteNoName').checked;
  350. options[3] = getId('_seLandmarkPoints').value;
  351. localStorage.WMELandmarkNamesScript = JSON.stringify(options);
  352. }
  353. }
  354. window.addEventListener("beforeunload", saveLandmarkNamesOptions, false);
  355.  
  356. // begin periodic updates
  357. window.setInterval(showLandmarkNames,500);
  358.  
  359. // trigger code when page is fully loaded, to catch any missing bits
  360. window.addEventListener("load", function(e) {
  361. var mapProblems = getId('map-problems-explanation')
  362. if (mapProblems !== null) mapProblems.style.display = "none";
  363. });
  364.  
  365. // register some events...
  366. Waze.map.events.register("zoomend", null, showLandmarkNames);
  367. Waze.map.events.register("changelayer", null, showLandmarkNames);
  368. }
  369.  
  370. /* engage! =================================================================== */
  371. bootstrapLandmarkNames();
  372.  
  373. /* end ======================================================================= */

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址