WME Place Interface Enhancements

Enhancements to various Place interfaces

目前为 2017-01-16 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name WME Place Interface Enhancements
  3. // @namespace https://greasyfork.org/users/30701-justins83-waze
  4. // @version 0.7.1
  5. // @description Enhancements to various Place interfaces
  6. // @include https://www.waze.com/editor/*
  7. // @include https://www.waze.com/*/editor/*
  8. // @include https://beta.waze.com/*
  9. // @exclude https://www.waze.com/user/editor*
  10. // @author JustinS83
  11. // @grant none
  12. // @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
  13. // @license GPLv3
  14. // ==/UserScript==
  15. var UpdateObject, MultiAction;
  16.  
  17. (function() {
  18. 'use strict';
  19.  
  20. var settings = {};
  21. var placeMenuSelector = "#edit-buttons > div > div.toolbar-button.waze-icon-place.toolbar-submenu.toolbar-group.toolbar-group-venues.ItemInactive > menu";
  22. var pointStyle = {
  23. pointRadius: 6,
  24. fillOpacity: 0,
  25. strokeColor: '#00ece3',
  26. strokeWidth: '2',
  27. strokeLinecap: 'round'
  28. };
  29. var layerName = "WME PIE";
  30. var newPlaceLayer;
  31. var placementMode = false;
  32. var drawPoly;
  33.  
  34. // Your code here...
  35. function bootstrap(tries) {
  36. tries = tries || 1;
  37.  
  38. if (window.W &&
  39. window.W.map &&
  40. window.W.model &&
  41. $) {
  42. init();
  43. } else if (tries < 1000) {
  44. setTimeout(function () {bootstrap(tries++);}, 200);
  45. }
  46. }
  47.  
  48. bootstrap();
  49.  
  50. function init(){
  51. var $section = $("<div>", {style:"padding:8px 16px", id:"WMEPIESettings"});
  52. $section.html([
  53. '<h4><b>WME Place Interface Enhancements</b></h4>',
  54. '<div class="controls-container" id="divAreaPlaceSizeControls">',
  55. '<div id="divShowAreaPlaceSize" class="controls-container"><input type="checkbox" id="_cbShowAreaPlaceSize" class="pieSettingsCheckbox" /><label for="_cbShowAreaPlaceSize">Show area Place size</label></div>',
  56. '<div id="divShowAreaPlaceSizeImperial"class="controls-container" style="padding-left:30px;"><input type="checkbox" id="_cbShowAreaPlaceSizeImperial" class="pieSettingsCheckbox" disabled /><label for ="_cbShowAreaPlaceSizeImperial"> Show imperial </label></div>',
  57. '<div id="divShowAreaPlaceSizeMetric" class="controls-container" style="padding-left:30px;"><input type="checkbox" id="_cbShowAreaPlaceSizeMetric" class="pieSettingsCheckbox" disabled /><label for ="_cbShowAreaPlaceSizeMetric"> Show metric</label></div>',
  58. '</div>',
  59. '<div class="controls-container" id="divShowLockButtonsRPP" title="Displays lock level buttons for Residential Place Points"><input type="checkbox" id="_cbShowLockButtonsRPP" class="pieSettingsCheckbox" /><label for="_cbShowLockButtonsRPP">Show lock buttons for RPPs</label></div>',
  60. '<div class="controls-container" id="divShowPlaceLocatorCrosshair" title="Centers the Place on screen and zooms to the defined level" ><input type="checkbox" id="_cbShowPlaceLocatorCrosshair" class="pieSettingsCheckbox" /><label for="_cbShowPlaceLocatorCrosshair">Show Place locator crosshair</label></br>',
  61. '<span class="controls-container" style="padding-left:30px;" title="The zoom level to use when centering on a Place">Zoom <select id="piePlaceZoom"><option value="10">10</option><option value="9">9</option><option value="8">8</option><option value="7">7</option><option value="6">6</option><option value="5">5</option><option value="4">4</option><option value="3">3</option><option value="2">2</option><option value="1">1</option><option value="0">0</option></select></span></div>',
  62. '<b>New Places</b></br>',
  63. '<div id="divEditRPPAfterCreated" class="controls-container" title="Automatically opens the RPP address edit window and focuses on the House Number entry"><input type="checkbox" id="_cbEditRPPAfterCreated" class="pieSettingsCheckbox"><label for="_cbEditRPPAfterCreated">Edit RPP address after created</label></div>',
  64. '<div id="divUseStreetFromClosestSeg" class="controls-container" title="Pulls the street name from the closest visible segment and inserts into the new Place&quot;s address"><input type="checkbox" id="_cbUseStreetFromClosestSeg" class="pieSettingsCheckbox"><label for="_cbUseStreetFromClosestSeg">Use street name from closest segment</label></div>',
  65. '<div id="divUseCityFromClosestSeg" class="controls-container" title="Pulls the city name from the closest visible segment and inserts into the new Place&quot;s address"><input type="checkbox" id="_cbUseCityFromClosestSeg" class="pieSettingsCheckbox"><label for="_cbUseCityFromClosestSeg">Use city name from closest segment</label></div>',
  66. '<div id="divDefaultLockLevel" class="controls-container" style="left:8px;" title="The lock level to set automatically when creating new Places">Lock level <select id="pieDefaultLockLevel">' + buildLockLevelsList() + '</select></div>',
  67. '<div class="controls-container" id="divPlaceMenuCustomization">',
  68. '<b>Place Menu Customization</b></br>',
  69. buildItemOption(1),
  70. buildItemOption(2),
  71. buildItemOption(3),
  72. buildItemOption(4),
  73. buildItemOption(5),
  74. buildItemOption(6),
  75. buildItemOption(7),
  76. buildItemOption(8),
  77. buildItemOption(9),
  78. buildItemOption(10),
  79. buildItemOption(11),
  80. '</div>'
  81.  
  82. ].join(' '));
  83.  
  84. UpdateObject = require("Waze/Action/UpdateObject");
  85. MultiAction = require("Waze/Action/MultiAction");
  86.  
  87. newPlaceLayer = new OL.Layer.Vector(layerName,{displayInLayerSwitcher: false});
  88. W.map.addLayer(newPlaceLayer);
  89.  
  90. injectCss();
  91. new WazeWrap.Interface.Tab('PIE', $section.html(), init2);
  92. }
  93.  
  94. function buildNewPlaceList(){
  95. //Clear out the Places menu
  96. $('#edit-buttons > div > div.toolbar-button.waze-icon-place.toolbar-submenu.toolbar-group.toolbar-group-venues.ItemInactive > menu').empty();
  97. var cat = "";
  98. var i;
  99. for(i=0;i<11;i++){
  100. cat = $('#pieItem' + (i+1))[0].value;
  101. if(cat !== "PARKING_LOT" && cat !== "RESIDENCE_HOME")
  102. $(placeMenuSelector).append('<div class="toolbar-group-item WazeControlDrawFeature ItemInactive" id="piePlaceMainItem' + (i+1) + '" data-category="'+ cat + '"><span class="menu-title">' + $('#pieItem' + (i+1))[0].options[$('#pieItem' + (i+1))[0].selectedIndex].innerHTML + '</span><div class="drawing-controls"><span class="drawing-control polygon secondary-control" id="piePlaceAreaItem' + (i+1) + '" data-category="' + cat + '" title="Place (area)"></span><span class="drawing-control main-control point" id="piePlacePointItem' + (i+1) + '" data-category="' + cat + '" title="Place (point)"></span></div></div>');
  103. else{
  104. if(cat === "RESIDENCE_HOME") //force point
  105. $(placeMenuSelector).append('<div class="toolbar-group-item WazeControlDrawFeature ItemInactive" id="piePlaceMainItem' + (i+1) + '" data-category="'+ cat + '"><span class="menu-title">' + $('#pieItem' + (i+1))[0].options[$('#pieItem' + (i+1))[0].selectedIndex].innerHTML + '</span></div>');
  106. else //Parking lot - force area
  107. $(placeMenuSelector).append('<div class="toolbar-group-item WazeControlDrawFeature ItemInactive" id="piePlaceAreaItem' + (i+1) + '" data-category="'+ cat + '"><span class="menu-title">' + $('#pieItem' + (i+1))[0].options[$('#pieItem' + (i+1))[0].selectedIndex].innerHTML + '</span></div>');
  108. }
  109. }
  110.  
  111. $('[id^="piePlaceMainItem"]').click(function(e){
  112. startPlacementMode($('#' + this.id).data("category"), true);
  113. });
  114.  
  115. $('[id^="piePlaceAreaItem"]').click(function(e){
  116. e.stopPropagation();
  117. startPlacementMode($('#' + this.id).data("category"), false);
  118. });
  119. }
  120.  
  121. function init2(){
  122. //Load settings
  123. loadSettings();
  124. //Set up event handlers
  125. $('#_cbShowAreaPlaceSize').change(function() {
  126. if(this.checked) {
  127. attachPlaceSizeHandlers();
  128. updatePlaceSizeDisplay();
  129. $('#_cbShowAreaPlaceSizeImperial')[0].disabled = false;
  130. $('#_cbShowAreaPlaceSizeMetric')[0].disabled = false;
  131. }
  132. else
  133. {
  134. removePlaceSizeHandlers();
  135. $('#AreaSize').remove();
  136. $('#_cbShowAreaPlaceSizeImperial')[0].disabled = true;
  137. $('#_cbShowAreaPlaceSizeMetric')[0].disabled = true;
  138. }
  139. });
  140.  
  141. $('#_cbShowLockButtonsRPP').change(function() {
  142. if(this.checked) {
  143. attachRPPLockButtonHandlers();
  144. }
  145. else
  146. {
  147. $('#pieRPPLockButtonsContainer').remove();
  148. W.selectionManager.events.unregister("selectionchanged", null, addLockButtons);
  149. W.model.actionManager.events.unregister("afterundoaction",null, addLockButtons);
  150. W.model.actionManager.events.unregister("afterclearactions",null, addLockButtons);
  151. W.model.actionManager.events.unregister("afteraction",null, addLockButtons);
  152. }
  153. });
  154.  
  155. $('#_cbShowPlaceLocatorCrosshair').change(function(){
  156. if(this.checked){
  157. W.selectionManager.events.register("selectionchanged", null, ShowPlaceLocatorCrosshair);
  158. W.model.actionManager.events.register("afterundoaction",null, ShowPlaceLocatorCrosshair);
  159. W.model.actionManager.events.register("afterclearactions",null, ShowPlaceLocatorCrosshair);
  160. W.model.actionManager.events.register("afteraction",null, ShowPlaceLocatorCrosshair);
  161. }
  162. else{
  163. W.selectionManager.events.unregister("selectionchanged", null, ShowPlaceLocatorCrosshair);
  164. W.model.actionManager.events.unregister("afterundoaction",null, ShowPlaceLocatorCrosshair);
  165. W.model.actionManager.events.unregister("afterclearactions",null, ShowPlaceLocatorCrosshair);
  166. W.model.actionManager.events.unregister("afteraction",null, ShowPlaceLocatorCrosshair);
  167. }
  168. });
  169.  
  170. //Load settings to interface
  171. setChecked('_cbShowAreaPlaceSize', settings.ShowAreaPlaceSize);
  172. setChecked('_cbShowAreaPlaceSizeImperial', settings.ShowAreaPlaceSizeImperial);
  173. setChecked('_cbShowAreaPlaceSizeMetric', settings.ShowAreaPlaceSizeMetric);
  174. setChecked('_cbShowLockButtonsRPP', settings.ShowLockButtonsRPP);
  175. setChecked('_cbEditRPPAfterCreated', settings.EditRPPAfterCreated);
  176. setChecked('_cbUseStreetFromClosestSeg', settings.UseStreetFromClosestSeg);
  177. setChecked('_cbUseCityFromClosestSeg', settings.UseCityFromClosestSeg);
  178. setChecked('_cbShowPlaceLocatorCrosshair', settings.ShowPlaceLocatorCrosshair);
  179. $('#piePlaceZoom')[0].value = settings.PlaceZoom;
  180. $('#pieDefaultLockLevel')[0].value = settings.DefaultLockLevel;
  181.  
  182. if(settings.ShowAreaPlaceSize){
  183. $('#_cbShowAreaPlaceSizeImperial')[0].disabled = false;
  184. $('#_cbShowAreaPlaceSizeMetric')[0].disabled = false;
  185. attachPlaceSizeHandlers();
  186. }
  187.  
  188. if(settings.ShowPlaceLocatorCrosshair){
  189. W.selectionManager.events.register("selectionchanged", null, ShowPlaceLocatorCrosshair);
  190. W.model.actionManager.events.register("afterundoaction",null, ShowPlaceLocatorCrosshair);
  191. W.model.actionManager.events.register("afterclearactions",null, ShowPlaceLocatorCrosshair);
  192. W.model.actionManager.events.register("afteraction",null, ShowPlaceLocatorCrosshair);
  193. ShowPlaceLocatorCrosshair(); //in case the user opened a PL with a Place selected
  194. }
  195.  
  196. if(settings.ShowLockButtonsRPP)
  197. attachRPPLockButtonHandlers();
  198.  
  199. $('.pieSettingsCheckbox').change(function() {
  200. var settingName = $(this)[0].id.substr(3);
  201. settings[settingName] = this.checked;
  202. saveSettings();
  203. });
  204.  
  205. $('#piePlaceZoom').change(function(){
  206. var settingName = $(this)[0].id.substr(3);
  207. settings[settingName] = $(this)[0].value;
  208. saveSettings();
  209. });
  210.  
  211. $('#pieDefaultLockLevel').change(function(){
  212. settings[$(this)[0].id.substr(3)] = $(this)[0].value;
  213. saveSettings();
  214. });
  215.  
  216. var i;
  217. //Whenever a Place item is changed, read the settings and save to localStorage
  218. $('[id^="pieItem"]').change(function(){
  219. for(i=0;i<11;i++){
  220. settings.NewPlacesList[i] = $('#pieItem'+(i+1))[0].value;
  221. }
  222. saveSettings();
  223. buildNewPlaceList();
  224. });
  225.  
  226. //Load settings into Place Customization list options
  227. for(i=0; i<11;i++)
  228. $('#pieItem'+(i+1))[0].value = settings.NewPlacesList[i];
  229.  
  230. //Build our new menu
  231. buildNewPlaceList();
  232.  
  233. //new WazeWrap.Interface.Shortcut('Create Residential Place', 'Place Interface Enhancements', 'A+r', function(){startPlacementMode("RESIDENCE_HOME", true);}, this).add();
  234. }
  235.  
  236. var areaCategory = "";
  237. function startPlacementMode(category, isPoint){
  238. $('#edit-buttons > div > div.toolbar-button.waze-icon-place.toolbar-submenu.toolbar-group.toolbar-group-venues.ItemInactive').removeClass("open");
  239. if(isPoint){
  240. $("#map").on('mousemove', MouseMoveHandler);
  241. $("#map").click(function(){endPlacementMode(category, isPoint);});
  242. }
  243. else{
  244. areaCategory = category;
  245. var polyDrawFeatureOptions = {callbacks : {"done": doneHandler}};
  246. drawPoly = new OpenLayers.Control.DrawFeature(newPlaceLayer, OpenLayers.Handler.Polygon, polyDrawFeatureOptions);
  247. W.map.addControl(drawPoly);
  248. drawPoly.activate();
  249.  
  250. }
  251. document.addEventListener('keyup', keyUpHandler, false);
  252. }
  253.  
  254. function doneHandler(geom){
  255. drawPoly.destroy();
  256. createPlace(geom, areaCategory, false);
  257. }
  258.  
  259. function keyUpHandler(e){
  260. if (e.keyCode == 27){
  261. disablePlacementMode();
  262. if(drawPoly !== "undefined")
  263. drawPoly.destroy();
  264. }
  265. else if(e.keyCode == 90 && e.ctrlKey)
  266. drawPoly.undo();
  267. else if(e.keyCode == 89 && e.ctrlKey)
  268. drawPoly.redo();
  269. else if(e.keyCode == 13)
  270. drawPoly.finishSketch();
  271. }
  272.  
  273. function disablePlacementMode(){
  274. $("#map").off('click');//, endPlacementMode);
  275. $("#map").off('mousemove', MouseMoveHandler);
  276. clearLayer();
  277. document.removeEventListener('keyup', keyUpHandler);
  278. }
  279.  
  280. function endPlacementMode(category, isPoint){
  281. disablePlacementMode();
  282. createPlace(getMousePos900913(), category, isPoint);
  283. }
  284.  
  285. function getMousePos900913(){
  286. var mousePosition = $('.WazeControlMousePosition').text().split(" ");
  287. return WazeWrap.Geometry.ConvertTo900913(mousePosition[0], mousePosition[1]);
  288. }
  289.  
  290. function MouseMoveHandler(e){
  291. clearLayer();
  292. drawCircle(getMousePos900913());
  293. }
  294.  
  295. function clearLayer() {
  296. var layer = W.map.getLayersByName(layerName)[0];
  297. layer.removeAllFeatures();
  298. }
  299.  
  300. function drawCircle(e){
  301. var pointFeature = new OL.Feature.Vector(new OL.Geometry.Point(e.lon, e.lat), {}, pointStyle);
  302. W.map.getLayersByName(layerName)[0].addFeatures([pointFeature]);
  303. }
  304.  
  305. function createPlace(pos, category, isPoint){
  306. var PlaceObject = require("Waze/Feature/Vector/Landmark");
  307. var AddPlace = require("Waze/Action/AddLandmark");
  308. var multiaction = new MultiAction();
  309. multiaction.setModel(W.model);
  310.  
  311. var NewPlace = new PlaceObject();
  312. if(isPoint)
  313. NewPlace.geometry = new OL.Geometry.Point(pos.lon, pos.lat);
  314. else{
  315. var points = [];
  316. var i;
  317. for(i=0;i<pos.components[0].components.length;i++){
  318. points.push(new OL.Geometry.Point(pos.components[0].components[i].x, pos.components[0].components[i].y));
  319. }
  320. var ring = new OpenLayers.Geometry.LinearRing(points);
  321. NewPlace.geometry = new OL.Geometry.Polygon([ring]);
  322.  
  323. }
  324.  
  325. NewPlace.attributes.categories.push(category);
  326. if(category === "RESIDENCE_HOME"){
  327. NewPlace._originalResidential = true;
  328. NewPlace.attributes.residential = true;
  329. }
  330. NewPlace.attributes.lockRank = Number(settings.DefaultLockLevel);
  331.  
  332. var closestSeg = WazeWrap.Geometry.findClosestSegment(new OL.Geometry.Point(pos.lon, pos.lat));
  333.  
  334. W.model.actionManager.add(new AddPlace(NewPlace));
  335. Waze.selectionManager.select([NewPlace]);
  336.  
  337. if(closestSeg){ //if we were able to find a segment, try to pull the city and/or street name if the options are enabled
  338. var newAttributes, UpdateFeatureAddress = require('Waze/Action/UpdateFeatureAddress'), address = closestSeg.getAddress();
  339.  
  340. newAttributes = {
  341. countryID: address.country.id,
  342. stateID: address.state.id,
  343. emptyCity: address.city.attributes.name ? null : true,
  344. emptyStreet: address.street.name ? null : true
  345. };
  346.  
  347. if(settings.UseStreetFromClosestSeg)
  348. newAttributes.streetName = address.street.name;
  349. else
  350. newAttributes.emptyStreet = true;
  351.  
  352. if(settings.UseCityFromClosestSeg)
  353. newAttributes.cityName = address.city.attributes.name;
  354. else
  355. newAttributes.emptyCity = true;
  356.  
  357. multiaction.doSubAction(new UpdateFeatureAddress(NewPlace, newAttributes));
  358. W.model.actionManager.add(multiaction);
  359. }
  360. else
  361. console.log("WMEPIE - No segment found; cannot set street or city name.");
  362.  
  363. if(category === "RESIDENCE_HOME" && settings.EditRPPAfterCreated)
  364. editRPPAddress();
  365. }
  366.  
  367. function editRPPAddress(rppTries){
  368. rppTries = rppTries || 1;
  369.  
  370. if ($('.edit-button').length > 0) {
  371. $('.edit-button').trigger("click");
  372. $('.house-number:first').focus();
  373.  
  374. } else if (rppTries < 1000) {
  375. console.log("not found");
  376. setTimeout(function () {editRPPAddress(rppTries++);}, 200);
  377. }
  378. }
  379.  
  380. function buildItemOption(itemNumber){
  381. var $section = $("<div>", {style:"padding:8px 16px", id:"piePlaceCat" + itemNumber});
  382. $section.html([
  383. 'Item ',
  384. itemNumber,
  385. buildItemList(itemNumber),
  386. '</br>'
  387. ].join(' '));
  388.  
  389. return $section.html();
  390. }
  391.  
  392. function buildLockLevelsList(){
  393. var $lockLevels = $("<div>");
  394. for(var i=0;i<WazeWrap.User.Rank();i++){
  395. $lockLevels.append("<option value=" + i + ">" + (i+1) + "</option>");
  396. }
  397. return $lockLevels.html();
  398. }
  399.  
  400. function buildItemList(itemNumber){
  401.  
  402. var $places = $("<div>");
  403. $places.html([
  404. '<select id="pieItem' + itemNumber + '">',
  405. '<option value="CAR_SERVICES" style="font-weight:bold;">Car Services</option>',
  406. '<option value="GAS_STATION">Gas Station</option>',
  407. '<option value="GARAGE_AUTOMOTIVE_SHOP">Garage / Automotive Shop</option>',
  408. '<option value="CAR_WASH">Car Wash</option>',
  409. '<option value="CHARGING_STATION">Charging Station</option>',
  410. '<option value="TRANSPORTATION" style="font-weight:bold;">Transportation</option>',
  411. '<option value="AIRPORT">Airport</option>',
  412. '<option value="BUS_STATION">Bus Station</option>',
  413. '<option value="FERRY_PIER">Ferry Pier</option>',
  414. '<option value="SEAPORT_MARINA_HARBOR">Seaport / Marina / Harbor</option>',
  415. '<option value="SUBWAY_STATION">Subway Station</option>',
  416. '<option value="TRAIN_STATION">Train Station</option>',
  417. '<option value="BRIDGE">Bridge</option>',
  418. '<option value="TUNNEL">Tunnel</option>',
  419. '<option value="TAXI_STATION">Taxi Station</option>',
  420. '<option value="JUNCTION_INTERCHANGE">Junction / Interchange</option>',
  421. '<option value="PROFESSIONAL_AND_PUBLIC" style="font-weight:bold;">Professional and public</option>',
  422. '<option value="COLLEGE_UNIVERSITY">College / University</option>',
  423. '<option value="SCHOOL">School</option>',
  424. '<option value="CONVENTIONS_EVENT_CENTER">Conventions / Event Center</option>',
  425. '<option value="GOVERNMENT">Government</option>',
  426. '<option value="LIBRARY">Library</option>',
  427. '<option value="CITY_HALL">City Hall</option>',
  428. '<option value="ORGANIZATION_OR_ASSOCIATION">Organization or Association</option>',
  429. '<option value="PRISON_CORRECTIONAL_FACILITY">Prison / Correctional Facility</option>',
  430. '<option value="COURTHOUSE">Courthouse</option>',
  431. '<option value="CEMETERY">Cemetery</option>',
  432. '<option value="FIRE_DEPARTMENT">Fire Department</option>',
  433. '<option value="POLICE_STATION">Police Station</option>',
  434. '<option value="MILITARY">Military</option>',
  435. '<option value="HOSPITAL_MEDICAL_CARE">Hospital / Medical Care</option>',
  436. '<option value="OFFICES">Offices</option>',
  437. '<option value="POST_OFFICE">Post Office</option>',
  438. '<option value="RELIGIOUS_CENTER">Religious Center</option>',
  439. '<option value="KINDERGARTEN">Kindergarten</option>',
  440. '<option value="FACTORY_INDUSTRIAL">Factory / Industrial</option>',
  441. '<option value="EMBASSY_CONSULATE">Embassy / Consulate</option>',
  442. '<option value="INFORMATION_POINT">Information Point</option>',
  443. '<option value="EMERGENCY_SHELTER">Emergency Shelter</option>',
  444. '<option value="SHOPPING_AND_SERVICES" style="font-weight:bold;">Shopping and services</option>',
  445. '<option value="ARTS_AND_CRAFTS">Arts & Crafts</option>',
  446. '<option value="BANK_FINANCIAL">Bank / Financial</option>',
  447. '<option value="SPORTING_GOODS">Sporting Goods</option>',
  448. '<option value="BOOKSTORE">Bookstore</option>',
  449. '<option value="PHOTOGRAPHY">Photography</option>',
  450. '<option value="CAR_DEALERSHIP">Car Dealership</option>',
  451. '<option value="FASHION_AND_CLOTHING">Fashion and Clothing</option>',
  452. '<option value="CONVENIENCE_STORE">Convenience Store</option>',
  453. '<option value="PERSONAL_CARE">Personal Care</option>',
  454. '<option value="DEPARTMENT_STORE">Department Store</option>',
  455. '<option value="PHARMACY">Pharmacy</option>',
  456. '<option value="ELECTRONICS">Electronics</option>',
  457. '<option value="FLOWERS">Flowers</option>',
  458. '<option value="FURNITURE_HOME_STORE">Furniture / Home Store</option>',
  459. '<option value="GIFTS">Gifts</option>',
  460. '<option value="GYM_FITNESS">Gym / Fitness</option>',
  461. '<option value="SWIMMING_POOL">Swimming Pool</option>',
  462. '<option value="HARDWARE_STORE">Hardware Store</option>',
  463. '<option value="MARKET">Market</option>',
  464. '<option value="SUPERMARKET_GROCERY">Supermarket / Grocery</option>',
  465. '<option value="JEWELRY">Jewelry</option>',
  466. '<option value="LAUNDRY_DRY_CLEAN">Laundry / Dry Clean</option>',
  467. '<option value="SHOPPING_CENTER">Shopping Center</option>',
  468. '<option value="MUSIC_STORE">Music Store</option>',
  469. '<option value="PET_STORE_VETERINARIAN_SERVICES">Pet Store / Veterinarian Services</option>',
  470. '<option value="TOY_STORE">Toy Store</option>',
  471. '<option value="TRAVEL_AGENCY">Travel Agency</option>',
  472. '<option value="ATM">ATM</option>',
  473. '<option value="CURRENCY_EXCHANGE">Currency Exchange</option>',
  474. '<option value="CAR_RENTAL">Car Rental</option>',
  475. '<option value="FOOD_AND_DRINK" style="font-weight:bold;">Food and Drink</option>',
  476. '<option value="RESTAURANT">Restaurant</option>',
  477. '<option value="BAKERY">Bakery</option>',
  478. '<option value="DESSERT">Dessert</option>',
  479. '<option value="CAFE">Coffee shop</option>',
  480. '<option value="FAST_FOOD">Fast Food</option>',
  481. '<option value="FOOD_COURT">Food Court</option>',
  482. '<option value="BAR">Bar</option>',
  483. '<option value="ICE_CREAM">Ice Cream</option>',
  484. '<option value="CULTURE_AND_ENTERTAINEMENT" style="font-weight:bold;">Culture & Entertainment</option>',
  485. '<option value="ART_GALLERY">Art Gallery</option>',
  486. '<option value="CASINO">Casino</option>',
  487. '<option value="CLUB">Club</option>',
  488. '<option value="TOURIST_ATTRACTION_HISTORIC_SITE">Tourist Attraction / Historic Site</option>',
  489. '<option value="MOVIE_THEATER">Movie Theater</option>',
  490. '<option value="MUSEUM">Museum</option>',
  491. '<option value="MUSIC_VENUE">Music Venue</option>',
  492. '<option value="PERFORMING_ARTS_VENUE">Performing Arts Venue</option>',
  493. '<option value="GAME_CLUB">Game Club</option>',
  494. '<option value="STADIUM_ARENA">Stadium / Arena</option>',
  495. '<option value="THEME_PARK">Theme Park</option>',
  496. '<option value="ZOO_AQUARIUM">Zoo / Aquarium</option>',
  497. '<option value="RACING_TRACK">Racing Track</option>',
  498. '<option value="THEATER">Theater</option>',
  499. '<option value="OTHER" style="font-weight:bold;">Other</option>',
  500. '<option value="CONSTRUCTION_SITE">Construction Site</option>',
  501. '<option value="LODGING" style="font-weight:bold;">Lodging</option>',
  502. '<option value="HOTEL">Hotel</option>',
  503. '<option value="HOSTEL">Hostel</option>',
  504. '<option value="CAMPING_TRAILER_PARK">Camping / Trailer Park</option>',
  505. '<option value="COTTAGE_CABIN">Cottage / Cabin</option>',
  506. '<option value="BED_AND_BREAKFAST">Bed & Breakfast</option>',
  507. '<option value="OUTDOORS" style="font-weight:bold;">Outdoors</option>',
  508. '<option value="PARK">Park</option>',
  509. '<option value="PLAYGROUND">Playground</option>',
  510. '<option value="BEACH">Beach</option>',
  511. '<option value="SPORTS_COURT">Sports Court</option>',
  512. '<option value="GOLF_COURSE">Golf Course</option>',
  513. '<option value="PLAZA">Plaza</option>',
  514. '<option value="PROMENADE">Promenade</option>',
  515. '<option value="POOL">Pool</option>',
  516. '<option value="SCENIC_LOOKOUT_VIEWPOINT">Scenic Lookout / Viewpoint</option>',
  517. '<option value="SKI_AREA">Ski Area</option>',
  518. '<option value="NATURAL_FEATURES" style="font-weight:bold;">Natural Features</option>',
  519. '<option value="ISLAND">Island</option>',
  520. '<option value="SEA_LAKE_POOL">Sea / Lake / Pool</option>',
  521. '<option value="RIVER_STREAM">River / Stream</option>',
  522. '<option value="FOREST_GROVE">Forest / Grove</option>',
  523. '<option value="FARM">Farm</option>',
  524. '<option value="CANAL">Canal</option>',
  525. '<option value="SWAMP_MARSH">Swamp / Marsh</option>',
  526. '<option value="DAM">Dam</option>',
  527. '<option value="PARKING_LOT" style="font-weight:bold;">Parking Lot</option>',
  528. '<option value="RESIDENCE_HOME" style="font-weight:bold;">Residential</option>',
  529. '</select>'
  530. ].join(' '));
  531.  
  532. return $places.html();
  533. }
  534.  
  535. function attachRPPLockButtonHandlers(){
  536. $('#pieRPPLockButtonsContainer').remove();
  537. W.selectionManager.events.register("selectionchanged", null, addLockButtons);
  538. W.model.actionManager.events.register("afterundoaction",null, addLockButtons);
  539. W.model.actionManager.events.register("afterclearactions",null, addLockButtons);
  540. W.model.actionManager.events.register("afteraction",null, addLockButtons);
  541. }
  542.  
  543. function attachPlaceSizeHandlers(){
  544. W.selectionManager.events.register("selectionchanged", null, updatePlaceSizeDisplay);
  545. W.model.actionManager.events.register("afteraction",null, updatePlaceSizeDisplay);
  546. W.model.actionManager.events.register("afterundoaction",null, updatePlaceSizeDisplay);
  547. W.model.actionManager.events.register("afterclearactions",null, updatePlaceSizeDisplay);
  548. W.model.actionManager.events.register("noActions",null, noActions);
  549. updatePlaceSizeDisplay();
  550. }
  551.  
  552. function removePlaceSizeHandlers(){
  553. W.selectionManager.events.unregister("selectionchanged", null, updatePlaceSizeDisplay);
  554. W.model.actionManager.events.unregister("afteraction",null, updatePlaceSizeDisplay);
  555. W.model.actionManager.events.unregister("afterundoaction",null, updatePlaceSizeDisplay);
  556. W.model.actionManager.events.unregister("afterclearactions",null, updatePlaceSizeDisplay);
  557. W.model.actionManager.events.unregister("noActions",null, noActions);
  558. }
  559.  
  560. function ShowPlaceLocatorCrosshair(){
  561. $('#pieCrosshairs').remove();
  562. if(W.selectionManager.selectedItems.length > 0){
  563. if(W.selectionManager.selectedItems[0].model.type === "venue"){
  564. var panelWidth = $('#landmark-edit-general').width();
  565. var $crosshairs = $('<div style="float:right;z-index:100;cursor: pointer;" id="pieCrosshairs" title="Zoom and center on Place"><i class="fa fa-crosshairs fa-lg" aria-hidden="true"></i></div>');
  566. $('#landmark-edit-general > form > div:nth-child(1) > i').after($crosshairs);
  567. $('#pieCrosshairs').click(function(){
  568. CenterOnPlace(W.selectionManager.selectedItems[0].model, settings.PlaceZoom);
  569. });
  570. }
  571. }
  572. }
  573.  
  574. function CenterOnPlace(venue, zoom){
  575. var centroid = venue.geometry.getCentroid();
  576. W.map.setCenter([centroid.x, centroid.y], zoom);
  577. }
  578.  
  579. function isChecked(checkboxId) {
  580. return $('#' + checkboxId).is(':checked');
  581. }
  582.  
  583. function setChecked(checkboxId, checked) {
  584. $('#' + checkboxId).prop('checked', checked);
  585. }
  586.  
  587. function noActions(){
  588. setTimeout(updatePlaceSizeDisplay, 100 ); //have to put in a delay for when the user uses undo to clear all actions - WME updates on top of my changes otherwise.
  589. }
  590.  
  591. function updatePlaceSizeDisplay(){
  592. var count = W.selectionManager.selectedItems.length;
  593. var metersArea = 0;
  594. var bold = false;
  595. if(count === 1){
  596. var venue = W.selectionManager.selectedItems[0];
  597. var isArea = venue.geometry.toString().match(/^POLYGON/);
  598. //var isPoint = venue.geometry.toString().match(/^POINT/);
  599.  
  600. if(venue.model.type === "venue" && isArea){
  601. if($('#AreaSize'))
  602. $('#AreaSize').remove();
  603. metersArea = W.selectionManager.selectedItems[0].model.geometry.getGeodesicArea(W.map.getProjectionObject());
  604.  
  605. if(metersArea > 0 && isArea){
  606. var ftArea = Math.round(metersArea * 10.76391 *100)/100;
  607.  
  608. var list = $('#landmark-edit-general > ul')[0];
  609. var newList = document.createElement("UL");
  610. newList.id = "AreaSize";
  611.  
  612. var newItem = document.createElement("LI");
  613. if(isChecked("_cbShowAreaPlaceSizeMetric")){
  614. newItem.innerHTML = "Area: " + metersArea.toFixed(2) + " m<sup>2</sup>";
  615. newList.appendChild(newItem);
  616. }
  617.  
  618. if(isChecked("_cbShowAreaPlaceSizeImperial")){
  619. newItem = document.createElement("LI");
  620. newItem.innerHTML = "Area: " + ftArea.toFixed(2) + " ft<sup>2</sup>";
  621. newList.appendChild(newItem);
  622. }
  623. if(metersArea < 500){
  624. newItem = document.createElement("LI");
  625. newItem.innerHTML = "<span style='color:red; font-weight:bold;'>Places smaller than 500 m<sup>2</sup>/5382 ft<sup>2</sup> will not show in the client</span>";
  626. newList.appendChild(newItem);
  627. }
  628. if(list.before != null)
  629. list.before(newList);
  630. else{
  631. var parent = $('#landmark-edit-general > ul')[0].parentNode;
  632. parent.insertBefore(newList,$('#landmark-edit-general > ul')[0]);
  633. }
  634.  
  635. $('#AreaSize').addClass("list-unstyled");
  636. $('#AreaSize').addClass("additional-attributes");
  637. }
  638. }
  639. }
  640. }
  641.  
  642. function loadSettings() {
  643. var loadedSettings = $.parseJSON(localStorage.getItem("WMEPIE_Settings"));
  644. var defaultSettings = {
  645. ShowAreaPlaceSize: false,
  646. ShowAreaPlaceSizeImperial: false,
  647. ShowAreaPlaceSizeMetric: false,
  648. ShowLockButtonsRPP: true,
  649. NewPlacesList: W.Config.venues.categories.clone(),
  650. EditRPPAfterCreated: false,
  651. UseStreetFromClosestSeg: false,
  652. UseCityFromClosestSeg: false,
  653. ShowPlaceLocatorCrosshair: false,
  654. PlaceZoom: 6,
  655. DefaultLockLevel: 0
  656. };
  657. settings = loadedSettings ? loadedSettings : defaultSettings;
  658. for (var prop in defaultSettings) {
  659. if (!settings.hasOwnProperty(prop))
  660. settings[prop] = defaultSettings[prop];
  661. }
  662.  
  663. if(settings.ShowAreaPlaceSizeImperial === false && settings.ShowAreaPlaceSizeMetric === false)
  664. if(Waze.prefs.attributes.isImperial)
  665. settings.ShowAreaPlaceSizeImperial = true;
  666. else
  667. settings.ShowAreaPlaceSizeMetric = true;
  668. }
  669.  
  670. function saveSettings() {
  671. if (localStorage) {
  672. var localsettings = {
  673. ShowAreaPlaceSize: settings.ShowAreaPlaceSize,
  674. ShowAreaPlaceSizeImperial: settings.ShowAreaPlaceSizeImperial,
  675. ShowAreaPlaceSizeMetric: settings.ShowAreaPlaceSizeMetric,
  676. ShowLockButtonsRPP: settings.ShowLockButtonsRPP,
  677. NewPlacesList: settings.NewPlacesList,
  678. EditRPPAfterCreated: settings.EditRPPAfterCreated,
  679. UseStreetFromClosestSeg: settings.UseStreetFromClosestSeg,
  680. UseCityFromClosestSeg: settings.UseCityFromClosestSeg,
  681. ShowPlaceLocatorCrosshair: settings.ShowPlaceLocatorCrosshair,
  682. PlaceZoom: settings.PlaceZoom,
  683. DefaultLockLevel: settings.DefaultLockLevel
  684. };
  685.  
  686. localStorage.setItem("WMEPIE_Settings", JSON.stringify(localsettings));
  687. }
  688. }
  689.  
  690. //Using the same display for lock buttons as ClickSaver (with permission from MapoMatic) - thanks MoM!
  691. function addLockButtons() {
  692. if(W.selectionManager.selectedItems.length > 0){
  693. var item = W.selectionManager.selectedItems[0];
  694. var isRPP = (item.model.type === "venue" && item.model.attributes.residential === true);
  695.  
  696. if(isRPP){
  697. var attr = item.model.attributes;
  698. var autoRank = attr.rank;
  699. var manualRank = attr.lockRank;
  700. var firstManualRank = manualRank;
  701. var userRank = WazeWrap.User.Rank() - 1;
  702. var maxAutoRank = autoRank;
  703. var disabled = false;
  704.  
  705. var $div = $('#pieRPPLockButtonsContainer');
  706. $div.remove();
  707. $div = $('<div>',{id:'pieRPPLockButtonsContainer',style:'margin-bottom:5px;'});
  708. $div.append('<label class="control-label">Lock</label>');
  709. var btnInfos = [];
  710.  
  711. for(var iBtn=0;iBtn<=6;iBtn++){btnInfos.push({r:iBtn,val:iBtn});}
  712. btnInfos.forEach(function(btnInfo){
  713. console.log(typeof manualRank);
  714. console.log(typeof btnInfo.val);
  715. var selected = (btnInfo.val == manualRank);
  716. disabled = userRank < btnInfo.val;
  717. if (btnInfo.val !== 6) {
  718. $div.append(
  719. $('<div>', {
  720. class:'btn btn-lh' + (selected ? ' btn-lh-selected':'') + (btnInfo.r < 6 & (userRank < btnInfo.r || disabled) ? ' disabled' : '')
  721. })
  722. .text(btnInfo.hasOwnProperty('title') ? btnInfo.title : btnInfo.r + 1)
  723. .data('val',btnInfo.hasOwnProperty('val') ? btnInfo.val : btnInfo.r + 1)
  724. .hover(function() {})
  725. .click(function() {
  726. if((userRank >= $(this).data('val')) && (btnInfo.r < 6)) {
  727. W.model.actionManager.add(new UpdateObject(item.model,{lockRank:($(this).data('val'))}));
  728. addLockButtons();
  729. }
  730. })
  731. );
  732. }
  733. });
  734. $('#landmark-edit-general > div').after($div);
  735. }
  736. }
  737. }
  738.  
  739. function injectCss() {
  740. var css = [
  741. // Lock button formatting
  742. '.btn-lh {cursor:pointer;padding:1px 6px;height:22px;border:solid 1px #c1c1c1;margin-right:3px;}',
  743. '.btn.btn-lh.btn-lh-selected {background-color:#6999ae;color:white}',
  744. '.btn.btn-lh.btn-lh-selected:hover {color:white}',
  745. '.btn.btn-lh.disabled {color:#909090;background-color:#f7f7f7;}',
  746. '.btn.btn-lh.btn-lh-selected.disabled {color:white;background-color:#6999ae;}'
  747. ].join(' ');
  748. $('<style type="text/css">' + css + '</style>').appendTo('head');
  749. }
  750.  
  751. function listPlaces(){
  752. var category = "";
  753. for(i=0; i<W.Config.venues.categories.length; i++){
  754. category = W.Config.venues.categories[i];
  755. console.log(category + " Main");
  756. var subCategories = W.Config.venues.subcategories[category];
  757. for(var j=0; j<subCategories.length;j++){
  758. console.log(subCategories[j]);
  759. }
  760. }
  761. }
  762. })();