WME PlaceNames

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

目前為 2014-10-28 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name WME PlaceNames
  3. // @version 0.2
  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.2"
  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 drc_style1 = new unsafeWindow.OpenLayers.Style({
  95. strokeDashstyle: 'solid',
  96. strokeColor : "${strokeColor}",
  97. strokeOpacity: 1.0,
  98. strokeWidth: "${strokeWidth}",
  99. fillColor: '#0040FF',
  100. fillOpacity: 1.0,
  101. pointRadius: "${pointRadius}",
  102. label : "${labelText}",
  103. fontFamily: "Tahoma, Courier New",
  104. labelOutlineColor: '#FFEEEE',
  105. labelOutlineWidth: 2,
  106. labelAlign: 'cm',
  107. fontColor: "#301130",
  108. fontOpacity: 1.0,
  109. fontSize: "11px",
  110. display: 'block'
  111. });
  112. var drc_mapLayer1 = new unsafeWindow.OpenLayers.Layer.Vector("Place Names", {
  113. displayInLayerSwitcher: true,
  114. uniqueName: "__DrawPlaceNames",
  115. styleMap: new unsafeWindow.OpenLayers.StyleMap(drc_style1)
  116. });
  117. drc_mapLayer1.setVisibility(true);
  118. //drc_mapLayer1.moveLayerToTop();
  119. unsafeWindow.Waze.map.addLayer(drc_mapLayer1);
  120. //var zLandmarks = Waze.map.getLayersBy("uniqueName", "landmarks")[0].getZIndex();
  121. //var zPlaceNames = drc_mapLayer1.getZIndex();
  122. //Waze.map.getLayersBy("uniqueName", "landmarks")[0].setZIndex(zPlaceNames);
  123. //drc_mapLayer1.setZIndex(zLandmarks);
  124. routeLayer = drc_mapLayer1;
  125. }
  126. else routeLayer = rlayers[0];
  127. routeLayer.removeAllFeatures();
  128. if (typeof Waze.model.venues == "undefined") {
  129. return;
  130. }
  131.  
  132. var showNames = routeLayer.getVisibility() && Waze.map.getLayersBy("uniqueName", "landmarks")[0].getVisibility();
  133. // if checkbox unticked, reset places to original style
  134. if (!showNames
  135. && !getId('_cbLandmarkColors').checked
  136. && !getId('_cbLandmarkHiliteNoName').checked) {
  137. for (var mark in Waze.model.venues.objects) {
  138. var venue = Waze.model.venues.get(mark);
  139. var poly = getId(venue.geometry.id);
  140. if (poly !== null) {
  141. if (poly.getAttribute("stroke-opacity") != 1) {
  142. poly.setAttribute("fill","#d191d6");
  143. poly.setAttribute("stroke","#d191d6");
  144. poly.setAttribute("fill-opacity",0.3);
  145. poly.setAttribute("stroke-opacity",1);
  146. }
  147. }
  148. }
  149. return;
  150. }
  151.  
  152. var specificCity = getId('_cbLandmarkHiliteNoName').checked;
  153. var colorLandmarks = getId('_cbLandmarkColors').checked;
  154. var showPoints = getId('_cbLandmarkPoints').checked;
  155. //var routeLayer = unsafeWindow.Waze.map.getLayersBy("uniqueName","landmarks")[0];
  156. //routeLayer.styleMap.styles.default = drc_style1;
  157.  
  158. for (var mark in Waze.model.venues.objects) {
  159. var venue = Waze.model.venues.get(mark);
  160. var poly = getId(venue.geometry.id);
  161. if (poly !== null && venue.geometry.toString().match(/^POLYGON/)) {
  162. venueStreet = Waze.model.streets.get(venue.attributes.streetID);
  163. selectedCityMatch = (venue.attributes.name.length == 0);
  164.  
  165. if(showNames && venue.attributes.name.length > 0)
  166. {
  167. // Add label texts
  168. var labelFeatures = [];
  169. var pt = new OpenLayers.Geometry.Point((venue.geometry.bounds.left + venue.geometry.bounds.right)/2, (venue.geometry.bounds.top + venue.geometry.bounds.bottom)/2);
  170. var closest =_.min(routeLayer.features, function(feature) {
  171. return feature.geometry.distanceTo(pt);
  172. });
  173. //console.log(closest);
  174. var wrappedText = wordWrap(venue.attributes.name, 30);
  175. var textFeature = new OpenLayers.Feature.Vector( pt, {labelText: wrappedText, fontColor: '#F0F0F0', pointRadius: 0 } );
  176. labelFeatures.push(textFeature);
  177. routeLayer.addFeatures(labelFeatures);
  178. //if(closest != Infinity && closest.geometry.bounds.intersectsBounds(textFeature.geometry.bounds))
  179. //{
  180. // routeLayer.removeFeatures(labelFeatures);
  181. //}
  182. }
  183. // Production polygons: #d191d6, Beta editor polygons: #c290c6
  184. if ((poly.getAttribute("fill") == "#d191d6" || poly.getAttribute("fill") == "#c290c6") && poly.getAttribute("stroke-opacity") == 1) {
  185. var categories = venue.attributes.categories;
  186.  
  187. if(colorLandmarks)
  188. {
  189. // gas station = orange
  190. if (categories.indexOf("GAS_STATION") > -1) {
  191. poly.setAttribute("fill","#f90");
  192. poly.setAttribute("stroke","#f90");
  193. }
  194. // parking lot = cyan
  195. else if (categories.indexOf("PARKING_LOT") > -1) {
  196. poly.setAttribute("fill","#099");
  197. poly.setAttribute("stroke","#0cc");
  198. }
  199. // water = blue
  200. else if (categories.indexOf("RIVER_STREAM") > -1 ||
  201. categories.indexOf("SEA_LAKE_POOL") > -1) {
  202. poly.setAttribute("fill","#09f");
  203. poly.setAttribute("stroke","#06c");
  204. }
  205. // park/grass/trees = green
  206. else if (categories.indexOf("PARK") > -1 ||
  207. categories.indexOf("FARM") > -1 ||
  208. categories.indexOf("FOREST_GROVE") > -1 ||
  209. categories.indexOf("GOLF_COURSE") > -1) {
  210. poly.setAttribute("fill","#4f4");
  211. poly.setAttribute("stroke","#6a6");
  212. }
  213. }
  214.  
  215. poly.setAttribute("stroke-opacity",0.97);
  216. // highlight places which have no name
  217. if (poly.getAttribute("fill") == "#d191d6" || poly.getAttribute("fill") == "#c290c6") {
  218. if (specificCity && selectedCityMatch) {
  219. poly.setAttribute("fill","#ff8");
  220. poly.setAttribute("stroke","#cc0");
  221. }
  222. }
  223. // if was yellow and now not yellow, reset
  224. else if (poly.getAttribute("fill") == "#ff8" && (!specificCity || !selectedCityMatch)) {
  225. poly.setAttribute("fill","#d191d6");
  226. poly.setAttribute("stroke","#d191d6");
  227. poly.setAttribute("stroke-opacity",1);
  228. }
  229. }
  230. }
  231. if(poly !== null && venue.geometry.toString().match(/^POINT/) && showPoints == true && showNames == true && venue.attributes.name.length > 0)
  232. {
  233. // Add label texts
  234. var labelFeatures = [];
  235. var pt = new OpenLayers.Geometry.Point(venue.geometry.x, venue.geometry.y);
  236. var wrappedText = wordWrap(venue.attributes.name, 30);
  237. var textFeature = new OpenLayers.Feature.Vector( pt, {labelText: wrappedText, fontColor: '#F0F0F0', pointRadius: 0 } );
  238. labelFeatures.push(textFeature);
  239. routeLayer.addFeatures(labelFeatures);
  240. }
  241. }
  242. }
  243.  
  244. function toggleOptions () {
  245. return false;
  246. }
  247.  
  248. /* helper function */
  249. function getElementsByClassName(classname, node) {
  250. if(!node) node = document.getElementsByTagName("body")[0];
  251. var a = [];
  252. var re = new RegExp('\\b' + classname + '\\b');
  253. var els = node.getElementsByTagName("*");
  254. for (var i=0,j=els.length; i<j; i++)
  255. if (re.test(els[i].className)) a.push(els[i]);
  256. return a;
  257. }
  258.  
  259. function getId(node) {
  260. return document.getElementById(node);
  261. }
  262.  
  263. /* =========================================================================== */
  264.  
  265. function initialiseLandmarkNames()
  266. {
  267. // global variables
  268. advancedMode = false;
  269. betaMode = location.hostname.match(/editor-beta.waze.com/);
  270. lastSelected = null;
  271. lastModified = false;
  272. selectedLines = [];
  273.  
  274. // add new box to left of the map
  275. var addon = document.createElement('section');
  276. addon.id = "landmarkname-addon";
  277.  
  278. if (navigator.userAgent.match(/Chrome/)) {
  279. addon.innerHTML = '<b>'
  280. + 'WME PlaceNames</b> &nbsp; v' + wmepn_version;
  281. } else {
  282. addon.innerHTML = '<b>'
  283. + 'WME PlaceNames</b> &nbsp; v' + wmepn_version;
  284. }
  285.  
  286. // highlight landmarks
  287. section = document.createElement('p');
  288. section.style.padding = "8px 16px";
  289. //section.style.textIndent = "-16px";
  290. section.id = "nameLandmarks";
  291. section.innerHTML = '<input type="checkbox" id="_cbLandmarkColors" /> <b>Color places</b><br>'
  292. + '<input type="checkbox" id="_cbLandmarkHiliteNoName" /> <b>Highlight places without name</b><br>'
  293. + '<input type="checkbox" id="_cbLandmarkPoints" /> <b>Include point place names</b><br>';
  294. addon.appendChild(section);
  295.  
  296. var userTabs = getId('user-info');
  297. var navTabs = getElementsByClassName('nav-tabs', userTabs)[0];
  298. var tabContent = getElementsByClassName('tab-content', userTabs)[0];
  299.  
  300. newtab = document.createElement('li');
  301. newtab.innerHTML = '<a href="#sidepanel-landmarknames" data-toggle="tab">PlaceNames</a>';
  302. navTabs.appendChild(newtab);
  303.  
  304. addon.id = "sidepanel-landmarknames";
  305. addon.className = "tab-pane";
  306. tabContent.appendChild(addon);
  307.  
  308. // setup onclick handlers for instant update:
  309. getId('_cbLandmarkColors').onclick = resetLandmarks;
  310. getId('_cbLandmarkHiliteNoName').onclick = resetLandmarks;
  311. getId('_cbLandmarkPoints').onclick = resetLandmarks;
  312.  
  313. // restore saved settings
  314. if (localStorage.WMELandmarkNamesScript) {
  315. console.log("WME LandmarkNames: loading options");
  316. options = JSON.parse(localStorage.WMELandmarkNamesScript);
  317.  
  318. getId('_cbLandmarkColors').checked = options[1];
  319. getId('_cbLandmarkHiliteNoName').checked = options[2];
  320. getId('_cbLandmarkPoints').checked = options[3];
  321. } else {
  322. getId('_cbLandmarkColors').checked = true;
  323. getId('_cbLandmarkHiliteNoName').checked = true;
  324. getId('_cbLandmarkPoints').checked = false;
  325. }
  326.  
  327. if (typeof Waze.model.venues == "undefined") {
  328. getId('_cbLandmarkColors').checked = false;
  329. getId('_cbLandmarkHiliteNoName').checked = false;
  330. getId('_cbLandmarkPoints').checked = false;
  331. getId('_cbLandmarkColors').disabled = true;
  332. getId('_cbLandmarkHiliteNoName').disabled = true;
  333. getId('_cbLandmarkPoints').disabled = true;
  334. }
  335.  
  336. // overload the WME exit function
  337. saveLandmarkNamesOptions = function() {
  338. if (localStorage) {
  339. console.log("WME LandmarkNames: saving options");
  340. var options = [];
  341.  
  342. // preserve previous options which may get lost after logout
  343. if (localStorage.WMELandmarkNamesScript)
  344. options = JSON.parse(localStorage.WMELandmarkNamesScript);
  345. options[1] = getId('_cbLandmarkColors').checked;
  346. options[2] = getId('_cbLandmarkHiliteNoName').checked;
  347. options[3] = getId('_cbLandmarkPoints').checked;
  348. localStorage.WMELandmarkNamesScript = JSON.stringify(options);
  349. }
  350. }
  351. window.addEventListener("beforeunload", saveLandmarkNamesOptions, false);
  352.  
  353. // begin periodic updates
  354. window.setInterval(showLandmarkNames,500);
  355.  
  356. // trigger code when page is fully loaded, to catch any missing bits
  357. window.addEventListener("load", function(e) {
  358. var mapProblems = getId('map-problems-explanation')
  359. if (mapProblems !== null) mapProblems.style.display = "none";
  360. });
  361.  
  362. // register some events...
  363. Waze.map.events.register("zoomend", null, showLandmarkNames);
  364. Waze.map.events.register("changelayer", null, showLandmarkNames);
  365. }
  366.  
  367. /* engage! =================================================================== */
  368. bootstrapLandmarkNames();
  369.  
  370. /* end ======================================================================= */

QingJ © 2025

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