WME PlaceNames PLUS

Show area and point place names in WME, color and highlight places by type and properties (waze-ua fork)

  1. // ==UserScript==
  2. // @name WME PlaceNames PLUS
  3. // @version 2025.05.02.001
  4. // @description Show area and point place names in WME, color and highlight places by type and properties (waze-ua fork)
  5. // @match https://beta.waze.com/*editor*
  6. // @match https://www.waze.com/*editor*
  7. // @exclude https://www.waze.com/*user/*editor/*
  8. // @copyright Vinkoy, ragacs, waze-ua
  9. // @namespace https://greasyfork.org/uk/users/160654-waze-ukraine
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. /* jshint -W033 */
  14. /* jshint esversion: 11 */
  15.  
  16. /* global W */
  17. /* global $ */
  18. /* global OpenLayers */
  19. /* global require */
  20. /* global I18n */
  21.  
  22. // global variables
  23. var wmepn_NameLayer
  24. var wmepn_uniqueLayerName = '__PlaceNamesPlusLayer'
  25. var wmepn_scriptName = 'Place Names +'
  26.  
  27. var wmepn_translations = {
  28. 'en':
  29. {
  30. enable_script: 'Enable script',
  31. enable_script_tooltip: 'Toggle highlighting and place names layer\nUse the Layer selector or Shift+N hot key to toggle names only',
  32. color_places: 'Color places',
  33. color_places_tooltip: 'Color the places like WMECH does',
  34. highlight_places: 'Highlight places without name/HN',
  35. highlight_places_tooltip: 'Highlight public places without name and private places without house number (yellow)',
  36. highlight_address: 'Places without address',
  37. highlight_address_tooltip: 'Highlight places without street or house number (dashed green)',
  38. highlight_dif_address: 'The name doesn\'t match the house number',
  39. highlight_dif_address_tooltip: 'Check if the name matches the house number. Highlights (Other and Public places), where the name doesn\'t match the house number (dashed red)',
  40. highlight_small: 'Place area less than',
  41. highlight_small_tooltip: 'Highlight places area less than specified (red). Small places may not be visible in app',
  42. highlight_linked: 'Linked places',
  43. highlight_linked_tooltip: 'Highlight places linked to Google (cyan)',
  44. highlight_not_linked: 'Not linked places',
  45. highlight_not_linked_tooltip: 'Highlight places NOT linked to Google (cyan)',
  46. show_address: 'Show address',
  47. show_address_tooltip: 'Show address under the name',
  48. show: 'Show',
  49. show_tooltip: 'Select desired names to show',
  50. option_area: 'Area',
  51. option_point: 'POI',
  52. option_residential: 'Residential',
  53. option_comments: 'Comments',
  54. filter: 'Filter',
  55. filter_tooltip: 'Filter only the names containing this string (you could use regex e.g. /school/i)',
  56. show_locklevel: 'Show lock level',
  57. show_locklevel_tooltip: 'Display lock level after the name, like [L3] or [L4]',
  58. stop_over: 'Stop over',
  59. stop_over_tooltip: 'Limit displayed place names to the specified value',
  60. option_unlimited: 'Unlimited',
  61. show_zoom: 'Zoom',
  62. show_zoom_tooltip: 'Minimum zoom to display the names',
  63. showing: 'Showing',
  64. place_names_and: {
  65. one: 'place name and',
  66. other: 'place names and'
  67. },
  68. house_numbers: {
  69. one: 'house number',
  70. other: 'house numbers'
  71. },
  72. enable_disable_script: 'Enable/Disable script',
  73. increase_square_to: 'Increase POI square up to',
  74. increase_square_to_2: 'm² (minimal square to display in app)',
  75. square: 'Square',
  76. square_m_2: 'm²',
  77. hotkey: 'Hotkey',
  78. make: 'Make',
  79. translator: 'translated by [Your Waze Nickname]'
  80. },
  81. 'hu':
  82. {
  83. enable_script: 'Szkript engedélyezése',
  84. enable_script_tooltip: 'A színezés, kiemelés és a Helynevek réteg bekapcsolása\nHasználd a rétegválasztót vagy a Shift+N forróbillentyűt, ha csak a neveket akarod kapcsolgatni',
  85. color_places: 'Helyek színezése',
  86. color_places_tooltip: 'Helyek színezése, ahogyan a WMECH teszi',
  87. highlight_places: 'Név/hsz nélküli helyek kiemelése',
  88. highlight_places_tooltip: 'Kiemeli (sárgával) a névtelen nyilvános helyeket és a házszám nélküli magánházakat',
  89. show: 'Mutasd',
  90. show_tooltip: 'Válaszd ki a megmutatni kívánt neveket',
  91. option_area: 'Csak terület',
  92. option_point: 'Terület és pont',
  93. option_residential: 'Csak pont',
  94. filter: 'Szűrő',
  95. filter_tooltip: 'Csak azokat a neveket mutassa, amik ezt a szöveget tartalmazzák (reguláris kifejezések használhatók, pl. /iskola/i)',
  96. show_locklevel: 'Védelem mutatása',
  97. show_locklevel_tooltip: 'Mutassa a védelmi szintet is a név után, pl. [L3] vagy [L4]',
  98. stop_over: 'Maximum',
  99. stop_over_tooltip: 'A képernyőn egyszerre látható név-feliratok számát korlátozza',
  100. option_unlimited: 'Korlátlan',
  101. showing: 'Látható',
  102. place_names_and: 'helynév és',
  103. house_numbers: 'házszám',
  104. enable_disable_script: '[translate_me]',
  105. increase_square_to: '[translate_me]',
  106. increase_square_to_2: 'm² ([translate_me])',
  107. square: '[translate_me]',
  108. square_m_2: 'm²',
  109. hotkey: '[translate_me]',
  110. make: '[translate_me]',
  111. translator: 'fordította ragacs'
  112. },
  113. 'cs':
  114. {
  115. enable_script: 'Povolit skript',
  116. enable_script_tooltip: 'Přepínač zvýraznění a jmen míst\nPoužijte menu Vrstvy nebo klávesovou zkratku Shift+N, aby se zobrazila jen jména míst',
  117. color_places: 'Barevné odlišení',
  118. color_places_tooltip: 'Barevné odlišení jako WMECH',
  119. highlight_places: 'Odlišit nepojmenovaná místa',
  120. highlight_places_tooltip: 'Odlišit nepojmenovaná veřejná místa a soukromá místa bez čísla domu (žlutě)',
  121. show: 'Zobrazit',
  122. show_tooltip: 'Zobrazit požadovaná jména',
  123. option_area: 'Jen plochy',
  124. option_point: 'Plochy a body',
  125. option_residential: 'Jen body',
  126. filter: 'Filtr',
  127. filter_tooltip: 'Filtrovat jen jména obsahující tento řetězec (lze použít regex např. /škola/i)',
  128. show_locklevel: 'Ukázat zámek',
  129. show_locklevel_tooltip: 'Zobrazit zámek za jménem místa (např. [L3] nebo [L4])',
  130. stop_over: 'Omezení',
  131. stop_over_tooltip: 'Omezit zobrazená místa na zadanou hodnotu',
  132. option_unlimited: 'Bez omezení',
  133. showing: 'Zobrazení',
  134. place_names_and: 'jména míst a',
  135. house_numbers: 'čísla domů',
  136. enable_disable_script: '[translate_me]',
  137. increase_square_to: '[translate_me]',
  138. increase_square_to_2: 'm² ([translate_me])',
  139. square: '[translate_me]',
  140. square_m_2: 'm²',
  141. hotkey: '[translate_me]',
  142. make: '[translate_me]',
  143. translator: 'překládal bures'
  144. },
  145. 'nl':
  146. {
  147. enable_script: 'Script inschakelen',
  148. enable_script_tooltip: 'De laag voor het weergeven en markeren van plaatsnamen beheren\nGebruik de laagselector of Shift+N om enkel de namen te beheren',
  149. color_places: 'Voeg kleur toe aan plaatsen',
  150. color_places_tooltip: 'Kleur de plaatsen in zoals het WMECH-script dit doet',
  151. highlight_places: 'Markeer plaatsen zonder naam of huisnummer',
  152. highlight_places_tooltip: 'Markeer publieke plaatsen zonder naam en private plaatsen zonder huisnummer (geel)',
  153. show: 'Weergave',
  154. show_tooltip: 'Selecteer welke namen er moeten weergegeven worden',
  155. option_area: 'Enkel gebieden',
  156. option_point: 'Gebieden en punten',
  157. option_residential: 'Enkel punten',
  158. filter: 'Filter',
  159. filter_tooltip: 'Toon enkel de plaatsen met de volgende naam (je kan ook een regex gebruiken zoals /school/i)',
  160. show_locklevel: 'Lock-level weergeven',
  161. show_locklevel_tooltip: 'Geef het lock-level weer achter de naam als [L3] of [L4]',
  162. stop_over: 'Beperk aantal plaatsnamen',
  163. stop_over_tooltip: 'Beperk het aantal weergegeven plaatsnamen tot dit aantal',
  164. option_unlimited: 'Onbeperkt',
  165. showing: 'Huidige weergave: ',
  166. place_names_and: {
  167. one: 'plaatsnaam en',
  168. other: 'plaatsnamen en'
  169. },
  170. house_numbers: {
  171. one: 'huisnummer',
  172. other: 'huisnummers'
  173. },
  174. enable_disable_script: '[translate_me]',
  175. increase_square_to: '[translate_me]',
  176. increase_square_to_2: 'm² ([translate_me])',
  177. square: '[translate_me]',
  178. square_m_2: 'm²',
  179. hotkey: '[translate_me]',
  180. make: '[translate_me]',
  181. translator: 'vertaald door Glodenox'
  182. },
  183. 'uk':
  184. {
  185. enable_script: 'Увімкнути скрипт',
  186. enable_script_tooltip: 'Увімкнути підсвічування та відображення імен POI',
  187. color_places: 'Кольорові POI',
  188. color_places_tooltip: 'Відображати кольорові POI в залежності від їх типу',
  189. highlight_places: 'POI без імені',
  190. highlight_places_tooltip: 'Підсвічувати POI без імені (жовтий)',
  191. highlight_address: 'POI без адреси',
  192. highlight_address_tooltip: 'Підсвічувати POI, у яких не заповнені поля адреси: вулиця і номер будинку (зелений пунктир)',
  193. highlight_dif_address: 'Ім\'я не збігається з номером будинку',
  194. highlight_dif_address_tooltip: 'Перевірка відповідності імені контура з номером будинку в адресі. Підсвічує POI (Інше / контур будівлі та Громадське місце), у яких ім\'я не збігається з номером будинку в адресі (червоний пунктир)',
  195. highlight_small: 'POI з площею менше ',
  196. highlight_small_tooltip: 'Підсвічування POI з площею менше зазначеної (червоний). Маленькі POI можуть не відображатися в застосунку',
  197. highlight_linked: 'Лінковані POI',
  198. highlight_linked_tooltip: 'Підсвічувати POI, що мають прив\'язку до адреси Google (блакитний)',
  199. highlight_not_linked: 'Нелінковані POI',
  200. highlight_not_linked_tooltip: 'Підсвічувати POI, без прив\'язки до адреси Google (блакитний)',
  201. show_address: 'Відображати адресу POI',
  202. show_address_tooltip: 'Відображати адресу POI під ім\'ям',
  203. show: 'Відображати ім\'я (адресу)',
  204. show_tooltip: 'Вибрати для відображення імені',
  205. option_area: 'Області',
  206. option_point: 'Точкові POI',
  207. option_residential: 'АТ',
  208. option_comments: 'Коментарі',
  209. filter: 'Фільтр',
  210. filter_tooltip: 'Фільтр відображення в назві (можна використовувати regex, наприклад / школа/i)',
  211. show_locklevel: 'Відображати рівень блокування',
  212. show_locklevel_tooltip: 'Відображати рівень блокування після імені, наприклад, [L3] або [L4]',
  213. stop_over: 'Кількість відображуваних імен',
  214. stop_over_tooltip: 'Обмеження кількості відображуваних імен на карті',
  215. option_unlimited: 'Без обмеження',
  216. show_zoom: 'Масштаб ',
  217. show_zoom_tooltip: 'Мінімальний масштаб для відображення імен',
  218. showing: 'Відображається',
  219. place_names_and: 'імен POI та',
  220. house_numbers: 'АТ',
  221. enable_disable_script: 'Увімкнути/Вимкнути скрипт',
  222. increase_square_to: 'Збільшити площу POI до',
  223. increase_square_to_2: 'м² (мінімальна площа для відображення у застосунку)',
  224. square: 'Площа',
  225. square_m_2: 'м²',
  226. hotkey: 'Горяча клавіша',
  227. make: 'Зробити',
  228. translator: 'перекладено Vinkoy та waze-ua'
  229. },
  230. 'ru':
  231. {
  232. enable_script: 'Включить скрипт',
  233. enable_script_tooltip: 'Включить подсветку и отображение имен POI',
  234. color_places: 'Цветные POI',
  235. color_places_tooltip: 'Отображать цветные POI в зависимости от их типа',
  236. highlight_places: 'POI без имени',
  237. highlight_places_tooltip: 'Подсвечивать POI без имени (желтый)',
  238. highlight_address: 'POI без адреса',
  239. highlight_address_tooltip: 'Подсвечивать POI, у которых не заполнены поля адреса: улица и номер дома (зеленый пунктир)',
  240. highlight_dif_address: 'Имя не совпадает с номером дома',
  241. highlight_dif_address_tooltip: 'Проверка соответствия имени контура с номером дома в адресе. Подсвечивает POI (Другое/контур здания и Общественное место), у которых имя не совпадает с номером дома в адресе (красный пунктир)',
  242. highlight_small: 'POI с площадью менее',
  243. highlight_small_tooltip: 'Подсветка POI с площадью меньше указанной (красный). Маленькие POI могут не отображаться в приложении',
  244. highlight_linked: 'Линкованные POI',
  245. highlight_linked_tooltip: 'Подсвечивать POI, имеющие привязку к адресу Google (голубой)',
  246. highlight_not_linked: 'Нелинкованные POI',
  247. highlight_not_linked_tooltip: 'Подсвечивать POI, без привязки к адресу Google (голубой)',
  248. show_address: 'Отображать адрес POI',
  249. show_address_tooltip: 'Отображать адрес POI под именем',
  250. show: 'Отображать имя (адрес)',
  251. show_tooltip: 'Выбрать для отображения имени',
  252. option_area: 'Области',
  253. option_point: 'POI-точки',
  254. option_residential: 'ПТ',
  255. option_comments: 'Комментарии',
  256. filter: 'Фильтр',
  257. filter_tooltip: 'Фильтр отображения по имени (можно использовать regex, например /школа/i)',
  258. show_locklevel: 'Отображать уровень блокировки',
  259. show_locklevel_tooltip: 'Отображать уровень блокировки после имени, например, [L3] или [L4]',
  260. stop_over: 'Количество отображаемых имен',
  261. stop_over_tooltip: 'Ограничение количества отображаемых имен на карте',
  262. option_unlimited: 'Без ограничения',
  263. show_zoom: 'Масштаб',
  264. show_zoom_tooltip: 'Минимальный масштаб для отображения имен',
  265. showing: 'Отображается',
  266. place_names_and: 'имен POI и',
  267. house_numbers: 'ПТ',
  268. enable_disable_script: 'Включить/выключить скрипт',
  269. increase_square_to: 'Увеличить площадь POI до',
  270. increase_square_to_2: 'м² (минимальная площадь для отображения в приложении)',
  271. square: 'Площадь',
  272. square_m_2: 'м²',
  273. hotkey: 'Горячая клавиша',
  274. make: 'Сделать',
  275. translator: 'translated and modified by Vinkoy'
  276. }
  277. }
  278.  
  279. // Using parts from highlight and route speed scripts by various authors
  280.  
  281. /* bootstrap, will call initialiseLandmarkNames() */
  282. function bootstrapLandmarkNames() {
  283. /* begin running the code! */
  284. if (W?.userscripts?.state.isReady) {
  285. initialiseLandmarkNames();
  286. } else {
  287. document.addEventListener("wme-ready", initialiseLandmarkNames, {
  288. once: true
  289. });
  290. }
  291. }
  292.  
  293. function wmepn_wordWrap(str, maxWidth) {
  294. function testWhite(x) {
  295. var white = new RegExp(/^[ \t\r\n\f]$/) // We are not using \s because it matches non-breaking space too
  296. return white.test(x.charAt(0))
  297. }
  298.  
  299. var newLineStr = '\n'
  300. var done = false
  301. var res = ''
  302. do {
  303. var found = false
  304. // Inserts new line at first whitespace of the line
  305. for (let i = maxWidth - 1; i >= 0; i--) {
  306. if (testWhite(str.charAt(i))) {
  307. res = res + [str.slice(0, i), newLineStr].join('')
  308. str = str.slice(i + 1)
  309. found = true
  310. break
  311. }
  312. }
  313. // Inserts new line at maxWidth position, the word is too long to wrap
  314. if (!found && str.length > maxWidth) {
  315. res += [str.slice(0, maxWidth), newLineStr].join('')
  316. str = str.slice(maxWidth)
  317. }
  318.  
  319. if (str.length <= maxWidth) {
  320. res = res + str
  321. done = true
  322. }
  323. } while (!done)
  324.  
  325. return res
  326. }
  327.  
  328. function wmepn_addTextFeature(pt, wrappedText, showAddresses, yOffset, style, addressText, addrOffset) {
  329. var labelFeatures = []
  330. var attrs = {
  331. labelText: wrappedText,
  332. fontColor: '#F0F0F0',
  333. pointRadius: 0
  334. }
  335. if (yOffset) {
  336. attrs.yOffset = yOffset
  337. }
  338. if (style) {
  339. attrs.style = style
  340. }
  341. var textFeature = new OpenLayers.Feature.Vector(pt, attrs)
  342. labelFeatures.push(textFeature)
  343.  
  344. if (showAddresses) {
  345. var addrAttrs = {
  346. labelText: addressText,
  347. style: 'italic',
  348. pointRadius: 0
  349. }
  350. if (addrOffset) {
  351. addrAttrs.yOffset = addrOffset
  352. }
  353. var addrFeature = new OpenLayers.Feature.Vector(pt, addrAttrs)
  354. labelFeatures.push(addrFeature)
  355. }
  356. wmepn_NameLayer.addFeatures(labelFeatures)
  357. }
  358.  
  359. function wmepn_setDefaultVenuesAttributes(fill, stroke, fillOpacity, strokeOpacity, strokeDasharray) {
  360. let venues = W.model.venues
  361. for (let mark in venues.objects) {
  362. let poly = null
  363. if (W.map.venueLayer.featureMap.has(mark)) {
  364. let domID = W.map.venueLayer.featureMap.get(mark).geometry.id
  365. poly = wmepn_getId(domID)
  366. } else {
  367. let venue = venues.getObjectById(mark)
  368. poly = wmepn_getId(venue.getOLGeometry().id)
  369. }
  370. if (poly !== null) {
  371. if (poly.getAttribute('stroke-opacity') != 1) {
  372. poly.setAttribute('fill', fill)
  373. poly.setAttribute('stroke', stroke)
  374. poly.setAttribute('fill-opacity', fillOpacity)
  375. poly.setAttribute('stroke-opacity', strokeOpacity)
  376. poly.setAttribute('stroke-dasharray', strokeDasharray)
  377. }
  378. }
  379. }
  380. }
  381.  
  382. function wmepn_resetLandmarks() {
  383. wmepn_setDefaultVenuesAttributes('#d191d6', '#d191d6', 0.3, 1, 'none')
  384. wmepn_showLandmarkNames()
  385. }
  386.  
  387. function wmepn_showLandmarkNames() {
  388. wmepn_NameLayer.removeAllFeatures()
  389. if (typeof W.model.venues == 'undefined' || !wmepn_getId('_cbLandmarkNamesEnable') || wmepn_getId('_cbLandmarkNamesEnable').checked === false) {
  390. if (wmepn_getId('_stLandmarkNumber')) wmepn_getId('_stLandmarkNumber').innerHTML = 0
  391. if (wmepn_getId('_stLandmarkHNNumber')) wmepn_getId('_stLandmarkHNNumber').innerHTML = 0
  392. return
  393. }
  394. var venues = W.model.venues
  395. var streets = W.model.streets
  396. var showNames = wmepn_NameLayer.getVisibility() && W.map.getLayerByUniqueName('venues').getVisibility()
  397.  
  398. // if checkbox unticked, reset places to original style
  399. if (!showNames &&
  400. !wmepn_getId('_cbLandmarkColors').checked &&
  401. !wmepn_getId('_cbLandmarkhighlightNoName').checked &&
  402. !wmepn_getId('_cbLandmarkhighlightNoAddress').checked &&
  403. !wmepn_getId('_cbLandmarkhighlightDifHN').checked &&
  404. !wmepn_getId('_cbLandmarkhighlightSmall').checked) {
  405.  
  406. wmepn_setDefaultVenuesAttributes('#d191d6', '#d191d6', 0.3, 1, 'none')
  407.  
  408. wmepn_getId('_stLandmarkNumber').innerHTML = 0
  409. wmepn_getId('_stLandmarkHNNumber').innerHTML = 0
  410. return
  411. }
  412.  
  413. var highlightNoName = wmepn_getId('_cbLandmarkhighlightNoName').checked
  414. var colorLandmarks = wmepn_getId('_cbLandmarkColors').checked
  415. var highlightNoAddress = wmepn_getId('_cbLandmarkhighlightNoAddress').checked
  416. var highlightDifHN = wmepn_getId('_cbLandmarkhighlightDifHN').checked
  417. var highlightSmall = wmepn_getId('_cbLandmarkhighlightSmall').checked
  418. var highlightLinked = wmepn_getId('_cbShowLinked').checked
  419. var highlightNotLinked = wmepn_getId('_cbShowNotLinked').checked
  420. var showAddresses = wmepn_getId('_cbLandmarkShowAddresses').checked
  421. var minArea = wmepn_getId('_minArea').value
  422. var showPoints = wmepn_getId('_cbShowPoi').checked
  423. var showAreas = wmepn_getId('_cbShowArea').checked
  424. var showResidentials = wmepn_getId('_cbShowRH').checked
  425. var showComments = wmepn_getId('_cbShowComment').checked
  426. var showLockLevel = wmepn_getId('_cbLandmarkLockLevel').checked
  427. var limitNames = wmepn_getId('_seLandmarkLimit').value
  428. var nameFilterArray = wmepn_getId('_inLandmarkNameFilter').value.split('/')
  429. var nameFilter = (nameFilterArray.length > 1 ? nameFilterArray[1] : nameFilterArray[0])
  430. var nameFilterOptions = nameFilterArray[2]
  431. var nameFilterRegEx = (nameFilterArray.length > 1 ? new RegExp(nameFilter, nameFilterOptions) : null)
  432. var doFilter = function (name) {
  433. if (nameFilter.length === 0) {
  434. return true // show all when no filter entered
  435. }
  436. if (nameFilterRegEx === null) {
  437. return (name.indexOf(nameFilter) >= 0)
  438. } else {
  439. return nameFilterRegEx.test(name)
  440. }
  441. }
  442.  
  443. var drawnNames = 0
  444. var drawnHNs = 0
  445.  
  446. for (let mark in venues.objects) {
  447. let venue = venues.getObjectById(mark)
  448. let olGeom = venue.getOLGeometry()
  449. let isPoint = (olGeom.toString().match(/^POINT/) != null)
  450. let isArea = (olGeom.toString().match(/^POLYGON/) != null)
  451. let isRH = venue.attributes.residential
  452. let houseNumber = venue.attributes.houseNumber ? venue.attributes.houseNumber : ''
  453. let trimmedName = isRH ? houseNumber : venue.attributes.name.trim()
  454. let noTrName = (trimmedName.length === 0)
  455. if (showLockLevel) trimmedName += (noTrName ? '' : '\n') + '[L' + (venue.attributes.lockRank + 1) + ']'
  456.  
  457. let poly = null
  458. if (W.map.venueLayer.featureMap.has(mark)) {
  459. let domID = W.map.venueLayer.featureMap.get(mark).geometry.id
  460. poly = wmepn_getId(domID)
  461. } else {
  462. poly = wmepn_getId(olGeom.id)
  463. }
  464. if (poly !== null) {
  465. let venueStreet = streets.getObjectById(venue.attributes.streetID)
  466. let haveNoName = (isRH ? (houseNumber.length === 0) : noTrName)
  467. let hasHN = houseNumber !== '' && houseNumber != null
  468. let hasStreet = venueStreet != null && venueStreet.attributes.name != null && venueStreet.attributes.name !== ''
  469. let haveNoAddress = !hasHN || !hasStreet
  470.  
  471. if (showNames && (showAreas || showPoints || showResidentials) && (limitNames == 0 || drawnNames < limitNames) &&
  472. (W.map.zoom >= wmepn_getId('_zoomLevel').value)) {
  473.  
  474. let wrappedText = wmepn_wordWrap(trimmedName, 30)
  475. let addressText = ''
  476. let words = 1
  477.  
  478. if (showAddresses && (showAreas && isArea || showPoints && isPoint || showResidentials && isRH)) {
  479. // how many words in POI name (needed to determine offsetY below)
  480. words = wrappedText.replace(/\n/g, ' ') + ' '
  481. words = words.split(/\s* \s*/).length - 1
  482. addressText = hasStreet ? venueStreet.attributes.name.trim() : addressText
  483. addressText = hasHN ? (hasStreet ? (addressText + ', ' + houseNumber) : houseNumber) : addressText
  484. addressText = (addressText.length > 0) ? ('(' + addressText + ')') : addressText
  485. }
  486. let filterMatched = (!noTrName && doFilter(trimmedName)) || (hasHN && isRH && doFilter(houseNumber)) || (showAddresses && doFilter(addressText))
  487. let pt
  488. let addrOffset
  489. if (showAreas && isArea && filterMatched) {
  490. // Add label texts
  491. //var bounds = olGeom.bounds;
  492. //if(bounds.getWidth() * bounds.getHeight() * .3 > olGeom.getArea() && venue.attributes.entryExitPoints.length > 0)
  493. // pt = venue.attributes.entryExitPoints[0].point;
  494. //else
  495. pt = olGeom.getCentroid()
  496.  
  497. addrOffset = wmepn_getYoffset(words, wrappedText.length)
  498. wmepn_addTextFeature(pt, wrappedText, showAddresses, null, null, addressText, addrOffset)
  499.  
  500. drawnNames++
  501. }
  502.  
  503. pt = new OpenLayers.Geometry.Point(olGeom.x, olGeom.y)
  504. if (showPoints && isPoint && !isRH && filterMatched) {
  505. // Add label texts
  506. addrOffset = wmepn_getYoffset(words, wrappedText.length)
  507. wmepn_addTextFeature(pt, wrappedText, showAddresses, 15, null, addressText, addrOffset)
  508.  
  509. drawnNames++
  510. }
  511. if (showResidentials && isPoint && isRH && filterMatched) {
  512. // Add label texts
  513. wmepn_addTextFeature(pt, wrappedText, showAddresses, 15, 'italic', addressText, -15)
  514.  
  515. drawnHNs++
  516. }
  517. }
  518.  
  519. wmepn_getId('_stLandmarkNumber').innerHTML = drawnNames
  520. wmepn_getId('_stLandmarkHNNumber').innerHTML = drawnHNs
  521.  
  522. if (W.selectionManager.hasSelectedFeatures() && W.selectionManager.getSelectedFeatures()[0].featureType === 'venue') {
  523. let area_poi = wmepn_getId('WME.PlaceNames-Square')
  524. if (!area_poi) {
  525. let wcp = document.getElementsByClassName('additional-attributes list-unstyled')
  526. if (wcp && wcp.length > 0) {
  527. let li = document.createElement('LI')
  528. li.setAttribute('id', 'WME.PlaceNames-Square')
  529. wcp[0].appendChild(li)
  530. area_poi = wmepn_getId('WME.PlaceNames-Square')
  531. }
  532. }
  533.  
  534. if (area_poi) {
  535. let v_id = W.selectionManager.getSelectedDataModelObjects()[0].attributes.id
  536. let getv = W.model.venues.getObjectById(v_id)
  537. if (typeof getv === 'undefined' || typeof getv.getOLGeometry().getGeodesicArea === 'undefined') {
  538. area_poi.innerHTML = ''
  539. } else {
  540. let square = getv.getOLGeometry().getGeodesicArea(W.map.getProjectionObject())
  541. area_poi.style = (square < minArea) ? 'color: red;' : 'color: black;'
  542. area_poi.innerHTML = I18n.t('wmepn.square') + ': ' + square.toFixed(2) + ' ' +
  543. I18n.t('wmepn.square_m_2') + ' (<a href=\'#\' id=\'_modifyArea\' title=\'' +
  544. I18n.t('wmepn.hotkey') + ' "Y"\'>' + I18n.t('wmepn.make') + ' ~' + minArea + I18n.t('wmepn.square_m_2') + '</a>)'
  545. $('#_modifyArea').click(modifyArea)
  546. }
  547. }
  548. }
  549.  
  550. // Production polygons: #d191d6, Beta editor polygons: #c290c6
  551. if ((poly.getAttribute('fill') == '#d191d6' || poly.getAttribute('fill') == '#c290c6') && poly.getAttribute('stroke-opacity') == 1) {
  552. var categories = venue.attributes.categories
  553. var colored = false
  554.  
  555. if (colorLandmarks) {
  556. // gas station = orange
  557. if (categories.indexOf('GAS_STATION') > -1) {
  558. poly.setAttribute('fill', '#f90')
  559. poly.setAttribute('stroke', '#f90')
  560. colored = true
  561. }
  562. // parking lot = cyan
  563. else if (categories.indexOf('PARKING_LOT') > -1) {
  564. poly.setAttribute('fill', '#099')
  565. poly.setAttribute('stroke', '#0cc')
  566. colored = true
  567. }
  568. // water = blue
  569. else if (categories.indexOf('RIVER_STREAM') > -1 ||
  570. categories.indexOf('SEA_LAKE_POOL') > -1) {
  571. poly.setAttribute('fill', '#09f')
  572. poly.setAttribute('stroke', '#06c')
  573. colored = true
  574. }
  575. // park/grass/trees = green
  576. else if (categories.indexOf('PARK') > -1 ||
  577. categories.indexOf('FARM') > -1 ||
  578. categories.indexOf('FOREST_GROVE') > -1 ||
  579. categories.indexOf('GOLF_COURSE') > -1) {
  580. poly.setAttribute('fill', '#4f4')
  581. poly.setAttribute('stroke', '#6a6')
  582. colored = true
  583. }
  584. }
  585.  
  586. poly.setAttribute('stroke-opacity', 0.97)
  587. poly.setAttribute('stroke-dasharray', 'none')
  588.  
  589. var isNature = 0
  590. isNature = (
  591. (venue.attributes.categories[0] === 'PARKING_LOT') ||
  592. (venue.attributes.categories[0] === 'RIVER_STREAM') ||
  593. (venue.attributes.categories[0] === 'SEA_LAKE_POOL') ||
  594. (venue.attributes.categories[0] === 'PARK') ||
  595. (venue.attributes.categories[0] === 'FARM') ||
  596. (venue.attributes.categories[0] === 'FOREST_GROVE') ||
  597. (venue.attributes.categories[0] === 'GOLF_COURSE')
  598. )
  599.  
  600. // highlight places with place surface area less than _minArea
  601. if (highlightSmall && isArea && (W.map.zoom >= 3) &&
  602. (olGeom.getGeodesicArea(W.map.getProjectionObject()) < minArea)) {
  603. poly.setAttribute('fill', '#f00')
  604. poly.setAttribute('stroke', '#f00')
  605. }
  606. // then highlight places which have no name and not colored
  607. else if (highlightNoName && haveNoName && (colored === false)) {
  608. poly.setAttribute('fill', '#ff8')
  609. poly.setAttribute('stroke', '#cc0')
  610. }
  611. // if was yellow and now not yellow, reset
  612. else if (poly.getAttribute('fill') == '#ff8' && (!highlightNoName || !haveNoName)) {
  613. poly.setAttribute('fill', '#d191d6')
  614. poly.setAttribute('stroke', '#d191d6')
  615. poly.setAttribute('stroke-opacity', 1)
  616. }
  617.  
  618. // highlight places with linked Google address
  619. if (highlightLinked && venue.attributes.externalProviderIDs.length > 0) {
  620. poly.setAttribute('stroke', '#0ff')
  621. colored = true
  622. }
  623. // highlight places without linked Google address
  624. else if (highlightNotLinked && !isRH && venue.attributes.externalProviderIDs.length === 0) {
  625. poly.setAttribute('stroke', '#0ff')
  626. colored = true
  627. }
  628. // highlight places which have no address
  629. else if (highlightNoAddress && !isNature && haveNoAddress &&
  630. (W.map.zoom >= wmepn_getId('_zoomLevel').value)) {
  631. poly.setAttribute('stroke', '#0f0')
  632. poly.setAttribute('stroke-dasharray', '4 7')
  633. colored = true
  634. }
  635. // highlight places which have different name and HN
  636. else if (highlightDifHN && (colored == false) && (W.map.zoom >= wmepn_getId('_zoomLevel').value) && hasHN && !haveNoName &&
  637. ((venue.attributes.categories[0] === 'OTHER') || (venue.attributes.categories[0] === 'PROFESSIONAL_AND_PUBLIC')) &&
  638. (!(houseNumber == venue.attributes.name.trim() || houseNumber == venue.attributes.name.trim().split(',')[0]))) {
  639. poly.setAttribute('stroke', '#f00')
  640. poly.setAttribute('stroke-dasharray', '4 7')
  641. colored = true
  642. }
  643. }
  644. }
  645. }
  646. if (W.map.getLayerByUniqueName('mapComments')?.getVisibility()) {
  647. for (let mark in W.model.mapComments.objects) {
  648. let comment = W.model.mapComments.getObjectById(mark)
  649. let olGeom = comment.getOLGeometry()
  650. let isPoint = olGeom.toString().match(/^POINT/)
  651. let isArea = olGeom.toString().match(/^POLYGON/)
  652. let isComment = comment.type === 'mapComment'
  653. let trimmedName = comment.attributes.subject
  654. let noTrName = (trimmedName.length === 0)
  655. if (showLockLevel) trimmedName += (noTrName ? '' : '\n') + '[L' + (comment.attributes.lockRank + 1) + ']'
  656.  
  657. let poly = null
  658. if (W.map.commentLayer.featureMap.has(mark)) {
  659. let domID = W.map.commentLayer.featureMap.get(mark).geometry.id
  660. poly = wmepn_getId(domID)
  661. } else {
  662. poly = wmepn_getId(olGeom.id)
  663. }
  664. if (poly !== null) {
  665. if (showComments && (limitNames == 0 || drawnNames < limitNames) &&
  666. (W.map.zoom >= wmepn_getId('_zoomLevel').value)) {
  667. let wrappedText = wmepn_wordWrap(trimmedName, 30)
  668. let commentBody = ''
  669. let words = 1
  670. let commentsWords = 1
  671.  
  672. if (showAddresses && (showComments && isComment)) {
  673. // how many words in Comment subject (needed to determine offsetY below)
  674. words = wrappedText.replace(/\n/g, ' ') + ' '
  675. words = words.split(/\s* \s*/).length - 1
  676. commentBody = comment.attributes.body === '' || comment.attributes.body === 'undefined' ? commentBody : wmepn_wordWrap(comment.attributes.body, 30)
  677. commentsWords = commentBody.replace(/\n/g, ' ') + ' '
  678. commentsWords = commentsWords.split(/\s* \s*/).length - 1
  679. }
  680. let filterMatched = (!noTrName && doFilter(trimmedName)) || (showAddresses && doFilter(commentBody))
  681. if (showComments && ((showAreas && isArea) || (!showAreas && !showPoints)) && filterMatched) {
  682. // Add label texts
  683. //let bounds = olGeom.bounds;
  684. let pt = olGeom.getCentroid()
  685.  
  686. let offsetY = wmepn_getYoffset(words, wrappedText.length)
  687. offsetY += wmepn_getYoffset(commentsWords, commentBody.length)
  688.  
  689. wmepn_addTextFeature(pt, wrappedText, showAddresses, null, null, commentBody, offsetY)
  690.  
  691. drawnNames++
  692. }
  693.  
  694. if (showComments && ((showPoints && isPoint) || (!showAreas && !showPoints)) && filterMatched) {
  695. // Add label texts
  696. let pt = new OpenLayers.Geometry.Point(olGeom.x, olGeom.y)
  697.  
  698. let offsetY = wmepn_getYoffset(words, wrappedText.length)
  699. offsetY += wmepn_getYoffset(commentsWords, commentBody.length)
  700.  
  701. wmepn_addTextFeature(pt, wrappedText, showAddresses, 15, null, commentBody, offsetY)
  702.  
  703. drawnNames++
  704. }
  705. }
  706. }
  707. }
  708. }
  709. wmepn_getId('_stLandmarkNumber').innerHTML = '<i>' + drawnNames + '</i> ' + I18n.t('wmepn.place_names_and', { count: drawnNames })
  710. wmepn_getId('_stLandmarkHNNumber').innerHTML = '<i>' + drawnHNs + '</i> ' + I18n.t('wmepn.house_numbers', { count: drawnHNs })
  711. }
  712.  
  713. function wmepn_getYoffset(words, length) {
  714.  
  715. return (words == 1) ? (-12) : (((words > 1) &&
  716. (length < 60)) ? (-15) :
  717. (length < 90) ? (-20) :
  718. (length < 120) ? (-25) :
  719. (length < 150) ? (-30) :
  720. (length < 180) ? (-35) :
  721. (length < 210) ? (-40) :
  722. (length < 240) ? (-45) :
  723. (length < 270) ? (-50) : (-55))
  724. }
  725.  
  726. var modifyArea = function() {
  727. if (!W.selectionManager.hasSelectedFeatures() ||
  728. W.selectionManager.getSelectectionObjectType() !== 'venue' ||
  729. !W.selectionManager.getSelectedDataModelObjects()[0].isGeometryEditable()) {
  730. return
  731. }
  732.  
  733. var requiredArea = parseInt(wmepn_getId('_minArea').value, 10) + 5
  734. var selectedLandmark = W.selectionManager.getSelectedDataModelObjects()[0]
  735. var oldGeometry = selectedLandmark.getOLGeometry().clone()
  736. var newGeometry = selectedLandmark.getOLGeometry().clone()
  737. var centerPT = newGeometry.getCentroid()
  738. var oldArea = oldGeometry.getGeodesicArea(W.map.getProjectionObject())
  739.  
  740. var scale = Math.sqrt(requiredArea / oldArea)
  741. newGeometry.resize(scale, centerPT)
  742.  
  743. var wazeActionUpdateFeatureGeometry = require('Waze/Action/UpdateFeatureGeometry')
  744. var action = new wazeActionUpdateFeatureGeometry(selectedLandmark, W.model.venues, oldGeometry, newGeometry)
  745. W.model.actionManager.add(action)
  746. }
  747.  
  748. /* helper function */
  749. function wmepn_getId(node) {
  750. return document.getElementById(node)
  751. }
  752.  
  753. /* =========================================================================== */
  754.  
  755. async function initialiseLandmarkNames() {
  756. // Some internationalization
  757. I18n.translations[I18n.locale].wmepn = wmepn_translations[I18n.locale] === undefined ? wmepn_translations[I18n.defaultLocale] : wmepn_translations[I18n.locale]
  758. I18n.translations[I18n.locale].layers.name[wmepn_uniqueLayerName] = wmepn_scriptName
  759.  
  760. // add new box to left of the map
  761. var addon = document.createElement('section')
  762. var translator = I18n.defaultLocale == I18n.locale ? '' : 'title="' + I18n.t('wmepn.translator') + '"'
  763.  
  764. addon.id = 'landmarkname-addon'
  765. addon.innerHTML = '<b>' +
  766. '<a href="https://www.waze.com/forum/viewtopic.php?f=819&t=116843" target="_blank" ' +
  767. translator + '>' + GM_info.script.name + '</a></b> &nbsp; v' + GM_info.script.version
  768. if (wmepn_translations[I18n.locale] === undefined) {
  769. addon.innerHTML += ' <small>[<a href="https://www.waze.com/forum/viewtopic.php?f=819&t=116843&p=1302802#p1302802" target="_blank">translate me!</a>]</small>'
  770. }
  771.  
  772. // highlight landmarks
  773. var section = document.createElement('p')
  774. section.style.padding = '8px 16px'
  775. //section.style.textIndent = "-16px";
  776. section.id = 'nameLandmarks'
  777. section.innerHTML =
  778. '<div title="' + I18n.t('wmepn.enable_script_tooltip') + '"><input type="checkbox" id="_cbLandmarkNamesEnable" /> <b>' + I18n.t('wmepn.enable_script') + '</b></div>' +
  779. '<div title="' + I18n.t('wmepn.color_places_tooltip') + '"><input type="checkbox" id="_cbLandmarkColors" /> <b>' + I18n.t('wmepn.color_places') + '</b></div>' +
  780. '<div title="' + I18n.t('wmepn.highlight_places_tooltip') + '"><input type="checkbox" id="_cbLandmarkhighlightNoName"/> <b>' + I18n.t('wmepn.highlight_places') + '</b></div>' +
  781. '<div title="' + I18n.t('wmepn.highlight_address_tooltip') + '"><input type="checkbox" id="_cbLandmarkhighlightNoAddress"/> <b>' + I18n.t('wmepn.highlight_address') + '</b></div>' +
  782. '<div title="' + I18n.t('wmepn.highlight_dif_address_tooltip') + '"><input type="checkbox" id="_cbLandmarkhighlightDifHN"/> <b>' + I18n.t('wmepn.highlight_dif_address') + '</b></div>' +
  783. '<div title="' + I18n.t('wmepn.highlight_linked_tooltip') + '"><input type="checkbox" id="_cbShowLinked" /> <b>' + I18n.t('wmepn.highlight_linked') + '</b></div>' +
  784. '<div title="' + I18n.t('wmepn.highlight_not_linked_tooltip') + '"><input type="checkbox" id="_cbShowNotLinked" /> <b>' + I18n.t('wmepn.highlight_not_linked') + '</b></div>' +
  785. '<div title="' + I18n.t('wmepn.highlight_small_tooltip') + '"><input type="checkbox" id="_cbLandmarkhighlightSmall"/> <b>' + I18n.t('wmepn.highlight_small') +
  786. '</b><input id="_minArea" style="width: 40px;"/><b>' + I18n.t('wmepn.square_m_2') + '</b></div>' +
  787. '<div title="' + I18n.t('wmepn.show_address_tooltip') + '"><input type="checkbox" id="_cbLandmarkShowAddresses"/> <b>' + I18n.t('wmepn.show_address') + '</b></div>' +
  788. '<div title="' + I18n.t('wmepn.show_tooltip') + '"><b>' + I18n.t('wmepn.show') + ':</b></div>' +
  789. '<div title="' + I18n.t('wmepn.show') + ' ' + I18n.t('wmepn.option_area') + '" style="padding-left: 20px;"><input type="checkbox" id="_cbShowArea"> ' + I18n.t('wmepn.option_area') + '</div>' +
  790. '<div title="' + I18n.t('wmepn.show') + ' ' + I18n.t('wmepn.option_point') + '" style="padding-left: 20px;"><input type="checkbox" id="_cbShowPoi"> ' + I18n.t('wmepn.option_point') + '</div>' +
  791. '<div title="' + I18n.t('wmepn.show') + ' ' + I18n.t('wmepn.option_residential') + '" style="padding-left: 20px;"><input type="checkbox" id="_cbShowRH"> ' + I18n.t('wmepn.option_residential') + '</div>' +
  792. '<div title="' + I18n.t('wmepn.show') + ' ' + I18n.t('wmepn.option_comments') + '" style="padding-left: 20px;"><input type="checkbox" id="_cbShowComment"> ' + I18n.t('wmepn.option_comments') + '</div>' +
  793. '<div title="' + I18n.t('wmepn.filter_tooltip') + '"><b>' + I18n.t('wmepn.filter') + ':</b><input type="text" id="_inLandmarkNameFilter"/></div>' +
  794. '<div title="' + I18n.t('wmepn.show_locklevel_tooltip') + '"><input type="checkbox" id="_cbLandmarkLockLevel" /> <b>' + I18n.t('wmepn.show_locklevel') + '</b></div>' +
  795. '<div title="' + I18n.t('wmepn.stop_over_tooltip') + '"><b>' + I18n.t('wmepn.stop_over') + '</b> <select id="_seLandmarkLimit">' +
  796. '<option value="0">' + I18n.t('wmepn.option_unlimited') + '</option>' +
  797. '<option value="500">500</option>' +
  798. '<option value="200">200</option>' +
  799. '<option value="100">100</option>' +
  800. '<option value="50">50</option>' +
  801. '<option value="25">25</option>' +
  802. '<option value="10">10</option>' +
  803. '</select></div>' +
  804. '<div><small>' + I18n.t('wmepn.showing') + ' <span id="_stLandmarkNumber"></span> <span id="_stLandmarkHNNumber"></span></small></div>' +
  805. '<div title="' + I18n.t('wmepn.show_zoom_tooltip') + '"><b>' + I18n.t('wmepn.show_zoom') + '</b><input type="number" id="_zoomLevel"/></div>'
  806. addon.appendChild(section)
  807.  
  808. const { tabLabel, tabPane } = W.userscripts.registerSidebarTab("sidepanel-wmepn");
  809.  
  810. tabLabel.innerText = wmepn_scriptName;
  811. tabLabel.title = wmepn_scriptName;
  812.  
  813. tabPane.innerHTML = addon.innerHTML;
  814.  
  815. await W.userscripts.waitForElementConnected(tabPane);
  816. // setup onclick handlers for instant update:
  817. wmepn_getId('_cbLandmarkColors').onclick = wmepn_resetLandmarks
  818. wmepn_getId('_cbLandmarkhighlightNoName').onclick = wmepn_resetLandmarks
  819. wmepn_getId('_cbLandmarkhighlightNoAddress').onclick = wmepn_resetLandmarks
  820. wmepn_getId('_cbLandmarkhighlightDifHN').onclick = wmepn_resetLandmarks
  821. wmepn_getId('_cbLandmarkhighlightSmall').onclick = wmepn_resetLandmarks
  822. wmepn_getId('_cbLandmarkNamesEnable').onclick = wmepn_resetLandmarks
  823. wmepn_getId('_inLandmarkNameFilter').oninput = wmepn_showLandmarkNames
  824. wmepn_getId('_cbLandmarkLockLevel').onclick = wmepn_showLandmarkNames
  825. wmepn_getId('_seLandmarkLimit').onchange = wmepn_showLandmarkNames
  826. wmepn_getId('_zoomLevel').onchange = wmepn_resetLandmarks
  827. wmepn_getId('_cbLandmarkShowAddresses').onclick = wmepn_resetLandmarks
  828. wmepn_getId('_minArea').onchange = wmepn_resetLandmarks
  829. wmepn_getId('_cbShowArea').onclick = wmepn_resetLandmarks
  830. wmepn_getId('_cbShowPoi').onclick = wmepn_resetLandmarks
  831. wmepn_getId('_cbShowRH').onclick = wmepn_resetLandmarks
  832. wmepn_getId('_cbShowComment').onclick = wmepn_resetLandmarks
  833. wmepn_getId('_cbShowLinked').onclick = function () {
  834. if (wmepn_getId('_cbShowLinked').checked) {
  835. wmepn_getId('_cbShowNotLinked').checked = false
  836. }
  837. wmepn_resetLandmarks()
  838. }
  839. wmepn_getId('_cbShowNotLinked').onclick = function () {
  840. if (wmepn_getId('_cbShowNotLinked').checked) {
  841. wmepn_getId('_cbShowLinked').checked = false
  842. }
  843. wmepn_resetLandmarks()
  844. }
  845.  
  846. // Create PlaceName layer
  847. var rlayers = W.map.getLayersBy('uniqueName', wmepn_uniqueLayerName)
  848. if (rlayers.length == 0) {
  849. var lname = wmepn_scriptName
  850. var style = new OpenLayers.Style({
  851. strokeDashstyle: 'solid',
  852. strokeColor: '${strokeColor}',
  853. strokeOpacity: 1.0,
  854. strokeWidth: '${strokeWidth}',
  855. fillColor: '#0040FF',
  856. fillOpacity: 1.0,
  857. pointRadius: '${pointRadius}',
  858. label: '${labelText}',
  859. fontFamily: 'Tahoma, Courier New',
  860. labelOutlineColor: '#FFEEEE',
  861. labelOutlineWidth: 2,
  862. labelAlign: 'cm',
  863. fontColor: '#301130',
  864. fontOpacity: 1.0,
  865. fontSize: '11px',
  866. display: 'block',
  867. labelYOffset: '${yOffset}',
  868. fontStyle: '${style}'
  869. })
  870. var nameLayer = new OpenLayers.Layer.Vector(lname, {
  871. displayInLayerSwitcher: true,
  872. uniqueName: wmepn_uniqueLayerName,
  873. shortcutKey: 'S+n',
  874. accelerator: 'toggle' + lname.replace(/\s+/g, ''),
  875. styleMap: new OpenLayers.StyleMap(style),
  876. visibility: true
  877. })
  878. W.map.addLayer(nameLayer)
  879.  
  880. wmepn_NameLayer = nameLayer
  881. } else wmepn_NameLayer = rlayers[0]
  882.  
  883. // restore saved settings
  884. if (localStorage.WMELandmarkNamesScript) {
  885. console.log('WME PlaceNames: loading options')
  886. var options = JSON.parse(localStorage.WMELandmarkNamesScript)
  887.  
  888. wmepn_getId('_cbLandmarkColors').checked = options[1]
  889. wmepn_getId('_cbLandmarkhighlightNoName').checked = options[2]
  890. if (options[3] !== undefined)
  891. wmepn_getId('_cbShowArea').checked = options[3]
  892. wmepn_NameLayer.setVisibility(options[4])
  893. if (options[5] !== undefined)
  894. wmepn_getId('_cbLandmarkNamesEnable').checked = options[5]
  895. else wmepn_NameLayer.setVisibility(true)
  896. if (options[6] !== undefined)
  897. wmepn_getId('_inLandmarkNameFilter').value = options[6]
  898. if (options[7] !== undefined)
  899. wmepn_getId('_cbLandmarkLockLevel').checked = options[7]
  900. if (options[8] !== undefined)
  901. wmepn_getId('_seLandmarkLimit').value = options[8]
  902. else
  903. wmepn_getId('_seLandmarkLimit').value = 100
  904. if (options[9] !== undefined)
  905. wmepn_getId('_zoomLevel').value = options[9]
  906. else
  907. wmepn_getId('_zoomLevel').value = 17
  908. if (options[10] !== undefined)
  909. wmepn_getId('_cbLandmarkhighlightSmall').checked = options[10]
  910. if (options[11] !== undefined)
  911. wmepn_getId('_cbLandmarkhighlightNoAddress').checked = options[11]
  912. if (options[12] !== undefined)
  913. wmepn_getId('_cbLandmarkShowAddresses').checked = options[12]
  914. if (options[13] !== undefined)
  915. wmepn_getId('_cbLandmarkhighlightDifHN').checked = options[13]
  916. if (options[14] !== undefined)
  917. wmepn_getId('_minArea').value = options[14]
  918. else
  919. wmepn_getId('_minArea').value = 650
  920. if (options[15] !== undefined)
  921. wmepn_getId('_cbShowPoi').checked = options[15]
  922. if (options[16] !== undefined)
  923. wmepn_getId('_cbShowRH').checked = options[16]
  924. if (options[17] !== undefined)
  925. wmepn_getId('_cbShowLinked').checked = options[17]
  926. if (options[18] !== undefined)
  927. wmepn_getId('_cbShowNotLinked').checked = options[18]
  928. if (options[19] !== undefined)
  929. wmepn_getId('_cbShowComment').checked = options[19]
  930.  
  931. } else {
  932. wmepn_getId('_cbLandmarkColors').checked = true
  933. wmepn_getId('_cbLandmarkhighlightNoName').checked = true
  934. wmepn_getId('_cbLandmarkhighlightNoAddress').checked = true
  935. wmepn_getId('_cbLandmarkhighlightDifHN').checked = true
  936. wmepn_getId('_cbLandmarkhighlightSmall').checked = true
  937. wmepn_getId('_cbLandmarkShowAddresses').checked = true
  938. wmepn_getId('_cbShowArea').checked = true
  939. wmepn_getId('_cbShowPoi').checked = true
  940. wmepn_getId('_cbShowRH').checked = true
  941. wmepn_getId('_cbShowComment').checked = true
  942. wmepn_NameLayer.setVisibility(true)
  943. wmepn_getId('_cbLandmarkNamesEnable').checked = true
  944. wmepn_getId('_cbLandmarkLockLevel').checked = false
  945. wmepn_getId('_cbShowLinked').checked = false
  946. wmepn_getId('_cbShowNotLinked').checked = false
  947. wmepn_getId('_seLandmarkLimit').value = 100
  948. wmepn_getId('_zoomLevel').value = 17
  949. wmepn_getId('_minArea').value = 650
  950. }
  951.  
  952. // add layer to menu
  953. var $ul = $('.collapsible-GROUP_DISPLAY')
  954. var $li = document.createElement('li')
  955. var checkbox = document.createElement('wz-checkbox')
  956. checkbox.id = 'layer-switcher-item_placenames_plus'
  957. checkbox.className = 'hydrated'
  958. checkbox.type = 'checkbox'
  959. checkbox.checked = wmepn_NameLayer.getVisibility()
  960. checkbox.appendChild(document.createTextNode(wmepn_scriptName))
  961. checkbox.onclick = function () {
  962. wmepn_NameLayer.setVisibility(!wmepn_NameLayer.getVisibility())
  963. }
  964. $li.append(checkbox)
  965. $ul.append($li)
  966.  
  967. if (typeof W.model.venues == 'undefined') {
  968. wmepn_getId('_cbLandmarkColors').checked = false
  969. wmepn_getId('_cbLandmarkhighlightNoName').checked = false
  970. wmepn_getId('_cbLandmarkhighlightNoAddress').checked = false
  971. wmepn_getId('_cbLandmarkhighlightDifHN').checked = false
  972. wmepn_getId('_cbLandmarkhighlightSmall').checked = false
  973. wmepn_getId('_cbLandmarkShowAddresses').checked = false
  974. wmepn_getId('_cbLandmarkColors').disabled = true
  975. wmepn_getId('_cbLandmarkhighlightNoName').disabled = true
  976. wmepn_getId('_cbLandmarkhighlightNoAddress').disabled = true
  977. wmepn_getId('_cbLandmarkhighlightDifHN').disabled = true
  978. wmepn_getId('_cbLandmarkhighlightSmall').checked = true
  979. wmepn_getId('_cbShowArea').checked = true
  980. wmepn_getId('_cbShowPoi').checked = true
  981. wmepn_getId('_cbShowRH').checked = true
  982. wmepn_getId('_cbShowComment').checked = true
  983. wmepn_getId('_cbLandmarkLockLevel').disabled = true
  984. wmepn_getId('_cbShowLinked').disabled = true
  985. wmepn_getId('_cbShowNotLinked').disabled = true
  986. wmepn_getId('_seLandmarkLimit').disabled = true
  987. wmepn_getId('_cbLandmarkShowAddresses').checked = true
  988. }
  989.  
  990. // overload the WME exit function
  991. var wmepn_saveLandmarkNamesOptions = function () {
  992. if (localStorage) {
  993. console.log('WME PlaceNames: saving options')
  994. var options = []
  995.  
  996. // preserve previous options which may get lost after logout
  997. if (localStorage.WMELandmarkNamesScript) {
  998. options = JSON.parse(localStorage.WMELandmarkNamesScript)
  999. }
  1000.  
  1001. options[1] = wmepn_getId('_cbLandmarkColors').checked
  1002. options[2] = wmepn_getId('_cbLandmarkhighlightNoName').checked
  1003. options[3] = wmepn_getId('_cbShowArea').checked
  1004. options[4] = wmepn_NameLayer.getVisibility()
  1005. options[5] = wmepn_getId('_cbLandmarkNamesEnable').checked
  1006. options[6] = wmepn_getId('_inLandmarkNameFilter').value
  1007. options[7] = wmepn_getId('_cbLandmarkLockLevel').checked
  1008. options[8] = wmepn_getId('_seLandmarkLimit').value
  1009. options[9] = wmepn_getId('_zoomLevel').value
  1010. options[10] = wmepn_getId('_cbLandmarkhighlightSmall').checked
  1011. options[11] = wmepn_getId('_cbLandmarkhighlightNoAddress').checked
  1012. options[12] = wmepn_getId('_cbLandmarkShowAddresses').checked
  1013. options[13] = wmepn_getId('_cbLandmarkhighlightDifHN').checked
  1014. options[14] = wmepn_getId('_minArea').value
  1015. options[15] = wmepn_getId('_cbShowPoi').checked
  1016. options[16] = wmepn_getId('_cbShowRH').checked
  1017. options[17] = wmepn_getId('_cbShowLinked').checked
  1018. options[18] = wmepn_getId('_cbShowNotLinked').checked
  1019. options[19] = wmepn_getId('_cbShowComment').checked
  1020.  
  1021. localStorage.WMELandmarkNamesScript = JSON.stringify(options)
  1022. }
  1023. }
  1024. window.addEventListener('beforeunload', wmepn_saveLandmarkNamesOptions, false)
  1025.  
  1026. // trigger code when page is fully loaded, to catch any missing bits
  1027. window.addEventListener('load', function () {
  1028. var mapProblems = wmepn_getId('map-problems-explanation')
  1029. if (mapProblems !== null) mapProblems.style.display = 'none'
  1030. })
  1031.  
  1032. // register some events...
  1033. W.map.events.register('zoomend', null, wmepn_showLandmarkNames)
  1034. W.map.events.register('changelayer', null, wmepn_showLandmarkNames)
  1035. W.map.events.register('mouseout', null, wmepn_showLandmarkNames)
  1036. W.selectionManager.events.register('selectionchanged', null, wmepn_showLandmarkNames)
  1037.  
  1038. I18n.translations[I18n.locale].keyboard_shortcuts.groups['default'].members.WME_PlaceNames_enable =
  1039. I18n.t('wmepn.enable_disable_script') + ' ' + wmepn_scriptName
  1040. W.accelerators.addAction('WME_PlaceNames_enable', { group: 'default' })
  1041. W.accelerators.events.register('WME_PlaceNames_enable', null, enablePlaceNames)
  1042. W.accelerators._registerShortcuts({ 'S+n': 'WME_PlaceNames_enable' })
  1043.  
  1044. I18n.translations[I18n.locale].keyboard_shortcuts.groups['default'].members.WME_PlaceNames_increase =
  1045. I18n.t('wmepn.increase_square_to') + ' ' + wmepn_getId('_minArea').value.toString() + I18n.t('wmepn.increase_square_to_2')
  1046. W.accelerators.addAction('WME_PlaceNames_increase', { group: 'default' })
  1047. W.accelerators.events.register('WME_PlaceNames_increase', null, modifyArea)
  1048. W.accelerators._registerShortcuts({ 'y': 'WME_PlaceNames_increase' })
  1049. }
  1050.  
  1051. var enablePlaceNames = function() {
  1052. wmepn_getId('_cbLandmarkNamesEnable').click()
  1053. }
  1054.  
  1055. /* engage! =================================================================== */
  1056. bootstrapLandmarkNames()
  1057.  
  1058. /* end ======================================================================= */